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]

Thumb-2 shift aliases


The patch below makes ARM gas accept

  mov reg, reg, <shift> N

as an alias for

  <shift> reg, reg, N

In unified syntax Thumb mode.
Also corresponding bits added to the testsuite.

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

Paul

2007-06-14  Paul Brook  <paul@codesourcery.com>

	gas/
	* config/tc-arm.c (do_t_mov_cmp): Handle shift by register and
	narrow shift by immediate.

	gas/testsuite/
	* gas/arm/thumb32.s: Add tests for shift instructions.
	* gas/arm/thumb32.d: Ditto.

Index: gas/config/tc-arm.c
===================================================================
RCS file: /var/cvsroot/src-cvs/src/gas/config/tc-arm.c,v
retrieving revision 1.330
diff -u -p -r1.330 tc-arm.c
--- gas/config/tc-arm.c	6 Jun 2007 17:36:54 -0000	1.330
+++ gas/config/tc-arm.c	14 Jun 2007 17:05:22 -0000
@@ -9544,11 +9544,98 @@ do_t_mov_cmp (void)
 	      inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
 	    }
 	}
+      else if (inst.operands[1].shifted && inst.operands[1].immisreg
+	       && (inst.instruction == T_MNEM_mov
+		   || inst.instruction == T_MNEM_movs))
+	{
+	  /* Register shifts are encoded as separate shift instructions.  */
+	  bfd_boolean flags = (inst.instruction == T_MNEM_movs);
+
+	  if (current_it_mask)
+	    narrow = !flags;
+	  else
+	    narrow = flags;
+
+	  if (inst.size_req == 4)
+	    narrow = FALSE;
+
+	  if (!low_regs || inst.operands[1].imm > 7)
+	    narrow = FALSE;
+
+	  if (inst.operands[0].reg != inst.operands[1].reg)
+	    narrow = FALSE;
+
+	  switch (inst.operands[1].shift_kind)
+	    {
+	    case SHIFT_LSL:
+	      opcode = narrow ? T_OPCODE_LSL_R : THUMB_OP32 (T_MNEM_lsl);
+	      break;
+	    case SHIFT_ASR:
+	      opcode = narrow ? T_OPCODE_ASR_R : THUMB_OP32 (T_MNEM_asr);
+	      break;
+	    case SHIFT_LSR:
+	      opcode = narrow ? T_OPCODE_LSR_R : THUMB_OP32 (T_MNEM_lsr);
+	      break;
+	    case SHIFT_ROR:
+	      opcode = narrow ? T_OPCODE_ROR_R : THUMB_OP32 (T_MNEM_ror);
+	      break;
+	    default:
+	      abort();
+	    }
+
+	  inst.instruction = opcode;
+	  if (narrow)
+	    {
+	      inst.instruction |= inst.operands[0].reg;
+	      inst.instruction |= inst.operands[1].imm << 3;
+	    }
+	  else
+	    {
+	      if (flags)
+		inst.instruction |= CONDS_BIT;
+
+	      inst.instruction |= inst.operands[0].reg << 8;
+	      inst.instruction |= inst.operands[1].reg << 16;
+	      inst.instruction |= inst.operands[1].imm;
+	    }
+	}
       else if (!narrow)
 	{
-	  inst.instruction = THUMB_OP32 (inst.instruction);
-	  inst.instruction |= inst.operands[0].reg << r0off;
-	  encode_thumb32_shifted_operand (1);
+	  /* Some mov with immediate shift have narrow variants.
+	     Register shifts are handled above.  */
+	  if (low_regs && inst.operands[1].shifted
+	      && (inst.instruction == T_MNEM_mov
+		  || inst.instruction == T_MNEM_movs))
+	    {
+	      if (current_it_mask)
+		narrow = (inst.instruction == T_MNEM_mov);
+	      else
+		narrow = (inst.instruction == T_MNEM_movs);
+	    }
+
+	  if (narrow)
+	    {
+	      switch (inst.operands[1].shift_kind)
+		{
+		case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_I; break;
+		case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break;
+		case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_I; break;
+		default: narrow = FALSE; break;
+		}
+	    }
+
+	  if (narrow)
+	    {
+	      inst.instruction |= inst.operands[0].reg;
+	      inst.instruction |= inst.operands[1].reg << 3;
+	      inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
+	    }
+	  else
+	    {
+	      inst.instruction = THUMB_OP32 (inst.instruction);
+	      inst.instruction |= inst.operands[0].reg << r0off;
+	      encode_thumb32_shifted_operand (1);
+	    }
 	}
       else
 	switch (inst.instruction)
Index: gas/testsuite/gas/arm/thumb32.d
===================================================================
RCS file: /var/cvsroot/src-cvs/src/gas/testsuite/gas/arm/thumb32.d,v
retrieving revision 1.23
diff -u -p -r1.23 thumb32.d
--- gas/testsuite/gas/arm/thumb32.d	5 Jun 2007 22:02:46 -0000	1.23
+++ gas/testsuite/gas/arm/thumb32.d	14 Jun 2007 19:44:02 -0000
@@ -1001,3 +1001,32 @@ Disassembly of section .text:
 0[0-9a-f]+ <[^>]+> f935 1b30 	ldrsh.w	r1, \[r5\], #48
 0[0-9a-f]+ <[^>]+> f935 1930 	ldrsh.w	r1, \[r5\], #-48
 0[0-9a-f]+ <[^>]+> f935 1009 	ldrsh.w	r1, \[r5, r9\]
+0[0-9a-f]+ <[^>]+> 00a1      	lsls	r1, r4, #2
+0[0-9a-f]+ <[^>]+> ea5f 0389 	movs.w	r3, r9, lsl #2
+0[0-9a-f]+ <[^>]+> fa12 f103 	lsls.w	r1, r2, r3
+0[0-9a-f]+ <[^>]+> 4099      	lsls	r1, r3
+0[0-9a-f]+ <[^>]+> fa11 f109 	lsls.w	r1, r1, r9
+0[0-9a-f]+ <[^>]+> fa02 f103 	lsl.w	r1, r2, r3
+0[0-9a-f]+ <[^>]+> fa01 f103 	lsl.w	r1, r1, r3
+0[0-9a-f]+ <[^>]+> 08a1      	lsrs	r1, r4, #2
+0[0-9a-f]+ <[^>]+> ea5f 0399 	movs.w	r3, r9, lsr #2
+0[0-9a-f]+ <[^>]+> fa32 f103 	lsrs.w	r1, r2, r3
+0[0-9a-f]+ <[^>]+> 40d9      	lsrs	r1, r3
+0[0-9a-f]+ <[^>]+> fa31 f109 	lsrs.w	r1, r1, r9
+0[0-9a-f]+ <[^>]+> fa22 f103 	lsr.w	r1, r2, r3
+0[0-9a-f]+ <[^>]+> fa21 f103 	lsr.w	r1, r1, r3
+0[0-9a-f]+ <[^>]+> 10a1      	asrs	r1, r4, #2
+0[0-9a-f]+ <[^>]+> ea5f 03a9 	movs.w	r3, r9, asr #2
+0[0-9a-f]+ <[^>]+> fa52 f103 	asrs.w	r1, r2, r3
+0[0-9a-f]+ <[^>]+> 4119      	asrs	r1, r3
+0[0-9a-f]+ <[^>]+> fa51 f109 	asrs.w	r1, r1, r9
+0[0-9a-f]+ <[^>]+> fa42 f103 	asr.w	r1, r2, r3
+0[0-9a-f]+ <[^>]+> fa41 f103 	asr.w	r1, r1, r3
+0[0-9a-f]+ <[^>]+> ea5f 01b4 	movs.w	r1, r4, ror #2
+0[0-9a-f]+ <[^>]+> ea5f 03b9 	movs.w	r3, r9, ror #2
+0[0-9a-f]+ <[^>]+> fa72 f103 	rors.w	r1, r2, r3
+0[0-9a-f]+ <[^>]+> 41d9      	rors	r1, r3
+0[0-9a-f]+ <[^>]+> fa71 f109 	rors.w	r1, r1, r9
+0[0-9a-f]+ <[^>]+> fa62 f103 	ror.w	r1, r2, r3
+0[0-9a-f]+ <[^>]+> fa61 f103 	ror.w	r1, r1, r3
+0[0-9a-f]+ <[^>]+> bf00      	nop
Index: gas/testsuite/gas/arm/thumb32.s
===================================================================
RCS file: /var/cvsroot/src-cvs/src/gas/testsuite/gas/arm/thumb32.s,v
retrieving revision 1.13
diff -u -p -r1.13 thumb32.s
--- gas/testsuite/gas/arm/thumb32.s	5 Jun 2007 22:02:46 -0000	1.13
+++ gas/testsuite/gas/arm/thumb32.s	14 Jun 2007 19:43:49 -0000
@@ -803,3 +803,17 @@ srs:
 	ldaddr sb
 	ldaddr h
 	ldaddr sh
+	.macro movshift op s="s"
+	movs r1, r4, \op #2
+	movs r3, r9, \op #2
+	movs r1, r2, \op r3
+	movs r1, r1, \op r3
+	movs r1, r1, \op r9
+	mov r1, r2, \op r3
+	mov r1, r1, \op r3
+	.endm
+	movshift lsl
+	movshift lsr
+	movshift asr
+	movshift ror
+	nop


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