gas/
authorDaniel Gutson <dgutson@codesourcery.com>
Fri, 12 Feb 2010 20:15:13 +0000 (20:15 +0000)
committerDaniel Gutson <dgutson@codesourcery.com>
Fri, 12 Feb 2010 20:15:13 +0000 (20:15 +0000)
* 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.

14 files changed:
ChangeLog
gas/config/tc-arm.c
gas/testsuite/gas/arm/sp-pc-usage-t.d
gas/testsuite/gas/arm/sp-pc-usage-t.s
gas/testsuite/gas/arm/sp-pc-validations-bad-t.d [new file with mode: 0644]
gas/testsuite/gas/arm/sp-pc-validations-bad-t.l [new file with mode: 0644]
gas/testsuite/gas/arm/sp-pc-validations-bad-t.s [new file with mode: 0644]
gas/testsuite/gas/arm/sp-pc-validations-bad.d [new file with mode: 0644]
gas/testsuite/gas/arm/sp-pc-validations-bad.l [new file with mode: 0644]
gas/testsuite/gas/arm/sp-pc-validations-bad.s [new file with mode: 0644]
gas/testsuite/gas/arm/thumb2_bcond.d
gas/testsuite/gas/arm/thumb2_bcond.s
gas/testsuite/gas/arm/unpredictable.d
gas/testsuite/gas/arm/unpredictable.s

index 7d8f7f2..5bbbe4a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,45 @@
+2010-02-12  Daniel Gutson  <dgutson@codesourcery.com>
+
+       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.
+
 2010-01-31  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        Sync from gcc:
index 2add801..4706600 100644 (file)
@@ -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),
index 8b21aeb..706f2a1 100644 (file)
@@ -24,65 +24,60 @@ Disassembly of section .text:
 00000036 <foo\+0x36> f8df d000         ldr.w   sp, \[pc\]      ; 00000038 <foo\+0x38>
 0000003a <foo\+0x3a> f850 d00f         ldr.w   sp, \[r0, pc\]
 0000003e <foo\+0x3e> 9000              str     r0, \[sp, #0\]
-00000040 <foo\+0x40> f8cf 0000         str.w   r0, \[pc\]      ; 00000044 <foo\+0x44>
-00000044 <foo\+0x44> f8c0 f000         str.w   pc, \[r0\]
-00000048 <foo\+0x48> f8c0 d000         str.w   sp, \[r0\]
-0000004c <foo\+0x4c> f8cf f000         str.w   pc, \[pc\]      ; 00000050 <foo\+0x50>
-00000050 <foo\+0x50> f8cd d000         str.w   sp, \[sp\]
-00000054 <foo\+0x54> f8cd f000         str.w   pc, \[sp\]
-00000058 <foo\+0x58> f8cf d000         str.w   sp, \[pc\]      ; 0000005c <foo\+0x5c>
-0000005c <foo\+0x5c> f840 d00f         str.w   sp, \[r0, pc\]
-00000060 <foo\+0x60> 4468              add     r0, sp
-00000062 <foo\+0x62> eb1d 0000         adds.w  r0, sp, r0
-00000066 <foo\+0x66> eb0d 0040         add.w   r0, sp, r0, lsl #1
-0000006a <foo\+0x6a> eb1d 0040         adds.w  r0, sp, r0, lsl #1
-0000006e <foo\+0x6e> f11d 0f00         cmn.w   sp, #0
-00000072 <foo\+0x72> eb1d 0f00         cmn.w   sp, r0
-00000076 <foo\+0x76> eb1d 0f40         cmn.w   sp, r0, lsl #1
-0000007a <foo\+0x7a> f1bd 0f00         cmp.w   sp, #0
-0000007e <foo\+0x7e> 4585              cmp     sp, r0
-00000080 <foo\+0x80> ebbd 0f40         cmp.w   sp, r0, lsl #1
-00000084 <foo\+0x84> b080              sub     sp, #0
-00000086 <foo\+0x86> f1bd 0d00         subs.w  sp, sp, #0
-0000008a <foo\+0x8a> f1ad 0000         sub.w   r0, sp, #0
-0000008e <foo\+0x8e> f1bd 0000         subs.w  r0, sp, #0
-00000092 <foo\+0x92> b001              add     sp, #4
-00000094 <foo\+0x94> a801              add     r0, sp, #4
-00000096 <foo\+0x96> f11d 0d04         adds.w  sp, sp, #4
-0000009a <foo\+0x9a> f11d 0004         adds.w  r0, sp, #4
-0000009e <foo\+0x9e> f20d 0004         addw    r0, sp, #4
-000000a2 <foo\+0xa2> b001              add     sp, #4
-000000a4 <foo\+0xa4> f11d 0d04         adds.w  sp, sp, #4
-000000a8 <foo\+0xa8> f20d 0d04         addw    sp, sp, #4
+00000040 <foo\+0x40> f8c0 d000         str.w   sp, \[r0\]
+00000044 <foo\+0x44> f8cd d000         str.w   sp, \[sp\]
+00000048 <foo\+0x48> f840 d00f         str.w   sp, \[r0, pc\]
+0000004c <foo\+0x4c> 4468              add     r0, sp
+0000004e <foo\+0x4e> eb1d 0000         adds.w  r0, sp, r0
+00000052 <foo\+0x52> eb0d 0040         add.w   r0, sp, r0, lsl #1
+00000056 <foo\+0x56> eb1d 0040         adds.w  r0, sp, r0, lsl #1
+0000005a <foo\+0x5a> f11d 0f00         cmn.w   sp, #0
+0000005e <foo\+0x5e> eb1d 0f00         cmn.w   sp, r0
+00000062 <foo\+0x62> eb1d 0f40         cmn.w   sp, r0, lsl #1
+00000066 <foo\+0x66> f1bd 0f00         cmp.w   sp, #0
+0000006a <foo\+0x6a> 4585              cmp     sp, r0
+0000006c <foo\+0x6c> ebbd 0f40         cmp.w   sp, r0, lsl #1
+00000070 <foo\+0x70> b080              sub     sp, #0
+00000072 <foo\+0x72> f1bd 0d00         subs.w  sp, sp, #0
+00000076 <foo\+0x76> f1ad 0000         sub.w   r0, sp, #0
+0000007a <foo\+0x7a> f1bd 0000         subs.w  r0, sp, #0
+0000007e <foo\+0x7e> b001              add     sp, #4
+00000080 <foo\+0x80> a801              add     r0, sp, #4
+00000082 <foo\+0x82> f11d 0d04         adds.w  sp, sp, #4
+00000086 <foo\+0x86> f11d 0004         adds.w  r0, sp, #4
+0000008a <foo\+0x8a> f20d 0004         addw    r0, sp, #4
+0000008e <foo\+0x8e> b001              add     sp, #4
+00000090 <foo\+0x90> f11d 0d04         adds.w  sp, sp, #4
+00000094 <foo\+0x94> f20d 0d04         addw    sp, sp, #4
+00000098 <foo\+0x98> 4485              add     sp, r0
+0000009a <foo\+0x9a> 4468              add     r0, sp
+0000009c <foo\+0x9c> eb0d 0040         add.w   r0, sp, r0, lsl #1
+000000a0 <foo\+0xa0> eb1d 0d00         adds.w  sp, sp, r0
+000000a4 <foo\+0xa4> eb1d 0000         adds.w  r0, sp, r0
+000000a8 <foo\+0xa8> eb1d 0040         adds.w  r0, sp, r0, lsl #1
 000000ac <foo\+0xac> 4485              add     sp, r0
-000000ae <foo\+0xae> 4468              add     r0, sp
-000000b0 <foo\+0xb0> eb0d 0040         add.w   r0, sp, r0, lsl #1
-000000b4 <foo\+0xb4> eb1d 0d00         adds.w  sp, sp, r0
-000000b8 <foo\+0xb8> eb1d 0000         adds.w  r0, sp, r0
-000000bc <foo\+0xbc> eb1d 0040         adds.w  r0, sp, r0, lsl #1
-000000c0 <foo\+0xc0> 4485              add     sp, r0
-000000c2 <foo\+0xc2> eb0d 0d40         add.w   sp, sp, r0, lsl #1
-000000c6 <foo\+0xc6> eb1d 0d00         adds.w  sp, sp, r0
-000000ca <foo\+0xca> eb1d 0d40         adds.w  sp, sp, r0, lsl #1
-000000ce <foo\+0xce> 44ed              add     sp, sp
-000000d0 <foo\+0xd0> f1ad 0000         sub.w   r0, sp, #0
-000000d4 <foo\+0xd4> f1bd 0000         subs.w  r0, sp, #0
-000000d8 <foo\+0xd8> f2ad 0000         subw    r0, sp, #0
-000000dc <foo\+0xdc> b080              sub     sp, #0
-000000de <foo\+0xde> f1bd 0d00         subs.w  sp, sp, #0
-000000e2 <foo\+0xe2> f2ad 0d00         subw    sp, sp, #0
-000000e6 <foo\+0xe6> b080              sub     sp, #0
-000000e8 <foo\+0xe8> f1bd 0d00         subs.w  sp, sp, #0
-000000ec <foo\+0xec> ebad 0040         sub.w   r0, sp, r0, lsl #1
-000000f0 <foo\+0xf0> ebbd 0040         subs.w  r0, sp, r0, lsl #1
-000000f4 <foo\+0xf4> ebad 0d40         sub.w   sp, sp, r0, lsl #1
-000000f8 <foo\+0xf8> ebbd 0d40         subs.w  sp, sp, r0, lsl #1
-000000fc <foo\+0xfc> a001              add     r0, pc, #4      ; \(adr r0, 00000104 <foo\+0x104>\)
-000000fe <foo\+0xfe> f2af 0004         subw    r0, pc, #4
-00000102 <foo\+0x102> f20f 0004        addw    r0, pc, #4
-00000106 <foo\+0x106> f2af 0004        subw    r0, pc, #4
-0000010a <foo\+0x10a> f20f 0004        addw    r0, pc, #4
-0000010e <foo\+0x10e> f2af 0004        subw    r0, pc, #4
-00000112 <foo\+0x112> bf00[    ]+nop
-00000114 <foo\+0x114> bf00[    ]+nop
-00000116 <foo\+0x116> bf00[    ]+nop
+000000ae <foo\+0xae> eb0d 0d40         add.w   sp, sp, r0, lsl #1
+000000b2 <foo\+0xb2> eb1d 0d00         adds.w  sp, sp, r0
+000000b6 <foo\+0xb6> eb1d 0d40         adds.w  sp, sp, r0, lsl #1
+000000ba <foo\+0xba> 44ed              add     sp, sp
+000000bc <foo\+0xbc> f1ad 0000         sub.w   r0, sp, #0
+000000c0 <foo\+0xc0> f1bd 0000         subs.w  r0, sp, #0
+000000c4 <foo\+0xc4> f2ad 0000         subw    r0, sp, #0
+000000c8 <foo\+0xc8> b080              sub     sp, #0
+000000ca <foo\+0xca> f1bd 0d00         subs.w  sp, sp, #0
+000000ce <foo\+0xce> f2ad 0d00         subw    sp, sp, #0
+000000d2 <foo\+0xd2> b080              sub     sp, #0
+000000d4 <foo\+0xd4> f1bd 0d00         subs.w  sp, sp, #0
+000000d8 <foo\+0xd8> ebad 0040         sub.w   r0, sp, r0, lsl #1
+000000dc <foo\+0xdc> ebbd 0040         subs.w  r0, sp, r0, lsl #1
+000000e0 <foo\+0xe0> ebad 0d40         sub.w   sp, sp, r0, lsl #1
+000000e4 <foo\+0xe4> ebbd 0d40         subs.w  sp, sp, r0, lsl #1
+000000e8 <foo\+0xe8> a001              add     r0, pc, #4      ; \(adr r0, 000000f0 <foo\+0xf0>\)
+000000ea <foo\+0xea> f2af 0004         subw    r0, pc, #4
+000000ee <foo\+0xee> f20f 0004         addw    r0, pc, #4
+000000f2 <foo\+0xf2> f2af 0004         subw    r0, pc, #4
+000000f6 <foo\+0xf6> f20f 0004         addw    r0, pc, #4
+000000fa <foo\+0xfa> f2af 0004         subw    r0, pc, #4
+000000fe <foo\+0xfe> bf00[     ]+nop
+00000100 <foo\+0x100> bf00[    ]+nop
+00000102 <foo\+0x102> bf00[    ]+nop
index cf38594..1756866 100644 (file)
@@ -38,13 +38,8 @@ ldr  sp, [pc]
 ldr    sp, [r0, +pc]
 
 str    r0, [sp]
-str    r0, [pc]
-str    pc, [r0]
 str    sp, [r0]
-str    pc, [pc]
 str    sp, [sp]
-str    pc, [sp]
-str    sp, [pc]
 str    sp, [r0, +pc]
 
 @ R13 as the first operand <Rn> in any add{s}, cmn, cmp, or sub{s} instruction.
diff --git a/gas/testsuite/gas/arm/sp-pc-validations-bad-t.d b/gas/testsuite/gas/arm/sp-pc-validations-bad-t.d
new file mode 100644 (file)
index 0000000..8579f43
--- /dev/null
@@ -0,0 +1,2 @@
+# name: Invalid SP and PC operands test - THUMB
+# error-output: sp-pc-validations-bad-t.l
diff --git a/gas/testsuite/gas/arm/sp-pc-validations-bad-t.l b/gas/testsuite/gas/arm/sp-pc-validations-bad-t.l
new file mode 100644 (file)
index 0000000..120f6f3
--- /dev/null
@@ -0,0 +1,243 @@
+[^:]*: Assembler messages:
+[^:]*:27: Error: branch must be last instruction in IT block -- `ldreq r15,\[r0\]'
+[^:]*:28: Error: branch must be last instruction in IT block -- `ldreq r15,\[r0,#0\]'
+[^:]*:29: Error: branch must be last instruction in IT block -- `ldreq r15,\[sp\]'
+[^:]*:30: Error: branch must be last instruction in IT block -- `ldreq r15,\[sp,#0\]'
+[^:]*:31: Error: branch must be last instruction in IT block -- `ldreq.w r15,\[r0\]'
+[^:]*:32: Error: branch must be last instruction in IT block -- `ldreq.w r15,\[r0,#0\]'
+[^:]*:33: Error: branch must be last instruction in IT block -- `ldreq r15,\[r0,#-4\]'
+[^:]*:34: Error: branch must be last instruction in IT block -- `ldreq r15,\[r0\],#4'
+[^:]*:35: Error: branch must be last instruction in IT block -- `ldreq r15,\[r0,#0\]!'
+[^:]*:38: Error: branch must be last instruction in IT block -- `ldreq r15,label'
+[^:]*:39: Error: branch must be last instruction in IT block -- `ldreq.w r15,label'
+[^:]*:40: Error: branch must be last instruction in IT block -- `ldreq.w r15,\[pc,#-0\]'
+[^:]*:43: Error: branch must be last instruction in IT block -- `ldreq r15,\[r0,r1\]'
+[^:]*:44: Error: branch must be last instruction in IT block -- `ldreq.w r15,\[r0,r1\]'
+[^:]*:45: Error: branch must be last instruction in IT block -- `ldreq.w r15,\[r0,r1,LSL#2\]'
+[^:]*:48: Error: r15 not allowed here -- `ldrb pc,\[r0,#4\]'
+[^:]*:50: Error: r13 not allowed here -- `ldrb.w sp,\[r0,#4\]'
+[^:]*:51: Error: r15 not allowed here -- `ldrb.w pc,\[r0,#4\]'
+[^:]*:52: Error: r15 not allowed here -- `ldrb pc,\[r0,#-4\]'
+[^:]*:54: Error: r15 not allowed here -- `ldrb pc,\[r0\],#4'
+[^:]*:55: Error: r13 not allowed here -- `ldrb sp,\[r0\],#4'
+[^:]*:56: Error: r15 not allowed here -- `ldrb pc,\[r0,#4\]!'
+[^:]*:57: Error: r13 not allowed here -- `ldrb sp,\[r0,#4\]!'
+[^:]*:60: Error: r15 not allowed here -- `ldrb pc,label'
+[^:]*:61: Error: r15 not allowed here -- `ldrb pc,\[PC,#-0\]'
+[^:]*:62: Error: r13 not allowed here -- `ldrb sp,label'
+[^:]*:63: Error: r13 not allowed here -- `ldrb sp,\[PC,#-0\]'
+[^:]*:66: Error: r15 not allowed here -- `ldrb pc,\[r0,r1\]'
+[^:]*:67: Error: cannot use register index with PC-relative addressing -- `ldrb r0,\[pc,r1\]'
+[^:]*:68: Error: r15 not allowed here -- `ldrb r0,\[r1,pc\]'
+[^:]*:69: Error: r15 not allowed here -- `ldrb.w pc,\[r0,r1,LSL#1\]'
+[^:]*:70: Error: r13 not allowed here -- `ldrb.w sp,\[r0,r1\]'
+[^:]*:71: Error: r15 not allowed here -- `ldrb.w r2,\[r0,pc,LSL#2\]'
+[^:]*:72: Error: r13 not allowed here -- `ldrb.w r2,\[r0,sp,LSL#2\]'
+[^:]*:75: Error: r15 not allowed here -- `ldrbt pc,\[r0,#4\]'
+[^:]*:76: Error: r13 not allowed here -- `ldrbt sp,\[r0,#4\]'
+[^:]*:79: Error: r15 not allowed here -- `ldrd pc,r0,\[r1\]'
+[^:]*:80: Error: r13 not allowed here -- `ldrd sp,r0,\[r1\]'
+[^:]*:81: Error: r15 not allowed here -- `ldrd r0,pc,\[r1\]'
+[^:]*:82: Error: r13 not allowed here -- `ldrd r0,sp,\[r1\]'
+[^:]*:83: Error: r15 not allowed here -- `ldrd pc,r0,\[r1\],#4'
+[^:]*:84: Error: r13 not allowed here -- `ldrd sp,r0,\[r1\],#4'
+[^:]*:85: Error: r15 not allowed here -- `ldrd r0,pc,\[r1\],#4'
+[^:]*:86: Error: r13 not allowed here -- `ldrd r0,sp,\[r1\],#4'
+[^:]*:87: Error: r15 not allowed here -- `ldrd pc,r0,\[r1,#4\]!'
+[^:]*:88: Error: r13 not allowed here -- `ldrd sp,r0,\[r1,#4\]!'
+[^:]*:89: Error: r15 not allowed here -- `ldrd r0,pc,\[r1,#4\]!'
+[^:]*:90: Error: r13 not allowed here -- `ldrd r0,sp,\[r1,#4\]!'
+[^:]*:93: Error: r15 not allowed here -- `ldrd pc,r0,label'
+[^:]*:94: Error: r13 not allowed here -- `ldrd sp,r0,label'
+[^:]*:95: Error: r15 not allowed here -- `ldrd r0,pc,label'
+[^:]*:96: Error: r13 not allowed here -- `ldrd r0,sp,label'
+[^:]*:97: Error: r15 not allowed here -- `ldrd pc,r0,\[pc,#-0\]'
+[^:]*:98: Error: r13 not allowed here -- `ldrd sp,r0,\[pc,#-0\]'
+[^:]*:99: Error: r15 not allowed here -- `ldrd r0,pc,\[pc,#-0\]'
+[^:]*:100: Error: r13 not allowed here -- `ldrd r0,sp,\[pc,#-0\]'
+[^:]*:105: Error: r15 not allowed here -- `ldrex pc,\[r0\]'
+[^:]*:106: Error: r13 not allowed here -- `ldrex sp,\[r0\]'
+[^:]*:107: Error: r15 not allowed here -- `ldrex r0,\[pc\]'
+[^:]*:108: Error: r15 not allowed here -- `ldrexb pc,\[r0\]'
+[^:]*:109: Error: r13 not allowed here -- `ldrexb sp,\[r0\]'
+[^:]*:110: Error: r15 not allowed here -- `ldrexb r0,\[pc\]'
+[^:]*:111: Error: r15 not allowed here -- `ldrexd pc,r0,\[r1\]'
+[^:]*:112: Error: r13 not allowed here -- `ldrexd sp,r0,\[r1\]'
+[^:]*:113: Error: r15 not allowed here -- `ldrexd r0,pc,\[r1\]'
+[^:]*:114: Error: r13 not allowed here -- `ldrexd r0,sp,\[r1\]'
+[^:]*:115: Error: r15 not allowed here -- `ldrexd r0,r1,\[pc\]'
+[^:]*:116: Error: r15 not allowed here -- `ldrexh pc,\[r0\]'
+[^:]*:117: Error: r13 not allowed here -- `ldrexh sp,\[r0\]'
+[^:]*:118: Error: r15 not allowed here -- `ldrexh r0,\[pc\]'
+[^:]*:121: Error: r15 not allowed here -- `ldrh pc,\[r0\]'
+[^:]*:122: Error: r15 not allowed here -- `ldrh pc,\[r0,#4\]'
+[^:]*:125: Error: r15 not allowed here -- `ldrh.w pc,\[r0\]'
+[^:]*:126: Error: r15 not allowed here -- `ldrh.w pc,\[r0,#4\]'
+[^:]*:127: Error: r13 not allowed here -- `ldrh.w sp,\[r0\]'
+[^:]*:128: Error: r13 not allowed here -- `ldrh.w sp,\[r0,#4\]'
+[^:]*:129: Error: r15 not allowed here -- `ldrh pc,\[r0,#-3\]'
+[^:]*:131: Error: r15 not allowed here -- `ldrh pc,\[r0\],#4'
+[^:]*:132: Error: r13 not allowed here -- `ldrh sp,\[r0\],#4'
+[^:]*:133: Error: r15 not allowed here -- `ldrh pc,\[r0,#4\]!'
+[^:]*:134: Error: r13 not allowed here -- `ldrh sp,\[r0,#4\]!'
+[^:]*:137: Error: r15 not allowed here -- `ldrh pc,label'
+[^:]*:138: Error: r15 not allowed here -- `ldrh pc,\[pc,#-0\]'
+[^:]*:139: Error: r13 not allowed here -- `ldrh sp,label'
+[^:]*:140: Error: r13 not allowed here -- `ldrh sp,\[pc,#-0\]'
+[^:]*:143: Error: r15 not allowed here -- `ldrh pc,\[r0,r1\]'
+[^:]*:144: Error: cannot use register index with PC-relative addressing -- `ldrh r0,\[pc,r1\]'
+[^:]*:145: Error: r15 not allowed here -- `ldrh r0,\[r1,pc\]'
+[^:]*:146: Error: r15 not allowed here -- `ldrh.w pc,\[r0,r1,LSL#1\]'
+[^:]*:147: Error: r13 not allowed here -- `ldrh.w sp,\[r0,r1,LSL#1\]'
+[^:]*:148: Error: r15 not allowed here -- `ldrh.w r2,\[r0,pc,LSL#1\]'
+[^:]*:149: Error: r13 not allowed here -- `ldrh.w r2,\[r0,sp,LSL#1\]'
+[^:]*:152: Error: r15 not allowed here -- `ldrht pc,\[r0,#4\]'
+[^:]*:153: Error: r13 not allowed here -- `ldrht sp,\[r0,#4\]'
+[^:]*:156: Error: r15 not allowed here -- `ldrsb pc,\[r0,#4\]'
+[^:]*:158: Error: r13 not allowed here -- `ldrsb sp,\[r0,#4\]'
+[^:]*:159: Error: r15 not allowed here -- `ldrsb pc,\[r0,#-4\]'
+[^:]*:160: Error: r13 not allowed here -- `ldrsb sp,\[r0,#-4\]'
+[^:]*:161: Error: r15 not allowed here -- `ldrsb pc,\[r0\],#4'
+[^:]*:162: Error: r13 not allowed here -- `ldrsb sp,\[r0\],#4'
+[^:]*:163: Error: r15 not allowed here -- `ldrsb pc,\[r0,#4\]!'
+[^:]*:164: Error: r13 not allowed here -- `ldrsb sp,\[r0,#4\]!'
+[^:]*:167: Error: r15 not allowed here -- `ldrsb pc,label'
+[^:]*:168: Error: r15 not allowed here -- `ldrsb pc,\[pc,#-0\]'
+[^:]*:169: Error: r13 not allowed here -- `ldrsb sp,label'
+[^:]*:170: Error: r13 not allowed here -- `ldrsb sp,\[pc,#-0\]'
+[^:]*:173: Error: r15 not allowed here -- `ldrsb pc,\[r0,r1\]'
+[^:]*:174: Error: cannot use register index with PC-relative addressing -- `ldrsb r0,\[pc,r1\]'
+[^:]*:175: Error: r15 not allowed here -- `ldrsb r0,\[r1,pc\]'
+[^:]*:176: Error: r15 not allowed here -- `ldrsb.w pc,\[r0,r1,LSL#2\]'
+[^:]*:178: Error: r13 not allowed here -- `ldrsb.w sp,\[r0,r1,LSL#2\]'
+[^:]*:179: Error: r15 not allowed here -- `ldrsb.w r2,\[r0,pc,LSL#2\]'
+[^:]*:180: Error: r13 not allowed here -- `ldrsb.w r2,\[r0,sp,LSL#2\]'
+[^:]*:184: Error: r15 not allowed here -- `ldrsbt pc,\[r0,#4\]'
+[^:]*:185: Error: r13 not allowed here -- `ldrsbt sp,\[r0,#4\]'
+[^:]*:189: Error: r15 not allowed here -- `ldrsh pc,\[r0,#4\]'
+[^:]*:190: Error: r13 not allowed here -- `ldrsh sp,\[r0,#4\]'
+[^:]*:191: Error: r15 not allowed here -- `ldrsh pc,\[r0,#-4\]'
+[^:]*:192: Error: r15 not allowed here -- `ldrsh pc,\[r0\],#4'
+[^:]*:193: Error: r15 not allowed here -- `ldrsh pc,\[r0,#4\]!'
+[^:]*:194: Error: r13 not allowed here -- `ldrsh sp,\[r0,#-4\]'
+[^:]*:195: Error: r13 not allowed here -- `ldrsh sp,\[r0\],#4'
+[^:]*:196: Error: r13 not allowed here -- `ldrsh sp,\[r0,#4\]!'
+[^:]*:199: Error: r15 not allowed here -- `ldrsh pc,label'
+[^:]*:200: Error: r13 not allowed here -- `ldrsh sp,label'
+[^:]*:201: Error: r13 not allowed here -- `ldrsh sp,\[pc,#-0\]'
+[^:]*:204: Error: r15 not allowed here -- `ldrsh pc,\[r0,r1\]'
+[^:]*:205: Error: cannot use register index with PC-relative addressing -- `ldrsh r0,\[pc,r1\]'
+[^:]*:206: Error: r15 not allowed here -- `ldrsh r0,\[r1,pc\]'
+[^:]*:208: Error: r15 not allowed here -- `ldrsh.w pc,\[r0,r1,LSL#3\]'
+[^:]*:209: Error: r13 not allowed here -- `ldrsh.w sp,\[r0,r1,LSL#3\]'
+[^:]*:210: Error: r13 not allowed here -- `ldrsh.w r0,\[r1,sp,LSL#3\]'
+[^:]*:211: Error: r15 not allowed here -- `ldrsh.w r0,\[r1,pc,LSL#3\]'
+[^:]*:215: Error: r15 not allowed here -- `ldrsht pc,\[r0,#4\]'
+[^:]*:216: Error: r13 not allowed here -- `ldrsht sp,\[r0,#4\]'
+[^:]*:220: Error: r15 not allowed here -- `ldrt pc,\[r0,#4\]'
+[^:]*:221: Error: r13 not allowed here -- `ldrt sp,\[r0,#4\]'
+[^:]*:226: Error: r15 not allowed here -- `str pc,\[r0,#4\]'
+[^:]*:227: Error: cannot use register index with PC-relative addressing -- `str.w r0,\[pc,#4\]'
+[^:]*:228: Error: cannot use register index with PC-relative addressing -- `str r0,\[pc,#-4\]'
+[^:]*:229: Error: cannot use post-indexing with PC-relative addressing -- `str r0,\[pc\],#4'
+[^:]*:230: Error: cannot use writeback with PC-relative addressing -- `str r0,\[pc,#4\]!'
+[^:]*:233: Error: cannot use register index with PC-relative addressing -- `str.w r0,\[pc,r1\]'
+[^:]*:234: Error: cannot use register index with PC-relative addressing -- `str.w r0,\[pc,r1,LSL#2\]'
+[^:]*:240: Error: cannot use register index with PC-relative addressing -- `strb.w r0,\[pc,#4\]'
+[^:]*:241: Error: r15 not allowed here -- `strb.w pc,\[r0,#4\]'
+[^:]*:242: Error: r13 not allowed here -- `strb.w sp,\[r0,#4\]'
+[^:]*:243: Error: cannot use register index with PC-relative addressing -- `strb r0,\[pc,#-4\]'
+[^:]*:244: Error: cannot use post-indexing with PC-relative addressing -- `strb r0,\[pc\],#4'
+[^:]*:245: Error: cannot use writeback with PC-relative addressing -- `strb r0,\[pc,#4\]!'
+[^:]*:246: Error: r15 not allowed here -- `strb pc,\[r0,#-4\]'
+[^:]*:247: Error: r15 not allowed here -- `strb pc,\[r0\],#4'
+[^:]*:248: Error: r15 not allowed here -- `strb pc,\[r0,#4\]!'
+[^:]*:249: Error: r13 not allowed here -- `strb sp,\[r0,#-4\]'
+[^:]*:250: Error: r13 not allowed here -- `strb sp,\[r0\],#4'
+[^:]*:251: Error: r13 not allowed here -- `strb sp,\[r0,#4\]!'
+[^:]*:254: Error: cannot use register index with PC-relative addressing -- `strb.w r0,\[pc,r1\]'
+[^:]*:255: Error: cannot use register index with PC-relative addressing -- `strb.w r0,\[pc,r1,LSL#2\]'
+[^:]*:256: Error: r15 not allowed here -- `strb.w pc,\[r0,r1\]'
+[^:]*:257: Error: r15 not allowed here -- `strb.w pc,\[r0,r1,LSL#2\]'
+[^:]*:258: Error: r13 not allowed here -- `strb.w sp,\[r0,r1\]'
+[^:]*:259: Error: r13 not allowed here -- `strb.w sp,\[r0,r1,LSL#2\]'
+[^:]*:260: Error: r15 not allowed here -- `strb.w r0,\[r1,pc\]'
+[^:]*:261: Error: r15 not allowed here -- `strb.w r0,\[r1,pc,LSL#2\]'
+[^:]*:262: Error: r13 not allowed here -- `strb.w r0,\[r1,sp\]'
+[^:]*:263: Error: r13 not allowed here -- `strb.w r0,\[r1,sp,LSL#2\]'
+[^:]*:266: Error: cannot use register index with PC-relative addressing -- `strbt r0,\[pc,#4\]'
+[^:]*:267: Error: r15 not allowed here -- `strbt pc,\[r0,#4\]'
+[^:]*:268: Error: r13 not allowed here -- `strbt sp,\[r0,#4\]'
+[^:]*:271: Error: cannot use register index with PC-relative addressing -- `strd r0,r1,\[pc,#4\]'
+[^:]*:272: Error: cannot use post-indexing with PC-relative addressing -- `strd r0,r1,\[pc\],#4'
+[^:]*:273: Error: cannot use writeback with PC-relative addressing -- `strd r0,r1,\[pc,#4\]!'
+[^:]*:274: Error: r15 not allowed here -- `strd pc,r0,\[r1,#4\]'
+[^:]*:275: Error: r15 not allowed here -- `strd pc,r0,\[r1\],#4'
+[^:]*:276: Error: r15 not allowed here -- `strd pc,r0,\[r1,#4\]!'
+[^:]*:277: Error: r13 not allowed here -- `strd sp,r0,\[r1,#4\]'
+[^:]*:278: Error: r13 not allowed here -- `strd sp,r0,\[r1\],#4'
+[^:]*:279: Error: r13 not allowed here -- `strd sp,r0,\[r1,#4\]!'
+[^:]*:280: Error: r15 not allowed here -- `strd r0,pc,\[r1,#4\]'
+[^:]*:281: Error: r15 not allowed here -- `strd r0,pc,\[r1\],#4'
+[^:]*:282: Error: r15 not allowed here -- `strd r0,pc,\[r1,#4\]!'
+[^:]*:283: Error: r13 not allowed here -- `strd r0,sp,\[r1,#4\]'
+[^:]*:284: Error: r13 not allowed here -- `strd r0,sp,\[r1\],#4'
+[^:]*:285: Error: r13 not allowed here -- `strd r0,sp,\[r1,#4\]!'
+[^:]*:291: Error: r15 not allowed here -- `strex pc,r0,\[r1\]'
+[^:]*:292: Error: r15 not allowed here -- `strex pc,r0,\[r1,#4\]'
+[^:]*:293: Error: r13 not allowed here -- `strex sp,r0,\[r1\]'
+[^:]*:294: Error: r13 not allowed here -- `strex sp,r0,\[r1,#4\]'
+[^:]*:295: Error: r15 not allowed here -- `strex r0,pc,\[r1\]'
+[^:]*:296: Error: r15 not allowed here -- `strex r0,pc,\[r1,#4\]'
+[^:]*:297: Error: r13 not allowed here -- `strex r0,sp,\[r1\]'
+[^:]*:298: Error: r13 not allowed here -- `strex r0,sp,\[r1,#4\]'
+[^:]*:299: Error: r15 not allowed here -- `strex r0,r1,\[pc\]'
+[^:]*:300: Error: r15 not allowed here -- `strex r0,r1,\[pc,#4\]'
+[^:]*:303: Error: r15 not allowed here -- `strexb pc,r0,\[r1\]'
+[^:]*:304: Error: r13 not allowed here -- `strexb sp,r0,\[r1\]'
+[^:]*:305: Error: r15 not allowed here -- `strexb r0,pc,\[r1\]'
+[^:]*:306: Error: r13 not allowed here -- `strexb r0,sp,\[r1\]'
+[^:]*:307: Error: r15 not allowed here -- `strexb r0,r1,\[pc\]'
+[^:]*:310: Error: r15 not allowed here -- `strexd pc,r0,r1,\[r2\]'
+[^:]*:311: Error: r13 not allowed here -- `strexd sp,r0,r1,\[r2\]'
+[^:]*:312: Error: r15 not allowed here -- `strexd r0,pc,r1,\[r2\]'
+[^:]*:313: Error: r13 not allowed here -- `strexd r0,sp,r1,\[r2\]'
+[^:]*:314: Error: r15 not allowed here -- `strexd r0,r1,pc,\[r2\]'
+[^:]*:315: Error: r13 not allowed here -- `strexd r0,r1,sp,\[r2\]'
+[^:]*:316: Error: r15 not allowed here -- `strexd r0,r1,r2,\[pc\]'
+[^:]*:319: Error: r15 not allowed here -- `strexh pc,r0,\[r1\]'
+[^:]*:320: Error: r13 not allowed here -- `strexh sp,r0,\[r1\]'
+[^:]*:321: Error: r15 not allowed here -- `strexh r0,pc,\[r1\]'
+[^:]*:322: Error: r13 not allowed here -- `strexh r0,sp,\[r1\]'
+[^:]*:323: Error: r15 not allowed here -- `strexh r0,r1,\[pc\]'
+[^:]*:326: Error: cannot use register index with PC-relative addressing -- `strh.w r0,\[pc\]'
+[^:]*:327: Error: cannot use register index with PC-relative addressing -- `strh.w r0,\[pc,#4\]'
+[^:]*:328: Error: cannot use register index with PC-relative addressing -- `strh r0,\[pc,#-4\]'
+[^:]*:329: Error: cannot use post-indexing with PC-relative addressing -- `strh r0,\[pc\],#4'
+[^:]*:330: Error: cannot use writeback with PC-relative addressing -- `strh r0,\[pc,#4\]!'
+[^:]*:333: Error: cannot use register index with PC-relative addressing -- `strh.w r0,\[pc,r1\]'
+[^:]*:334: Error: cannot use register index with PC-relative addressing -- `strh.w r0,\[pc,r1,LSL#2\]'
+[^:]*:335: Error: r15 not allowed here -- `strh.w pc,\[r0,#4\]'
+[^:]*:336: Error: r15 not allowed here -- `strh.w pc,\[r0\]'
+[^:]*:337: Error: r13 not allowed here -- `strh.w sp,\[r0,#4\]'
+[^:]*:338: Error: r13 not allowed here -- `strh.w sp,\[r0\]'
+[^:]*:339: Error: r15 not allowed here -- `strh pc,\[r0,#-4\]'
+[^:]*:340: Error: r15 not allowed here -- `strh pc,\[r0\],#4'
+[^:]*:341: Error: r15 not allowed here -- `strh pc,\[r0,#4\]!'
+[^:]*:342: Error: r13 not allowed here -- `strh sp,\[r0,#-4\]'
+[^:]*:343: Error: r13 not allowed here -- `strh sp,\[r0\],#4'
+[^:]*:344: Error: r13 not allowed here -- `strh sp,\[r0,#4\]!'
+[^:]*:345: Error: r15 not allowed here -- `strh.w pc,\[r0,r1\]'
+[^:]*:346: Error: r13 not allowed here -- `strh.w sp,\[r0,r1\]'
+[^:]*:347: Error: r15 not allowed here -- `strh.w r0,\[r1,pc\]'
+[^:]*:348: Error: r13 not allowed here -- `strh.w r0,\[r1,sp\]'
+[^:]*:349: Error: r15 not allowed here -- `strh.w pc,\[r0,r1,LSL#2\]'
+[^:]*:350: Error: r13 not allowed here -- `strh.w sp,\[r0,r1,LSL#2\]'
+[^:]*:351: Error: r15 not allowed here -- `strh.w r0,\[r1,pc,LSL#2\]'
+[^:]*:352: Error: r13 not allowed here -- `strh.w r0,\[r1,sp,LSL#2\]'
+[^:]*:355: Error: cannot use register index with PC-relative addressing -- `strht r0,\[pc,#4\]'
+[^:]*:356: Error: r15 not allowed here -- `strht pc,\[r0,#4\]'
+[^:]*:357: Error: r13 not allowed here -- `strht sp,\[pc,#4\]'
+[^:]*:360: Error: cannot use register index with PC-relative addressing -- `strt r0,\[pc,#4\]'
+[^:]*:361: Error: r15 not allowed here -- `strt pc,\[r0,#4\]'
+[^:]*:362: Error: r13 not allowed here -- `strt sp,\[r0,#4\]'
diff --git a/gas/testsuite/gas/arm/sp-pc-validations-bad-t.s b/gas/testsuite/gas/arm/sp-pc-validations-bad-t.s
new file mode 100644 (file)
index 0000000..4252cba
--- /dev/null
@@ -0,0 +1,367 @@
+.syntax unified
+.thumb
+
+.macro it_test opcode operands:vararg
+itt eq
+\opcode\()eq r15, \operands
+moveq r0, r0
+.endm
+
+.macro it_testw opcode operands:vararg
+itt eq
+\opcode\()eq.w r15, \operands
+moveq r0, r0
+.endm
+
+.macro LOAD operands:vararg
+it_test ldr, \operands
+.endm
+
+.macro LOADw operands:vararg
+it_testw ldr, \operands
+.endm
+
+@ Loads ===============================================================
+
+@ LDR (register)
+LOAD  [r0]
+LOAD  [r0,#0]
+LOAD  [sp]
+LOAD  [sp,#0]
+LOADw [r0]
+LOADw [r0,#0]
+LOAD  [r0,#-4]
+LOAD  [r0],#4
+LOAD  [r0,#0]!
+
+@ LDR (literal)
+LOAD  label
+LOADw label
+LOADw [pc, #-0]
+
+@ LDR (register)
+LOAD  [r0, r1]
+LOADw [r0, r1]
+LOADw [r0, r1, LSL #2]
+
+@ LDRB (immediate, Thumb)
+ldrb   pc, [r0,#4]                     @ low reg
+@ldrb  r0, [pc,#4]                     @ ALLOWED!
+ldrb.w sp, [r0,#4]                     @ Unpredictable
+ldrb.w pc, [r0,#4]                     @ => PLD
+ldrb   pc, [r0, #-4]                   @ => PLD
+@ LDRB<c><q> <Rt>, [<Rn>, #+<imm>]     => See LDRBT
+ldrb   pc, [r0],#4                     @ BadReg
+ldrb   sp, [r0],#4                     @ ditto
+ldrb   pc,[r0,#4]!                     @ ditto
+ldrb   sp,[r0,#4]!                     @ ditto
+
+@ LDRB (literal)
+ldrb   pc,label                        @ => PLD
+ldrb   pc,[PC,#-0]                     @ => PLD (special case)
+ldrb   sp,label                        @ Unpredictable
+ldrb   sp,[PC,#-0]                     @ ditto
+
+@ LDRB (register)
+ldrb   pc,[r0,r1]                      @ low reg
+ldrb   r0,[pc,r1]                      @ ditto
+ldrb   r0,[r1,pc]                      @ ditto
+ldrb.w pc,[r0,r1,LSL #1]               @ => PLD
+ldrb.w sp,[r0,r1]                      @ Unpredictable
+ldrb.w r2,[r0,pc,LSL #2]               @ BadReg
+ldrb.w r2,[r0,sp,LSL #2]               @ ditto
+
+@ LDRBT
+ldrbt  pc, [r0, #4]                    @ BadReg
+ldrbt  sp, [r0, #4]                    @ ditto
+
+@ LDRD (immediate)
+ldrd pc, r0, [r1]                      @ BadReg
+ldrd sp, r0, [r1]                      @ ditto
+ldrd r0, pc, [r1]                      @ ditto
+ldrd r0, sp, [r1]                      @ ditto
+ldrd pc, r0, [r1], #4                  @ ditto
+ldrd sp, r0, [r1], #4                  @ ditto
+ldrd r0, pc, [r1], #4                  @ ditto
+ldrd r0, sp, [r1], #4                  @ ditto
+ldrd pc, r0, [r1, #4]!                 @ ditto
+ldrd sp, r0, [r1, #4]!                 @ ditto
+ldrd r0, pc, [r1, #4]!                 @ ditto
+ldrd r0, sp, [r1, #4]!                 @ ditto
+
+@ LDRD (literal)
+ldrd pc, r0, label                     @ BadReg
+ldrd sp, r0, label                     @ ditto
+ldrd r0, pc, label                     @ ditto
+ldrd r0, sp, label                     @ ditto
+ldrd pc, r0, [pc, #-0]                 @ ditto
+ldrd sp, r0, [pc, #-0]                 @ ditto
+ldrd r0, pc, [pc, #-0]                 @ ditto
+ldrd r0, sp, [pc, #-0]                 @ ditto
+
+@ LDRD (register): ARM only
+
+@ LDREX/B/D/H
+ldrex  pc, [r0]                                @ BadReg
+ldrex  sp, [r0]                                @ ditto
+ldrex  r0, [pc]                                @ Unpredictable
+ldrexb pc, [r0]                                @ BadReg
+ldrexb sp, [r0]                                @ ditto
+ldrexb r0, [pc]                                @ Unpredictable
+ldrexd pc, r0, [r1]                    @ BadReg
+ldrexd sp, r0, [r1]                    @ ditto
+ldrexd r0, pc, [r1]                    @ ditto
+ldrexd r0, sp, [r1]                    @ ditto
+ldrexd r0, r1, [pc]                    @ Unpredictable
+ldrexh pc, [r0]                                @ BadReg
+ldrexh sp, [r0]                                @ ditto
+ldrexh r0, [pc]                                @ Unpredictable
+
+@ LDRH (immediate)
+ldrh pc, [r0]                          @ low reg
+ldrh pc, [r0, #4]                      @ ditto
+@ldrh r0, [pc]                         @ ALLOWED!
+@ldrh r0, [pc, #4]                     @ ditto
+ldrh.w pc, [r0]                                @ => Unallocated memory hints
+ldrh.w pc, [r0, #4]                    @ ditto
+ldrh.w sp, [r0]                                @ Unpredictable
+ldrh.w sp, [r0, #4]                    @ ditto
+ldrh pc, [r0, #-3]                     @ => Unallocated memory hint
+@ LDRH<c><q> <Rt>, [<Rn>, #+<imm>]     => See LDRHT
+ldrh pc,[r0],#4                                @ BadReg
+ldrh sp,[r0],#4                                @ ditto
+ldrh pc,[r0,#4]!                       @ ditto
+ldrh sp,[r0,#4]!                       @ ditto
+
+@ LDRH (literal)
+ldrh pc, label                         @ Unallocated memory hint
+ldrh pc, [pc, #-0]                     @ ditto
+ldrh sp, label                         @ Unpredictable
+ldrh sp, [pc, #-0]                     @ ditto
+
+@ LDRH (register)
+ldrh pc, [r0, r1]                      @ low reg
+ldrh r0, [pc, r1]                      @ ditto
+ldrh r0, [r1, pc]                      @ ditto
+ldrh.w pc,[r0,r1,LSL #1]               @ => Unallocated memory hints
+ldrh.w sp,[r0,r1,LSL #1]               @ Unpredictable
+ldrh.w r2,[r0,pc,LSL #1]               @ ditto
+ldrh.w r2,[r0,sp,LSL #1]               @ ditto
+
+@ LDRHT
+ldrht pc, [r0, #4]                     @ BadReg
+ldrht sp, [r0, #4]                     @ ditto
+
+@ LDRSB (immediate)
+ldrsb pc, [r0, #4]                     @ => PLI
+@ldrsb r0, [pc, #4]                    => LDRSB (literal)
+ldrsb sp, [r0, #4]                     @ Unpredictable
+ldrsb pc, [r0, #-4]                    @ => PLI
+ldrsb sp,[r0,#-4]                      @ BadReg
+ldrsb pc,[r0],#4                       @ ditto
+ldrsb sp,[r0],#4                       @ ditto
+ldrsb pc,[r0,#4]!                      @ ditto
+ldrsb sp,[r0,#4]!                      @ ditto
+
+@ LDRSB (literal)
+ldrsb pc, label                                @ => PLI
+ldrsb pc, [pc, #-0]                    @ => PLI
+ldrsb sp, label                                @ Unpredictable
+ldrsb sp, [pc, #-0]                    @ ditto
+
+@ LDRSB (register)
+ldrsb pc, [r0, r1]                     @ low reg
+ldrsb r0, [pc, r1]                     @ ditto
+ldrsb r0, [r1, pc]                     @ ditto
+ldrsb.w pc, [r0, r1, LSL #2]           @ => PLI
+@ldrsb.w r0, [pc, r0, LSL #2]          => LDRSB (literal)
+ldrsb.w sp, [r0, r1, LSL #2]           @ Unpredictable
+ldrsb.w r2, [r0, pc, LSL #2]           @ ditto
+ldrsb.w r2, [r0, sp, LSL #2]           @ ditto
+
+@ LDRSBT
+@ldrsbt r0, [pc, #4]                   => LDRSB (literal)
+ldrsbt pc, [r0, #4]                    @ BadReg
+ldrsbt sp, [r0, #4]                    @ ditto
+
+@ LDRSH (immediate)
+@ldrsh r0,[pc,#4]                      => LDRSH (literal)
+ldrsh pc,[r0,#4]                       @ => Unallocated memory hints
+ldrsh sp,[r0,#4]                       @ Unpredictable
+ldrsh pc, [r0, #-4]                    @ => Unallocated memory hints
+ldrsh pc,[r0],#4                       @ BadReg
+ldrsh pc,[r0,#4]!                      @ ditto
+ldrsh sp,[r0,#-4]                      @ ditto
+ldrsh sp,[r0],#4                       @ ditto
+ldrsh sp,[r0,#4]!                      @ ditto
+
+@ LDRSH (literal)
+ldrsh pc, label                                @ => Unallocated memory hints
+ldrsh sp, label                                @ Unpredictable
+ldrsh sp, [pc,#-0]                     @ ditto
+
+@ LDRSH (register)
+ldrsh pc,[r0,r1]                       @ low reg
+ldrsh r0,[pc,r1]                       @ ditto
+ldrsh r0,[r1,pc]                       @ ditto
+@ldrsh.w r0,[pc,r1,LSL #3]             => LDRSH (literal)
+ldrsh.w pc,[r0,r1,LSL #3]              @ => Unallocated memory hints
+ldrsh.w sp,[r0,r1,LSL #3]              @ Unpredictable
+ldrsh.w r0,[r1,sp,LSL #3]              @ BadReg
+ldrsh.w r0,[r1,pc,LSL #3]              @ ditto
+
+@ LDRSHT
+@ldrsht r0,[pc,#4]                     => LDRSH (literal)
+ldrsht pc,[r0,#4]                      @ BadReg
+ldrsht sp,[r0,#4]                      @ ditto
+
+@ LDRT
+@ldrt r0,[pc,#4]                       => LDR (literal)
+ldrt pc,[r0,#4]                                @ BadReg
+ldrt sp,[r0,#4]                                @ ditto
+
+@ Stores ==============================================================
+
+@ STR (immediate, Thumb)
+str pc, [r0, #4]                       @ Unpredictable
+str.w r0, [pc, #4]                     @ Undefined
+str r0, [pc, #-4]                      @ ditto
+str r0, [pc], #4                       @ ditto
+str r0, [pc, #4]!                      @ ditto
+
+@ STR (register)
+str.w r0,[pc,r1]                       @ Undefined
+str.w r0,[pc,r1,LSL #2]                        @ ditto
+@str.w pc,[r0,r1{,LSL #<imm2>}]                @ Unpredictable
+@str.w r1,[r0,sp{,LSL #<imm2>}]                @ ditto
+@str.w r1,[r0,pc{,LSL #<imm2>}]                @ ditto
+
+@ STRB (immediate, Thumb)
+strb.w r0,[pc,#4]                      @ Undefined
+strb.w pc,[r0,#4]                      @ Unpredictable
+strb.w sp,[r0,#4]                      @ ditto
+strb r0,[pc,#-4]                       @ Undefined
+strb r0,[pc],#4                                @ ditto
+strb r0,[pc,#4]!                       @ ditto
+strb pc,[r0,#-4]                       @ Unpredictable
+strb pc,[r0],#4                                @ ditto
+strb pc,[r0,#4]!                       @ ditto
+strb sp,[r0,#-4]                       @ ditto
+strb sp,[r0],#4                                @ ditto
+strb sp,[r0,#4]!                       @ ditto
+
+@ STRB (register)
+strb.w r0,[pc,r1]                      @ Undefined
+strb.w r0,[pc,r1,LSL #2]               @ ditto
+strb.w pc,[r0,r1]                      @ Unpredictable
+strb.w pc,[r0,r1,LSL #2]               @ ditto
+strb.w sp,[r0,r1]                      @ ditto
+strb.w sp,[r0,r1,LSL #2]               @ ditto
+strb.w r0,[r1,pc]                      @ ditto
+strb.w r0,[r1,pc,LSL #2]               @ ditto
+strb.w r0,[r1,sp]                      @ ditto
+strb.w r0,[r1,sp,LSL #2]               @ ditto
+
+@ STRBT
+strbt r0,[pc,#4]                       @ Undefined
+strbt pc,[r0,#4]                       @ Unpredictable
+strbt sp,[r0,#4]                       @ ditto
+
+@ STRD (immediate)
+strd r0,r1,[pc,#4]                     @ Unpredictable
+strd r0,r1,[pc],#4                     @ ditto
+strd r0,r1,[pc,#4]!                    @ ditto
+strd pc,r0,[r1,#4]                     @ ditto
+strd pc,r0,[r1],#4                     @ ditto
+strd pc,r0,[r1,#4]!                    @ ditto
+strd sp,r0,[r1,#4]                     @ ditto
+strd sp,r0,[r1],#4                     @ ditto
+strd sp,r0,[r1,#4]!                    @ ditto
+strd r0,pc,[r1,#4]                     @ ditto
+strd r0,pc,[r1],#4                     @ ditto
+strd r0,pc,[r1,#4]!                    @ ditto
+strd r0,sp,[r1,#4]                     @ ditto
+strd r0,sp,[r1],#4                     @ ditto
+strd r0,sp,[r1,#4]!                    @ ditto
+
+@ STRD (register)
+@No thumb.
+
+@ STREX
+strex pc,r0,[r1]                       @ Unpredictable
+strex pc,r0,[r1,#4]                    @ ditto
+strex sp,r0,[r1]                       @ ditto
+strex sp,r0,[r1,#4]                    @ ditto
+strex r0,pc,[r1]                       @ ditto
+strex r0,pc,[r1,#4]                    @ ditto
+strex r0,sp,[r1]                       @ ditto
+strex r0,sp,[r1,#4]                    @ ditto
+strex r0,r1,[pc]                       @ ditto
+strex r0,r1,[pc,#4]                    @ ditto
+
+@ STREXB
+strexb pc,r0,[r1]                      @ Unpredictable
+strexb sp,r0,[r1]                      @ ditto
+strexb r0,pc,[r1]                      @ ditto
+strexb r0,sp,[r1]                      @ ditto
+strexb r0,r1,[pc]                      @ ditto
+
+@ STREXD
+strexd pc,r0,r1,[r2]                   @ Unpredictable
+strexd sp,r0,r1,[r2]                   @ ditto
+strexd r0,pc,r1,[r2]                   @ ditto
+strexd r0,sp,r1,[r2]                   @ ditto
+strexd r0,r1,pc,[r2]                   @ ditto
+strexd r0,r1,sp,[r2]                   @ ditto
+strexd r0,r1,r2,[pc]                   @ ditto
+
+@ STREXH
+strexh pc,r0,[r1]                      @ Unpredictable
+strexh sp,r0,[r1]                      @ ditto
+strexh r0,pc,[r1]                      @ ditto
+strexh r0,sp,[r1]                      @ ditto
+strexh r0,r1,[pc]                      @ ditto
+
+@ STRH (immediate, Thumb)
+strh.w r0,[pc]                         @ Undefined
+strh.w r0,[pc,#4]                      @ ditto
+strh r0,[pc,#-4]                       @ ditto
+strh r0,[pc],#4                                @ ditto
+strh r0,[pc,#4]!                       @ ditto
+
+@ STRH (register)
+strh.w r0,[pc,r1]                      @ Undefined
+strh.w r0,[pc,r1,LSL #2]               @ ditto
+strh.w pc,[r0,#4]                      @ Unpredictable
+strh.w pc,[r0]                         @ ditto
+strh.w sp,[r0,#4]                      @ ditto
+strh.w sp,[r0]                         @ ditto
+strh pc,[r0,#-4]                       @ ditto
+strh pc,[r0],#4                                @ ditto
+strh pc,[r0,#4]!                       @ ditto
+strh sp,[r0,#-4]                       @ ditto
+strh sp,[r0],#4                                @ ditto
+strh sp,[r0,#4]!                       @ ditto
+strh.w pc,[r0,r1]                      @ ditto
+strh.w sp,[r0,r1]                      @ ditto
+strh.w r0,[r1,pc]                      @ ditto
+strh.w r0,[r1,sp]                      @ ditto
+strh.w pc,[r0,r1,LSL #2]               @ ditto
+strh.w sp,[r0,r1,LSL #2]               @ ditto
+strh.w r0,[r1,pc,LSL #2]               @ ditto
+strh.w r0,[r1,sp,LSL #2]               @ ditto
+
+@ STRHT
+strht r0,[pc,#4]                       @ Undefined
+strht pc,[r0,#4]                       @ Unpredictable
+strht sp,[pc,#4]                       @ ditto
+
+@ STRT
+strt r0,[pc,#4]                                @ Undefined
+strt pc,[r0,#4]                                @ Unpredictable
+strt sp,[r0,#4]                                @ ditto
+
+@ ============================================================================
+
+.label:
+ldr r0, [r1]
diff --git a/gas/testsuite/gas/arm/sp-pc-validations-bad.d b/gas/testsuite/gas/arm/sp-pc-validations-bad.d
new file mode 100644 (file)
index 0000000..558a683
--- /dev/null
@@ -0,0 +1,2 @@
+# name: Invalid SP and PC operands test - ARM
+# error-output: sp-pc-validations-bad.l
diff --git a/gas/testsuite/gas/arm/sp-pc-validations-bad.l b/gas/testsuite/gas/arm/sp-pc-validations-bad.l
new file mode 100644 (file)
index 0000000..002dbb2
--- /dev/null
@@ -0,0 +1,172 @@
+[^:]*: Assembler messages:
+[^:]*:11: Error: cannot use register index with PC-relative addressing -- `ldr r0,\[r1,pc,LSL#2\]'
+[^:]*:12: Error: cannot use register index with PC-relative addressing -- `ldr r0,\[r1,pc,LSL#2\]!'
+[^:]*:13: Error: cannot use register index with PC-relative addressing -- `ldr r0,\[r1\],pc,LSL#2'
+[^:]*:14: Error: cannot use register index with PC-relative addressing -- `ldr r0,\[pc,r1,LSL#2\]!'
+[^:]*:15: Error: cannot use register index with PC-relative addressing -- `ldr r0,\[pc\],r1,LSL#2'
+[^:]*:18: Error: r15 not allowed here -- `ldrb pc,\[r0,#4\]'
+[^:]*:19: Error: r15 not allowed here -- `ldrb pc,\[r0\],#4'
+[^:]*:20: Error: r15 not allowed here -- `ldrb pc,\[r0,#4\]!'
+[^:]*:23: Error: r15 not allowed here -- `ldrb pc,label'
+[^:]*:24: Error: r15 not allowed here -- `ldrb pc,\[pc,#-0\]'
+[^:]*:27: Error: r15 not allowed here -- `ldrb pc,\[r0,r1,LSL#2\]'
+[^:]*:28: Error: r15 not allowed here -- `ldrb pc,\[r0,r1,LSL#2\]!'
+[^:]*:29: Error: r15 not allowed here -- `ldrb pc,\[r0\],r1,LSL#2'
+[^:]*:30: Error: cannot use register index with PC-relative addressing -- `ldrb r0,\[r1,pc,LSL#2\]'
+[^:]*:31: Error: cannot use register index with PC-relative addressing -- `ldrb r0,\[r1,pc,LSL#2\]!'
+[^:]*:32: Error: cannot use register index with PC-relative addressing -- `ldrb r0,\[r1\],pc,LSL#2'
+[^:]*:33: Error: cannot use register index with PC-relative addressing -- `ldrb r0,\[pc,r1,LSL#2\]!'
+[^:]*:34: Error: cannot use register index with PC-relative addressing -- `ldrb r0,\[pc\],r1,LSL#2'
+[^:]*:37: Error: r15 not allowed here -- `ldrbt pc,\[r0\],#4'
+[^:]*:38: Error: cannot use register index with PC-relative addressing -- `ldrbt r0,\[pc\],#4'
+[^:]*:39: Error: r15 not allowed here -- `ldrbt pc,\[r0\],r1,LSL#4'
+[^:]*:40: Error: cannot use register index with PC-relative addressing -- `ldrbt r0,\[pc\],r1,LSL#4'
+[^:]*:41: Error: cannot use register index with PC-relative addressing -- `ldrbt r0,\[r1\],pc,LSL#4'
+[^:]*:44: Error: r15 not allowed here -- `ldrd r0,pc,\[r1,#4\]'
+[^:]*:45: Error: r15 not allowed here -- `ldrd r0,pc,\[r1\],#4'
+[^:]*:46: Error: r15 not allowed here -- `ldrd r0,pc,\[r1,#4\]!'
+[^:]*:49: Error: r15 not allowed here -- `ldrd r0,pc,label'
+[^:]*:50: Error: r15 not allowed here -- `ldrd r0,pc,\[PC,#-0\]'
+[^:]*:53: Error: r15 not allowed here -- `ldrd r0,pc,\[r1,r2\]'
+[^:]*:54: Error: r15 not allowed here -- `ldrd r0,pc,\[r1,r2\]!'
+[^:]*:55: Error: r15 not allowed here -- `ldrd r0,pc,\[r1\],r2'
+[^:]*:56: Error: cannot use register index with PC-relative addressing -- `ldrd r0,r1,\[r2,pc\]'
+[^:]*:57: Error: cannot use register index with PC-relative addressing -- `ldrd r0,r1,\[r2,pc\]!'
+[^:]*:58: Error: cannot use register index with PC-relative addressing -- `ldrd r0,r1,\[r2\],pc'
+[^:]*:59: Error: cannot use register index with PC-relative addressing -- `ldrd r0,r1,\[pc,r2\]!'
+[^:]*:60: Error: cannot use register index with PC-relative addressing -- `ldrd r0,r1,\[pc\],r2'
+[^:]*:63: Error: r15 not allowed here -- `ldrex pc,\[r0\]'
+[^:]*:64: Error: instruction does not accept this addressing mode -- `ldrex r0,\[pc\]'
+[^:]*:67: Error: r15 not allowed here -- `ldrexb pc,\[r0\]'
+[^:]*:68: Error: r15 not allowed here -- `ldrexb r0,\[pc\]'
+[^:]*:71: Error: r15 not allowed here -- `ldrexd r0,r1,\[pc\]'
+[^:]*:74: Error: r15 not allowed here -- `ldrexh pc,\[r0\]'
+[^:]*:75: Error: r15 not allowed here -- `ldrexh r0,\[pc\]'
+[^:]*:78: Error: r15 not allowed here -- `ldrh pc,\[r0,#4\]'
+[^:]*:79: Error: r15 not allowed here -- `ldrh pc,\[r0\],#4'
+[^:]*:80: Error: r15 not allowed here -- `ldrh pc,\[r0,#4\]!'
+[^:]*:83: Error: r15 not allowed here -- `ldrh pc,label'
+[^:]*:84: Error: r15 not allowed here -- `ldrh pc,\[pc,#-0\]'
+[^:]*:87: Error: r15 not allowed here -- `ldrh pc,\[r0,r1\]'
+[^:]*:88: Error: r15 not allowed here -- `ldrh pc,\[r0,r1\]!'
+[^:]*:89: Error: r15 not allowed here -- `ldrh pc,\[r0\],r1'
+[^:]*:90: Error: cannot use register index with PC-relative addressing -- `ldrh r0,\[r1,pc\]'
+[^:]*:91: Error: cannot use register index with PC-relative addressing -- `ldrh r0,\[r1,pc\]!'
+[^:]*:92: Error: cannot use register index with PC-relative addressing -- `ldrh r0,\[r1\],pc'
+[^:]*:93: Error: cannot use register index with PC-relative addressing -- `ldrh r0,\[pc,r1\]!'
+[^:]*:94: Error: cannot use register index with PC-relative addressing -- `ldrh r0,\[pc\],r1'
+[^:]*:97: Error: r15 not allowed here -- `ldrht pc,\[r0\],#4'
+[^:]*:98: Error: cannot use writeback with PC-relative addressing -- `ldrht r0,\[pc\],#4'
+[^:]*:99: Error: r15 not allowed here -- `ldrht pc,\[r0\],r1'
+[^:]*:100: Error: cannot use register index with PC-relative addressing -- `ldrht r0,\[pc\],r1'
+[^:]*:101: Error: cannot use register index with PC-relative addressing -- `ldrht r0,\[r1\],pc'
+[^:]*:104: Error: r15 not allowed here -- `ldrsb pc,\[r0,#4\]'
+[^:]*:105: Error: r15 not allowed here -- `ldrsb pc,\[r0\],#4'
+[^:]*:106: Error: r15 not allowed here -- `ldrsb pc,\[r0,#4\]!'
+[^:]*:109: Error: r15 not allowed here -- `ldrsb pc,label'
+[^:]*:110: Error: r15 not allowed here -- `ldrsb pc,\[pc,#-0\]'
+[^:]*:113: Error: r15 not allowed here -- `ldrsb pc,\[r0,r1\]'
+[^:]*:114: Error: r15 not allowed here -- `ldrsb pc,\[r0,r1\]!'
+[^:]*:115: Error: r15 not allowed here -- `ldrsb pc,\[r0\],r1'
+[^:]*:116: Error: cannot use register index with PC-relative addressing -- `ldrsb r0,\[r1,pc\]'
+[^:]*:117: Error: cannot use register index with PC-relative addressing -- `ldrsb r0,\[r1,pc\]!'
+[^:]*:118: Error: cannot use register index with PC-relative addressing -- `ldrsb r0,\[r1\],pc'
+[^:]*:119: Error: cannot use register index with PC-relative addressing -- `ldrsb r0,\[pc,r1\]!'
+[^:]*:120: Error: cannot use register index with PC-relative addressing -- `ldrsb r0,\[pc\],r1'
+[^:]*:123: Error: r15 not allowed here -- `ldrsbt pc,\[r0\],#4'
+[^:]*:124: Error: cannot use writeback with PC-relative addressing -- `ldrsbt r0,\[pc\],#4'
+[^:]*:125: Error: r15 not allowed here -- `ldrsbt pc,\[r0\],r1'
+[^:]*:126: Error: cannot use register index with PC-relative addressing -- `ldrsbt r0,\[pc\],r1'
+[^:]*:127: Error: cannot use register index with PC-relative addressing -- `ldrsbt r0,\[r1\],pc'
+[^:]*:130: Error: r15 not allowed here -- `ldrsh pc,\[r0,#4\]'
+[^:]*:131: Error: r15 not allowed here -- `ldrsh pc,\[r0\],#4'
+[^:]*:132: Error: r15 not allowed here -- `ldrsh pc,\[r0,#4\]!'
+[^:]*:135: Error: r15 not allowed here -- `ldrsh pc,label'
+[^:]*:136: Error: r15 not allowed here -- `ldrsh pc,\[pc,#-0\]'
+[^:]*:139: Error: r15 not allowed here -- `ldrsh pc,\[r0,r1\]'
+[^:]*:140: Error: r15 not allowed here -- `ldrsh pc,\[r0,r1\]!'
+[^:]*:141: Error: r15 not allowed here -- `ldrsh pc,\[r0\],r1'
+[^:]*:142: Error: cannot use register index with PC-relative addressing -- `ldrsh r0,\[r1,pc\]'
+[^:]*:143: Error: cannot use register index with PC-relative addressing -- `ldrsh r0,\[r1,pc\]!'
+[^:]*:144: Error: cannot use register index with PC-relative addressing -- `ldrsh r0,\[r1\],pc'
+[^:]*:145: Error: cannot use register index with PC-relative addressing -- `ldrsh r0,\[pc,r1\]!'
+[^:]*:146: Error: cannot use register index with PC-relative addressing -- `ldrsh r0,\[pc\],r1'
+[^:]*:149: Error: r15 not allowed here -- `ldrsht pc,\[r0\],#4'
+[^:]*:150: Error: cannot use writeback with PC-relative addressing -- `ldrsht r0,\[pc\],#4'
+[^:]*:151: Error: r15 not allowed here -- `ldrsht pc,\[r0\],r1'
+[^:]*:152: Error: cannot use register index with PC-relative addressing -- `ldrsht r0,\[pc\],r1'
+[^:]*:153: Error: cannot use register index with PC-relative addressing -- `ldrsht r0,\[r1\],pc'
+[^:]*:156: Error: r15 not allowed here -- `ldrt pc,\[r0\],#4'
+[^:]*:157: Error: cannot use register index with PC-relative addressing -- `ldrt r0,\[pc\],#4'
+[^:]*:158: Error: r15 not allowed here -- `ldrt pc,\[r0\],r1,LSL#4'
+[^:]*:159: Error: cannot use register index with PC-relative addressing -- `ldrt r0,\[pc\],r1,LSL#4'
+[^:]*:160: Error: cannot use register index with PC-relative addressing -- `ldrt r0,\[r1\],pc,LSL#4'
+[^:]*:165: Error: cannot use register index with PC-relative addressing -- `str r0,\[pc,#4\]'
+[^:]*:166: Error: cannot use register index with PC-relative addressing -- `str r0,\[pc\],#4'
+[^:]*:167: Error: cannot use register index with PC-relative addressing -- `str r0,\[pc,#4\]!'
+[^:]*:170: Error: cannot use register index with PC-relative addressing -- `str r0,\[r1,pc,LSL#4\]'
+[^:]*:171: Error: cannot use register index with PC-relative addressing -- `str r0,\[r1,pc,LSL#4\]!'
+[^:]*:172: Error: cannot use register index with PC-relative addressing -- `str r0,\[r1\],pc,LSL#4'
+[^:]*:175: Error: r15 not allowed here -- `strb pc,\[r0,#4\]'
+[^:]*:176: Error: r15 not allowed here -- `strb pc,\[r0\],#4'
+[^:]*:177: Error: r15 not allowed here -- `strb pc,\[r0,#4\]!'
+[^:]*:178: Error: cannot use register index with PC-relative addressing -- `strb r0,\[pc\],#4'
+[^:]*:179: Error: cannot use register index with PC-relative addressing -- `strb r0,\[pc,#4\]!'
+[^:]*:182: Error: r15 not allowed here -- `strb pc,\[r0,r1,LSL#4\]'
+[^:]*:183: Error: r15 not allowed here -- `strb pc,\[r0,r1,LSL#4\]!'
+[^:]*:184: Error: r15 not allowed here -- `strb pc,\[r0\],r1,LSL#4'
+[^:]*:185: Error: cannot use register index with PC-relative addressing -- `strb r1,\[r0,pc,LSL#4\]'
+[^:]*:186: Error: cannot use register index with PC-relative addressing -- `strb r1,\[r0,pc,LSL#4\]!'
+[^:]*:187: Error: cannot use register index with PC-relative addressing -- `strb r1,\[r0\],pc,LSL#4'
+[^:]*:188: Error: cannot use register index with PC-relative addressing -- `strb r0,\[pc,r1,LSL#4\]!'
+[^:]*:189: Error: cannot use register index with PC-relative addressing -- `strb r0,\[pc\],r1,LSL#4'
+[^:]*:192: Error: r15 not allowed here -- `strbt pc,\[r0\],#4'
+[^:]*:193: Error: cannot use register index with PC-relative addressing -- `strbt r0,\[pc\],#4'
+[^:]*:194: Error: r15 not allowed here -- `strbt pc,\[r0\],r1,LSL#4'
+[^:]*:195: Error: cannot use register index with PC-relative addressing -- `strbt r0,\[pc\],r1,LSL#4'
+[^:]*:196: Error: cannot use register index with PC-relative addressing -- `strbt r0,\[r1\],pc,LSL#4'
+[^:]*:199: Error: r15 not allowed here -- `strd r0,pc,\[r1,#4\]'
+[^:]*:200: Error: r15 not allowed here -- `strd r0,pc,\[r1\],#4'
+[^:]*:201: Error: r15 not allowed here -- `strd r0,pc,\[r1,#4\]!'
+[^:]*:202: Error: cannot use writeback with PC-relative addressing -- `strd r0,r1,\[pc\],#4'
+[^:]*:203: Error: cannot use writeback with PC-relative addressing -- `strd r0,r1,\[pc,#4\]!'
+[^:]*:206: Error: r15 not allowed here -- `strd r0,pc,\[r1,r2\]'
+[^:]*:207: Error: r15 not allowed here -- `strd r0,pc,\[r1,r2\]!'
+[^:]*:208: Error: r15 not allowed here -- `strd r0,pc,\[r1\],r2'
+[^:]*:209: Error: cannot use register index with PC-relative addressing -- `strd r0,r1,\[r2,pc\]'
+[^:]*:210: Error: cannot use register index with PC-relative addressing -- `strd r0,r1,\[r2,pc\]!'
+[^:]*:211: Error: cannot use register index with PC-relative addressing -- `strd r0,r1,\[r2\],pc'
+[^:]*:212: Error: cannot use register index with PC-relative addressing -- `strd r0,r1,\[pc,r2\]!'
+[^:]*:213: Error: cannot use register index with PC-relative addressing -- `strd r0,r1,\[pc\],r2'
+[^:]*:216: Error: r15 not allowed here -- `strex pc,r0,\[r1\]'
+[^:]*:217: Error: r15 not allowed here -- `strex r0,pc,\[r1\]'
+[^:]*:218: Error: instruction does not accept this addressing mode -- `strex r0,r1,\[pc\]'
+[^:]*:221: Error: r15 not allowed here -- `strexb pc,r0,\[r1\]'
+[^:]*:222: Error: r15 not allowed here -- `strexb r0,pc,\[r1\]'
+[^:]*:223: Error: instruction does not accept this addressing mode -- `strexb r0,r1,\[pc\]'
+[^:]*:226: Error: r15 not allowed here -- `strexd pc,r0,r1,\[r2\]'
+[^:]*:227: Error: r15 not allowed here -- `strexd r0,r1,r2,\[pc\]'
+[^:]*:230: Error: r15 not allowed here -- `strexh pc,r0,\[r1\]'
+[^:]*:231: Error: r15 not allowed here -- `strexh r0,pc,\[r1\]'
+[^:]*:232: Error: instruction does not accept this addressing mode -- `strexh r0,r1,\[pc\]'
+[^:]*:235: Error: r15 not allowed here -- `strh pc,\[r0,#4\]'
+[^:]*:236: Error: r15 not allowed here -- `strh pc,\[r0\],#4'
+[^:]*:237: Error: r15 not allowed here -- `strh pc,\[r0,#4\]!'
+[^:]*:238: Error: cannot use writeback with PC-relative addressing -- `strh r0,\[pc\],#4'
+[^:]*:239: Error: cannot use writeback with PC-relative addressing -- `strh r0,\[pc,#4\]!'
+[^:]*:242: Error: r15 not allowed here -- `strh pc,\[r0,r1\]'
+[^:]*:243: Error: r15 not allowed here -- `strh pc,\[r0,r1\]!'
+[^:]*:244: Error: r15 not allowed here -- `strh pc,\[r0\],r1'
+[^:]*:245: Error: cannot use register index with PC-relative addressing -- `strh r0,\[r1,pc\]'
+[^:]*:246: Error: cannot use register index with PC-relative addressing -- `strh r0,\[r1,pc\]!'
+[^:]*:247: Error: cannot use register index with PC-relative addressing -- `strh r0,\[r1\],pc'
+[^:]*:248: Error: cannot use register index with PC-relative addressing -- `strh r0,\[pc,r1\]!'
+[^:]*:249: Error: cannot use register index with PC-relative addressing -- `strh r0,\[pc\],r1'
+[^:]*:252: Error: r15 not allowed here -- `strht pc,\[r0\],#4'
+[^:]*:253: Error: cannot use writeback with PC-relative addressing -- `strht r0,\[pc\],#4'
+[^:]*:254: Error: r15 not allowed here -- `strht pc,\[r0\],r1'
+[^:]*:255: Error: cannot use register index with PC-relative addressing -- `strht r0,\[pc\],r1'
+[^:]*:256: Error: cannot use register index with PC-relative addressing -- `strht r0,\[r1\],pc'
+[^:]*:259: Error: cannot use register index with PC-relative addressing -- `strt r0,\[pc\],#4'
+[^:]*:260: Error: cannot use register index with PC-relative addressing -- `strt r0,\[pc\],r1,LSL#4'
+[^:]*:261: Error: cannot use register index with PC-relative addressing -- `strt r0,\[r1\],pc,LSL#4'
diff --git a/gas/testsuite/gas/arm/sp-pc-validations-bad.s b/gas/testsuite/gas/arm/sp-pc-validations-bad.s
new file mode 100644 (file)
index 0000000..94ecdac
--- /dev/null
@@ -0,0 +1,266 @@
+.syntax unified
+
+@ Loads, ARM ================================================================
+.arm
+
+@ LDR (immediate, ARM)
+@ LDR (literal)
+@No unpredictable or undefined combinations.
+
+@ LDR (register)
+ldr r0,[r1,pc, LSL #2]                 @ Unpredictable
+ldr r0,[r1,pc, LSL #2]!                        @ ditto
+ldr r0,[r1],pc, LSL #2                 @ ditto
+ldr r0,[pc,r1, LSL #2]!                        @ ditto
+ldr r0,[pc],r1, LSL #2                 @ ditto
+
+@ LDRB (immediate, ARM)
+ldrb pc,[r0,#4]                                @ Unpredictable
+ldrb pc,[r0],#4                                @ ditto
+ldrb pc,[r0,#4]!                       @ ditto
+
+@ LDRB (literal)
+ldrb pc, label                         @ Unpredictable
+ldrb pc,[pc,#-0]                       @ ditto
+
+@ LDRB (register)
+ldrb pc,[r0,r1, LSL #2]                        @ Unpredictable
+ldrb pc,[r0,r1, LSL #2]!               @ ditto
+ldrb pc,[r0],r1, LSL #2                        @ ditto
+ldrb r0,[r1,pc, LSL #2]                        @ ditto
+ldrb r0,[r1,pc, LSL #2]!               @ ditto
+ldrb r0,[r1],pc, LSL #2                        @ ditto
+ldrb r0,[pc,r1, LSL #2]!               @ ditto
+ldrb r0,[pc],r1, LSL #2                        @ ditto
+
+@ LDRBT
+ldrbt pc,[r0],#4                       @ Unpredictable
+ldrbt r0,[pc],#4                       @ ditto
+ldrbt pc,[r0],r1, LSL #4               @ ditto
+ldrbt r0,[pc],r1, LSL #4               @ ditto
+ldrbt r0,[r1],pc, LSL #4               @ ditto
+
+@ LDRD (immediate)
+ldrd r0,pc,[r1,#4]                     @ Unpredictable
+ldrd r0,pc,[r1],#4                     @ ditto
+ldrd r0,pc,[r1,#4]!                    @ ditto
+
+@ LDRD (literal)
+ldrd r0,pc, label                      @ Unpredictable
+ldrd r0,pc,[PC,#-0]                    @ ditto
+
+@ LDRD (register)
+ldrd r0,pc,[r1,r2]                     @ Unpredictable
+ldrd r0,pc,[r1,r2]!                    @ ditto
+ldrd r0,pc,[r1],r2                     @ ditto
+ldrd r0,r1,[r2,pc]                     @ ditto
+ldrd r0,r1,[r2,pc]!                    @ ditto
+ldrd r0,r1,[r2],pc                     @ ditto
+ldrd r0,r1,[pc,r2]!                    @ ditto
+ldrd r0,r1,[pc],r2                     @ ditto
+
+@ LDREX
+ldrex pc,[r0]                          @ Unpredictable
+ldrex r0,[pc]                          @ ditto
+
+@ LDREXB
+ldrexb pc,[r0]                         @ Unpredictable
+ldrexb r0,[pc]                         @ ditto
+
+@ LDREXD
+ldrexd r0,r1,[pc]                      @ Unpredictable
+
+@ LDREXH
+ldrexh pc,[r0]                         @ Unpredictable
+ldrexh r0,[pc]                         @ ditto
+
+@ LDRH (immediate, ARM)
+ldrh pc,[r0,#4]                                @ Unpredictable
+ldrh pc,[r0],#4                                @ ditto
+ldrh pc,[r0,#4]!                       @ ditto
+
+@ LDRH (literal)
+ldrh pc, label                         @ Unpredictable
+ldrh pc,[pc,#-0]                       @ ditto
+
+@ LDRH (register)
+ldrh pc,[r0,r1]                                @ Unpredictable
+ldrh pc,[r0,r1]!                       @ ditto
+ldrh pc,[r0],r1                                @ ditto
+ldrh r0,[r1,pc]                                @ ditto
+ldrh r0,[r1,pc]!                       @ ditto
+ldrh r0,[r1],pc                                @ ditto
+ldrh r0,[pc,r1]!                       @ ditto
+ldrh r0,[pc],r1                                @ ditto
+
+@ LDRHT
+ldrht pc, [r0], #4                     @ Unpredictable
+ldrht r0, [pc], #4                     @ ditto
+ldrht pc, [r0], r1                     @ ditto
+ldrht r0, [pc], r1                     @ ditto
+ldrht r0, [r1], pc                     @ ditto
+
+@ LDRSB (immediate)
+ldrsb pc,[r0,#4]                       @ Unpredictable
+ldrsb pc,[r0],#4                       @ ditto
+ldrsb pc,[r0,#4]!                      @ ditto
+
+@ LDRSB (literal)
+ldrsb pc, label                                @ Unpredictable
+ldrsb pc,[pc,#-0]                      @ ditto
+
+@ LDRSB (register)
+ldrsb pc,[r0,r1]                       @ Unpredictable
+ldrsb pc,[r0,r1]!                      @ ditto
+ldrsb pc,[r0],r1                       @ ditto
+ldrsb r0,[r1,pc]                       @ ditto
+ldrsb r0,[r1,pc]!                      @ ditto
+ldrsb r0,[r1],pc                       @ ditto
+ldrsb r0,[pc,r1]!                      @ ditto
+ldrsb r0,[pc],r1                       @ ditto
+
+@ LDRSBT
+ldrsbt pc, [r0], #4                    @ Unpredictable
+ldrsbt r0, [pc], #4                    @ ditto
+ldrsbt pc, [r0], r1                    @ ditto
+ldrsbt r0, [pc], r1                    @ ditto
+ldrsbt r0, [r1], pc                    @ ditto
+
+@ LDRSH (immediate)
+ldrsh pc,[r0,#4]                       @ Unpredictable
+ldrsh pc,[r0],#4                       @ ditto
+ldrsh pc,[r0,#4]!                      @ ditto
+
+@ LDRSH (literal)
+ldrsh pc, label                                @ Unpredictable
+ldrsh pc,[pc,#-0]                      @ ditto
+
+@ LDRSH (register)
+ldrsh pc,[r0,r1]                       @ Unpredictable
+ldrsh pc,[r0,r1]!                      @ ditto
+ldrsh pc,[r0],r1                       @ ditto
+ldrsh r0,[r1,pc]                       @ ditto
+ldrsh r0,[r1,pc]!                      @ ditto
+ldrsh r0,[r1],pc                       @ ditto
+ldrsh r0,[pc,r1]!                      @ ditto
+ldrsh r0,[pc],r1                       @ ditto
+
+@ LDRSHT
+ldrsht pc, [r0], #4                    @ Unpredictable
+ldrsht r0, [pc], #4                    @ ditto
+ldrsht pc, [r0], r1                    @ ditto
+ldrsht r0, [pc], r1                    @ ditto
+ldrsht r0, [r1], pc                    @ ditto
+
+@ LDRT
+ldrt pc, [r0], #4                      @ Unpredictable
+ldrt r0, [pc], #4                      @ ditto
+ldrt pc,[r0],r1, LSL #4                        @ ditto
+ldrt r0,[pc],r1, LSL #4                        @ ditto
+ldrt r0,[r1],pc, LSL #4                        @ ditto
+
+@ Stores, ARM ================================================================
+
+@ STR (immediate, ARM)
+str r0,[pc,#4]                         @ Unpredictable
+str r0,[pc],#4                         @ ditto
+str r0,[pc,#4]!                                @ ditto
+
+@ STR (register)
+str r0,[r1,pc, LSL #4]                 @ Unpredictable
+str r0,[r1,pc, LSL #4]!                        @ ditto
+str r0,[r1],pc, LSL #4                 @ ditto
+
+@ STRB (immediate, ARM)
+strb pc,[r0,#4]                                @ Unpredictable
+strb pc,[r0],#4                                @ ditto
+strb pc,[r0,#4]!                       @ ditto
+strb r0,[pc],#4                                @ ditto
+strb r0,[pc,#4]!                       @ ditto
+
+@ STRB (register)
+strb pc,[r0,r1, LSL #4]                        @ Unpredictable
+strb pc,[r0,r1, LSL #4]!               @ ditto
+strb pc,[r0],r1, LSL #4                        @ ditto
+strb r1,[r0,pc, LSL #4]                        @ ditto
+strb r1,[r0,pc, LSL #4]!               @ ditto
+strb r1,[r0],pc, LSL #4                        @ ditto
+strb r0,[pc,r1, LSL #4]!               @ ditto
+strb r0,[pc],r1, LSL #4                        @ ditto
+
+@ STRBT
+strbt pc,[r0],#4                       @ Unpredictable
+strbt r0,[pc],#4                       @ ditto
+strbt pc,[r0],r1, LSL #4               @ ditto
+strbt r0,[pc],r1, LSL #4               @ ditto
+strbt r0,[r1],pc, LSL #4               @ ditto
+
+@ STRD (immediate)
+strd r0,pc,[r1,#4]                     @ ditto
+strd r0,pc,[r1],#4                     @ ditto
+strd r0,pc,[r1,#4]!                    @ ditto
+strd r0,r1,[pc],#4                     @ ditto
+strd r0,r1,[pc,#4]!                    @ ditto
+
+@STRD (register)
+strd r0,pc,[r1,r2]                     @ Unpredictable
+strd r0,pc,[r1,r2]!                    @ ditto
+strd r0,pc,[r1],r2                     @ ditto
+strd r0,r1,[r2,pc]                     @ ditto
+strd r0,r1,[r2,pc]!                    @ ditto
+strd r0,r1,[r2],pc                     @ ditto
+strd r0,r1,[pc,r2]!                    @ ditto
+strd r0,r1,[pc],r2                     @ ditto
+
+@ STREX
+strex pc,r0,[r1]                       @ Unpredictable
+strex r0,pc,[r1]                       @ ditto
+strex r0,r1,[pc]                       @ ditto
+
+@ STREXB
+strexb pc,r0,[r1]                      @ Unpredictable
+strexb r0,pc,[r1]                      @ ditto
+strexb r0,r1,[pc]                      @ ditto
+
+@ STREXD
+strexd pc,r0,r1,[r2]                   @ Unpredictable
+strexd r0,r1,r2,[pc]                   @ ditto
+
+@ STREXH
+strexh pc,r0,[r1]                      @ Unpredictable
+strexh r0,pc,[r1]                      @ ditto
+strexh r0,r1,[pc]                      @ ditto
+
+@ STRH (immediate, ARM)
+strh pc,[r0,#4]                                @ Unpredictable
+strh pc,[r0],#4                                @ ditto
+strh pc,[r0,#4]!                       @ ditto
+strh r0,[pc],#4                                @ ditto
+strh r0,[pc,#4]!                       @ ditto
+
+@ STRH (register)
+strh pc,[r0,r1]                                @ Unpredictable
+strh pc,[r0,r1]!                       @ ditto
+strh pc,[r0],r1                                @ ditto
+strh r0,[r1,pc]                                @ ditto
+strh r0,[r1,pc]!                       @ ditto
+strh r0,[r1],pc                                @ ditto
+strh r0,[pc,r1]!                       @ ditto
+strh r0,[pc],r1                                @ ditto
+
+@ STRHT
+strht pc, [r0], #4                     @ Unpredictable
+strht r0, [pc], #4                     @ ditto
+strht pc, [r0], r1                     @ ditto
+strht r0, [pc], r1                     @ ditto
+strht r0, [r1], pc                     @ ditto
+
+@ STRT
+strt r0, [pc], #4                      @ Unpredictable
+strt r0, [pc],r1, LSL #4               @ ditto
+strt r0, [r1],pc, LSL #4               @ ditto
+
+@ ============================================================================
+
+.label:
+ldr r0, [r1]
index 02903a9..96f6903 100644 (file)
@@ -18,8 +18,10 @@ Disassembly of section .text:
 0+01a <[^>]+> e8d4 f001        tbbgt   \[r4, r1\]
 0+01e <[^>]+> bfb8             it      lt
 0+020 <[^>]+> df00             svclt   0
-0+022 <[^>]+> bfdc             itt     le
-0+024 <[^>]+> be00             bkpt    0x0000
-0+026 <[^>]+> bf00             nople
-0+028 <[^>]+> bf00             nop
-0+02a <[^>]+> bf00             nop
+0+022 <[^>]+> bf08             it      eq
+0+024 <[^>]+> f8d0 f000        ldreq.w pc, \[r0\]
+0+028 <[^>]+> bfdc             itt     le
+0+02a <[^>]+> be00             bkpt    0x0000
+0+02c <[^>]+> bf00             nople
+0+02e <[^>]+> bf00             nop
+0+030 <[^>]+> bf00             nop
index 4a066f2..aef6e8f 100644 (file)
@@ -18,6 +18,8 @@ thumb2_bcond:
        tbbgt [r4, r1]
        it lt
        svclt 0
+       it eq
+       ldreq pc, [r0]
        itt le
        bkpt #0
        nople
index 8cba074..e78727a 100644 (file)
@@ -70,7 +70,5 @@ Disassembly of section .text:
 0+0fc <[^>]+> [^<]+<UNPREDICTABLE>
 0+100 <[^>]+> [^<]+<UNPREDICTABLE>
 0+104 <[^>]+> [^<]+<UNPREDICTABLE>
-0+108 <[^>]+> [^<]+<UNPREDICTABLE>
-0+10c <[^>]+> [^<]+<UNPREDICTABLE>
-0+110 <[^>]+> e1a00000[        ]+nop[  ]+; \(mov r0, r0\)
+0+108 <[^>]+> e1a00000[        ]+nop[  ]+; \(mov r0, r0\)
 #pass
index 7849676..5fab0a4 100644 (file)
@@ -55,8 +55,6 @@ unpredictable:
         .word   0xe92f0010      @ stmdb   r15!, { r4 }
         .word   0xe82f0020      @ stmda   r15!, { r5 }
 
-        strb    pc, [r0, r1]
-        strbt   pc, [r0], r1
         .word   0xe180f0b1      @ strh    pc, [r0, r1]
 
         .word   0xe103f092      @ swp     r15, r2, [r3]