This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH v2 08/17] Move Thumb 32 bits instruction decode functions to arch/arm-insn-reloc.c
- From: Antoine Tremblay <antoine dot tremblay at ericsson dot com>
- To: <gdb-patches at sourceware dot org>
- Cc: Simon Marchi <simon dot marchi at ericsson dot com>
- Date: Thu, 9 Jun 2016 08:56:06 -0400
- Subject: [PATCH v2 08/17] Move Thumb 32 bits instruction decode functions to arch/arm-insn-reloc.c
- Authentication-results: sourceware.org; auth=none
- References: <1465476975-25062-1-git-send-email-antoine dot tremblay at ericsson dot com>
From: Simon Marchi <simon.marchi@ericsson.com>
This patch does the same as the previous one, but for 32-bits Thumb
instructions-related functions.
gdb/ChangeLog:
* arch/arm-insn-reloc.h (struct thumb_32bit_insn_reloc_visitor):
Move from arm-tdep.c.
(thumb_32bit_relocate_insn): New declaration.
* arch/arm-insn-reloc.c (thumb2_decode_dp_shift_reg): Move from
arm-tdep.c.
(thumb2_decode_ext_reg_ld_st): Likewise.
(thumb2_decode_svc_copro): Likewise.
(decode_thumb_32bit_ld_mem_hints): Likewise.
(thumb_32bit_relocate_insn): Likewise.
* arm-tdep.c (struct thumb_32bit_insn_reloc_visitor): Move to
arch/arm-insn-reloc.h.
(thumb2_decode_dp_shift_reg): Move to arch/arm-insn-reloc.c.
(thumb2_decode_ext_reg_ld_st): Likewise.
(thumb2_decode_svc_copro): Likewise.
(decode_thumb_32bit_ld_mem_hints): Likewise.
(thumb_32bit_relocate_insn): Likewise.
---
gdb/arch/arm-insn-reloc.c | 274 +++++++++++++++++++++++++++++++++++++++++
gdb/arch/arm-insn-reloc.h | 32 +++++
gdb/arm-tdep.c | 301 ----------------------------------------------
3 files changed, 306 insertions(+), 301 deletions(-)
diff --git a/gdb/arch/arm-insn-reloc.c b/gdb/arch/arm-insn-reloc.c
index adf6243..f598c64 100644
--- a/gdb/arch/arm-insn-reloc.c
+++ b/gdb/arch/arm-insn-reloc.c
@@ -470,3 +470,277 @@ arm_relocate_insn (uint32_t insn, struct arm_insn_reloc_visitor *visitor,
return err;
}
+
+/* Decode shifted register instructions. */
+
+static int
+thumb2_decode_dp_shift_reg (uint16_t insn1, uint16_t insn2,
+ struct thumb_32bit_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data)
+{
+ /* PC is only allowed to be used in instruction MOV. */
+
+ unsigned int op = bits (insn1, 5, 8);
+ unsigned int rn = bits (insn1, 0, 3);
+
+ if (op == 0x2 && rn == 0xf) /* MOV */
+ return visitor->alu_imm (insn1, insn2, data);
+ else
+ return visitor->others (insn1, insn2, "dp (shift reg)", data);
+}
+
+
+/* Decode extension register load/store. Exactly the same as
+ arm_decode_ext_reg_ld_st. */
+
+static int
+thumb2_decode_ext_reg_ld_st (uint16_t insn1, uint16_t insn2,
+ struct thumb_32bit_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data)
+{
+ unsigned int opcode = bits (insn1, 4, 8);
+
+ switch (opcode)
+ {
+ case 0x04: case 0x05:
+ return visitor->others (insn1, insn2, "vfp/neon vmov", data);
+
+ case 0x08: case 0x0c: /* 01x00 */
+ case 0x0a: case 0x0e: /* 01x10 */
+ case 0x12: case 0x16: /* 10x10 */
+ return visitor->others (insn1, insn2, "vfp/neon vstm/vpush", data);
+
+ case 0x09: case 0x0d: /* 01x01 */
+ case 0x0b: case 0x0f: /* 01x11 */
+ case 0x13: case 0x17: /* 10x11 */
+ return visitor->others (insn1, insn2, "vfp/neon vldm/vpop", data);
+
+ case 0x10: case 0x14: case 0x18: case 0x1c: /* vstr. */
+ return visitor->others (insn1, insn2, "vstr", data);
+ case 0x11: case 0x15: case 0x19: case 0x1d: /* vldr. */
+ return visitor->copro_load_store (insn1, insn2, data);
+ }
+
+ /* Should be unreachable. */
+ return 1;
+}
+
+
+static int
+decode_thumb_32bit_ld_mem_hints (uint16_t insn1, uint16_t insn2,
+ struct thumb_32bit_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data)
+{
+ int rt = bits (insn2, 12, 15);
+ int rn = bits (insn1, 0, 3);
+ int op1 = bits (insn1, 7, 8);
+
+ switch (bits (insn1, 5, 6))
+ {
+ case 0: /* Load byte and memory hints */
+ if (rt == 0xf) /* PLD/PLI */
+ {
+ if (rn == 0xf)
+ /* PLD literal or Encoding T3 of PLI(immediate, literal). */
+ return visitor->preload (insn1, insn2, data);
+ else
+ return visitor->others (insn1, insn2, "pli/pld", data);
+ }
+ else
+ {
+ if (rn == 0xf) /* LDRB/LDRSB (literal) */
+ return visitor->load_literal (insn1, insn2, data, 1);
+ else
+ return visitor->others (insn1, insn2, "ldrb{reg, immediate}/ldrbt",
+ data);
+ }
+
+ break;
+ case 1: /* Load halfword and memory hints. */
+ if (rt == 0xf) /* PLD{W} and Unalloc memory hint. */
+ return visitor->others (insn1, insn2, "pld/unalloc memhint", data);
+ else
+ {
+ if (rn == 0xf)
+ return visitor->load_literal (insn1, insn2, data, 2);
+ else
+ return visitor->others (insn1, insn2, "ldrh/ldrht", data);
+ }
+ break;
+ case 2: /* Load word */
+ {
+ int insn2_bit_8_11 = bits (insn2, 8, 11);
+
+ if (rn == 0xf)
+ return visitor->load_literal (insn1, insn2, data, 4);
+ else if (op1 == 0x1) /* Encoding T3 */
+ return visitor->load_reg_imm (insn1, insn2, data, 0, 1);
+ else /* op1 == 0x0 */
+ {
+ if (insn2_bit_8_11 == 0xc || (insn2_bit_8_11 & 0x9) == 0x9)
+ /* LDR (immediate) */
+ return visitor->load_reg_imm (insn1, insn2, data,
+ bit (insn2, 8), 1);
+ else if (insn2_bit_8_11 == 0xe) /* LDRT */
+ return visitor->others (insn1, insn2, "ldrt", data);
+ else
+ /* LDR (register) */
+ return visitor->load_reg_imm (insn1, insn2, data, 0, 0);
+ }
+ break;
+ }
+ default:
+ return visitor->undef (insn1, insn2, data);
+ }
+ return 0;
+}
+
+static int
+thumb2_decode_svc_copro (uint16_t insn1, uint16_t insn2,
+ struct thumb_32bit_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data)
+{
+ unsigned int coproc = bits (insn2, 8, 11);
+ unsigned int bit_5_8 = bits (insn1, 5, 8);
+ unsigned int bit_9 = bit (insn1, 9);
+ unsigned int bit_4 = bit (insn1, 4);
+
+ if (bit_9 == 0)
+ {
+ if (bit_5_8 == 2)
+ return visitor->others (insn1, insn2,
+ "neon 64bit xfer/mrrc/mrrc2/mcrr/mcrr2", data);
+ else if (bit_5_8 == 0) /* UNDEFINED. */
+ return visitor->undef (insn1, insn2, data);
+ else
+ {
+ /*coproc is 101x. SIMD/VFP, ext registers load/store. */
+ if ((coproc & 0xe) == 0xa)
+ return thumb2_decode_ext_reg_ld_st (insn1, insn2, visitor, data);
+ else /* coproc is not 101x. */
+ {
+ if (bit_4 == 0) /* STC/STC2. */
+ return visitor->others (insn1, insn2, "stc/stc2", data);
+ else /* LDC/LDC2 {literal, immeidate}. */
+ return visitor->copro_load_store (insn1, insn2, data);
+ }
+ }
+ }
+ else
+ return visitor->others (insn1, insn2, "coproc", data);
+
+ return 0;
+}
+
+int
+thumb_32bit_relocate_insn (uint16_t insn1, uint16_t insn2,
+ struct thumb_32bit_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data)
+{
+ int err = 0;
+ unsigned short op = bit (insn2, 15);
+ unsigned int op1 = bits (insn1, 11, 12);
+
+ switch (op1)
+ {
+ case 1:
+ {
+ switch (bits (insn1, 9, 10))
+ {
+ case 0:
+ if (bit (insn1, 6))
+ {
+ /* Load/store {dual, execlusive}, table branch. */
+ if (bits (insn1, 7, 8) == 1 && bits (insn1, 4, 5) == 1
+ && bits (insn2, 5, 7) == 0)
+ err = visitor->table_branch (insn1, insn2, data);
+ else
+ /* PC is not allowed to use in load/store {dual, exclusive}
+ instructions. */
+ err = visitor->others (insn1, insn2, "load/store dual/ex",
+ data);
+ }
+ else /* load/store multiple */
+ {
+ switch (bits (insn1, 7, 8))
+ {
+ case 0: case 3: /* SRS, RFE */
+ err = visitor->others (insn1, insn2, "srs/rfe", data);
+ break;
+ case 1: case 2: /* LDM/STM/PUSH/POP */
+ err = visitor->block_xfer (insn1, insn2, data);
+ break;
+ }
+ }
+ break;
+
+ case 1:
+ /* Data-processing (shift register). */
+ err = thumb2_decode_dp_shift_reg (insn1, insn2, visitor, data);
+ break;
+ default: /* Coprocessor instructions. */
+ err = thumb2_decode_svc_copro (insn1, insn2, visitor, data);
+ break;
+ }
+ break;
+ }
+ case 2: /* op1 = 2 */
+ if (op) /* Branch and misc control. */
+ {
+ if (bit (insn2, 14) /* BLX/BL */
+ || bit (insn2, 12) /* Unconditional branch */
+ || (bits (insn1, 7, 9) != 0x7)) /* Conditional branch */
+ err = visitor->b_bl_blx (insn1, insn2, data);
+ else
+ err = visitor->others (insn1, insn2, "misc ctrl", data);
+ }
+ else
+ {
+ if (bit (insn1, 9)) /* Data processing (plain binary imm). */
+ {
+ int op = bits (insn1, 4, 8);
+ int rn = bits (insn1, 0, 3);
+ if ((op == 0 || op == 0xa) && rn == 0xf)
+ err = visitor->pc_relative_32bit (insn1, insn2, data);
+ else
+ err = visitor->others (insn1, insn2, "dp/pb", data);
+ }
+ else /* Data processing (modified immeidate) */
+ err = visitor->others (insn1, insn2, "dp/mi", data);
+ }
+ break;
+ case 3: /* op1 = 3 */
+ switch (bits (insn1, 9, 10))
+ {
+ case 0:
+ if (bit (insn1, 4))
+ err = decode_thumb_32bit_ld_mem_hints (insn1, insn2, visitor, data);
+ else /* NEON Load/Store and Store single data item */
+ err = visitor->others (insn1, insn2, "neon elt/struct load/store",
+ data);
+ break;
+ case 1: /* op1 = 3, bits (9, 10) == 1 */
+ switch (bits (insn1, 7, 8))
+ {
+ case 0: case 1: /* Data processing (register) */
+ err = visitor->others (insn1, insn2, "dp(reg)", data);
+ break;
+ case 2: /* Multiply and absolute difference */
+ err = visitor->others (insn1, insn2, "mul/mua/diff", data);
+ break;
+ case 3: /* Long multiply and divide */
+ err = visitor->others (insn1, insn2, "lmul/lmua", data);
+ break;
+ }
+ break;
+ default: /* Coprocessor instructions */
+ err = thumb2_decode_svc_copro (insn1, insn2, visitor, data);
+ break;
+ }
+ break;
+ default:
+ err = 1;
+ }
+
+ return err;
+}
diff --git a/gdb/arch/arm-insn-reloc.h b/gdb/arch/arm-insn-reloc.h
index 18d3916..ebfc89a 100644
--- a/gdb/arch/arm-insn-reloc.h
+++ b/gdb/arch/arm-insn-reloc.h
@@ -42,8 +42,40 @@ struct arm_insn_reloc_visitor
int (*unpred) (uint32_t insn, struct arm_insn_reloc_data *data);
};
+struct thumb_32bit_insn_reloc_visitor
+{
+ int (*alu_imm) (uint16_t insn1, uint16_t insn2,
+ struct arm_insn_reloc_data *data);
+ int (*b_bl_blx) (uint16_t insn1, uint16_t insn2,
+ struct arm_insn_reloc_data *data);
+ int (*block_xfer) (uint16_t insn1, uint16_t insn2,
+ struct arm_insn_reloc_data *data);
+ int (*copro_load_store) (uint16_t insn1, uint16_t insn2,
+ struct arm_insn_reloc_data *data);
+ int (*load_literal) (uint16_t insn1, uint16_t insn2,
+ struct arm_insn_reloc_data *data, int size);
+ int (*load_reg_imm) (uint16_t insn1, uint16_t insn2,
+ struct arm_insn_reloc_data *data, int writeback,
+ int immed);
+ int (*others) (uint16_t insn1, uint16_t insn2, const char *iname,
+ struct arm_insn_reloc_data *data);
+ int (*pc_relative_32bit) (uint16_t insn1, uint16_t insn2,
+ struct arm_insn_reloc_data *data);
+ int (*preload) (uint16_t insn1, uint16_t insn2,
+ struct arm_insn_reloc_data *data);
+ int (*undef) (uint16_t insn1, uint16_t insn2,
+ struct arm_insn_reloc_data *data);
+ int (*table_branch) (uint16_t insn1, uint16_t insn2,
+ struct arm_insn_reloc_data *data);
+};
+
extern int arm_relocate_insn (uint32_t insn,
struct arm_insn_reloc_visitor *visitor,
struct arm_insn_reloc_data *data);
+extern int thumb_32bit_relocate_insn (
+ uint16_t insn1, uint16_t insn2,
+ struct thumb_32bit_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data);
+
#endif /* ARM_INSN_RELOC_H */
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 1af4d36..4f4b6b2 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -4481,33 +4481,6 @@ struct arm_insn_reloc_data
struct regcache *regs;
};
-struct thumb_32bit_insn_reloc_visitor
-{
- int (*alu_imm) (uint16_t insn1, uint16_t insn2,
- struct arm_insn_reloc_data *data);
- int (*b_bl_blx) (uint16_t insn1, uint16_t insn2,
- struct arm_insn_reloc_data *data);
- int (*block_xfer) (uint16_t insn1, uint16_t insn2,
- struct arm_insn_reloc_data *data);
- int (*copro_load_store) (uint16_t insn1, uint16_t insn2,
- struct arm_insn_reloc_data *data);
- int (*load_literal) (uint16_t insn1, uint16_t insn2,
- struct arm_insn_reloc_data *data, int size);
- int (*load_reg_imm) (uint16_t insn1, uint16_t insn2,
- struct arm_insn_reloc_data *data, int writeback,
- int immed);
- int (*others) (uint16_t insn1, uint16_t insn2, const char *iname,
- struct arm_insn_reloc_data *data);
- int (*pc_relative_32bit) (uint16_t insn1, uint16_t insn2,
- struct arm_insn_reloc_data *data);
- int (*preload) (uint16_t insn1, uint16_t insn2,
- struct arm_insn_reloc_data *data);
- int (*undef) (uint16_t insn1, uint16_t insn2,
- struct arm_insn_reloc_data *data);
- int (*table_branch) (uint16_t insn1, uint16_t insn2,
- struct arm_insn_reloc_data *data);
-};
-
struct thumb_16bit_insn_reloc_visitor
{
int (*alu_reg) (uint16_t insn, struct arm_insn_reloc_data *data);
@@ -6504,97 +6477,6 @@ arm_copy_unpred (uint32_t insn, struct arm_insn_reloc_data *data)
/* The decode_* functions are instruction decoding helpers. They mostly follow
the presentation in the ARM ARM. */
-/* Decode shifted register instructions. */
-
-static int
-thumb2_decode_dp_shift_reg (uint16_t insn1, uint16_t insn2,
- struct thumb_32bit_insn_reloc_visitor *visitor,
- struct arm_insn_reloc_data *data)
-{
- /* PC is only allowed to be used in instruction MOV. */
-
- unsigned int op = bits (insn1, 5, 8);
- unsigned int rn = bits (insn1, 0, 3);
-
- if (op == 0x2 && rn == 0xf) /* MOV */
- return visitor->alu_imm (insn1, insn2, data);
- else
- return visitor->others (insn1, insn2, "dp (shift reg)", data);
-}
-
-
-/* Decode extension register load/store. Exactly the same as
- arm_decode_ext_reg_ld_st. */
-
-static int
-thumb2_decode_ext_reg_ld_st (uint16_t insn1, uint16_t insn2,
- struct thumb_32bit_insn_reloc_visitor *visitor,
- struct arm_insn_reloc_data *data)
-{
- unsigned int opcode = bits (insn1, 4, 8);
-
- switch (opcode)
- {
- case 0x04: case 0x05:
- return visitor->others (insn1, insn2, "vfp/neon vmov", data);
-
- case 0x08: case 0x0c: /* 01x00 */
- case 0x0a: case 0x0e: /* 01x10 */
- case 0x12: case 0x16: /* 10x10 */
- return visitor->others (insn1, insn2, "vfp/neon vstm/vpush", data);
-
- case 0x09: case 0x0d: /* 01x01 */
- case 0x0b: case 0x0f: /* 01x11 */
- case 0x13: case 0x17: /* 10x11 */
- return visitor->others (insn1, insn2, "vfp/neon vldm/vpop", data);
-
- case 0x10: case 0x14: case 0x18: case 0x1c: /* vstr. */
- return visitor->others (insn1, insn2, "vstr", data);
- case 0x11: case 0x15: case 0x19: case 0x1d: /* vldr. */
- return visitor->copro_load_store (insn1, insn2, data);
- }
-
- /* Should be unreachable. */
- return 1;
-}
-
-static int
-thumb2_decode_svc_copro (uint16_t insn1, uint16_t insn2,
- struct thumb_32bit_insn_reloc_visitor *visitor,
- struct arm_insn_reloc_data *data)
-{
- unsigned int coproc = bits (insn2, 8, 11);
- unsigned int bit_5_8 = bits (insn1, 5, 8);
- unsigned int bit_9 = bit (insn1, 9);
- unsigned int bit_4 = bit (insn1, 4);
-
- if (bit_9 == 0)
- {
- if (bit_5_8 == 2)
- return visitor->others (insn1, insn2,
- "neon 64bit xfer/mrrc/mrrc2/mcrr/mcrr2", data);
- else if (bit_5_8 == 0) /* UNDEFINED. */
- return visitor->undef (insn1, insn2, data);
- else
- {
- /*coproc is 101x. SIMD/VFP, ext registers load/store. */
- if ((coproc & 0xe) == 0xa)
- return thumb2_decode_ext_reg_ld_st (insn1, insn2, visitor, data);
- else /* coproc is not 101x. */
- {
- if (bit_4 == 0) /* STC/STC2. */
- return visitor->others (insn1, insn2, "stc/stc2", data);
- else /* LDC/LDC2 {literal, immeidate}. */
- return visitor->copro_load_store (insn1, insn2, data);
- }
- }
- }
- else
- return visitor->others (insn1, insn2, "coproc", data);
-
- return 0;
-}
-
static void
install_pc_relative (struct arm_insn_reloc_data *data, int rd)
{
@@ -6996,189 +6878,6 @@ thumb_16bit_relocate_insn (uint16_t insn1,
return err;
}
-static int
-decode_thumb_32bit_ld_mem_hints (uint16_t insn1, uint16_t insn2,
- struct thumb_32bit_insn_reloc_visitor *visitor,
- struct arm_insn_reloc_data *data)
-{
- int rt = bits (insn2, 12, 15);
- int rn = bits (insn1, 0, 3);
- int op1 = bits (insn1, 7, 8);
-
- switch (bits (insn1, 5, 6))
- {
- case 0: /* Load byte and memory hints */
- if (rt == 0xf) /* PLD/PLI */
- {
- if (rn == 0xf)
- /* PLD literal or Encoding T3 of PLI(immediate, literal). */
- return visitor->preload (insn1, insn2, data);
- else
- return visitor->others (insn1, insn2, "pli/pld", data);
- }
- else
- {
- if (rn == 0xf) /* LDRB/LDRSB (literal) */
- return visitor->load_literal (insn1, insn2, data, 1);
- else
- return visitor->others (insn1, insn2, "ldrb{reg, immediate}/ldrbt",
- data);
- }
-
- break;
- case 1: /* Load halfword and memory hints. */
- if (rt == 0xf) /* PLD{W} and Unalloc memory hint. */
- return visitor->others (insn1, insn2, "pld/unalloc memhint", data);
- else
- {
- if (rn == 0xf)
- return visitor->load_literal (insn1, insn2, data, 2);
- else
- return visitor->others (insn1, insn2, "ldrh/ldrht", data);
- }
- break;
- case 2: /* Load word */
- {
- int insn2_bit_8_11 = bits (insn2, 8, 11);
-
- if (rn == 0xf)
- return visitor->load_literal (insn1, insn2, data, 4);
- else if (op1 == 0x1) /* Encoding T3 */
- return visitor->load_reg_imm (insn1, insn2, data, 0, 1);
- else /* op1 == 0x0 */
- {
- if (insn2_bit_8_11 == 0xc || (insn2_bit_8_11 & 0x9) == 0x9)
- /* LDR (immediate) */
- return visitor->load_reg_imm (insn1, insn2, data,
- bit (insn2, 8), 1);
- else if (insn2_bit_8_11 == 0xe) /* LDRT */
- return visitor->others (insn1, insn2, "ldrt", data);
- else
- /* LDR (register) */
- return visitor->load_reg_imm (insn1, insn2, data, 0, 0);
- }
- break;
- }
- default:
- return visitor->undef (insn1, insn2, data);
- }
- return 0;
-}
-
-static int
-thumb_32bit_relocate_insn (uint16_t insn1, uint16_t insn2,
- struct thumb_32bit_insn_reloc_visitor *visitor,
- struct arm_insn_reloc_data *data)
-{
- int err = 0;
- unsigned short op = bit (insn2, 15);
- unsigned int op1 = bits (insn1, 11, 12);
-
- switch (op1)
- {
- case 1:
- {
- switch (bits (insn1, 9, 10))
- {
- case 0:
- if (bit (insn1, 6))
- {
- /* Load/store {dual, execlusive}, table branch. */
- if (bits (insn1, 7, 8) == 1 && bits (insn1, 4, 5) == 1
- && bits (insn2, 5, 7) == 0)
- err = visitor->table_branch (insn1, insn2, data);
- else
- /* PC is not allowed to use in load/store {dual, exclusive}
- instructions. */
- err = visitor->others (insn1, insn2, "load/store dual/ex",
- data);
- }
- else /* load/store multiple */
- {
- switch (bits (insn1, 7, 8))
- {
- case 0: case 3: /* SRS, RFE */
- err = visitor->others (insn1, insn2, "srs/rfe", data);
- break;
- case 1: case 2: /* LDM/STM/PUSH/POP */
- err = visitor->block_xfer (insn1, insn2, data);
- break;
- }
- }
- break;
-
- case 1:
- /* Data-processing (shift register). */
- err = thumb2_decode_dp_shift_reg (insn1, insn2, visitor, data);
- break;
- default: /* Coprocessor instructions. */
- err = thumb2_decode_svc_copro (insn1, insn2, visitor, data);
- break;
- }
- break;
- }
- case 2: /* op1 = 2 */
- if (op) /* Branch and misc control. */
- {
- if (bit (insn2, 14) /* BLX/BL */
- || bit (insn2, 12) /* Unconditional branch */
- || (bits (insn1, 7, 9) != 0x7)) /* Conditional branch */
- err = visitor->b_bl_blx (insn1, insn2, data);
- else
- err = visitor->others (insn1, insn2, "misc ctrl", data);
- }
- else
- {
- if (bit (insn1, 9)) /* Data processing (plain binary imm). */
- {
- int op = bits (insn1, 4, 8);
- int rn = bits (insn1, 0, 3);
- if ((op == 0 || op == 0xa) && rn == 0xf)
- err = visitor->pc_relative_32bit (insn1, insn2, data);
- else
- err = visitor->others (insn1, insn2, "dp/pb", data);
- }
- else /* Data processing (modified immeidate) */
- err = visitor->others (insn1, insn2, "dp/mi", data);
- }
- break;
- case 3: /* op1 = 3 */
- switch (bits (insn1, 9, 10))
- {
- case 0:
- if (bit (insn1, 4))
- err = decode_thumb_32bit_ld_mem_hints (insn1, insn2, visitor, data);
- else /* NEON Load/Store and Store single data item */
- err = visitor->others (insn1, insn2, "neon elt/struct load/store",
- data);
- break;
- case 1: /* op1 = 3, bits (9, 10) == 1 */
- switch (bits (insn1, 7, 8))
- {
- case 0: case 1: /* Data processing (register) */
- err = visitor->others (insn1, insn2, "dp(reg)", data);
- break;
- case 2: /* Multiply and absolute difference */
- err = visitor->others (insn1, insn2, "mul/mua/diff", data);
- break;
- case 3: /* Long multiply and divide */
- err = visitor->others (insn1, insn2, "lmul/lmua", data);
- break;
- }
- break;
- default: /* Coprocessor instructions */
- err = thumb2_decode_svc_copro (insn1, insn2, visitor, data);
- break;
- }
- break;
- default:
- err = 1;
- }
-
- return err;
-
-}
-
static struct arm_insn_reloc_visitor arm_insn_reloc_visitor =
{
arm_copy_alu_imm,
--
2.8.1