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]

ARM SRS bugs


The attached patch fixes some issues with the ARM/Thumb SRS instruction.
Gas was incorrectly encoding the Thumb variants of these instructions.
In addition, Arm have changes the assembly syntax for these instructions to 
include an explicit base registers. Currently the only legal base register is 
r13 (aka sp). The old syntax is still accepted.

An optional first argument requires a tweak to parse_operands. When the first 
operand is absent we don't have a comma to skip over when parsing 
the "second" operand.

Tested on arm-none-eabi.
Applied to head.

Paul

2007-03-24  Paul Brook  <paul@codesourcery.com>
	Mark Shinwell  <shinwell@codesourcery.com>

	gas/
	* config/tc-arm.c (operand_parse_code): Add OP_oRRw.
	(parse_operands): Don't expect comma if first operand missing.
	Handle OP_oRRw.
	(do_srs): Encode register number, checking it is r13.  Update comment.
	(insns): Update SRS entries to take a register.

	gas/testsuite/
	* gas/arm/archv6.s: Add new SRS tests.
	* gas/arm/archv6.d: Update expected output.
	* gas/arm/thumb32.s: Add new SRS tests.
	* gas/arm/thumb32.d: Update expected output.
	* gas/arm/srs-t2.d: New.
	* gas/arm/srs-t2.l: New.
	* gas/arm/srs-t2.s: New.
	* gas/arm/srs-arm.d: New.
	* gas/arm/srs-arm.l: New.
	* gas/arm/srs-arm.s: New.

	opcodes/
	* arm-dis.c (arm_opcodes): Print SRS base register.
Index: gas/config/tc-arm.c
===================================================================
--- gas/config/tc-arm.c	(revision 166694)
+++ gas/config/tc-arm.c	(working copy)
@@ -5452,6 +5452,7 @@ enum operand_parse_code
 
   OP_oRR,	 /* ARM register */
   OP_oRRnpc,	 /* ARM register, not the PC */
+  OP_oRRw,	 /* ARM register, not r15, optional trailing ! */
   OP_oRND,       /* Optional Neon double precision register */
   OP_oRNQ,       /* Optional Neon quad precision register */
   OP_oRNDQ,      /* Optional Neon double or quad precision register */
@@ -5556,7 +5557,7 @@ parse_operands (char *str, const unsigne
 	  backtrack_index = i;
 	}
 
-      if (i > 0)
+      if (i > 0 && (i > 1 || inst.operands[0].present))
 	po_char_or_fail (',');
 
       switch (upat[i])
@@ -5712,6 +5713,7 @@ parse_operands (char *str, const unsigne
 	  break;
 
 	case OP_RRw:
+	case OP_oRRw:
 	  po_reg_or_fail (REG_TYPE_RN);
 	  if (skip_past_char (&str, '!') == SUCCESS)
 	    inst.operands[i].writeback = 1;
@@ -5999,6 +6001,7 @@ parse_operands (char *str, const unsigne
 	case OP_RRnpc:
 	case OP_RRnpcb:
 	case OP_RRw:
+	case OP_oRRw:
 	case OP_RRnpc_I0:
 	  if (inst.operands[i].isreg && inst.operands[i].reg == REG_PC)
 	    inst.error = BAD_PC;
@@ -7436,13 +7439,25 @@ do_smul (void)
   inst.instruction |= inst.operands[2].reg << 8;
 }
 
-/* ARM V6 srs (argument parse).	 */
+/* ARM V6 srs (argument parse).  The variable fields in the encoding are
+   the same for both ARM and Thumb-2.  */
 
 static void
 do_srs (void)
 {
-  inst.instruction |= inst.operands[0].imm;
-  if (inst.operands[0].writeback)
+  int reg;
+
+  if (inst.operands[0].present)
+    {
+      reg = inst.operands[0].reg;
+      constraint (reg != 13, _("SRS base register must be r13"));
+    }
+  else
+    reg = 13;
+
+  inst.instruction |= reg << 16;
+  inst.instruction |= inst.operands[1].imm;
+  if (inst.operands[0].writeback || inst.operands[1].writeback)
     inst.instruction |= WRITE_BACK;
 }
 
@@ -14966,10 +14981,10 @@ static const struct asm_opcode insns[] =
  TCE(smuadx,	700f030, fb20f010, 3, (RRnpc, RRnpc, RRnpc),	   smul, t_simd),
  TCE(smusd,	700f050, fb40f000, 3, (RRnpc, RRnpc, RRnpc),	   smul, t_simd),
  TCE(smusdx,	700f070, fb40f010, 3, (RRnpc, RRnpc, RRnpc),	   smul, t_simd),
- TUF(srsia,	8cd0500, e980c000, 1, (I31w),			   srs,  srs),
-  UF(srsib,	9cd0500,           1, (I31w),			   srs),
-  UF(srsda,	84d0500,	   1, (I31w),			   srs),
- TUF(srsdb,	94d0500, e800c000, 1, (I31w),			   srs,  srs),
+ TUF(srsia,	8c00500, e980c000, 2, (oRRw, I31w),		   srs,  srs),
+  UF(srsib,	9c00500,           2, (oRRw, I31w),		   srs),
+  UF(srsda,	8400500,	   2, (oRRw, I31w),		   srs),
+ TUF(srsdb,	9400500, e800c000, 2, (oRRw, I31w),		   srs,  srs),
  TCE(ssat16,	6a00f30, f3200000, 3, (RRnpc, I16, RRnpc),	   ssat16, t_ssat16),
  TCE(strex,	1800f90, e8400000, 3, (RRnpc, RRnpc, ADDR),	   strex,  t_strex),
  TCE(umaal,	0400090, fbe00060, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,  t_mlal),
Index: opcodes/arm-dis.c
===================================================================
--- opcodes/arm-dis.c	(revision 166694)
+++ opcodes/arm-dis.c	(working copy)
@@ -923,7 +923,7 @@ static const struct opcode32 arm_opcodes
   {ARM_EXT_V6, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19r, %0-3r, %8-11r"},
   {ARM_EXT_V6, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
   {ARM_EXT_V6, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
-  {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t#%0-4d%21'!"},
+  {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t%16-19r%21'!, #%0-4d"},
   {ARM_EXT_V6, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15r, #%16-20W, %0-3r"},
   {ARM_EXT_V6, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, LSL #%7-11d"},
   {ARM_EXT_V6, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, ASR #%7-11d"},
@@ -1239,8 +1239,8 @@ static const struct opcode32 thumb32_opc
   {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
   {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
   {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
-  {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb%c\t#%0-4d%21'!"},
-  {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia%c\t#%0-4d%21'!"},
+  {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"},
+  {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia%c\t%16-19r%21'!, #%0-4d"},
   {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"},
   {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"},
   {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"},
Index: gas/testsuite/gas/arm/srs-t2.l
===================================================================
--- gas/testsuite/gas/arm/srs-t2.l	(revision 0)
+++ gas/testsuite/gas/arm/srs-t2.l	(revision 0)
@@ -0,0 +1,3 @@
+[^:]*: Assembler messages:
+[^:]*:8: Error: SRS base register must be r13 -- `srsdb r4,#13'
+[^:]*:9: Error: SRS base register must be r13 -- `srsia r4,#13'
Index: gas/testsuite/gas/arm/srs-t2.s
===================================================================
--- gas/testsuite/gas/arm/srs-t2.s	(revision 0)
+++ gas/testsuite/gas/arm/srs-t2.s	(revision 0)
@@ -0,0 +1,10 @@
+       .arch   armv6t2
+
+foo:
+       srsdb   r13, #13
+       srsdb   r13!, #13
+       srsia   r13, #13
+       srsia   r13!, #13
+       srsdb   r4, #13
+       srsia   r4, #13
+
Index: gas/testsuite/gas/arm/thumb32.d
===================================================================
--- gas/testsuite/gas/arm/thumb32.d	(revision 166694)
+++ gas/testsuite/gas/arm/thumb32.d	(working copy)
@@ -954,3 +954,7 @@ Disassembly of section .text:
 0[0-9a-f]+ <[^>]+> e890 0300 	ldmiaeq.w	r0, \{r8, r9\}
 0[0-9a-f]+ <[^>]+> e880 0300 	stmiaeq.w	r0, \{r8, r9\}
 0[0-9a-f]+ <[^>]+> bf00      	nop
+0[0-9a-f]+ <[^>]+> e98d c010 	srsia	sp, #16
+0[0-9a-f]+ <[^>]+> e80d c010 	srsdb	sp, #16
+0[0-9a-f]+ <[^>]+> e9ad c015 	srsia	sp!, #21
+0[0-9a-f]+ <[^>]+> e9ad c00a 	srsia	sp!, #10
Index: gas/testsuite/gas/arm/thumb32.s
===================================================================
--- gas/testsuite/gas/arm/thumb32.s	(revision 166694)
+++ gas/testsuite/gas/arm/thumb32.s	(working copy)
@@ -769,3 +769,9 @@ xta:	
 	ldmeq	r0, {r8, r9}
 	stmeq	r0, {r8, r9}
 	nop
+
+srs:
+	srsia sp, #16
+	srsdb sp, #16
+	srsia sp!, #21
+	srsia sp!, #10
Index: gas/testsuite/gas/arm/archv6.d
===================================================================
--- gas/testsuite/gas/arm/archv6.d	(revision 166694)
+++ gas/testsuite/gas/arm/archv6.d	(working copy)
@@ -116,8 +116,8 @@ Disassembly of section .text:
 0+1b0 <[^>]*> d701f352 ?	smusdle	r1, r2, r3
 0+1b4 <[^>]*> e701f372 ?	smusdx	r1, r2, r3
 0+1b8 <[^>]*> d701f372 ?	smusdxle	r1, r2, r3
-0+1bc <[^>]*> f8cd0510 ?	srsia	#16
-0+1c0 <[^>]*> f9ed0510 ?	srsib	#16!
+0+1bc <[^>]*> f8cd0510 ?	srsia	sp, #16
+0+1c0 <[^>]*> f9ed0510 ?	srsib	sp!, #16
 0+1c4 <[^>]*> e6a01012 ?	ssat	r1, #1, r2
 0+1c8 <[^>]*> e6a01152 ?	ssat	r1, #1, r2, ASR #2
 0+1cc <[^>]*> e6a01112 ?	ssat	r1, #1, r2, LSL #2
@@ -219,3 +219,5 @@ Disassembly of section .text:
 0+34c <[^>]*> 16ef2475 ?	uxtbne r2,r5, ROR #8
 0+350 <[^>]*> f10a00ca ?	cpsie	if,#10
 0+354 <[^>]*> f10a00d5 ?	cpsie	if,#21
+0+358 <[^>]*> f8cd0510 ?	srsia	sp, #16
+0+35c <[^>]*> f9ed0510 ?	srsib	sp!, #16
Index: gas/testsuite/gas/arm/archv6.s
===================================================================
--- gas/testsuite/gas/arm/archv6.s	(revision 166694)
+++ gas/testsuite/gas/arm/archv6.s	(working copy)
@@ -216,3 +216,5 @@ label:
 	uxtbne r2, r5, ROR #8
 	cpsie if, #10
 	cpsie if, #21
+	srsia sp, #16
+	srsib sp!, #16
Index: gas/testsuite/gas/arm/srs-arm.d
===================================================================
--- gas/testsuite/gas/arm/srs-arm.d	(revision 0)
+++ gas/testsuite/gas/arm/srs-arm.d	(revision 0)
@@ -0,0 +1,2 @@
+# name: SRS instruction in ARM mode
+# error-output: srs-arm.l
Index: gas/testsuite/gas/arm/srs-arm.l
===================================================================
--- gas/testsuite/gas/arm/srs-arm.l	(revision 0)
+++ gas/testsuite/gas/arm/srs-arm.l	(revision 0)
@@ -0,0 +1,5 @@
+[^:]*: Assembler messages:
+[^:]*:12: Error: SRS base register must be r13 -- `srsdb r4,#13'
+[^:]*:13: Error: SRS base register must be r13 -- `srsda r4,#13'
+[^:]*:14: Error: SRS base register must be r13 -- `srsia r4,#13'
+[^:]*:15: Error: SRS base register must be r13 -- `srsib r4,#13'
Index: gas/testsuite/gas/arm/srs-arm.s
===================================================================
--- gas/testsuite/gas/arm/srs-arm.s	(revision 0)
+++ gas/testsuite/gas/arm/srs-arm.s	(revision 0)
@@ -0,0 +1,16 @@
+       .arch   armv6
+
+foo:
+       srsdb   r13, #13
+       srsdb   r13!, #13
+       srsia   r13, #13
+       srsia   r13!, #13
+       srsda   r13, #13
+       srsda   r13!, #13
+       srsib   r13, #13
+       srsib   r13!, #13
+       srsdb   r4, #13
+       srsda   r4, #13
+       srsia   r4, #13
+       srsib   r4, #13
+
Index: gas/testsuite/gas/arm/srs-t2.d
===================================================================
--- gas/testsuite/gas/arm/srs-t2.d	(revision 0)
+++ gas/testsuite/gas/arm/srs-t2.d	(revision 0)
@@ -0,0 +1,2 @@
+# name: SRS instruction in Thumb-2 mode
+# error-output: srs-t2.l

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