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] Thumb2 gas fixes


The attached patch fixed 4 thumb2 gas bugs:

- Immediate operands allow shifted 8-bit constants, unlike arm which allows 
rotated constants.
- ALU operations do not allow shift by register operands.
- Incorrect encoding of shifted index addressing modes.
- Incorrect encoding of ldm and stm instructions

Tested on arm-none-eabi.
Ok?

Paul

2005-08-04  Paul Brook  <paul@codesourcery.com>

gas/
	* config/tc-arm.c (encode_thumb32_immediate): Only accept shifted
	constants.
	(encode_thumb32_shifted_operand): Prohibit register shifts.
	(encode_thumb32_addr_mode): Fix typo.
	(insns): Correct thumb2 ldm and stm opcodes.
gas/testsuite/
	* gas/arm/thumb32.d: Update ldm/stm dests.
	* gas/arm/thumb32.s: Ditto.
Index: gas/config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.216
diff -u -p -r1.216 tc-arm.c
--- gas/config/tc-arm.c	3 Aug 2005 09:50:42 -0000	1.216
+++ gas/config/tc-arm.c	3 Aug 2005 22:12:47 -0000
@@ -3989,14 +3994,14 @@ encode_thumb32_immediate (unsigned int v
 {
   unsigned int a, i;
 
-  if (val <= 255)
+  if (val <= 0xff)
     return val;
 
-  for (i = 0; i < 32; i++)
+  for (i = 1; i <= 24; i++)
     {
-      a = rotate_left (val, i);
-      if (a >= 128 && a <= 255)
-	return (a & 0x7f) | (i << 7);
+      a = val >> i;
+      if ((val & ~(0xff << i)) == 0)
+	return ((val >> i) & 0x7f) | ((32 - i) << 7);
     }
 
   a = val & 0xff;
@@ -5637,6 +5642,8 @@ encode_thumb32_shifted_operand (int i)
   unsigned int value = inst.reloc.exp.X_add_number;
   unsigned int shift = inst.operands[i].shift_kind;
 
+  constraint (inst.operands[i].immisreg,
+	      _("shift by register not allowed in thumb mode"));
   inst.instruction |= inst.operands[i].reg;
   if (shift == SHIFT_RRX)
     inst.instruction |= SHIFT_ROR << 4;
@@ -5695,9 +5702,10 @@ encode_thumb32_addr_mode (int i, bfd_boo
 	{
 	  constraint (inst.reloc.exp.X_op != O_constant,
 		      _("expression too complex"));
-	  constraint (inst.reloc.exp.X_add_number < 0 || inst.reloc.exp.X_add_number > 3,
+	  constraint (inst.reloc.exp.X_add_number < 0
+		      || inst.reloc.exp.X_add_number > 3,
 		      _("shift out of range"));
-	  inst.instruction |= inst.reloc.exp.X_op << 4;
+	  inst.instruction |= inst.reloc.exp.X_add_number << 4;
 	}
       inst.reloc.type = BFD_RELOC_UNUSED;
     }
@@ -8268,11 +8339,11 @@ static const struct asm_opcode insns[] =
  TC3(strt,	4200000, f8400e00, 2, (RR, ADDR),    ldstt, t_ldstt),
  TC3(strbt,	4600000, f8200e00, 2, (RR, ADDR),    ldstt, t_ldstt),
 
- TC3(stmdb,	9000000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
- TC3(stmfd,     9000000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
+ TC3(stmdb,	9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
+ TC3(stmfd,     9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
 
- TC3(ldmdb,	9100000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
- TC3(ldmea,	9100000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
+ TC3(ldmdb,	9100000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
+ TC3(ldmea,	9100000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
 
  /* V1 instructions with no Thumb analogue at all.  */
   CE(rsc,	0e00000,	   3, (RR, oRR, SH), arit),
Index: gas/testsuite/gas/arm/thumb32.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/thumb32.d,v
retrieving revision 1.9
diff -u -p -r1.9 thumb32.d
--- gas/testsuite/gas/arm/thumb32.d	29 Jul 2005 17:39:38 -0000	1.9
+++ gas/testsuite/gas/arm/thumb32.d	3 Aug 2005 22:12:47 -0000
@@ -634,8 +634,8 @@ Disassembly of section .text:
 0+79a <[^>]+> e889 0007 	stmia\.w	r9, \{r0, r1, r2\}
 0+79e <[^>]+> e880 0580 	stmia\.w	r0, \{r7, r8, sl\}
 0+7a2 <[^>]+> e8a0 0580 	stmia\.w	r0!, \{r7, r8, sl\}
-0+7a6 <[^>]+> e900 0580 	stmdb	r0, \{r7, r8, sl\}
-0+7aa <[^>]+> e910 0580 	ldmdb	r0, \{r7, r8, sl\}
+0+7a6 <[^>]+> e910 0580 	ldmdb	r0, \{r7, r8, sl\}
+0+7aa <[^>]+> e900 0580 	stmdb	r0, \{r7, r8, sl\}
 0+7ae <[^>]+> fb00 0000 	mla	r0, r0, r0, r0
 0+7b2 <[^>]+> fb00 0010 	mls	r0, r0, r0, r0
 0+7b6 <[^>]+> fb00 0900 	mla	r9, r0, r0, r0
@@ -1021,3 +1021,5 @@ Disassembly of section .text:
 0+d1c <[^>]+> e8d0 f018 	tbh	\[r0, r8, lsl #1\]
 0+d20 <[^>]+> f84d 8d04 	str.w	r8, \[sp, #-4\]!
 0+d24 <[^>]+> f85d 8b04 	ldr.w	r8, \[sp\], #4
+0+d28 <[^>]+> e930 0580 	ldmdb	r0!, \{r7, r8, sl\}
+0+d2c <[^>]+> e920 0580 	stmdb	r0!, \{r7, r8, sl\}
Index: gas/testsuite/gas/arm/thumb32.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/thumb32.s,v
retrieving revision 1.5
diff -u -p -r1.5 thumb32.s
--- gas/testsuite/gas/arm/thumb32.s	29 Jul 2005 17:39:38 -0000	1.5
+++ gas/testsuite/gas/arm/thumb32.s	3 Aug 2005 22:12:47 -0000
@@ -756,3 +770,6 @@ xta:	
 
 	push	{r8}
 	pop	{r8}
+
+	ldmdb	r0!, {r7,r8,r10}
+	stmdb	r0!, {r7,r8,r10}

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