Commit 48440620 authored by Peter Crosthwaite's avatar Peter Crosthwaite Committed by Andreas Färber
Browse files

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: default avatarPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: default avatarPeter Crosthwaite <crosthwaite.peter@gmail.com>
Signed-off-by: default avatarAndreas Färber <afaerber@suse.de>
parent fb200d5f
Loading
Loading
Loading
Loading
+0 −32
Original line number Diff line number Diff line
@@ -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)
+35 −0
Original line number Diff line number Diff line
@@ -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)