This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Added validations for undefined and unpredictable ARM loads/stores


The attached patch adds validations for the invalid usages of PC and SP registers on loads/stores, both Thumb and ARM.
I went through the ARMARM checking for UNDEFINED and UNPREDICTABLE situations related to these instructions and registers.


The general goals I followed were:
- try to modify as specific functionalities as possible, in order to avoid collateral effects (by inadvertently changing other insns). The earliest place I found was the operands parsing validation, which are led by the insns table. (this is, I ensured that my change applies to a single insn).
- at the same time, I tried to provide "generic means" reusable from many places.


In order to achieve these goals, this patch performs the following changes:
- I added new operand validators: OP_RRnpcsp (avoid PC and SP) and OP_oRRnpcsp (optional counterpart of the former).
- Since some operand validation rules differ between ARM and THUMB, I added the ability to specify different operand validators for the same operand (one for ARM and another for THUMB); I did this by changing the operand type from char to int, and using 16 bits for ARM and 16 for THUMB; a new macro (MIX_ARM_THUMB_OPERANDS) mixes two given operands. Some (mixed) operands were very common, so I added them as a shortcut: OP_RRnpc_npcsp (mix between OP_RRnpc for ARM, and OP_RRnpcsp for THUMB), and its optional counterpart.
- Some validations were inside the addressing modes, not reachable from the operands parser, so I changed some encode_xxx_addr functions in order to add them. I also opted this since the encoding functions did some validations already, so I wanted to be consistent with that.
- finally, most of the changes went to the insns table, as I wanted to, minimizing changes to functions that encode many mnemonics (e.g. *_ldst).


I tested this by running the following test suites:
    * binutils
    * gas (with added test case)
    * ld

Please let me know if OK to commit.

Thanks,
	Daniel.

ChangeLog:
    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.


-- Daniel Gutson CodeSourcery www.codesourcery.com
? validations.patch
Index: gas/config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.428
diff -u -p -r1.428 tc-arm.c
--- gas/config/tc-arm.c	29 Jan 2010 16:02:39 -0000	1.428
+++ gas/config/tc-arm.c	10 Feb 2010 19:36:06 -0000
@@ -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_o
   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 unsigne
 
   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 unsigne
       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 unsigne
 	  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 unsigne
 	    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_
 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_boole
     }
   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_boole
 
   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_boo
   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_boo
     }
   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_op
 #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: gas/testsuite/gas/arm/sp-pc-usage-t.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/sp-pc-usage-t.d,v
retrieving revision 1.1
diff -u -p -r1.1 sp-pc-usage-t.d
--- gas/testsuite/gas/arm/sp-pc-usage-t.d	10 Aug 2009 14:42:39 -0000	1.1
+++ gas/testsuite/gas/arm/sp-pc-usage-t.d	10 Feb 2010 19:36:06 -0000
@@ -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: gas/testsuite/gas/arm/sp-pc-usage-t.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/sp-pc-usage-t.s,v
retrieving revision 1.1
diff -u -p -r1.1 sp-pc-usage-t.s
--- gas/testsuite/gas/arm/sp-pc-usage-t.s	10 Aug 2009 14:42:39 -0000	1.1
+++ gas/testsuite/gas/arm/sp-pc-usage-t.s	10 Feb 2010 19:36:06 -0000
@@ -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.
Index: gas/testsuite/gas/arm/sp-pc-validations-bad-t.d
===================================================================
RCS file: gas/testsuite/gas/arm/sp-pc-validations-bad-t.d
diff -N gas/testsuite/gas/arm/sp-pc-validations-bad-t.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/sp-pc-validations-bad-t.d	10 Feb 2010 19:36:06 -0000
@@ -0,0 +1,2 @@
+# name: Invalid SP and PC operands test - THUMB
+# error-output: sp-pc-validations-bad-t.l
Index: gas/testsuite/gas/arm/sp-pc-validations-bad-t.l
===================================================================
RCS file: gas/testsuite/gas/arm/sp-pc-validations-bad-t.l
diff -N gas/testsuite/gas/arm/sp-pc-validations-bad-t.l
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/sp-pc-validations-bad-t.l	10 Feb 2010 19:36:06 -0000
@@ -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\]'
Index: gas/testsuite/gas/arm/sp-pc-validations-bad-t.s
===================================================================
RCS file: gas/testsuite/gas/arm/sp-pc-validations-bad-t.s
diff -N gas/testsuite/gas/arm/sp-pc-validations-bad-t.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/sp-pc-validations-bad-t.s	10 Feb 2010 19:36:06 -0000
@@ -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]
Index: gas/testsuite/gas/arm/sp-pc-validations-bad.d
===================================================================
RCS file: gas/testsuite/gas/arm/sp-pc-validations-bad.d
diff -N gas/testsuite/gas/arm/sp-pc-validations-bad.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/sp-pc-validations-bad.d	10 Feb 2010 19:36:06 -0000
@@ -0,0 +1,2 @@
+# name: Invalid SP and PC operands test - ARM
+# error-output: sp-pc-validations-bad.l
Index: gas/testsuite/gas/arm/sp-pc-validations-bad.l
===================================================================
RCS file: gas/testsuite/gas/arm/sp-pc-validations-bad.l
diff -N gas/testsuite/gas/arm/sp-pc-validations-bad.l
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/sp-pc-validations-bad.l	10 Feb 2010 19:36:06 -0000
@@ -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'
Index: gas/testsuite/gas/arm/sp-pc-validations-bad.s
===================================================================
RCS file: gas/testsuite/gas/arm/sp-pc-validations-bad.s
diff -N gas/testsuite/gas/arm/sp-pc-validations-bad.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/sp-pc-validations-bad.s	10 Feb 2010 19:36:06 -0000
@@ -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: gas/testsuite/gas/arm/thumb2_bcond.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/thumb2_bcond.d,v
retrieving revision 1.4
diff -u -p -r1.4 thumb2_bcond.d
--- gas/testsuite/gas/arm/thumb2_bcond.d	7 Jun 2006 14:08:18 -0000	1.4
+++ gas/testsuite/gas/arm/thumb2_bcond.d	10 Feb 2010 19:36:06 -0000
@@ -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: gas/testsuite/gas/arm/thumb2_bcond.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/thumb2_bcond.s,v
retrieving revision 1.1
diff -u -p -r1.1 thumb2_bcond.s
--- gas/testsuite/gas/arm/thumb2_bcond.s	20 Mar 2006 15:38:02 -0000	1.1
+++ gas/testsuite/gas/arm/thumb2_bcond.s	10 Feb 2010 19:36:06 -0000
@@ -18,6 +18,8 @@ thumb2_bcond:
 	tbbgt [r4, r1]
 	it lt
 	svclt 0
+	it eq
+	ldreq pc, [r0]
 	itt le
 	bkpt #0
 	nople
Index: gas/testsuite/gas/arm/unpredictable.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/unpredictable.d,v
retrieving revision 1.2
diff -u -p -r1.2 unpredictable.d
--- gas/testsuite/gas/arm/unpredictable.d	17 Dec 2009 09:52:17 -0000	1.2
+++ gas/testsuite/gas/arm/unpredictable.d	10 Feb 2010 19:36:06 -0000
@@ -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: gas/testsuite/gas/arm/unpredictable.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/unpredictable.s,v
retrieving revision 1.2
diff -u -p -r1.2 unpredictable.s
--- gas/testsuite/gas/arm/unpredictable.s	17 Dec 2009 09:52:18 -0000	1.2
+++ gas/testsuite/gas/arm/unpredictable.s	10 Feb 2010 19:36:06 -0000
@@ -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]

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]