@@ -4480,6 +4480,28 @@ struct arm_insn_reloc_data
struct regcache *regs;
};
+struct arm_insn_reloc_visitor
+{
+ int (*alu_imm) (uint32_t insn, struct arm_insn_reloc_data *data);
+ int (*alu_reg) (uint32_t insn, struct arm_insn_reloc_data *data);
+ int (*alu_shifted_reg) (uint32_t insn, struct arm_insn_reloc_data *data);
+ int (*b_bl_blx) (uint32_t insn, struct arm_insn_reloc_data *data);
+ int (*block_xfer) (uint32_t insn, struct arm_insn_reloc_data *data);
+ int (*bx_blx_reg) (uint32_t insn, struct arm_insn_reloc_data *data);
+ int (*copro_load_store) (uint32_t insn, struct arm_insn_reloc_data *data);
+ int (*extra_ld_st) (uint32_t insn, struct arm_insn_reloc_data *data,
+ int unprivileged);
+ int (*ldr_str_ldrb_strb) (uint32_t insn, struct arm_insn_reloc_data *data,
+ int load, int size, int usermode);
+ int (*others) (uint32_t insn, const char *iname,
+ struct arm_insn_reloc_data *data);
+ int (*preload) (uint32_t insn, struct arm_insn_reloc_data *data);
+ int (*preload_reg) (uint32_t insn, struct arm_insn_reloc_data *data);
+ int (*svc) (uint32_t insn, struct arm_insn_reloc_data *data);
+ int (*undef) (uint32_t insn, struct arm_insn_reloc_data *data);
+ int (*unpred) (uint32_t insn, struct arm_insn_reloc_data *data);
+};
+
/* Helper for register reads for displaced stepping. In particular, this
returns the PC as it would be seen by the instruction at its original
location. */
@@ -6462,91 +6484,94 @@ arm_copy_unpred (uint32_t insn, struct arm_insn_reloc_data *data)
the presentation in the ARM ARM. */
static int
-arm_decode_misc_memhint_neon (uint32_t insn, struct arm_insn_reloc_data *data)
+arm_decode_misc_memhint_neon (uint32_t insn,
+ struct arm_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data)
{
unsigned int op1 = bits (insn, 20, 26), op2 = bits (insn, 4, 7);
unsigned int rn = bits (insn, 16, 19);
if (op1 == 0x10 && (op2 & 0x2) == 0x0 && (rn & 0xe) == 0x0)
- return arm_copy_unmodified (insn, "cps", data);
+ return visitor->others (insn, "cps", data);
else if (op1 == 0x10 && op2 == 0x0 && (rn & 0xe) == 0x1)
- return arm_copy_unmodified (insn, "setend", data);
+ return visitor->others (insn, "setend", data);
else if ((op1 & 0x60) == 0x20)
- return arm_copy_unmodified (insn, "neon dataproc", data);
+ return visitor->others (insn, "neon dataproc", data);
else if ((op1 & 0x71) == 0x40)
- return arm_copy_unmodified (insn, "neon elt/struct load/store", data);
+ return visitor->others (insn, "neon elt/struct load/store", data);
else if ((op1 & 0x77) == 0x41)
- return arm_copy_unmodified (insn, "unallocated mem hint", data);
+ return visitor->others (insn, "unallocated mem hint", data);
else if ((op1 & 0x77) == 0x45)
- return arm_copy_preload (insn, data); /* pli. */
+ return visitor->preload (insn, data); /* pli. */
else if ((op1 & 0x77) == 0x51)
{
if (rn != 0xf)
- return arm_copy_preload (insn, data); /* pld/pldw. */
+ return visitor->preload (insn, data); /* pld/pldw. */
else
- return arm_copy_unpred (insn, data);
+ return visitor->unpred (insn, data);
}
else if ((op1 & 0x77) == 0x55)
- return arm_copy_preload (insn, data); /* pld/pldw. */
+ return visitor->preload (insn, data); /* pld/pldw. */
else if (op1 == 0x57)
switch (op2)
{
- case 0x1: return arm_copy_unmodified (insn, "clrex", data);
- case 0x4: return arm_copy_unmodified (insn, "dsb", data);
- case 0x5: return arm_copy_unmodified (insn, "dmb", data);
- case 0x6: return arm_copy_unmodified (insn, "isb", data);
- default: return arm_copy_unpred (insn, data);
+ case 0x1: return visitor->others (insn, "clrex", data);
+ case 0x4: return visitor->others (insn, "dsb", data);
+ case 0x5: return visitor->others (insn, "dmb", data);
+ case 0x6: return visitor->others (insn, "isb", data);
+ default: return visitor->unpred (insn, data);
}
else if ((op1 & 0x63) == 0x43)
- return arm_copy_unpred (insn, data);
+ return visitor->unpred (insn, data);
else if ((op2 & 0x1) == 0x0)
switch (op1 & ~0x80)
{
case 0x61:
- return arm_copy_unmodified (insn, "unallocated mem hint", data);
+ return visitor->others (insn, "unallocated mem hint", data);
case 0x65:
- return arm_copy_preload_reg (insn, data); /* pli reg. */
+ return visitor->preload_reg (insn, data); /* pli reg. */
case 0x71: case 0x75:
/* pld/pldw reg. */
- return arm_copy_preload_reg (insn, data);
+ return visitor->preload_reg (insn, data);
case 0x63: case 0x67: case 0x73: case 0x77:
- return arm_copy_unpred (insn, data);
+ return visitor->unpred (insn, data);
default:
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
}
else
- return arm_copy_undef (insn, data); /* Probably unreachable. */
+ return visitor->undef (insn, data); /* Probably unreachable. */
}
static int
-arm_decode_unconditional (uint32_t insn, struct arm_insn_reloc_data *data)
+arm_decode_unconditional (uint32_t insn, struct arm_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data)
{
if (bit (insn, 27) == 0)
- return arm_decode_misc_memhint_neon (insn, data);
+ return arm_decode_misc_memhint_neon (insn, visitor, data);
/* Switch on bits: 0bxxxxx321xxx0xxxxxxxxxxxxxxxxxxxx. */
else switch (((insn & 0x7000000) >> 23) | ((insn & 0x100000) >> 20))
{
case 0x0: case 0x2:
- return arm_copy_unmodified (insn, "srs", data);
+ return visitor->others (insn, "srs", data);
case 0x1: case 0x3:
- return arm_copy_unmodified (insn, "rfe", data);
+ return visitor->others (insn, "rfe", data);
case 0x4: case 0x5: case 0x6: case 0x7:
- return arm_copy_b_bl_blx (insn, data);
+ return visitor->b_bl_blx (insn, data);
case 0x8:
switch ((insn & 0xe00000) >> 21)
{
case 0x1: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7:
/* stc/stc2. */
- return arm_copy_copro_load_store (insn, data);
+ return visitor->copro_load_store (insn, data);
case 0x2:
- return arm_copy_unmodified (insn, "mcrr/mcrr2", data);
+ return visitor->others (insn, "mcrr/mcrr2", data);
default:
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
}
case 0x9:
@@ -6556,53 +6581,54 @@ arm_decode_unconditional (uint32_t insn, struct arm_insn_reloc_data *data)
{
case 0x1: case 0x3:
/* ldc/ldc2 imm (undefined for rn == pc). */
- return rn_f ? arm_copy_undef (insn, data)
- : arm_copy_copro_load_store (insn, data);
+ return rn_f ? visitor->undef (insn, data)
+ : visitor->copro_load_store (insn, data);
case 0x2:
- return arm_copy_unmodified (insn, "mrrc/mrrc2", data);
+ return visitor->others (insn, "mrrc/mrrc2", data);
case 0x4: case 0x5: case 0x6: case 0x7:
/* ldc/ldc2 lit (undefined for rn != pc). */
- return rn_f ? arm_copy_copro_load_store (insn, data)
- : arm_copy_undef (insn, data);
+ return rn_f ? visitor->copro_load_store (insn, data)
+ : visitor->undef (insn, data);
default:
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
}
}
case 0xa:
- return arm_copy_unmodified (insn, "stc/stc2", data);
+ return visitor->others (insn, "stc/stc2", data);
case 0xb:
if (bits (insn, 16, 19) == 0xf)
/* ldc/ldc2 lit. */
- return arm_copy_copro_load_store (insn, data);
+ return visitor->copro_load_store (insn, data);
else
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
case 0xc:
if (bit (insn, 4))
- return arm_copy_unmodified (insn, "mcr/mcr2", data);
+ return visitor->others (insn, "mcr/mcr2", data);
else
- return arm_copy_unmodified (insn, "cdp/cdp2", data);
+ return visitor->others (insn, "cdp/cdp2", data);
case 0xd:
if (bit (insn, 4))
- return arm_copy_unmodified (insn, "mrc/mrc2", data);
+ return visitor->others (insn, "mrc/mrc2", data);
else
- return arm_copy_unmodified (insn, "cdp/cdp2", data);
+ return visitor->others (insn, "cdp/cdp2", data);
default:
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
}
}
/* Decode miscellaneous instructions in dp/misc encoding space. */
static int
-arm_decode_miscellaneous (uint32_t insn, struct arm_insn_reloc_data *data)
+arm_decode_miscellaneous (uint32_t insn, struct arm_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data)
{
unsigned int op2 = bits (insn, 4, 6);
unsigned int op = bits (insn, 21, 22);
@@ -6610,81 +6636,83 @@ arm_decode_miscellaneous (uint32_t insn, struct arm_insn_reloc_data *data)
switch (op2)
{
case 0x0:
- return arm_copy_unmodified (insn, "mrs/msr", data);
+ return visitor->others (insn, "mrs/msr", data);
case 0x1:
if (op == 0x1) /* bx. */
- return arm_copy_bx_blx_reg (insn, data);
+ return visitor->bx_blx_reg (insn, data);
else if (op == 0x3)
- return arm_copy_unmodified (insn, "clz", data);
+ return visitor->others (insn, "clz", data);
else
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
case 0x2:
if (op == 0x1)
- /* Not really supported. */
- return arm_copy_unmodified (insn, "bxj", data);
+ /* Not really supported. */
+ return visitor->others (insn, "bxj", data);
else
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
case 0x3:
if (op == 0x1)
- return arm_copy_bx_blx_reg (insn, data); /* blx register. */
+ return visitor->bx_blx_reg (insn, data); /* blx register. */
else
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
case 0x5:
- return arm_copy_unmodified (insn, "saturating add/sub", data);
+ return visitor->others (insn, "saturating add/sub", data);
case 0x7:
if (op == 0x1)
- return arm_copy_unmodified (insn, "bkpt", data);
+ return visitor->others (insn, "bkpt", data);
else if (op == 0x3)
- /* Not really supported. */
- return arm_copy_unmodified (insn, "smc", data);
+ /* Not really supported. */
+ return visitor->others (insn, "smc", data);
default:
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
}
}
static int
-arm_decode_dp_misc (uint32_t insn, struct arm_insn_reloc_data *data)
+arm_decode_dp_misc (uint32_t insn, struct arm_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data)
{
if (bit (insn, 25))
switch (bits (insn, 20, 24))
{
case 0x10:
- return arm_copy_unmodified (insn, "movw", data);
+ return visitor->others (insn, "movw", data);
case 0x14:
- return arm_copy_unmodified (insn, "movt", data);
+ return visitor->others (insn, "movt", data);
- case 0x12: case 0x16:
- return arm_copy_unmodified (insn, "msr imm", data);
+ case 0x12:
+ case 0x16:
+ return visitor->others (insn, "msr imm", data);
default:
- return arm_copy_alu_imm (insn, data);
+ return visitor->alu_imm (insn, data);
}
else
{
uint32_t op1 = bits (insn, 20, 24), op2 = bits (insn, 4, 7);
if ((op1 & 0x19) != 0x10 && (op2 & 0x1) == 0x0)
- return arm_copy_alu_reg (insn, data);
+ return visitor->alu_reg (insn, data);
else if ((op1 & 0x19) != 0x10 && (op2 & 0x9) == 0x1)
- return arm_copy_alu_shifted_reg (insn, data);
+ return visitor->alu_shifted_reg (insn, data);
else if ((op1 & 0x19) == 0x10 && (op2 & 0x8) == 0x0)
- return arm_decode_miscellaneous (insn, data);
+ return arm_decode_miscellaneous (insn, visitor, data);
else if ((op1 & 0x19) == 0x10 && (op2 & 0x9) == 0x8)
- return arm_copy_unmodified (insn, "halfword mul/mla", data);
+ return visitor->others (insn, "halfword mul/mla", data);
else if ((op1 & 0x10) == 0x00 && op2 == 0x9)
- return arm_copy_unmodified (insn, "mul/mla", data);
+ return visitor->others (insn, "mul/mla", data);
else if ((op1 & 0x10) == 0x10 && op2 == 0x9)
- return arm_copy_unmodified (insn, "synch", data);
+ return visitor->others (insn, "synch", data);
else if (op2 == 0xb || (op2 & 0xd) == 0xd)
/* 2nd arg means "unprivileged". */
- return arm_copy_extra_ld_st (insn, data, (op1 & 0x12) == 0x02);
+ return visitor->extra_ld_st (insn, data, (op1 & 0x12) == 0x02);
}
/* Should be unreachable. */
@@ -6692,89 +6720,92 @@ arm_decode_dp_misc (uint32_t insn, struct arm_insn_reloc_data *data)
}
static int
-arm_decode_ld_st_word_ubyte (uint32_t insn, struct arm_insn_reloc_data *data)
+arm_decode_ld_st_word_ubyte (uint32_t insn,
+ struct arm_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data)
{
int a = bit (insn, 25), b = bit (insn, 4);
uint32_t op1 = bits (insn, 20, 24);
if ((!a && (op1 & 0x05) == 0x00 && (op1 & 0x17) != 0x02)
|| (a && (op1 & 0x05) == 0x00 && (op1 & 0x17) != 0x02 && !b))
- return arm_copy_ldr_str_ldrb_strb (insn, data, 0, 4, 0);
+ return visitor->ldr_str_ldrb_strb (insn, data, 0, 4, 0);
else if ((!a && (op1 & 0x17) == 0x02)
|| (a && (op1 & 0x17) == 0x02 && !b))
- return arm_copy_ldr_str_ldrb_strb (insn, data, 0, 4, 1);
+ return visitor->ldr_str_ldrb_strb (insn, data, 0, 4, 1);
else if ((!a && (op1 & 0x05) == 0x01 && (op1 & 0x17) != 0x03)
|| (a && (op1 & 0x05) == 0x01 && (op1 & 0x17) != 0x03 && !b))
- return arm_copy_ldr_str_ldrb_strb (insn, data, 1, 4, 0);
+ return visitor->ldr_str_ldrb_strb (insn, data, 1, 4, 0);
else if ((!a && (op1 & 0x17) == 0x03)
|| (a && (op1 & 0x17) == 0x03 && !b))
- return arm_copy_ldr_str_ldrb_strb (insn, data, 1, 4, 1);
+ return visitor->ldr_str_ldrb_strb (insn, data, 1, 4, 1);
else if ((!a && (op1 & 0x05) == 0x04 && (op1 & 0x17) != 0x06)
|| (a && (op1 & 0x05) == 0x04 && (op1 & 0x17) != 0x06 && !b))
- return arm_copy_ldr_str_ldrb_strb (insn, data, 0, 1, 0);
+ return visitor->ldr_str_ldrb_strb (insn, data, 0, 1, 0);
else if ((!a && (op1 & 0x17) == 0x06)
|| (a && (op1 & 0x17) == 0x06 && !b))
- return arm_copy_ldr_str_ldrb_strb (insn, data, 0, 1, 1);
+ return visitor->ldr_str_ldrb_strb (insn, data, 0, 1, 1);
else if ((!a && (op1 & 0x05) == 0x05 && (op1 & 0x17) != 0x07)
|| (a && (op1 & 0x05) == 0x05 && (op1 & 0x17) != 0x07 && !b))
- return arm_copy_ldr_str_ldrb_strb (insn, data, 1, 1, 0);
+ return visitor->ldr_str_ldrb_strb (insn, data, 1, 1, 0);
else if ((!a && (op1 & 0x17) == 0x07)
|| (a && (op1 & 0x17) == 0x07 && !b))
- return arm_copy_ldr_str_ldrb_strb (insn, data, 1, 1, 1);
+ return visitor->ldr_str_ldrb_strb (insn, data, 1, 1, 1);
/* Should be unreachable. */
return 1;
}
static int
-arm_decode_media (uint32_t insn, struct arm_insn_reloc_data *data)
+arm_decode_media (uint32_t insn, struct arm_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data)
{
switch (bits (insn, 20, 24))
{
case 0x00: case 0x01: case 0x02: case 0x03:
- return arm_copy_unmodified (insn, "parallel add/sub signed", data);
+ return visitor->others (insn, "parallel add/sub signed", data);
case 0x04: case 0x05: case 0x06: case 0x07:
- return arm_copy_unmodified (insn, "parallel add/sub unsigned", data);
+ return visitor->others (insn, "parallel add/sub unsigned", data);
case 0x08: case 0x09: case 0x0a: case 0x0b:
case 0x0c: case 0x0d: case 0x0e: case 0x0f:
- return arm_copy_unmodified (insn,
- "decode/pack/unpack/saturate/reverse", data);
+ return visitor->others (insn, "decode/pack/unpack/saturate/reverse",
+ data);
case 0x18:
if (bits (insn, 5, 7) == 0) /* op2. */
{
if (bits (insn, 12, 15) == 0xf)
- return arm_copy_unmodified (insn, "usad8", data);
+ return visitor->others (insn, "usad8", data);
else
- return arm_copy_unmodified (insn, "usada8", data);
+ return visitor->others (insn, "usada8", data);
}
else
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
case 0x1a: case 0x1b:
if (bits (insn, 5, 6) == 0x2) /* op2[1:0]. */
- return arm_copy_unmodified (insn, "sbfx", data);
+ return visitor->others (insn, "sbfx", data);
else
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
case 0x1c: case 0x1d:
if (bits (insn, 5, 6) == 0x0) /* op2[1:0]. */
{
if (bits (insn, 0, 3) == 0xf)
- return arm_copy_unmodified (insn, "bfc", data);
+ return visitor->others (insn, "bfc", data);
else
- return arm_copy_unmodified (insn, "bfi", data);
+ return visitor->others (insn, "bfi", data);
}
else
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
case 0x1e: case 0x1f:
if (bits (insn, 5, 6) == 0x2) /* op2[1:0]. */
- return arm_copy_unmodified (insn, "ubfx", data);
+ return visitor->others (insn, "ubfx", data);
else
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
}
/* Should be unreachable. */
@@ -6782,37 +6813,39 @@ arm_decode_media (uint32_t insn, struct arm_insn_reloc_data *data)
}
static int
-arm_decode_b_bl_ldmstm (uint32_t insn, struct arm_insn_reloc_data *data)
+arm_decode_b_bl_ldmstm (uint32_t insn, struct arm_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data)
{
if (bit (insn, 25))
- return arm_copy_b_bl_blx (insn, data);
+ return visitor->b_bl_blx (insn, data);
else
- return arm_copy_block_xfer (insn, data);
+ return visitor->block_xfer (insn, data);
}
static int
-arm_decode_ext_reg_ld_st (uint32_t insn, struct arm_insn_reloc_data *data)
+arm_decode_ext_reg_ld_st (uint32_t insn, struct arm_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data)
{
unsigned int opcode = bits (insn, 20, 24);
switch (opcode)
{
case 0x04: case 0x05: /* VFP/Neon mrrc/mcrr. */
- return arm_copy_unmodified (insn, "vfp/neon mrrc/mcrr", data);
+ return visitor->others (insn, "vfp/neon mrrc/mcrr", data);
case 0x08: case 0x0a: case 0x0c: case 0x0e:
case 0x12: case 0x16:
- return arm_copy_unmodified (insn, "vfp/neon vstm/vpush", data);
+ return visitor->others (insn, "vfp/neon vstm/vpush", data);
case 0x09: case 0x0b: case 0x0d: case 0x0f:
case 0x13: case 0x17:
- return arm_copy_unmodified (insn, "vfp/neon vldm/vpop", data);
+ return visitor->others (insn, "vfp/neon vldm/vpop", data);
case 0x10: case 0x14: case 0x18: case 0x1c: /* vstr. */
case 0x11: case 0x15: case 0x19: case 0x1d: /* vldr. */
/* Note: no writeback for these instructions. Bit 25 will always be
zero though (via caller), so the following works OK. */
- return arm_copy_copro_load_store (insn, data);
+ return visitor->copro_load_store (insn, data);
}
/* Should be unreachable. */
@@ -6874,47 +6907,48 @@ thumb2_decode_ext_reg_ld_st (uint16_t insn1, uint16_t insn2,
}
static int
-arm_decode_svc_copro (uint32_t insn, struct arm_insn_reloc_data *data)
+arm_decode_svc_copro (uint32_t insn, struct arm_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data)
{
unsigned int op1 = bits (insn, 20, 25);
int op = bit (insn, 4);
unsigned int coproc = bits (insn, 8, 11);
if ((op1 & 0x20) == 0x00 && (op1 & 0x3a) != 0x00 && (coproc & 0xe) == 0xa)
- return arm_decode_ext_reg_ld_st (insn, data);
+ return arm_decode_ext_reg_ld_st (insn, visitor, data);
else if ((op1 & 0x21) == 0x00 && (op1 & 0x3a) != 0x00
&& (coproc & 0xe) != 0xa)
/* stc/stc2. */
- return arm_copy_copro_load_store (insn, data);
+ return visitor->copro_load_store (insn, data);
else if ((op1 & 0x21) == 0x01 && (op1 & 0x3a) != 0x00
&& (coproc & 0xe) != 0xa)
/* ldc/ldc2 imm/lit. */
- return arm_copy_copro_load_store (insn, data);
+ return visitor->copro_load_store (insn, data);
else if ((op1 & 0x3e) == 0x00)
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
else if ((op1 & 0x3e) == 0x04 && (coproc & 0xe) == 0xa)
- return arm_copy_unmodified (insn, "neon 64bit xfer", data);
+ return visitor->others (insn, "neon 64bit xfer", data);
else if (op1 == 0x04 && (coproc & 0xe) != 0xa)
- return arm_copy_unmodified (insn, "mcrr/mcrr2", data);
+ return visitor->others (insn, "mcrr/mcrr2", data);
else if (op1 == 0x05 && (coproc & 0xe) != 0xa)
- return arm_copy_unmodified (insn, "mrrc/mrrc2", data);
+ return visitor->others (insn, "mrrc/mrrc2", data);
else if ((op1 & 0x30) == 0x20 && !op)
{
if ((coproc & 0xe) == 0xa)
- return arm_copy_unmodified (insn, "vfp dataproc", data);
+ return visitor->others (insn, "vfp dataproc", data);
else
- return arm_copy_unmodified (insn, "cdp/cdp2", data);
+ return visitor->others (insn, "cdp/cdp2", data);
}
else if ((op1 & 0x30) == 0x20 && op)
- return arm_copy_unmodified (insn, "neon 8/16/32 bit xfer", data);
+ return visitor->others (insn, "neon 8/16/32 bit xfer", data);
else if ((op1 & 0x31) == 0x20 && op && (coproc & 0xe) != 0xa)
- return arm_copy_unmodified (insn, "mcr/mcr2", data);
+ return visitor->others (insn, "mcr/mcr2", data);
else if ((op1 & 0x31) == 0x21 && op && (coproc & 0xe) != 0xa)
- return arm_copy_unmodified (insn, "mrc/mrc2", data);
+ return visitor->others (insn, "mrc/mrc2", data);
else if ((op1 & 0x30) == 0x30)
- return arm_copy_svc (insn, data);
+ return visitor->svc (insn, data);
else
- return arm_copy_undef (insn, data); /* Possibly unreachable. */
+ return visitor->undef (insn, data); /* Possibly unreachable. */
}
static int
@@ -7542,38 +7576,58 @@ thumb_32bit_relocate_insn (uint16_t insn1, uint16_t insn2,
}
static int
-arm_relocate_insn (uint32_t insn, struct arm_insn_reloc_data *data)
+arm_relocate_insn (uint32_t insn, struct arm_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data)
{
int err = 1;
if ((insn & 0xf0000000) == 0xf0000000)
- err = arm_decode_unconditional (insn, data);
+ err = arm_decode_unconditional (insn, visitor, data);
else switch (((insn & 0x10) >> 4) | ((insn & 0xe000000) >> 24))
{
case 0x0: case 0x1: case 0x2: case 0x3:
- err = arm_decode_dp_misc (insn, data);
+ err = arm_decode_dp_misc (insn, visitor, data);
break;
case 0x4: case 0x5: case 0x6:
- err = arm_decode_ld_st_word_ubyte (insn, data);
+ err = arm_decode_ld_st_word_ubyte (insn, visitor, data);
break;
case 0x7:
- err = arm_decode_media (insn, data);
+ err = arm_decode_media (insn, visitor, data);
break;
case 0x8: case 0x9: case 0xa: case 0xb:
- err = arm_decode_b_bl_ldmstm (insn, data);
+ err = arm_decode_b_bl_ldmstm (insn, visitor, data);
break;
case 0xc: case 0xd: case 0xe: case 0xf:
- err = arm_decode_svc_copro (insn, data);
+ err = arm_decode_svc_copro (insn, visitor, data);
break;
}
return err;
}
+static struct arm_insn_reloc_visitor arm_insn_reloc_visitor =
+{
+ arm_copy_alu_imm,
+ arm_copy_alu_reg,
+ arm_copy_alu_shifted_reg,
+ arm_copy_b_bl_blx,
+ arm_copy_block_xfer,
+ arm_copy_bx_blx_reg,
+ arm_copy_copro_load_store,
+ arm_copy_extra_ld_st,
+ arm_copy_ldr_str_ldrb_strb,
+ arm_copy_unmodified,
+ arm_copy_preload,
+ arm_copy_preload_reg,
+ arm_copy_svc,
+ arm_copy_undef,
+ arm_copy_unpred,
+};
+
void
arm_process_displaced_insn (struct gdbarch *gdbarch, CORE_ADDR from,
CORE_ADDR to, struct regcache *regs,
@@ -7608,7 +7662,7 @@ arm_process_displaced_insn (struct gdbarch *gdbarch, CORE_ADDR from,
dsc->is_thumb = 0;
dsc->insn_size = 4;
- err = arm_relocate_insn (insn, &reloc_data);
+ err = arm_relocate_insn (insn, &arm_insn_reloc_visitor, &reloc_data);
}
else
{