disas: arm: QOMify target specific disas setup

Move the target_disas() ARM specifics to the QOM disas_set_info hook
and delete the ARM specific code in disas.c.

This has the extra advantage of the more fully featured target_disas()
implementation now applying to monitor_disas().

Currently, target_disas() has multi-endian, thumb and AArch64
support whereas the existing monitor_disas() support only has vanilla
AA32 support.

E.G. Running an AA64 linux kernel the following -d in_asm disas happens
(taget_disas()):

IN:
0x0000000040000000:  580000c0      ldr x0, pc+24 (addr 0x40000018)
0x0000000040000004:  aa1f03e1      mov x1, xzr

However before this patch, disasing the same from the monitor:

(qemu) xp/i 0x40000000
0x0000000040000000:  580000c0      stmdapl  r0, {r6, r7}

After this patch:
(qemu) xp/i 0x40000000
0x0000000040000000:  580000c0      ldr x0, pc+24 (addr 0x40000018)

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
This commit is contained in:
Peter Crosthwaite 2015-06-23 20:57:35 -07:00 committed by Andreas Färber
parent fb200d5f00
commit 484406200e
2 changed files with 35 additions and 32 deletions

32
disas.c
View File

@ -151,14 +151,6 @@ bfd_vma bfd_getb16 (const bfd_byte *addr)
return (bfd_vma) v;
}
#ifdef TARGET_ARM
static int
print_insn_thumb1(bfd_vma pc, disassemble_info *info)
{
return print_insn_arm(pc | 1, info);
}
#endif
static int print_insn_objdump(bfd_vma pc, disassemble_info *info,
const char *prefix)
{
@ -191,7 +183,6 @@ static int print_insn_od_target(bfd_vma pc, disassemble_info *info)
/* Disassemble this for me please... (debugging). 'flags' has the following
values:
i386 - 1 means 16 bit code, 2 means 64 bit code
arm - bit 0 = thumb, bit 1 = reverse endian, bit 2 = A64
ppc - bits 0:15 specify (optionally) the machine instruction set;
bit 16 indicates little endian.
other targets - unused
@ -231,27 +222,6 @@ void target_disas(FILE *out, CPUState *cpu, target_ulong code,
s.info.mach = bfd_mach_i386_i386;
}
s.info.print_insn = print_insn_i386;
#elif defined(TARGET_ARM)
if (flags & 4) {
/* We might not be compiled with the A64 disassembler
* because it needs a C++ compiler; in that case we will
* fall through to the default print_insn_od case.
*/
#if defined(CONFIG_ARM_A64_DIS)
s.info.print_insn = print_insn_arm_a64;
#endif
} else if (flags & 1) {
s.info.print_insn = print_insn_thumb1;
} else {
s.info.print_insn = print_insn_arm;
}
if (flags & 2) {
#ifdef TARGET_WORDS_BIGENDIAN
s.info.endian = BFD_ENDIAN_LITTLE;
#else
s.info.endian = BFD_ENDIAN_BIG;
#endif
}
#elif defined(TARGET_SPARC)
s.info.print_insn = print_insn_sparc;
#ifdef TARGET_SPARC64
@ -488,8 +458,6 @@ void monitor_disas(Monitor *mon, CPUState *cpu,
s.info.mach = bfd_mach_i386_i386;
}
s.info.print_insn = print_insn_i386;
#elif defined(TARGET_ARM)
s.info.print_insn = print_insn_arm;
#elif defined(TARGET_ALPHA)
s.info.print_insn = print_insn_alpha;
#elif defined(TARGET_SPARC)

View File

@ -382,6 +382,39 @@ static inline void unset_feature(CPUARMState *env, int feature)
env->features &= ~(1ULL << feature);
}
static int
print_insn_thumb1(bfd_vma pc, disassemble_info *info)
{
return print_insn_arm(pc | 1, info);
}
static void arm_disas_set_info(CPUState *cpu, disassemble_info *info)
{
ARMCPU *ac = ARM_CPU(cpu);
CPUARMState *env = &ac->env;
if (is_a64(env)) {
/* We might not be compiled with the A64 disassembler
* because it needs a C++ compiler. Leave print_insn
* unset in this case to use the caller default behaviour.
*/
#if defined(CONFIG_ARM_A64_DIS)
info->print_insn = print_insn_arm_a64;
#endif
} else if (env->thumb) {
info->print_insn = print_insn_thumb1;
} else {
info->print_insn = print_insn_arm;
}
if (env->bswap_code) {
#ifdef TARGET_WORDS_BIGENDIAN
info->endian = BFD_ENDIAN_LITTLE;
#else
info->endian = BFD_ENDIAN_BIG;
#endif
}
}
#define ARM_CPUS_PER_CLUSTER 8
static void arm_cpu_initfn(Object *obj)
@ -1368,6 +1401,8 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
cc->gdb_core_xml_file = "arm-core.xml";
cc->gdb_stop_before_watchpoint = true;
cc->debug_excp_handler = arm_debug_excp_handler;
cc->disas_set_info = arm_disas_set_info;
}
static void cpu_register(const ARMCPUInfo *info)