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 subs pc


For historical reasons ARM returns frm an exception handler using subs pc, lr, 
#const or movs pc, lr. On Thumb-2 these use a special encoding and 
the "normal" ecodings are either reserved or mean something else.

The patch below fixes the encoding of these instructions. I have not attempted 
to catch all the invalid forms of these instructions. That will come as a 
later.

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

Paul

2007-03-25  Paul Brook  <paul@codesourcery.com>

	gas/
	* config/tc-arm.c (T2_SUBS_PC_LR): Define.
	(do_t_add_sub): Correctly encode subs pc, lr, #const.
	(do_t_mov_cmp): Correctly encode movs pc, lr.

	gas/testsulte/
	* gas/arm/thumb32.s: Add tests for subs pc, lr.
	* gas/arm/thumb32.d: Change error-output: to stderr:.
	Update expected output.

Index: gas/testsuite/gas/arm/thumb32.d
===================================================================
--- gas/testsuite/gas/arm/thumb32.d	(revision 172261)
+++ gas/testsuite/gas/arm/thumb32.d	(working copy)
@@ -3,7 +3,7 @@
 # objdump: -dr --prefix-addresses --show-raw-insn
 # The arm-aout and arm-pe ports do not support Thumb branch relocations.
 # not-target: *-*-*aout* *-*-pe
-# error-output: thumb32.l
+# stderr: thumb32.l
 
 .*: +file format .*arm.*
 
@@ -959,3 +959,7 @@ Disassembly of section .text:
 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
+0[0-9a-f]+ <[^>]+> f3de 8f00 	subs	pc, lr, #0
+0[0-9a-f]+ <[^>]+> f3de 8f00 	subs	pc, lr, #0
+0[0-9a-f]+ <[^>]+> f3de 8f04 	subs	pc, lr, #4
+0[0-9a-f]+ <[^>]+> f3de 8fff 	subs	pc, lr, #255
Index: gas/testsuite/gas/arm/thumb32.s
===================================================================
--- gas/testsuite/gas/arm/thumb32.s	(revision 172261)
+++ gas/testsuite/gas/arm/thumb32.s	(working copy)
@@ -775,3 +775,8 @@ srs:
 	srsdb sp, #16
 	srsia sp!, #21
 	srsia sp!, #10
+
+	movs pc, lr
+	subs pc, lr, #0
+	subs pc, lr, #4
+	subs pc, lr, #255
Index: gas/config/tc-arm.c
===================================================================
--- gas/config/tc-arm.c	(revision 172261)
+++ gas/config/tc-arm.c	(working copy)
@@ -560,6 +560,8 @@ struct asm_opcode
 #define OPCODE_MASK	0xfe1fffff
 #define V4_STR_BIT	0x00000020
 
+#define T2_SUBS_PC_LR	0xf3de8f00
+
 #define DATA_OP_SHIFT	21
 
 #define T2_OPCODE_MASK	0xfe1fffff
@@ -8444,7 +8446,21 @@ do_t_add_sub (void)
 	  if (inst.size_req == 4
 	      || (inst.size_req != 2 && !opcode))
 	    {
-	      if (Rs == REG_PC)
+	      if (Rd == REG_PC)
+		{
+		  constraint (Rs != REG_LR || inst.instruction != T_MNEM_subs,
+			     _("only SUBS PC, LR, #const allowed"));
+		  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 > 0xff,
+			     _("immediate value out of range"));
+		  inst.instruction = T2_SUBS_PC_LR
+				     | inst.reloc.exp.X_add_number;
+		  inst.reloc.type = BFD_RELOC_UNUSED;
+		  return;
+		}
+	      else if (Rs == REG_PC)
 		{
 		  /* Always use addw/subw.  */
 		  inst.instruction = add ? 0xf20f0000 : 0xf2af0000;
@@ -9502,6 +9519,16 @@ do_t_mov_cmp (void)
 	  || inst.operands[1].shifted)
 	narrow = FALSE;
 
+      /* MOVS PC, LR is encoded as SUBS PC, LR, #0.  */
+      if (opcode == T_MNEM_movs && inst.operands[1].isreg
+	  && !inst.operands[1].shifted
+	  && inst.operands[0].reg == REG_PC
+	  && inst.operands[1].reg == REG_LR)
+	{
+	  inst.instruction = T2_SUBS_PC_LR;
+	  return;
+	}
+
       if (!inst.operands[1].isreg)
 	{
 	  /* Immediate operand.  */


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