aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorDaniel Gutson <dgutson@codesourcery.com>2010-02-12 20:15:13 +0000
committerDaniel Gutson <dgutson@codesourcery.com>2010-02-12 20:15:13 +0000
commit5be8be5d5d9f0ff1ce3e319f0281e7d98103606b (patch)
treed9f1ab3128294dbb0eac8fa87fe626b1bdc9d174 /gas/config
parent081dfbf778bccf638e777fd4babc2911d0a59306 (diff)
downloadfsf-binutils-gdb-5be8be5d5d9f0ff1ce3e319f0281e7d98103606b.zip
fsf-binutils-gdb-5be8be5d5d9f0ff1ce3e319f0281e7d98103606b.tar.gz
fsf-binutils-gdb-5be8be5d5d9f0ff1ce3e319f0281e7d98103606b.tar.bz2
gas/
* config/tc-arm.c (asm_opcode): operands type change. (BAD_PC_ADDRESSING): New macro message. (BAD_PC_WRITEBACK): Likewise. (MIX_ARM_THUMB_OPERANDS): New macro. (operand_parse_code): Added enum values. (parse_operands): Added thumb/arm distinction, plus new enum values handling. (encode_arm_addr_mode_2): Validations enhanced. (encode_arm_addr_mode_3): Likewise. (do_rm_rd_rn): Likewise. (encode_thumb32_addr_mode): Likewise. (do_t_ldrex): Likewise. (do_t_ldst): Likewise. (do_t_strex): Likewise. (md_assemble): Call parse_operands with a new parameter. (OPS_1): New macro. (OPS_2): Likewise. (OPS_3): Likewise. (OPS_4): Likewise. (OPS_5): Likewise. (OPS_6): Likewise. (insns): Updated insns operands. gas/testsuite/ * gas/arm/sp-pc-validations-bad.d: New testcase. * gas/arm/sp-pc-validations-bad.l: New file. * gas/arm/sp-pc-validations-bad.s: New file. * gas/arm/sp-pc-validations-bad-t.d: New testcase. * gas/arm/sp-pc-validations-bad-t.l: New file. * gas/arm/sp-pc-validations-bad-t.s: New file. * gas/arm/sp-pc-usage-t.d: Removed invalid insns. * gas/arm/sp-pc-usage-t.s: Likewise. * gas/arm/unpredictable.d: Likewise. * gas/arm/unpredictable.s: Likewise. * gas/arm/thumb2_bcond.d: Added test. * gas/arm/thumb2_bcond.s: Likewise.
Diffstat (limited to 'gas/config')
-rw-r--r--gas/config/tc-arm.c184
1 files changed, 141 insertions, 43 deletions
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 2add801..4706600 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -559,7 +559,7 @@ struct asm_opcode
const char * template_name;
/* Parameters to instruction. */
- unsigned char operands[8];
+ unsigned int operands[8];
/* Conditional tag - see opcode_lookup. */
unsigned int tag : 4;
@@ -705,6 +705,10 @@ struct asm_opcode
#define BAD_IT_COND _("incorrect condition in IT block")
#define BAD_IT_IT _("IT falling in the range of a previous IT block")
#define MISSING_FNSTART _("missing .fnstart before unwinding directive")
+#define BAD_PC_ADDRESSING \
+ _("cannot use register index with PC-relative addressing")
+#define BAD_PC_WRITEBACK \
+ _("cannot use writeback with PC-relative addressing")
static struct hash_control * arm_ops_hsh;
static struct hash_control * arm_cond_hsh;
@@ -5729,6 +5733,11 @@ parse_neon_mov (char **str, int *which_operand)
return FAIL;
}
+/* Use this macro when the operand constraints are different
+ for ARM and THUMB (e.g. ldrd). */
+#define MIX_ARM_THUMB_OPERANDS(arm_operand, thumb_operand) \
+ ((arm_operand) | ((thumb_operand) << 16))
+
/* Matcher codes for parse_operands. */
enum operand_parse_code
{
@@ -5736,6 +5745,7 @@ enum operand_parse_code
OP_RR, /* ARM register */
OP_RRnpc, /* ARM register, not r15 */
+ OP_RRnpcsp, /* ARM register, neither r15 nor r13 (a.k.a. 'BadReg') */
OP_RRnpcb, /* ARM register, not r15, in square brackets */
OP_RRw, /* ARM register, not r15, optional trailing ! */
OP_RCP, /* Coprocessor number */
@@ -5835,6 +5845,7 @@ enum operand_parse_code
OP_oRR, /* ARM register */
OP_oRRnpc, /* ARM register, not the PC */
+ OP_oRRnpcsp, /* ARM register, neither the PC nor the SP (a.k.a. BadReg) */
OP_oRRw, /* ARM register, not r15, optional trailing ! */
OP_oRND, /* Optional Neon double precision register */
OP_oRNQ, /* Optional Neon quad precision register */
@@ -5846,6 +5857,11 @@ enum operand_parse_code
OP_oROR, /* ROR 0/8/16/24 */
OP_oBARRIER, /* Option argument for a barrier instruction. */
+ /* Some pre-defined mixed (ARM/THUMB) operands. */
+ OP_RR_npcsp = MIX_ARM_THUMB_OPERANDS (OP_RR, OP_RRnpcsp),
+ OP_RRnpc_npcsp = MIX_ARM_THUMB_OPERANDS (OP_RRnpc, OP_RRnpcsp),
+ OP_oRRnpc_npcsp = MIX_ARM_THUMB_OPERANDS (OP_oRRnpc, OP_oRRnpcsp),
+
OP_FIRST_OPTIONAL = OP_oI7b
};
@@ -5854,14 +5870,15 @@ enum operand_parse_code
structure. Returns SUCCESS or FAIL depending on whether the
specified grammar matched. */
static int
-parse_operands (char *str, const unsigned char *pattern)
+parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
{
- unsigned const char *upat = pattern;
+ unsigned const int *upat = pattern;
char *backtrack_pos = 0;
const char *backtrack_error = 0;
int i, val, backtrack_index = 0;
enum arm_reg_type rtype;
parse_operand_result result;
+ unsigned int op_parse_code;
#define po_char_or_fail(chr) \
do \
@@ -5952,7 +5969,12 @@ parse_operands (char *str, const unsigned char *pattern)
for (i = 0; upat[i] != OP_stop; i++)
{
- if (upat[i] >= OP_FIRST_OPTIONAL)
+ op_parse_code = upat[i];
+ if (op_parse_code >= 1<<16)
+ op_parse_code = thumb ? (op_parse_code >> 16)
+ : (op_parse_code & ((1<<16)-1));
+
+ if (op_parse_code >= OP_FIRST_OPTIONAL)
{
/* Remember where we are in case we need to backtrack. */
gas_assert (!backtrack_pos);
@@ -5964,11 +5986,13 @@ parse_operands (char *str, const unsigned char *pattern)
if (i > 0 && (i > 1 || inst.operands[0].present))
po_char_or_fail (',');
- switch (upat[i])
+ switch (op_parse_code)
{
/* Registers */
case OP_oRRnpc:
+ case OP_oRRnpcsp:
case OP_RRnpc:
+ case OP_RRnpcsp:
case OP_oRR:
case OP_RR: po_reg_or_fail (REG_TYPE_RN); break;
case OP_RCP: po_reg_or_fail (REG_TYPE_CP); break;
@@ -6371,13 +6395,13 @@ parse_operands (char *str, const unsigned char *pattern)
break;
default:
- as_fatal (_("unhandled operand code %d"), upat[i]);
+ as_fatal (_("unhandled operand code %d"), op_parse_code);
}
/* Various value-based sanity checks and shared operations. We
do not signal immediate failures for the register constraints;
this allows a syntax error to take precedence. */
- switch (upat[i])
+ switch (op_parse_code)
{
case OP_oRRnpc:
case OP_RRnpc:
@@ -6389,6 +6413,17 @@ parse_operands (char *str, const unsigned char *pattern)
inst.error = BAD_PC;
break;
+ case OP_oRRnpcsp:
+ case OP_RRnpcsp:
+ if (inst.operands[i].isreg)
+ {
+ if (inst.operands[i].reg == REG_PC)
+ inst.error = BAD_PC;
+ else if (inst.operands[i].reg == REG_SP)
+ inst.error = BAD_SP;
+ }
+ break;
+
case OP_CPSF:
case OP_ENDI:
case OP_oROR:
@@ -6674,10 +6709,15 @@ encode_arm_addr_mode_common (int i, bfd_boolean is_t)
static void
encode_arm_addr_mode_2 (int i, bfd_boolean is_t)
{
+ const bfd_boolean is_pc = (inst.operands[i].reg == REG_PC);
+
encode_arm_addr_mode_common (i, is_t);
if (inst.operands[i].immisreg)
{
+ constraint ((inst.operands[i].imm == REG_PC
+ || (is_pc && inst.operands[i].writeback)),
+ BAD_PC_ADDRESSING);
inst.instruction |= INST_IMMEDIATE; /* yes, this is backwards */
inst.instruction |= inst.operands[i].imm;
if (!inst.operands[i].negative)
@@ -6695,6 +6735,16 @@ encode_arm_addr_mode_2 (int i, bfd_boolean is_t)
}
else /* immediate offset in inst.reloc */
{
+ if (is_pc && !inst.reloc.pc_rel)
+ {
+ const bfd_boolean is_load = ((inst.instruction & LOAD_BIT) != 0);
+ /* BAD_PC_ADDRESSING Condition =
+ is_load => is_t
+ which becomes !is_load || is_t. */
+ constraint ((!is_load || is_t),
+ BAD_PC_ADDRESSING);
+ }
+
if (inst.reloc.type == BFD_RELOC_UNUSED)
inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
}
@@ -6718,12 +6768,18 @@ encode_arm_addr_mode_3 (int i, bfd_boolean is_t)
if (inst.operands[i].immisreg)
{
+ constraint ((inst.operands[i].imm == REG_PC
+ || inst.operands[i].reg == REG_PC),
+ BAD_PC_ADDRESSING);
inst.instruction |= inst.operands[i].imm;
if (!inst.operands[i].negative)
inst.instruction |= INDEX_UP;
}
else /* immediate offset in inst.reloc */
{
+ constraint ((inst.operands[i].reg == REG_PC && !inst.reloc.pc_rel
+ && inst.operands[i].writeback),
+ BAD_PC_WRITEBACK);
inst.instruction |= HWOFFSET_IMM;
if (inst.reloc.type == BFD_RELOC_UNUSED)
inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
@@ -6933,6 +6989,11 @@ do_rd_rn_rm (void)
static void
do_rm_rd_rn (void)
{
+ constraint ((inst.operands[2].reg == REG_PC), BAD_PC);
+ constraint (((inst.reloc.exp.X_op != O_constant
+ && inst.reloc.exp.X_op != O_illegal)
+ || inst.reloc.exp.X_add_number != 0),
+ BAD_ADDR_MODE);
inst.instruction |= inst.operands[0].reg;
inst.instruction |= inst.operands[1].reg << 12;
inst.instruction |= inst.operands[2].reg << 16;
@@ -7423,6 +7484,8 @@ do_ldrex (void)
|| inst.reloc.exp.X_add_number != 0,
_("offset must be zero in ARM encoding"));
+ constraint ((inst.operands[1].reg == REG_PC), BAD_PC);
+
inst.instruction |= inst.operands[0].reg << 12;
inst.instruction |= inst.operands[1].reg << 16;
inst.reloc.type = BFD_RELOC_UNUSED;
@@ -8672,12 +8735,13 @@ encode_thumb32_shifted_operand (int i)
Thumb32 format load or store instruction. Reject forms that cannot
be used with such instructions. If is_t is true, reject forms that
cannot be used with a T instruction; if is_d is true, reject forms
- that cannot be used with a D instruction. */
+ that cannot be used with a D instruction. If it is a store insn,
+ reject PC in Rn. */
static void
encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
{
- bfd_boolean is_pc = (inst.operands[i].reg == REG_PC);
+ const bfd_boolean is_pc = (inst.operands[i].reg == REG_PC);
constraint (!inst.operands[i].isreg,
_("Instruction does not support =N addresses"));
@@ -8685,7 +8749,7 @@ encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
inst.instruction |= inst.operands[i].reg << 16;
if (inst.operands[i].immisreg)
{
- constraint (is_pc, _("cannot use register index with PC-relative addressing"));
+ constraint (is_pc, BAD_PC_ADDRESSING);
constraint (is_t || is_d, _("cannot use register index with this instruction"));
constraint (inst.operands[i].negative,
_("Thumb does not support negative register indexing"));
@@ -8710,10 +8774,11 @@ encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
}
else if (inst.operands[i].preind)
{
- constraint (is_pc && inst.operands[i].writeback,
- _("cannot use writeback with PC-relative addressing"));
+ constraint (is_pc && inst.operands[i].writeback, BAD_PC_WRITEBACK);
constraint (is_t && inst.operands[i].writeback,
_("cannot use writeback with this instruction"));
+ constraint (is_pc && ((inst.instruction & THUMB2_LOAD_BIT) == 0)
+ && !inst.reloc.pc_rel, BAD_PC_ADDRESSING);
if (is_d)
{
@@ -9830,6 +9895,8 @@ do_t_ldrex (void)
|| inst.operands[1].negative,
BAD_ADDR_MODE);
+ constraint ((inst.operands[1].reg == REG_PC), BAD_PC);
+
inst.instruction |= inst.operands[0].reg << 12;
inst.instruction |= inst.operands[1].reg << 16;
inst.reloc.type = BFD_RELOC_ARM_T32_OFFSET_U8;
@@ -9889,6 +9956,8 @@ do_t_ldst (void)
/* [Rn, Rik] */
if (Rn <= 7 && inst.operands[1].imm <= 7)
goto op16;
+ else if (opcode != T_MNEM_ldr && opcode != T_MNEM_str)
+ reject_bad_reg (inst.operands[1].imm);
}
else if ((Rn <= 7 && opcode != T_MNEM_ldrsh
&& opcode != T_MNEM_ldrsb)
@@ -9928,6 +9997,12 @@ do_t_ldst (void)
}
}
/* Definitely a 32-bit variant. */
+
+ /* Do some validations regarding addressing modes. */
+ if (inst.operands[1].immisreg && opcode != T_MNEM_ldr
+ && opcode != T_MNEM_str)
+ reject_bad_reg (inst.operands[1].imm);
+
inst.instruction = THUMB_OP32 (opcode);
inst.instruction |= inst.operands[0].reg << 12;
encode_thumb32_addr_mode (1, /*is_t=*/FALSE, /*is_d=*/FALSE);
@@ -11177,6 +11252,8 @@ do_t_strex (void)
|| inst.operands[2].negative,
BAD_ADDR_MODE);
+ constraint (inst.operands[2].reg == REG_PC, BAD_PC);
+
inst.instruction |= inst.operands[0].reg << 8;
inst.instruction |= inst.operands[1].reg << 12;
inst.instruction |= inst.operands[2].reg << 16;
@@ -15653,7 +15730,7 @@ md_assemble (char *str)
inst.instruction = opcode->tvalue;
- if (!parse_operands (p, opcode->operands))
+ if (!parse_operands (p, opcode->operands, /*thumb=*/TRUE))
{
/* Prepare the it_insn_type for those encodings that don't set
it. */
@@ -15726,7 +15803,7 @@ md_assemble (char *str)
else
inst.instruction |= inst.cond << 28;
inst.size = INSN_SIZE;
- if (!parse_operands (p, opcode->operands))
+ if (!parse_operands (p, opcode->operands, /*thumb=*/FALSE))
{
it_fsm_pre_encode ();
opcode->aencode ();
@@ -16150,6 +16227,18 @@ static struct asm_barrier_opt barrier_opt_names[] =
#define OPS5(a,b,c,d,e) { OP_##a,OP_##b,OP_##c,OP_##d,OP_##e, }
#define OPS6(a,b,c,d,e,f) { OP_##a,OP_##b,OP_##c,OP_##d,OP_##e,OP_##f, }
+/* These macros are similar to the OPSn, but do not prepend the OP_ prefix.
+ This is useful when mixing operands for ARM and THUMB, i.e. using the
+ MIX_ARM_THUMB_OPERANDS macro.
+ In order to use these macros, prefix the number of operands with _
+ e.g. _3. */
+#define OPS_1(a) { a, }
+#define OPS_2(a,b) { a,b, }
+#define OPS_3(a,b,c) { a,b,c, }
+#define OPS_4(a,b,c,d) { a,b,c,d, }
+#define OPS_5(a,b,c,d,e) { a,b,c,d,e, }
+#define OPS_6(a,b,c,d,e,f) { a,b,c,d,e,f, }
+
/* These macros abstract out the exact format of the mnemonic table and
save some repeated characters. */
@@ -16370,9 +16459,11 @@ static const struct asm_opcode insns[] =
tC3("mvns", 1f00000, _mvns, 2, (RR, SH), mov, t_mvn_tst),
tCE("ldr", 4100000, _ldr, 2, (RR, ADDRGLDR),ldst, t_ldst),
- tC3("ldrb", 4500000, _ldrb, 2, (RR, ADDRGLDR),ldst, t_ldst),
- tCE("str", 4000000, _str, 2, (RR, ADDRGLDR),ldst, t_ldst),
- tC3("strb", 4400000, _strb, 2, (RR, ADDRGLDR),ldst, t_ldst),
+ tC3("ldrb", 4500000, _ldrb, 2, (RRnpc_npcsp, ADDRGLDR),ldst, t_ldst),
+ tCE("str", 4000000, _str, _2, (MIX_ARM_THUMB_OPERANDS (OP_RR,
+ OP_RRnpc),
+ OP_ADDRGLDR),ldst, t_ldst),
+ tC3("strb", 4400000, _strb, 2, (RRnpc_npcsp, ADDRGLDR),ldst, t_ldst),
tCE("stm", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
tC3("stmia", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
@@ -16422,10 +16513,10 @@ static const struct asm_opcode insns[] =
TC3w("teqs", 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst),
CL("teqp", 130f000, 2, (RR, SH), cmp),
- TC3("ldrt", 4300000, f8500e00, 2, (RR, ADDR), ldstt, t_ldstt),
- TC3("ldrbt", 4700000, f8100e00, 2, (RR, ADDR), ldstt, t_ldstt),
- TC3("strt", 4200000, f8400e00, 2, (RR, ADDR), ldstt, t_ldstt),
- TC3("strbt", 4600000, f8000e00, 2, (RR, ADDR), ldstt, t_ldstt),
+ TC3("ldrt", 4300000, f8500e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
+ TC3("ldrbt", 4700000, f8100e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
+ TC3("strt", 4200000, f8400e00, 2, (RR_npcsp, ADDR), ldstt, t_ldstt),
+ TC3("strbt", 4600000, f8000e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
TC3("stmdb", 9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
TC3("stmfd", 9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
@@ -16502,12 +16593,12 @@ static const struct asm_opcode insns[] =
#undef THUMB_VARIANT
#define THUMB_VARIANT & arm_ext_v4t
- tC3("ldrh", 01000b0, _ldrh, 2, (RR, ADDRGLDRS), ldstv4, t_ldst),
- tC3("strh", 00000b0, _strh, 2, (RR, ADDRGLDRS), ldstv4, t_ldst),
- tC3("ldrsh", 01000f0, _ldrsh, 2, (RR, ADDRGLDRS), ldstv4, t_ldst),
- tC3("ldrsb", 01000d0, _ldrsb, 2, (RR, ADDRGLDRS), ldstv4, t_ldst),
- tCM("ld","sh", 01000f0, _ldrsh, 2, (RR, ADDRGLDRS), ldstv4, t_ldst),
- tCM("ld","sb", 01000d0, _ldrsb, 2, (RR, ADDRGLDRS), ldstv4, t_ldst),
+ tC3("ldrh", 01000b0, _ldrh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
+ tC3("strh", 00000b0, _strh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
+ tC3("ldrsh", 01000f0, _ldrsh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
+ tC3("ldrsb", 01000d0, _ldrsb, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
+ tCM("ld","sh", 01000f0, _ldrsh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
+ tCM("ld","sb", 01000d0, _ldrsb, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
#undef ARM_VARIANT
#define ARM_VARIANT & arm_ext_v4t_5
@@ -16576,8 +16667,10 @@ static const struct asm_opcode insns[] =
#define THUMB_VARIANT &arm_ext_v6t2
TUF("pld", 450f000, f810f000, 1, (ADDR), pld, t_pld),
- TC3("ldrd", 00000d0, e8500000, 3, (RRnpc, oRRnpc, ADDRGLDRS), ldrd, t_ldstd),
- TC3("strd", 00000f0, e8400000, 3, (RRnpc, oRRnpc, ADDRGLDRS), ldrd, t_ldstd),
+ TC3("ldrd", 00000d0, e8500000, 3, (RRnpc_npcsp, oRRnpc_npcsp, ADDRGLDRS),
+ ldrd, t_ldstd),
+ TC3("strd", 00000f0, e8400000, 3, (RRnpc_npcsp, oRRnpc_npcsp,
+ ADDRGLDRS), ldrd, t_ldstd),
TCE("mcrr", c400000, ec400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
TCE("mrrc", c500000, ec500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
@@ -16606,8 +16699,9 @@ static const struct asm_opcode insns[] =
#undef THUMB_VARIANT
#define THUMB_VARIANT & arm_ext_v6t2
- TCE("ldrex", 1900f9f, e8500f00, 2, (RRnpc, ADDR), ldrex, t_ldrex),
- TCE("strex", 1800f90, e8400000, 3, (RRnpc, RRnpc, ADDR), strex, t_strex),
+ TCE("ldrex", 1900f9f, e8500f00, 2, (RRnpc_npcsp, ADDR), ldrex, t_ldrex),
+ TCE("strex", 1800f90, e8400000, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
+ strex, t_strex),
TUF("mcrr2", c400000, fc400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
TUF("mrrc2", c500000, fc500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
@@ -16741,17 +16835,21 @@ static const struct asm_opcode insns[] =
#undef THUMB_VARIANT
#define THUMB_VARIANT & arm_ext_v6_notm
-
- TCE("ldrexd", 1b00f9f, e8d0007f, 3, (RRnpc, oRRnpc, RRnpcb), ldrexd, t_ldrexd),
- TCE("strexd", 1a00f90, e8c00070, 4, (RRnpc, RRnpc, oRRnpc, RRnpcb), strexd, t_strexd),
+ TCE("ldrexd", 1b00f9f, e8d0007f, 3, (RRnpc_npcsp, oRRnpc_npcsp, RRnpcb),
+ ldrexd, t_ldrexd),
+ TCE("strexd", 1a00f90, e8c00070, 4, (RRnpc_npcsp, RRnpc_npcsp, oRRnpc_npcsp,
+ RRnpcb), strexd, t_strexd),
#undef THUMB_VARIANT
#define THUMB_VARIANT & arm_ext_v6t2
-
- TCE("ldrexb", 1d00f9f, e8d00f4f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
- TCE("ldrexh", 1f00f9f, e8d00f5f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
- TCE("strexb", 1c00f90, e8c00f40, 3, (RRnpc, RRnpc, ADDR), strex, rm_rd_rn),
- TCE("strexh", 1e00f90, e8c00f50, 3, (RRnpc, RRnpc, ADDR), strex, rm_rd_rn),
+ TCE("ldrexb", 1d00f9f, e8d00f4f, 2, (RRnpc_npcsp,RRnpcb),
+ rd_rn, rd_rn),
+ TCE("ldrexh", 1f00f9f, e8d00f5f, 2, (RRnpc_npcsp, RRnpcb),
+ rd_rn, rd_rn),
+ TCE("strexb", 1c00f90, e8c00f40, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
+ strex, rm_rd_rn),
+ TCE("strexh", 1e00f90, e8c00f50, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
+ strex, rm_rd_rn),
TUF("clrex", 57ff01f, f3bf8f2f, 0, (), noargs, noargs),
#undef ARM_VARIANT
@@ -16772,10 +16870,10 @@ static const struct asm_opcode insns[] =
TCE("movt", 3400000, f2c00000, 2, (RRnpc, HALF), mov16, t_mov16),
TCE("rbit", 6ff0f30, fa90f0a0, 2, (RR, RR), rd_rm, t_rbit),
- TC3("ldrht", 03000b0, f8300e00, 2, (RR, ADDR), ldsttv4, t_ldstt),
- TC3("ldrsht", 03000f0, f9300e00, 2, (RR, ADDR), ldsttv4, t_ldstt),
- TC3("ldrsbt", 03000d0, f9100e00, 2, (RR, ADDR), ldsttv4, t_ldstt),
- TC3("strht", 02000b0, f8200e00, 2, (RR, ADDR), ldsttv4, t_ldstt),
+ TC3("ldrht", 03000b0, f8300e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
+ TC3("ldrsht", 03000f0, f9300e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
+ TC3("ldrsbt", 03000d0, f9100e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
+ TC3("strht", 02000b0, f8200e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
UT("cbnz", b900, 2, (RR, EXP), t_cbz),
UT("cbz", b100, 2, (RR, EXP), t_cbz),