public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* Thumb32 assembler (42/69)
@ 2005-04-26 10:03 Zack Weinberg
  2005-04-26 15:20 ` Paul Brook
  0 siblings, 1 reply; 5+ messages in thread
From: Zack Weinberg @ 2005-04-26 10:03 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 323 bytes --]


Here we are going after bigger game: Thumb addresses can now be
handled by parse_operands.  This, plus some adjustments to tinsns,
allows the removal of lots of tiny wrapper functions.  And, again,
constant handling is deferred to md_apply_fix3 so that code is not
duplicated between there and the encoder functions.

zw


[-- Attachment #2: Type: text/plain, Size: 869 bytes --]


	* tc-arm.c (THUMB_LOAD_BIT): New constant.
	(parse_thumb_address): New function.
	(OP_TADDR): New operand parse code.
	(parse_operands): Handle it.  Delete code for OP_RLlb and OP_RLtb.
	(thumb_load_store): Rename do_t_ldst.  Use parse_operands.  Remove
	second and third arguments; determine size and direction of operation
	from inst.instruction.  Defer most constant handling to md_apply_fix3.
	(do_t_lds): Use TADDR, not RLlb and RLtb.
	(THUMB_REG_LO, THUMB_REG_ANY, THUMB_LOAD, THUMB_STORE, THUMB_WORD)
	(THUMB_HALFWORD, THUMB_BYTE, thumb_reg, OP_RLlb, OP_RLtb, do_t_ldr)
	(do_t_ldrb, do_t_ldrh, do_t_str, do_t_strb, do_t_strh):	Delete.
	(tinsns): Use do_t_ldst for ldr ldrb ldrh str strb strh.  Set opcode
	for these to the opcode for the 3-register form.
	(md_apply_fix3 <case BFD_RELOC_ARM_THUMB_OFFSET>): Correct check
	for non-word-aligned offset from PC.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 42.diff.txt --]
[-- Type: text/x-patch; name=42.diff.txt, Size: 15549 bytes --]

===================================================================
Index: gas/config/tc-arm.c
--- gas/config/tc-arm.c	(revision 44)
+++ gas/config/tc-arm.c	(revision 45)
@@ -197,6 +197,7 @@
     int imm;
     int present    : 1;  /* operand present */
     int isreg	   : 1;  /* operand was a register */
+    int immisreg   : 1;  /* .imm field is a second register */
     int writeback  : 1;  /* operand has trailing ! */
     int hasreloc   : 1;  /* operand has relocation suffix */
     int postind    : 1;  /* operand is post-indexed */
@@ -555,22 +556,10 @@
 #define T_OPCODE_BRANCH 0xe7fe
 
 #define THUMB_SIZE	2	/* Size of thumb instruction.  */
-#define THUMB_REG_LO	0x1
-#define THUMB_REG_ANY	0x3
 
-#define THUMB_H1	0x0080
-#define THUMB_H2	0x0040
-
-#define THUMB_LOAD 0
-#define THUMB_STORE 1
-
 #define THUMB_PP_PC_LR 0x0100
+#define THUMB_LOAD_BIT 0x0800
 
-/* These three are used for immediate shifts, do not alter.  */
-#define THUMB_WORD 2
-#define THUMB_HALFWORD 1
-#define THUMB_BYTE 0
-
 struct thumb_opcode
 {
   /* Basic string to match.  */
@@ -1275,28 +1264,6 @@
     }							\
 } while (0)
 
-/* Parse and validate that a register is of the right form, this saves
-   repeated checking of this information in many similar cases.
-   Unlike the 32-bit case we do not insert the register into the opcode
-   here, since the position is often unknown until the full instruction
-   has been parsed.  */
-
-static int
-thumb_reg (char ** strp, int hi_lo)
-{
-  int reg;
-
-  if ((reg = reg_required_here (strp, -1, REG_TYPE_RN)) == FAIL)
-    return FAIL;
-
-  if (hi_lo == THUMB_REG_LO && reg > 7)
-    {
-      inst.error = BAD_HIREG;
-      return FAIL;
-    }
-  return reg;
-}
-
 /* Register lists.  */
 
 static long
@@ -2451,6 +2418,100 @@
   return SUCCESS;
 }
 
+/* Parse a Thumb address expression:
+
+      [Rl]
+      [Rl, Rl]
+      [Rl, #imm]     ; 5 bits, *4
+      [SP/PC, #imm]  ; 8 bits, *4
+      =imm           ; pseudo (mov or lit-pool load)
+      label	     ; translated to [PC, offset]
+
+   Data is written to inst.operands[i] and/or inst.reloc.exp.
+   Returns SUCCESS or FAIL.  */
+
+static int
+parse_thumb_address (char **str, int i)
+{
+  char *s = *str;
+  int Rb, Ro;
+
+  if (*s == '[')
+    {
+      s++;
+      if ((Rb = arm_reg_parse (&s, REG_TYPE_RN)) == FAIL)
+	return FAIL;
+      if (Rb > 7 && Rb != REG_SP && Rb != REG_PC)
+	{
+	  inst.error = BAD_HIREG;
+	  return FAIL;
+	}
+      inst.operands[i].reg = Rb;
+      inst.operands[i].isreg = 1;
+      if (skip_past_comma (&s) != FAIL)
+	{
+	  if (is_immediate_prefix (*s))
+	    {
+	      s++;
+	      if (my_get_expression (&inst.reloc.exp, &s))
+		return FAIL;
+	    }
+	  else
+	    {
+	      if ((Ro = arm_reg_parse (&s, REG_TYPE_RN)) == FAIL)
+		return FAIL;
+	      if (Ro > 7 || Rb > 7)
+		{
+		  inst.error = BAD_HIREG;
+		  return FAIL;
+		}
+	      inst.operands[i].imm = Ro;
+	      inst.operands[i].immisreg = 1;
+	    }
+	}
+      else
+	{
+	  /* [Rd] == [Rd,#0] */
+	  inst.reloc.exp.X_op = O_constant;
+	  inst.reloc.exp.X_add_number = 0;
+	}
+      if (*s++ != ']')
+	{
+	  inst.error = BAD_ARGS;
+	  return FAIL;
+	}
+    }
+  else if (*s == '=')
+    {
+      s++;
+      if (my_get_expression (&inst.reloc.exp, &s))
+	return FAIL;
+
+      if (   inst.reloc.exp.X_op != O_constant
+	  && inst.reloc.exp.X_op != O_symbol)
+	{
+	  inst.error = "Constant expression expected";
+	  return FAIL;
+	}
+    }
+  else
+    {
+      if (my_get_expression (&inst.reloc.exp, &s))
+	return FAIL;
+
+      inst.reloc.exp.X_add_number -= 4; /* Pipeline offset.  */
+      if (inst.reloc.exp.X_op != O_constant)
+	inst.reloc.pc_rel = 1;
+      inst.operands[i].reg = REG_PC;
+      inst.operands[i].isreg = 1;
+    }
+
+  if (!inst.operands[i].immisreg)
+    inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
+  *str = s;
+  return SUCCESS;
+}
+
 /* Parse the flags argument to CPSI[ED].  Returns FAIL on error, or a
    value suitable for splatting into the AIF field of the instruction.  */
 
@@ -4270,8 +4331,6 @@
 #define OP_RRw     051  /* ARM register, not the PC, optional trailing ! */
 
 #define OP_RL      052  /* Thumb low register */
-#define OP_RLlb    053  /* Thumb low register, leading [ */
-#define OP_RLtb    054  /* Thumb low register, trailing ] */
 #define OP_RLw	   055	/* Thumb low register, optional trailing ! */
 
 #define OP_CPSF    060  /* CPS flags */
@@ -4281,6 +4340,8 @@
 #define OP_VRSLST  064	/* VFP single-precision register list */
 #define OP_VRDLST  065	/* VFP double-precision register list */
 
+#define OP_TADDR   070	/* Thumb memory address expression */
+
 /* This-or-that operands.  All have bit 7 set.  */
 #define OP_RR_EX   100  /* ARM register or expression */
 #define OP_RL_iEX  101  /* Thumb low register or expression with imm prefix */
@@ -4412,16 +4473,6 @@
 	    }
 	  break;
 
-	case OP_(RLlb):
-	  po_char_or_fail ('[');
-	  po_reg_or_fail (REG_TYPE_RN);
-	  break;
-
-	case OP_(RLtb):
-	  po_reg_or_fail (REG_TYPE_RN);
-	  po_char_or_fail (']');
-	  break;
-
 	  /* Immediates */
 	I0:
 	case OP_(I0):	 po_imm_or_fail (  0,      0, FALSE);	break;
@@ -4552,6 +4603,12 @@
 	  val = vfp_parse_reg_list (&str, &inst.operands[i].reg, 1);
 	  break;
 
+	  /* Addressing modes */
+	case OP_(TADDR):
+	  if (parse_thumb_address (&str, i))
+	    return FAIL;
+	  break;
+
 	default:
 	  as_fatal ("unhandled operand code %03o", *p);
 	}
@@ -4571,8 +4628,6 @@
 
 	case OP_(oRL):
 	case OP_(RL):
-	case OP_(RLlb):
-	case OP_(RLtb):
 	case OP_(RLw):
 	case OP_(oRL_iEX):
 	case OP_(RL_iEX):
@@ -6251,75 +6306,24 @@
 }
 
 static void
-thumb_load_store (char * str, int load_store, int size)
+do_t_ldst (char *str)
 {
-  int Rd, Rb, Ro = FAIL;
+  if (parse_operands (str, OPERANDS2(RL,TADDR)))
+    return;
 
-  if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
-      || skip_past_comma (&str) == FAIL)
+  if (!inst.operands[1].isreg) /* =expr pseudo */
     {
-      if (! inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
-
-  if (*str == '[')
-    {
-      str++;
-      if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
-	return;
-
-      if (skip_past_comma (&str) != FAIL)
+      if (inst.instruction & THUMB_LOAD_BIT)
 	{
-	  if (is_immediate_prefix (*str))
-	    {
-	      str++;
-	      expression_or_fail (&inst.reloc.exp, &str);
-	    }
-	  else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
-	    return;
-	}
-      else
-	{
-	  inst.reloc.exp.X_op = O_constant;
-	  inst.reloc.exp.X_add_number = 0;
-	}
-
-      if (*str != ']')
-	{
-	  inst.error = _("expected ']'");
-	  return;
-	}
-      str++;
-    }
-  else if (*str == '=')
-    {
-      if (load_store != THUMB_LOAD)
-	{
 	  inst.error = _("invalid pseudo operation");
 	  return;
 	}
 
-      /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
-      str++;
-
-      expression_or_fail (& inst.reloc.exp, & str);
-
-      end_of_line (str);
-
-      if (   inst.reloc.exp.X_op != O_constant
-	  && inst.reloc.exp.X_op != O_symbol)
-	{
-	  inst.error = "Constant expression expected";
-	  return;
-	}
-
       if (inst.reloc.exp.X_op == O_constant
 	  && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
 	{
 	  /* This can be done with a mov instruction.  */
-
-	  inst.instruction  = T_OPCODE_MOV_I8 | (Rd << 8);
+	  inst.instruction  = T_OPCODE_MOV_I8 | (inst.operands[0].reg << 8);
 	  inst.instruction |= inst.reloc.exp.X_add_number;
 	  return;
 	}
@@ -6327,123 +6331,67 @@
       /* Insert into literal pool.  */
       if (add_to_lit_pool () == FAIL)
 	{
-	  if (!inst.error)
-	    inst.error = "literal pool insertion failed";
+	  inst.error = _("literal pool insertion failed");
 	  return;
 	}
 
       inst.reloc.type   = BFD_RELOC_ARM_THUMB_OFFSET;
-      inst.reloc.pc_rel = 1;
-      inst.instruction  = T_OPCODE_LDR_PC | (Rd << 8);
-      /* Adjust ARM pipeline offset to Thumb.  */
-      inst.reloc.exp.X_add_number += 4;
-
-      return;
+      inst.reloc.exp.X_add_number += 4;  /* pipeline offset */
+      inst.operands[1].reg = REG_PC;
     }
-  else
-    {
-      expression_or_fail (&inst.reloc.exp, &str);
 
-      inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
-      inst.reloc.pc_rel = 1;
-      inst.reloc.exp.X_add_number -= 4; /* Pipeline offset.  */
-      inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
-      end_of_line (str);
-      return;
-    }
-
-  if (Rb == REG_PC || Rb == REG_SP)
+  if (inst.operands[1].reg == REG_PC || inst.operands[1].reg == REG_SP)
     {
-      if (size != THUMB_WORD)
+      if (inst.instruction & 0x0600)
 	{
 	  inst.error = _("byte or halfword not valid for base register");
 	  return;
 	}
-      else if (Rb == REG_PC && load_store != THUMB_LOAD)
+      else if (inst.operands[1].reg == REG_PC
+	       && !(inst.instruction & THUMB_LOAD_BIT))
 	{
 	  inst.error = _("r15 based store not allowed");
 	  return;
 	}
-      else if (Ro != FAIL)
+      else if (inst.operands[1].immisreg)
 	{
 	  inst.error = _("invalid base register for register offset");
 	  return;
 	}
 
-      if (Rb == REG_PC)
+      if (inst.operands[1].reg == REG_PC)
 	inst.instruction = T_OPCODE_LDR_PC;
-      else if (load_store == THUMB_LOAD)
+      else if (inst.instruction & THUMB_LOAD_BIT)
 	inst.instruction = T_OPCODE_LDR_SP;
       else
 	inst.instruction = T_OPCODE_STR_SP;
 
-      inst.instruction |= Rd << 8;
-      if (inst.reloc.exp.X_op == O_constant)
-	{
-	  unsigned offset = inst.reloc.exp.X_add_number;
-
-	  if (offset & ~0x3fc)
-	    {
-	      inst.error = _("invalid offset");
-	      return;
-	    }
-
-	  inst.instruction |= offset >> 2;
-	}
-      else
-	inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
+      inst.instruction |= inst.operands[0].reg << 8;
     }
-  else if (Rb > 7)
+  else if (!inst.operands[1].immisreg)
     {
-      inst.error = _("invalid base register in load/store");
-      return;
-    }
-  else if (Ro == FAIL)
-    {
       /* Immediate offset.  */
-      if (size == THUMB_WORD)
-	inst.instruction = (load_store == THUMB_LOAD
-			    ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
-      else if (size == THUMB_HALFWORD)
-	inst.instruction = (load_store == THUMB_LOAD
-			    ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
-      else
-	inst.instruction = (load_store == THUMB_LOAD
-			    ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
-
-      inst.instruction |= Rd | (Rb << 3);
-
-      if (inst.reloc.exp.X_op == O_constant)
+      switch (inst.instruction)
 	{
-	  unsigned offset = inst.reloc.exp.X_add_number;
-
-	  if (offset & ~(0x1f << size))
-	    {
-	      inst.error = _("invalid offset");
-	      return;
-	    }
-	  inst.instruction |= (offset >> size) << 6;
+	case T_OPCODE_STR_RW: inst.instruction = T_OPCODE_STR_IW; break;
+	case T_OPCODE_STR_RH: inst.instruction = T_OPCODE_STR_IH; break;
+	case T_OPCODE_STR_RB: inst.instruction = T_OPCODE_STR_IB; break;
+	case T_OPCODE_LDR_RW: inst.instruction = T_OPCODE_LDR_IW; break;
+	case T_OPCODE_LDR_RH: inst.instruction = T_OPCODE_LDR_IH; break;
+	case T_OPCODE_LDR_RB: inst.instruction = T_OPCODE_LDR_IB; break;
+	default: abort ();
 	}
-      else
-	inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
+
+      inst.instruction |= inst.operands[0].reg;
+      inst.instruction |= inst.operands[1].reg << 3;
     }
   else
     {
-      /* Register offset.  */
-      if (size == THUMB_WORD)
-	inst.instruction = (load_store == THUMB_LOAD
-			    ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
-      else if (size == THUMB_HALFWORD)
-	inst.instruction = (load_store == THUMB_LOAD
-			    ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
-      else
-	inst.instruction = (load_store == THUMB_LOAD
-			    ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
-
-      inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
+      /* Register offset.  Opcode is already correct.  */
+      inst.instruction |= inst.operands[0].reg;
+      inst.instruction |= inst.operands[1].reg << 3;
+      inst.instruction |= inst.operands[1].imm << 6;
     }
-
-  end_of_line (str);
 }
 
 static void
@@ -6678,9 +6626,7 @@
   if (parse_operands (str, OPERANDS1(RR)))
     return;
 
-  /* This sets THUMB_H2 from the top bit of reg.  */
   inst.instruction |= (inst.operands[0].reg << 3);
-
   /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC.  The reloc
      should cause the alignment to be checked once it is known.  This is
      because BX PC only works if the instruction is word aligned.  */
@@ -6741,32 +6687,19 @@
 }
 
 static void
-do_t_ldr (char * str)
-{
-  thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
-}
-
-static void
-do_t_ldrb (char * str)
-{
-  thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
-}
-
-static void
-do_t_ldrh (char * str)
-{
-  thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
-}
-
-static void
 do_t_lds (char * str)
 {
-  if (parse_operands (str, OPERANDS3(RL,RLlb,RLtb)))
+  if (parse_operands (str, OPERANDS2(RL,TADDR)))
     return;
+  if (!inst.operands[1].isreg || !inst.operands[1].immisreg)
+    {
+      inst.error = _("invalid addressing mode");
+      return;
+    }
 
   inst.instruction |= inst.operands[0].reg;
   inst.instruction |= inst.operands[1].reg << 3;
-  inst.instruction |= inst.operands[2].reg << 6;
+  inst.instruction |= inst.operands[1].imm << 6;
 }
 
 static void
@@ -6819,24 +6752,6 @@
 }
 
 static void
-do_t_str (char * str)
-{
-  thumb_load_store (str, THUMB_STORE, THUMB_WORD);
-}
-
-static void
-do_t_strb (char * str)
-{
-  thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
-}
-
-static void
-do_t_strh (char * str)
-{
-  thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
-}
-
-static void
 do_t_swi (char * str)
 {
   if (parse_operands (str, OPERANDS1(EXP)))
@@ -9568,9 +9483,9 @@
   {"cmp",	T_OPCODE_CMP_HR,2,	ARM_EXT_V4T, do_t_mov_cmp},
   {"eor",	0x4040,		2,	ARM_EXT_V4T, do_t_arit},
   {"ldmia",	0xc800,		2,	ARM_EXT_V4T, do_t_ldmstm},
-  {"ldr",	0x0000,		2,	ARM_EXT_V4T, do_t_ldr},
-  {"ldrb",	0x0000,		2,	ARM_EXT_V4T, do_t_ldrb},
-  {"ldrh",	0x0000,		2,	ARM_EXT_V4T, do_t_ldrh},
+  {"ldr",	T_OPCODE_LDR_RW,2,	ARM_EXT_V4T, do_t_ldst},
+  {"ldrb",	T_OPCODE_LDR_RB,2,	ARM_EXT_V4T, do_t_ldst},
+  {"ldrh",	T_OPCODE_LDR_RH,2,	ARM_EXT_V4T, do_t_ldst},
   {"ldrsb",	0x5600,		2,	ARM_EXT_V4T, do_t_lds},
   {"ldrsh",	0x5e00,		2,	ARM_EXT_V4T, do_t_lds},
   {"ldsb",	0x5600,		2,	ARM_EXT_V4T, do_t_lds},
@@ -9587,9 +9502,9 @@
   {"ror",	0x41c0,		2,	ARM_EXT_V4T, do_t_arit},
   {"sbc",	0x4180,		2,	ARM_EXT_V4T, do_t_arit},
   {"stmia",	0xc000,		2,	ARM_EXT_V4T, do_t_ldmstm},
-  {"str",	0x0000,		2,	ARM_EXT_V4T, do_t_str},
-  {"strb",	0x0000,		2,	ARM_EXT_V4T, do_t_strb},
-  {"strh",	0x0000,		2,	ARM_EXT_V4T, do_t_strh},
+  {"str",	T_OPCODE_STR_RW,2,	ARM_EXT_V4T, do_t_ldst},
+  {"strb",	T_OPCODE_STR_RB,2,	ARM_EXT_V4T, do_t_ldst},
+  {"strh",	T_OPCODE_STR_RH,2,	ARM_EXT_V4T, do_t_ldst},
   {"swi",	0xdf00,		2,	ARM_EXT_V4T, do_t_swi},
   {"sub",	0x8000,		2,	ARM_EXT_V4T, do_t_add_sub},
   {"tst",	T_OPCODE_TST,	2,	ARM_EXT_V4T, do_t_arit},
@@ -10839,11 +10754,11 @@
 	     aligned (since the final address produced must be, and
 	     we can only describe word-aligned immediate offsets).  */
 
-	  if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
+	  if (value & 3)
 	    as_bad_where (fixP->fx_file, fixP->fx_line,
-			  _("invalid offset, target not word aligned (0x%08X)"),
-			  (unsigned int) (fixP->fx_frag->fr_address
-					  + fixP->fx_where + value));
+			  _("invalid offset, target not word aligned (0x%08lX)"),
+			  (((unsigned int) fixP->fx_frag->fr_address
+			    + (unsigned int) fixP->fx_where) & ~3) + value);
 
 	  if ((value + 2) & ~0x3fe)
 	    as_bad_where (fixP->fx_file, fixP->fx_line,

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Thumb32 assembler (42/69)
  2005-04-26 10:03 Thumb32 assembler (42/69) Zack Weinberg
@ 2005-04-26 15:20 ` Paul Brook
  2005-04-29 11:57   ` Zack Weinberg
  2005-04-30  0:57   ` Zack Weinberg
  0 siblings, 2 replies; 5+ messages in thread
From: Paul Brook @ 2005-04-26 15:20 UTC (permalink / raw)
  To: binutils; +Cc: Zack Weinberg

On Tuesday 26 April 2005 10:55, Zack Weinberg wrote:
> constant handling is deferred to md_apply_fix3 so that code is not
> duplicated between there and the encoder functions.
>...
> @@ -10839,11 +10754,11 @@
>              aligned (since the final address produced must be, and
>              we can only describe word-aligned immediate offsets).  */
>  
> -         if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
> +         if (value & 3)
>             as_bad_where (fixP->fx_file, fixP->fx_line,
> -                         _("invalid offset, target not word aligned

Breaks the following assembly fragment: 

        .text
        .code 16
        .align 2
        .global _start
        .thumb_func
_start:
        ldr r0, foo
        ldr r0, foo
        ldr r0, [pc, #4]
        ldr r0, [pc, #4]
foo:
        .word 42

Paul

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Thumb32 assembler (42/69)
  2005-04-26 15:20 ` Paul Brook
@ 2005-04-29 11:57   ` Zack Weinberg
  2005-04-30  0:57   ` Zack Weinberg
  1 sibling, 0 replies; 5+ messages in thread
From: Zack Weinberg @ 2005-04-29 11:57 UTC (permalink / raw)
  To: Paul Brook; +Cc: binutils

Paul Brook <paul@codesourcery.com> writes:

> On Tuesday 26 April 2005 10:55, Zack Weinberg wrote:
>> constant handling is deferred to md_apply_fix3 so that code is not
>> duplicated between there and the encoder functions.
...
> Breaks the following assembly fragment: 
>
>         .text
>         .code 16
>         .align 2
>         .global _start
>         .thumb_func
> _start:
>         ldr r0, foo
>         ldr r0, foo
>         ldr r0, [pc, #4]
>         ldr r0, [pc, #4]
> foo:
>         .word 42

I have attempted to fix this, but I have not been entirely successful.

When md_apply_fix3 is called, the second 'ldr r0, foo' has an
identical fix structure to that generated for 'ldr r0, [pc, #4]'.
This is because fixup_segment is not aware of the pipeline offset, it
having been coded into some (not all) of the relevant instructions
rather than expressed with md_pcrel_from.  Accordingly I tried to
address the problem by using md_pcrel_from to express the pipeline
offset, instead of coding it into instructions.  This works great for
the above test case, however, it breaks two gas test cases and three
ld test cases, and I have not been able to compensate.

The appended patch is as far as I've gotten.  Note that some of the
changes to tc-arm.c and the testsuite are unrelated bugfixes which I
happened to notice while testing this patch - I let some incorrect
encodings slip past me into thumb32.d when I originally wrote it.  The
changes to arm-dis.c merely add label annotations to Thumb32
PC-relative ldr disassembly.

Any help would be appreciated.

zw

===================================================================
Index: gas/config/tc-arm.c
--- gas/config/tc-arm.c	(revision 85)
+++ gas/config/tc-arm.c	(working copy)
@@ -465,7 +465,7 @@ struct asm_opcode
 #define T_OPCODE_PUSH	0xb400
 #define T_OPCODE_POP	0xbc00
 
-#define T_OPCODE_BRANCH 0xe7fe
+#define T_OPCODE_BRANCH 0xe000
 
 #define THUMB_SIZE	2	/* Size of thumb instruction.  */
 #define THUMB_PP_PC_LR 0x0100
@@ -4051,8 +4051,6 @@ encode_arm_addr_mode_2 (int i, bfd_boole
     {
       if (inst.reloc.type == BFD_RELOC_UNUSED)
 	inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
-      if (inst.reloc.pc_rel)
-	inst.reloc.exp.X_add_number -= 8;  /* pipeline offset */
     }
 }
 
@@ -4083,8 +4081,6 @@ encode_arm_addr_mode_3 (int i, bfd_boole
       inst.instruction |= HWOFFSET_IMM;
       if (inst.reloc.type == BFD_RELOC_UNUSED)
 	inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
-      if (inst.reloc.pc_rel)
-	inst.reloc.exp.X_add_number -= 8;  /* pipeline offset */
     }
 }
 
@@ -4137,8 +4133,6 @@ encode_arm_cp_address (int i, int wb_ok,
     inst.reloc.type = reloc_override;
   else
     inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
-  if (inst.reloc.pc_rel)
-    inst.reloc.exp.X_add_number -= 8;
   return SUCCESS;
 }
 
@@ -4305,9 +4299,6 @@ do_adr (void)
   /* Frag hacking will turn this into a sub instruction if the offset turns
      out to be negative.  */
   inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
-#ifndef TE_WINCE
-  inst.reloc.exp.X_add_number -= 8; /* PC relative adjust.  */
-#endif
   inst.reloc.pc_rel = 1;
 }
 
@@ -4324,9 +4315,6 @@ do_adrl (void)
   /* Frag hacking will turn this into a sub instruction if the offset turns
      out to be negative.  */
   inst.reloc.type	       = BFD_RELOC_ARM_ADRL_IMMEDIATE;
-#ifndef TE_WINCE
-  inst.reloc.exp.X_add_number -= 8; /* PC relative adjust  */
-#endif
   inst.reloc.pc_rel	       = 1;
   inst.size		       = INSN_SIZE * 2;
 }
@@ -4408,13 +4396,10 @@ encode_branch (int default_reloc)
       constraint (inst.operands[0].imm != BFD_RELOC_ARM_PLT32,
 		  _("the only suffix valid here is '(plt)'"));
       inst.reloc.type	= BFD_RELOC_ARM_PLT32;
-      inst.reloc.pc_rel = 0;
     }
   else
-    {
-      inst.reloc.type = default_reloc;
-      inst.reloc.pc_rel = 1;
-    }
+    inst.reloc.type = default_reloc;
+  inst.reloc.pc_rel = 1;
 }
 
 static void
@@ -4448,7 +4433,7 @@ do_blx (void)
       /* Arg is an address; this instruction cannot be executed
 	 conditionally, and the opcode must be adjusted.  */
       constraint ((inst.instruction & COND_MASK) != COND_ALWAYS, BAD_COND);
-      inst.instruction = 0xfafffffe;
+      inst.instruction = 0xfa000000;
       encode_branch (BFD_RELOC_ARM_PCREL_BLX);
     }
 }
@@ -5639,6 +5624,7 @@ encode_thumb32_addr_mode (int i, bfd_boo
 	    inst.instruction |= 0x00000100;
 	}
       inst.reloc.type = BFD_RELOC_ARM_T32_OFFSET_IMM;
+      inst.reloc.pc_rel = is_pc;
     }
   else if (inst.operands[i].postind)
     {
@@ -5672,7 +5658,6 @@ encode_thumb32_addr_mode (int i, bfd_boo
   X(asrs,  1000, fa50f000),			\
   X(bic,   4380, ea200000),			\
   X(bics,  4380, ea300000),			\
-  X(blx,   4780, f000c000),			\
   X(cmn,   42c0, eb100f00),			\
   X(cmp,   2800, ebb00f00),			\
   X(cpsie, b660, f3af8400),			\
@@ -5869,7 +5854,6 @@ static void
 do_t_adr (void)
 {
   inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
-  inst.reloc.exp.X_add_number -= 4; /* PC relative adjust.  */
   inst.reloc.pc_rel = 1;
 
   inst.instruction |= inst.operands[0].reg << 4;
@@ -6096,7 +6080,7 @@ do_t_blx (void)
   else
     {
       /* No register.  This must be BLX(1).  */
-      inst.instruction = 0xf7ffeffe;
+      inst.instruction = 0xf700e800;
       inst.reloc.type	= BFD_RELOC_THUMB_PCREL_BLX;
       inst.reloc.pc_rel = 1;
     }
@@ -6109,7 +6093,7 @@ do_t_branch (void)
     {
       if (inst.instruction == T_OPCODE_BRANCH)
 	{
-	  inst.instruction = 0xf7ffbffe;
+	  inst.instruction = 0xf000b800;
 	  inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH25;
 	}
       else
@@ -6117,7 +6101,7 @@ do_t_branch (void)
 	  int cond = inst.instruction & 0x0f00;
 	  constraint (cond == 0xE00 || cond == 0xF00,
 		      _("invalid condition for wide conditional branch"));
-	  inst.instruction = (cond << 14) | 0xf43faffe;
+	  inst.instruction = (cond << 14) | 0xf0008000;
 	  inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH20;
 	}
     }
@@ -6454,8 +6438,6 @@ do_t_ldst (void)
 
       inst.instruction |= inst.operands[0].reg << 8;
       inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
-      if (inst.reloc.pc_rel)
-	inst.reloc.exp.X_add_number -= 4;  /* pipeline offset */
       return;
     }
 
@@ -7873,15 +7855,9 @@ static const struct asm_opcode insns[] =
  tCM(ldm,ia,	8900000, ldmia,    2, (RRw, REGLST), ldmstm, t_ldmstm),
  tCM(ldm,fd,	8900000, ldmia,    2, (RRw, REGLST), ldmstm, t_ldmstm),
 
- TCE(swi,	f000000, df00,     1, (EXPi),        swi, t_swi),
-#ifdef TE_WINCE
-  /* XXX This is the wrong place to do this.  Think multi-arch.	 */
- TCC(b,		a000000, e7fe, d,fe, 1, (EXPr),	    branch, t_branch),
- TCE(bl,	b000000, f7fffffe,   1, (EXPr),	    branch, t_branch23),
-#else
- TCC(b,		afffffe, e7fe, d,fe, 1, (EXPr),	    branch, t_branch),
- TCE(bl,	bfffffe, f7fffffe,   1, (EXPr),	    branch, t_branch23),
-#endif
+ TCE(swi,	f000000, df00,       1, (EXPi),        swi, t_swi),
+ TCC(b,		a000000, e000, d,00, 1, (EXPr),	    branch, t_branch),
+ TCE(bl,	b000000, f000f800,   1, (EXPr),	    branch, t_branch23),
 
   /* Pseudo ops.  */
  TCE(adr,	28f0000, 000f,	   2, (RR, EXP),    adr,  t_adr),
@@ -9652,33 +9628,31 @@ tc_arm_frame_initial_instructions (void)
 
 
 /* MD interface: Symbol and relocation handling.  */
-
-/* The knowledge of the PC's pipeline offset is built into the insns
-   themselves.	*/
-
 long
 md_pcrel_from (fixS * fixP)
 {
+  /* The pipeline offset is 4 for Thumb instructions, 8 for ARM.  */
   if (fixP->fx_addsy
       && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
       && fixP->fx_subsy == NULL)
-    return 0;
+    return fixP->tc_fix_data ? 4 : 8;
 
-  if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
+  if (!fixP->tc_fix_data)  /* ARM */
+    return fixP->fx_where + fixP->fx_frag->fr_address + 8;
+
+  /* PC relative load/store - not branches - on Thumb forces the
+     bottom two bits of the PC to zero.  */
+
+  switch (fixP->fx_r_type)
     {
-      /* PC relative addressing on the Thumb is slightly odd
-	 as the bottom two bits of the PC are forced to zero
-	 for the calculation.  */
-      return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
-    }
+    case BFD_RELOC_ARM_THUMB_ADD:
+    case BFD_RELOC_ARM_THUMB_OFFSET:
+    case BFD_RELOC_ARM_T32_OFFSET_IMM:
+      return ((fixP->fx_where + fixP->fx_frag->fr_address) & ~3) + 4;
 
-#ifdef TE_WINCE
-  /* The pattern was adjusted to accommodate CE's off-by-one fixups,
-     so we un-adjust here to compensate for the accommodation.	*/
-  return fixP->fx_where + fixP->fx_frag->fr_address + 8;
-#else
-  return fixP->fx_where + fixP->fx_frag->fr_address;
-#endif
+    default:
+      return fixP->fx_where + fixP->fx_frag->fr_address + 4;
+    }
 }
 
 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
@@ -9858,23 +9832,10 @@ md_apply_fix3 (fixS *	fixP,
      to an integer of different size.  We know the value is 0, 1, or 2.	 */
   int		 fix_is_thumb = (int) (size_t) fixP->tc_fix_data;
 
-  assert (fixP->fx_r_type <= BFD_RELOC_UNUSED);
-
   /* Note whether this will delete the relocation.  */
   if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
     fixP->fx_done = 1;
 
-  /* If this symbol is in a different section then we need to leave it for
-     the linker to deal with.  Unfortunately, md_pcrel_from can't tell,
-     so we have to undo it's effects here.  */
-  if (fixP->fx_pcrel)
-    {
-      if (fixP->fx_addsy != NULL
-	  && S_IS_DEFINED (fixP->fx_addsy)
-	  && S_GET_SEGMENT (fixP->fx_addsy) != seg)
-	value += md_pcrel_from (fixP);
-    }
-
   /* Remember value for emit_reloc.  */
   fixP->fx_addnumber = value;
 
@@ -10073,7 +10034,7 @@ md_apply_fix3 (fixS *	fixP,
 	    }
 	  newval &= ~0xff;
 	}
-      else if ((newval & 0x0000f000) == 0x0000f0000)
+      else if ((newval & 0x000f0000) == 0x000f0000)
 	{
 	  /* PC-relative, 12-bit offset.  */
 	  if (value >= 0)
@@ -10086,7 +10047,7 @@ md_apply_fix3 (fixS *	fixP,
 			    _("offset out of range"));
 	      break;
 	    }
-	  newval &= ~0xfff;
+	  newval &= ~0xfff;  /* clear secondary opcode */
 	}
       else if ((newval & 0x00000100) == 0x00000100)
 	{
@@ -10248,7 +10209,7 @@ md_apply_fix3 (fixS *	fixP,
 #define SEXT24(x)	((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
 
 #ifdef OBJ_ELF
-      value = fixP->fx_offset;
+      value = fixP->fx_offset - 8;
 #endif
 
       /* We are going to store value (shifted right by two) in the
@@ -10318,7 +10279,7 @@ md_apply_fix3 (fixS *	fixP,
 	newval = md_chars_to_number (buf, INSN_SIZE);
 
 #ifdef OBJ_ELF
-	value = fixP->fx_offset;
+	value = fixP->fx_offset - 8;
 #endif
 	hbit   = (value >> 1) & 1;
 	value  = (value >> 2) & 0x00ffffff;
@@ -10345,9 +10306,6 @@ md_apply_fix3 (fixS *	fixP,
     case BFD_RELOC_THUMB_PCREL_BRANCH7: /* CZB */
       newval = md_chars_to_number (buf, THUMB_SIZE);
       {
-	addressT diff = ((newval & 0x00f8) >> 2) | (newval & 0x0200) >> 3;
-	/* This one does not have the offset encoded in the pattern.  */
-	value = value + diff - 4;
 	/* CZB can only branch forward.  */
 	if (value & ~0x7e)
 	  as_bad_where (fixP->fx_file, fixP->fx_line,
@@ -10370,11 +10328,6 @@ md_apply_fix3 (fixS *	fixP,
     case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch.	*/
       newval = md_chars_to_number (buf, THUMB_SIZE);
       {
-	addressT diff = (newval & 0xff) << 1;
-	if (diff & 0x100)
-	  diff |= ~0xff;
-
-	value += diff;
 	if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
 	  as_bad_where (fixP->fx_file, fixP->fx_line,
 			_("branch out of range"));
@@ -10395,11 +10348,6 @@ md_apply_fix3 (fixS *	fixP,
     case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch.  */
       newval = md_chars_to_number (buf, THUMB_SIZE);
       {
-	addressT diff = (newval & 0x7ff) << 1;
-	if (diff & 0x800)
-	  diff |= ~0x7ff;
-
-	value += diff;
 	if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
 	  as_bad_where (fixP->fx_file, fixP->fx_line,
 			_("branch out of range"));
@@ -10420,21 +10368,10 @@ md_apply_fix3 (fixS *	fixP,
     case BFD_RELOC_THUMB_PCREL_BRANCH20:
       {
 	offsetT newval2;
-	addressT diff, S, J1, J2, lo, hi;
 
 	newval	= md_chars_to_number (buf, THUMB_SIZE);
 	newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
 
-	S  = !(newval & 0x0400);  /* flipped - 0=negative */
-	hi = (newval  & 0x003f);
-	J1 = (newval2 & 0x2000) >> 13;
-	J2 = (newval2 & 0x0800) >> 11;
-	lo = (newval2 & 0x07ff);
-
-	diff = ((S << 20) | (J2 << 19) | (J1 << 18) | (hi << 12) | (lo << 1));
-	diff -= (1 << 20);  /* sign extend */
-	value += diff;
-
 	if ((value & ~0x1fffff) && ((value & ~0x1fffff) != ~0x1fffff))
 	  as_bad_where (fixP->fx_file, fixP->fx_line,
 			_("conditional branch out of range"));
@@ -10450,6 +10387,7 @@ md_apply_fix3 (fixS *	fixP,
 	  }
 	else
 	  {
+	    addressT S, J1, J2, lo, hi;
 	    S  = (value & 0x00100000) >> 20;
 	    J2 = (value & 0x00080000) >> 19;
 	    J1 = (value & 0x00040000) >> 18;
@@ -10469,17 +10407,13 @@ md_apply_fix3 (fixS *	fixP,
     case BFD_RELOC_THUMB_PCREL_BRANCH23:
       {
 	offsetT newval2;
-	addressT diff;
 
 	newval	= md_chars_to_number (buf, THUMB_SIZE);
 	newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
-	diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
-	if (diff & 0x400000)
-	  diff |= ~0x3fffff;
+
 #ifdef OBJ_ELF
-	value = fixP->fx_offset;
+	value = fixP->fx_offset - 4;
 #endif
-	value += diff;
 
 	if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
 	  as_bad_where (fixP->fx_file, fixP->fx_line,
@@ -10528,25 +10462,10 @@ md_apply_fix3 (fixS *	fixP,
     case BFD_RELOC_THUMB_PCREL_BRANCH25:
       {
 	offsetT newval2;
-	addressT diff, S, I1, I2, lo, hi;
 
 	newval	= md_chars_to_number (buf, THUMB_SIZE);
 	newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
 
-	S  = (newval  & 0x0400) >> 10;
-	hi = (newval  & 0x03ff);
-	I1 = (newval2 & 0x2000) >> 13;
-	I2 = (newval2 & 0x0800) >> 11;
-	lo = (newval2 & 0x07ff);
-
-	I1 = !(I1 ^ S);
-	I2 = !(I2 ^ S);
-	S  = !S;
-
-	diff = ((S << 24) | (I1 << 23) | (I2 << 22) | (hi << 12) | (lo << 1));
-	diff -= (1 << 24);  /* sign extend */
-	value += diff;
-
 	if ((value & ~0x1ffffff) && ((value & ~0x1ffffff) != ~0x1ffffff))
 	  as_bad_where (fixP->fx_file, fixP->fx_line,
 			_("branch out of range"));
@@ -10562,6 +10481,7 @@ md_apply_fix3 (fixS *	fixP,
 	  }
 	else
 	  {
+	    addressT S, I1, I2, lo, hi;
 	    S  = (value & 0x01000000) >> 24;
 	    I1 = (value & 0x00800000) >> 23;
 	    I2 = (value & 0x00400000) >> 22;
===================================================================
Index: opcodes/arm-dis.c
--- opcodes/arm-dis.c	(revision 84)
+++ opcodes/arm-dis.c	(working copy)
@@ -1,4 +1,4 @@
-/* Instruction printing code for the ARM
+/* Instruction pritning code for the ARM
    Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
    Free Software Foundation, Inc.
    Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
@@ -2278,61 +2278,75 @@ print_insn_thumb32 (pc, info, given)
 		  unsigned int op  = (given & 0x00000f00) >> 8;
 		  unsigned int i12 = (given & 0x00000fff);
 		  unsigned int i8  = (given & 0x000000ff);
+		  bfd_boolean writeback = FALSE, postind = FALSE;
+		  int offset = 0;
 
 		  func (stream, "[%s", arm_regnames[Rn]);
 		  if (U) /* 12-bit positive immediate offset */
+		    offset = i12;
+		  else if (Rn == 15) /* 12-bit negative immediate offset */
+		    offset = -(int)i12;
+		  else if (op == 0x0) /* shifted register offset */
 		    {
-		      if (i12)
-			func (stream, ", #%u", i12);
+		      unsigned int Rm = (i8 & 0x0f);
+		      unsigned int sh = (i8 & 0x30) >> 4;
+		      func (stream, ", %s", arm_regnames[Rm]);
+		      if (sh)
+			func (stream, ", lsl #%u", sh);
 		      func (stream, "]");
+		      break;
 		    }
-		  else if (Rn == 15) /* 12-bit negative immediate offset */
-		    func (stream, ", #-%u]", i12);
 		  else switch (op)
 		    {
-		    case 0x0:  /* shifted register offset */
-		      {
-			unsigned int Rm = (i8 & 0x0f);
-			unsigned int sh = (i8 & 0x30) >> 4;
-			func (stream, ", %s", arm_regnames[Rm]);
-			if (sh)
-			  func (stream, ", lsl #%u", sh);
-			func (stream, "]");
-		      }
-		      break;
-
 		    case 0xE:  /* 8-bit positive immediate offset */
-		      if (i8)
-			func (stream, ", #%u", i8);
-		      func (stream, "]");
+		      offset = i8;
 		      break;
 
 		    case 0xC:  /* 8-bit negative immediate offset */
-		      func (stream, ", #-%u]", i8);
+		      offset = -i8;
 		      break;
 
 		    case 0xB:  /* 8-bit + preindex with wb */
-		      if (i8)
-			func (stream, ", #%u", i8);
-		      func (stream, "]!");
+		      offset = i8;
+		      writeback = TRUE;
 		      break;
 
 		    case 0x9:  /* 8-bit - preindex with wb */
-		      func (stream, ", #-%u]!", i8);
+		      offset = -i8;
+		      writeback = TRUE;
 		      break;
 
 		    case 0xF:  /* 8-bit + postindex */
-		      func (stream, "], #%u", i8);
+		      offset = i8;
+		      postind = TRUE;
 		      break;
 
 		    case 0xD:  /* 8-bit - postindex */
-		      func (stream, "], #-%u", i8);
+		      offset = -i8;
+		      postind = TRUE;
 		      break;
 
 		    default:
 		      func (stream, ", <undefined>]");
+		      goto skip;
+		    }
+
+		  if (postind)
+		    func (stream, "], #%d", offset);
+		  else
+		    {
+		      if (offset)
+			func (stream, ", #%d", offset);
+		      func (stream, writeback ? "]!" : "]");
+		    }
+
+		  if (Rn == 15)
+		    {
+		      func (stream, "\t; ");
+		      info->print_address_func (((pc + 4) & ~3) + offset, info);
 		    }
 		}
+	      skip:
 		break;
 
 	      case 'A':
@@ -2425,7 +2439,7 @@ print_insn_thumb32 (pc, info, given)
 		  unsigned int S = (given & 0x04000000u) >> 26;
 		  unsigned int J1 = (given & 0x00002000u) >> 13;
 		  unsigned int J2 = (given & 0x00000800u) >> 11;
-		  unsigned int offset = 0;
+		  int offset = 0;
 
 		  offset |= !S << 20;
 		  offset |= J2 << 19;
@@ -2434,7 +2448,7 @@ print_insn_thumb32 (pc, info, given)
 		  offset |= (given & 0x000007ff) << 1;
 		  offset -= (1 << 20);
 
-		  info->print_address_func ((bfd_vma)offset + pc + 4, info);
+		  info->print_address_func (pc + 4 + offset, info);
 		}
 		break;
 
@@ -2443,7 +2457,7 @@ print_insn_thumb32 (pc, info, given)
 		  unsigned int S = (given & 0x04000000u) >> 26;
 		  unsigned int I1 = (given & 0x00002000u) >> 13;
 		  unsigned int I2 = (given & 0x00000800u) >> 11;
-		  unsigned int offset = 0;
+		  int offset = 0;
 
 		  offset |= !S << 24;
 		  offset |= !(I1 ^ S) << 23;
@@ -2452,7 +2466,7 @@ print_insn_thumb32 (pc, info, given)
 		  offset |= (given & 0x000007ffu) << 1;
 		  offset -= (1 << 24);
 
-		  info->print_address_func ((bfd_vma)offset + pc + 4, info);
+		  info->print_address_func (pc + 4 + offset, info);
 		}
 		break;
 
===================================================================
Index: gas/testsuite/gas/arm/pic.d
--- gas/testsuite/gas/arm/pic.d	(revision 84)
+++ gas/testsuite/gas/arm/pic.d	(working copy)
@@ -6,9 +6,9 @@
 .*: +file format .*arm.*
 
 Disassembly of section .text:
-00+0 <[^>]*> eb...... 	bl	00+. <[^>]*>
-			0: R_ARM_PC24	foo.*
-00+4 <[^>]*> ebfffffe 	bl	0[0123456789abcdef]+ <[^>]*>
+0+0 <[^>]*> ebfffffe 	bl	0+0 <[^>]*>
+			0: R_ARM_PC24	foo
+0+4 <[^>]*> eb000000 	bl	0+8 <[^>]*>
 			4: R_ARM_PLT32	foo
 	\.\.\.
 			8: R_ARM_ABS32	sym
===================================================================
Index: gas/testsuite/gas/arm/thumb32.d
--- gas/testsuite/gas/arm/thumb32.d	(revision 84)
+++ gas/testsuite/gas/arm/thumb32.d	(working copy)
@@ -209,100 +209,100 @@ Disassembly of section .text:
 0+2ce <[^>]+> f3c0 5040 	ubfx	r0, r0, #21, #1
 0+2d2 <[^>]+> f340 0011 	sbfx	r0, r0, #0, #18
 0+2d6 <[^>]+> d0fe      	beq\.n	0+2d6 <[^>]+>
-0+2d8 <[^>]+> d029      	beq\.n	0+32e <[^>]+>
+0+2d8 <[^>]+> d02a      	beq\.n	0+330 <[^>]+>
 0+2da <[^>]+> d1fc      	bne\.n	0+2d6 <[^>]+>
-0+2dc <[^>]+> d127      	bne\.n	0+32e <[^>]+>
+0+2dc <[^>]+> d128      	bne\.n	0+330 <[^>]+>
 0+2de <[^>]+> d2fa      	bcs\.n	0+2d6 <[^>]+>
-0+2e0 <[^>]+> d225      	bcs\.n	0+32e <[^>]+>
+0+2e0 <[^>]+> d226      	bcs\.n	0+330 <[^>]+>
 0+2e2 <[^>]+> d2f8      	bcs\.n	0+2d6 <[^>]+>
-0+2e4 <[^>]+> d223      	bcs\.n	0+32e <[^>]+>
+0+2e4 <[^>]+> d224      	bcs\.n	0+330 <[^>]+>
 0+2e6 <[^>]+> d3f6      	bcc\.n	0+2d6 <[^>]+>
-0+2e8 <[^>]+> d321      	bcc\.n	0+32e <[^>]+>
+0+2e8 <[^>]+> d322      	bcc\.n	0+330 <[^>]+>
 0+2ea <[^>]+> d3f4      	bcc\.n	0+2d6 <[^>]+>
-0+2ec <[^>]+> d31f      	bcc\.n	0+32e <[^>]+>
+0+2ec <[^>]+> d320      	bcc\.n	0+330 <[^>]+>
 0+2ee <[^>]+> d3f2      	bcc\.n	0+2d6 <[^>]+>
-0+2f0 <[^>]+> d31d      	bcc\.n	0+32e <[^>]+>
+0+2f0 <[^>]+> d31e      	bcc\.n	0+330 <[^>]+>
 0+2f2 <[^>]+> d4f0      	bmi\.n	0+2d6 <[^>]+>
-0+2f4 <[^>]+> d41b      	bmi\.n	0+32e <[^>]+>
+0+2f4 <[^>]+> d41c      	bmi\.n	0+330 <[^>]+>
 0+2f6 <[^>]+> d5ee      	bpl\.n	0+2d6 <[^>]+>
-0+2f8 <[^>]+> d519      	bpl\.n	0+32e <[^>]+>
+0+2f8 <[^>]+> d51a      	bpl\.n	0+330 <[^>]+>
 0+2fa <[^>]+> d6ec      	bvs\.n	0+2d6 <[^>]+>
-0+2fc <[^>]+> d617      	bvs\.n	0+32e <[^>]+>
+0+2fc <[^>]+> d618      	bvs\.n	0+330 <[^>]+>
 0+2fe <[^>]+> d7ea      	bvc\.n	0+2d6 <[^>]+>
-0+300 <[^>]+> d715      	bvc\.n	0+32e <[^>]+>
+0+300 <[^>]+> d716      	bvc\.n	0+330 <[^>]+>
 0+302 <[^>]+> d8e8      	bhi\.n	0+2d6 <[^>]+>
-0+304 <[^>]+> d813      	bhi\.n	0+32e <[^>]+>
+0+304 <[^>]+> d814      	bhi\.n	0+330 <[^>]+>
 0+306 <[^>]+> d9e6      	bls\.n	0+2d6 <[^>]+>
-0+308 <[^>]+> d911      	bls\.n	0+32e <[^>]+>
+0+308 <[^>]+> d912      	bls\.n	0+330 <[^>]+>
 0+30a <[^>]+> d7e4      	bvc\.n	0+2d6 <[^>]+>
-0+30c <[^>]+> d70f      	bvc\.n	0+32e <[^>]+>
+0+30c <[^>]+> d710      	bvc\.n	0+330 <[^>]+>
 0+30e <[^>]+> d8e2      	bhi\.n	0+2d6 <[^>]+>
-0+310 <[^>]+> d80d      	bhi\.n	0+32e <[^>]+>
+0+310 <[^>]+> d80e      	bhi\.n	0+330 <[^>]+>
 0+312 <[^>]+> d9e0      	bls\.n	0+2d6 <[^>]+>
-0+314 <[^>]+> d90b      	bls\.n	0+32e <[^>]+>
+0+314 <[^>]+> d90c      	bls\.n	0+330 <[^>]+>
 0+316 <[^>]+> dade      	bge\.n	0+2d6 <[^>]+>
-0+318 <[^>]+> da09      	bge\.n	0+32e <[^>]+>
+0+318 <[^>]+> da0a      	bge\.n	0+330 <[^>]+>
 0+31a <[^>]+> dbdc      	blt\.n	0+2d6 <[^>]+>
-0+31c <[^>]+> db07      	blt\.n	0+32e <[^>]+>
+0+31c <[^>]+> db08      	blt\.n	0+330 <[^>]+>
 0+31e <[^>]+> dcda      	bgt\.n	0+2d6 <[^>]+>
-0+320 <[^>]+> dc05      	bgt\.n	0+32e <[^>]+>
+0+320 <[^>]+> dc06      	bgt\.n	0+330 <[^>]+>
 0+322 <[^>]+> ddd8      	ble\.n	0+2d6 <[^>]+>
-0+324 <[^>]+> dd03      	ble\.n	0+32e <[^>]+>
+0+324 <[^>]+> dd04      	ble\.n	0+330 <[^>]+>
 0+326 <[^>]+> ded6      	bal\.n	0+2d6 <[^>]+>
-0+328 <[^>]+> de01      	bal\.n	0+32e <[^>]+>
+0+328 <[^>]+> de02      	bal\.n	0+330 <[^>]+>
 0+32a <[^>]+> e7d4      	b\.n	0+2d6 <[^>]+>
-0+32c <[^>]+> e7ff      	b\.n	0+32e <[^>]+>
-0+32e <[^>]+> f43f affe 	beq\.w	0+32e <[^>]+>
-0+332 <[^>]+> f000 8058 	beq\.w	0+3e6 <[^>]+>
-0+336 <[^>]+> f47f affa 	bne\.w	0+32e <[^>]+>
-0+33a <[^>]+> f040 8054 	bne\.w	0+3e6 <[^>]+>
-0+33e <[^>]+> f4bf aff6 	bcs\.w	0+32e <[^>]+>
-0+342 <[^>]+> f080 8050 	bcs\.w	0+3e6 <[^>]+>
-0+346 <[^>]+> f4bf aff2 	bcs\.w	0+32e <[^>]+>
-0+34a <[^>]+> f080 804c 	bcs\.w	0+3e6 <[^>]+>
-0+34e <[^>]+> f4ff afee 	bcc\.w	0+32e <[^>]+>
-0+352 <[^>]+> f0c0 8048 	bcc\.w	0+3e6 <[^>]+>
-0+356 <[^>]+> f4ff afea 	bcc\.w	0+32e <[^>]+>
-0+35a <[^>]+> f0c0 8044 	bcc\.w	0+3e6 <[^>]+>
-0+35e <[^>]+> f4ff afe6 	bcc\.w	0+32e <[^>]+>
-0+362 <[^>]+> f0c0 8040 	bcc\.w	0+3e6 <[^>]+>
-0+366 <[^>]+> f53f afe2 	bmi\.w	0+32e <[^>]+>
-0+36a <[^>]+> f100 803c 	bmi\.w	0+3e6 <[^>]+>
-0+36e <[^>]+> f57f afde 	bpl\.w	0+32e <[^>]+>
-0+372 <[^>]+> f140 8038 	bpl\.w	0+3e6 <[^>]+>
-0+376 <[^>]+> f5bf afda 	bvs\.w	0+32e <[^>]+>
-0+37a <[^>]+> f180 8034 	bvs\.w	0+3e6 <[^>]+>
-0+37e <[^>]+> f5ff afd6 	bvc\.w	0+32e <[^>]+>
-0+382 <[^>]+> f1c0 8030 	bvc\.w	0+3e6 <[^>]+>
-0+386 <[^>]+> f63f afd2 	bhi\.w	0+32e <[^>]+>
-0+38a <[^>]+> f200 802c 	bhi\.w	0+3e6 <[^>]+>
-0+38e <[^>]+> f67f afce 	bls\.w	0+32e <[^>]+>
-0+392 <[^>]+> f240 8028 	bls\.w	0+3e6 <[^>]+>
-0+396 <[^>]+> f5ff afca 	bvc\.w	0+32e <[^>]+>
-0+39a <[^>]+> f1c0 8024 	bvc\.w	0+3e6 <[^>]+>
-0+39e <[^>]+> f63f afc6 	bhi\.w	0+32e <[^>]+>
-0+3a2 <[^>]+> f200 8020 	bhi\.w	0+3e6 <[^>]+>
-0+3a6 <[^>]+> f67f afc2 	bls\.w	0+32e <[^>]+>
-0+3aa <[^>]+> f240 801c 	bls\.w	0+3e6 <[^>]+>
-0+3ae <[^>]+> f6bf afbe 	bge\.w	0+32e <[^>]+>
-0+3b2 <[^>]+> f280 8018 	bge\.w	0+3e6 <[^>]+>
-0+3b6 <[^>]+> f6ff afba 	blt\.w	0+32e <[^>]+>
-0+3ba <[^>]+> f2c0 8014 	blt\.w	0+3e6 <[^>]+>
-0+3be <[^>]+> f73f afb6 	bgt\.w	0+32e <[^>]+>
-0+3c2 <[^>]+> f300 8010 	bgt\.w	0+3e6 <[^>]+>
-0+3c6 <[^>]+> f77f afb2 	ble\.w	0+32e <[^>]+>
-0+3ca <[^>]+> f340 800c 	ble\.w	0+3e6 <[^>]+>
-0+3ce <[^>]+> f7ff bfae 	b\.w	0+32e <[^>]+>
-0+3d2 <[^>]+> f000 b808 	b\.w	0+3e6 <[^>]+>
-0+3d6 <[^>]+> f000 f995 	bl	0+32e <[^>]+>
-			3d6: R_ARM_THM_CALL	\.text
-0+3da <[^>]+> f000 f9f1 	bl	0+3e6 <[^>]+>
-			3da: R_ARM_THM_CALL	\.text
-0+3de <[^>]+> f000 e995 	blx	0+32e <[^>]+>
-			3de: R_ARM_THM_XPC22	\.text
-0+3e2 <[^>]+> f000 e9f1 	blx	0+3e6 <[^>]+>
-			3e2: R_ARM_THM_XPC22	\.text
-0+3e6 <[^>]+> 4700      	bx	r0
+0+32c <[^>]+> e000      	b\.n	0+330 <[^>]+>
+0+32e <[^>]+> 46c0      	nop			\(mov r8, r8\)
+0+330 <[^>]+> f43f affe 	beq\.w	0+330 <[^>]+>
+0+334 <[^>]+> f000 8058 	beq\.w	0+3e8 <[^>]+>
+0+338 <[^>]+> f47f affa 	bne\.w	0+330 <[^>]+>
+0+33c <[^>]+> f040 8054 	bne\.w	0+3e8 <[^>]+>
+0+340 <[^>]+> f4bf aff6 	bcs\.w	0+330 <[^>]+>
+0+344 <[^>]+> f080 8050 	bcs\.w	0+3e8 <[^>]+>
+0+348 <[^>]+> f4bf aff2 	bcs\.w	0+330 <[^>]+>
+0+34c <[^>]+> f080 804c 	bcs\.w	0+3e8 <[^>]+>
+0+350 <[^>]+> f4ff afee 	bcc\.w	0+330 <[^>]+>
+0+354 <[^>]+> f0c0 8048 	bcc\.w	0+3e8 <[^>]+>
+0+358 <[^>]+> f4ff afea 	bcc\.w	0+330 <[^>]+>
+0+35c <[^>]+> f0c0 8044 	bcc\.w	0+3e8 <[^>]+>
+0+360 <[^>]+> f4ff afe6 	bcc\.w	0+330 <[^>]+>
+0+364 <[^>]+> f0c0 8040 	bcc\.w	0+3e8 <[^>]+>
+0+368 <[^>]+> f53f afe2 	bmi\.w	0+330 <[^>]+>
+0+36c <[^>]+> f100 803c 	bmi\.w	0+3e8 <[^>]+>
+0+370 <[^>]+> f57f afde 	bpl\.w	0+330 <[^>]+>
+0+374 <[^>]+> f140 8038 	bpl\.w	0+3e8 <[^>]+>
+0+378 <[^>]+> f5bf afda 	bvs\.w	0+330 <[^>]+>
+0+37c <[^>]+> f180 8034 	bvs\.w	0+3e8 <[^>]+>
+0+380 <[^>]+> f5ff afd6 	bvc\.w	0+330 <[^>]+>
+0+384 <[^>]+> f1c0 8030 	bvc\.w	0+3e8 <[^>]+>
+0+388 <[^>]+> f63f afd2 	bhi\.w	0+330 <[^>]+>
+0+38c <[^>]+> f200 802c 	bhi\.w	0+3e8 <[^>]+>
+0+390 <[^>]+> f67f afce 	bls\.w	0+330 <[^>]+>
+0+394 <[^>]+> f240 8028 	bls\.w	0+3e8 <[^>]+>
+0+398 <[^>]+> f5ff afca 	bvc\.w	0+330 <[^>]+>
+0+39c <[^>]+> f1c0 8024 	bvc\.w	0+3e8 <[^>]+>
+0+3a0 <[^>]+> f63f afc6 	bhi\.w	0+330 <[^>]+>
+0+3a4 <[^>]+> f200 8020 	bhi\.w	0+3e8 <[^>]+>
+0+3a8 <[^>]+> f67f afc2 	bls\.w	0+330 <[^>]+>
+0+3ac <[^>]+> f240 801c 	bls\.w	0+3e8 <[^>]+>
+0+3b0 <[^>]+> f6bf afbe 	bge\.w	0+330 <[^>]+>
+0+3b4 <[^>]+> f280 8018 	bge\.w	0+3e8 <[^>]+>
+0+3b8 <[^>]+> f6ff afba 	blt\.w	0+330 <[^>]+>
+0+3bc <[^>]+> f2c0 8014 	blt\.w	0+3e8 <[^>]+>
+0+3c0 <[^>]+> f73f afb6 	bgt\.w	0+330 <[^>]+>
+0+3c4 <[^>]+> f300 8010 	bgt\.w	0+3e8 <[^>]+>
+0+3c8 <[^>]+> f77f afb2 	ble\.w	0+330 <[^>]+>
+0+3cc <[^>]+> f340 800c 	ble\.w	0+3e8 <[^>]+>
+0+3d0 <[^>]+> f7ff bfae 	b\.w	0+330 <[^>]+>
+0+3d4 <[^>]+> f000 b808 	b\.w	0+3e8 <[^>]+>
+0+3d8 <[^>]+> f000 f996 	bl	0+330 <[^>]+>
+			3d8: R_ARM_THM_CALL	\.text
+0+3dc <[^>]+> f000 f9f2 	bl	0+3e8 <[^>]+>
+			3dc: R_ARM_THM_CALL	\.text
+0+3e0 <[^>]+> f000 e996 	blx	0+330 <[^>]+>
+			3e0: R_ARM_THM_XPC22	\.text
+0+3e4 <[^>]+> f000 e9f2 	blx	0+3e8 <[^>]+>
+			3e4: R_ARM_THM_XPC22	\.text
 0+3e8 <[^>]+> 4748      	bx	r9
 0+3ea <[^>]+> 4780      	blx	r0
 0+3ec <[^>]+> 47c8      	blx	r9
@@ -508,8 +508,8 @@ Disassembly of section .text:
 0+5b2 <[^>]+> f815 1d30 	ldrb\.w	r1, \[r5\], #-48
 0+5b6 <[^>]+> 5d29      	ldrb	r1, \[r5, r4\]
 0+5b8 <[^>]+> f819 100c 	ldrb\.w	r1, \[r9, ip\]
-0+5bc <[^>]+> f89f 10b0 	ldrb\.w	r1, \[pc, #176\]
-0+5c0 <[^>]+> f81f 1c26 	ldrb\.w	r1, \[pc, #-3110\]
+0+5bc <[^>]+> f89f 10ac 	ldrb\.w	r1, \[pc, #172\]	; 0+66c <[^>]+>
+0+5c0 <[^>]+> f81f 102a 	ldrb\.w	r1, \[pc, #-42\]	; 0+59a <[^>]+>
 0+5c4 <[^>]+> f995 1000 	ldrsb\.w	r1, \[r5\]
 0+5c8 <[^>]+> f995 1330 	ldrsb\.w	r1, \[r5, #816\]
 0+5cc <[^>]+> f915 1c30 	ldrsb\.w	r1, \[r5, #-48\]
@@ -519,8 +519,8 @@ Disassembly of section .text:
 0+5dc <[^>]+> f915 1d30 	ldrsb\.w	r1, \[r5\], #-48
 0+5e0 <[^>]+> 5729      	ldrsb	r1, \[r5, r4\]
 0+5e2 <[^>]+> f919 100c 	ldrsb\.w	r1, \[r9, ip\]
-0+5e6 <[^>]+> f99f 1086 	ldrsb\.w	r1, \[pc, #134\]
-0+5ea <[^>]+> f91f 1c50 	ldrsb\.w	r1, \[pc, #-3152\]
+0+5e6 <[^>]+> f99f 1084 	ldrsb\.w	r1, \[pc, #132\]	; 0+66c <[^>]+>
+0+5ea <[^>]+> f91f 1052 	ldrsb\.w	r1, \[pc, #-82\]	; 0+59a <[^>]+>
 0+5ee <[^>]+> f8b5 1000 	ldrh\.w	r1, \[r5\]
 0+5f2 <[^>]+> f8b5 1330 	ldrh\.w	r1, \[r5, #816\]
 0+5f6 <[^>]+> f835 1c30 	ldrh\.w	r1, \[r5, #-48\]
@@ -530,8 +530,8 @@ Disassembly of section .text:
 0+606 <[^>]+> f835 1d30 	ldrh\.w	r1, \[r5\], #-48
 0+60a <[^>]+> 5b29      	ldrh	r1, \[r5, r4\]
 0+60c <[^>]+> f839 100c 	ldrh\.w	r1, \[r9, ip\]
-0+610 <[^>]+> f8bf 105c 	ldrh\.w	r1, \[pc, #92\]
-0+614 <[^>]+> f83f 1c7a 	ldrh\.w	r1, \[pc, #-3194\]
+0+610 <[^>]+> f8bf 1058 	ldrh\.w	r1, \[pc, #88\]	; 0+66c <[^>]+>
+0+614 <[^>]+> f83f 107e 	ldrh\.w	r1, \[pc, #-126\]	; 0+59a <[^>]+>
 0+618 <[^>]+> f9b5 1000 	ldrsh\.w	r1, \[r5\]
 0+61c <[^>]+> f9b5 1330 	ldrsh\.w	r1, \[r5, #816\]
 0+620 <[^>]+> f935 1c30 	ldrsh\.w	r1, \[r5, #-48\]
@@ -541,8 +541,8 @@ Disassembly of section .text:
 0+630 <[^>]+> f935 1d30 	ldrsh\.w	r1, \[r5\], #-48
 0+634 <[^>]+> 5f29      	ldrsh	r1, \[r5, r4\]
 0+636 <[^>]+> f939 100c 	ldrsh\.w	r1, \[r9, ip\]
-0+63a <[^>]+> f9bf 1032 	ldrsh\.w	r1, \[pc, #50\]
-0+63e <[^>]+> f93f 1ca4 	ldrsh\.w	r1, \[pc, #-3236\]
+0+63a <[^>]+> f9bf 1030 	ldrsh\.w	r1, \[pc, #48\]	; 0+66c <[^>]+>
+0+63e <[^>]+> f93f 10a6 	ldrsh\.w	r1, \[pc, #-166\]	; 0+59a <[^>]+>
 0+642 <[^>]+> f8d5 1000 	ldr\.w	r1, \[r5\]
 0+646 <[^>]+> f8d5 1330 	ldr\.w	r1, \[r5, #816\]
 0+64a <[^>]+> f855 1c30 	ldr\.w	r1, \[r5, #-48\]
@@ -552,8 +552,8 @@ Disassembly of section .text:
 0+65a <[^>]+> f855 1d30 	ldr\.w	r1, \[r5\], #-48
 0+65e <[^>]+> 5929      	ldr	r1, \[r5, r4\]
 0+660 <[^>]+> f859 100c 	ldr\.w	r1, \[r9, ip\]
-0+664 <[^>]+> f8df 1008 	ldr\.w	r1, \[pc, #8\]
-0+668 <[^>]+> f85f 1cce 	ldr\.w	r1, \[pc, #-3278\]
+0+664 <[^>]+> f8df 1004 	ldr\.w	r1, \[pc, #4\]	; 0+66c <[^>]+>
+0+668 <[^>]+> f85f 10d2 	ldr\.w	r1, \[pc, #-210\]	; 0+59a <[^>]+>
 0+66c <[^>]+> f885 1000 	strb\.w	r1, \[r5\]
 0+670 <[^>]+> f885 1330 	strb\.w	r1, \[r5, #816\]
 0+674 <[^>]+> f805 1c30 	strb\.w	r1, \[r5, #-48\]
@@ -563,8 +563,8 @@ Disassembly of section .text:
 0+684 <[^>]+> f805 1d30 	strb\.w	r1, \[r5\], #-48
 0+688 <[^>]+> 5529      	strb	r1, \[r5, r4\]
 0+68a <[^>]+> f809 100c 	strb\.w	r1, \[r9, ip\]
-0+68e <[^>]+> f88f 1088 	strb\.w	r1, \[pc, #136\]
-0+692 <[^>]+> f80f 1c26 	strb\.w	r1, \[pc, #-3110\]
+0+68e <[^>]+> f88f 1086 	strb\.w	r1, \[pc, #134\]	; 0+716 <[^>]+>
+0+692 <[^>]+> f80f 1028 	strb\.w	r1, \[pc, #-40\]	; 0+66c <[^>]+>
 0+696 <[^>]+> f8a5 1000 	strh\.w	r1, \[r5\]
 0+69a <[^>]+> f8a5 1330 	strh\.w	r1, \[r5, #816\]
 0+69e <[^>]+> f825 1c30 	strh\.w	r1, \[r5, #-48\]
@@ -574,8 +574,8 @@ Disassembly of section .text:
 0+6ae <[^>]+> f825 1d30 	strh\.w	r1, \[r5\], #-48
 0+6b2 <[^>]+> 5329      	strh	r1, \[r5, r4\]
 0+6b4 <[^>]+> f829 100c 	strh\.w	r1, \[r9, ip\]
-0+6b8 <[^>]+> f8af 105e 	strh\.w	r1, \[pc, #94\]
-0+6bc <[^>]+> f82f 1c50 	strh\.w	r1, \[pc, #-3152\]
+0+6b8 <[^>]+> f8af 105a 	strh\.w	r1, \[pc, #90\]	; 0+716 <[^>]+>
+0+6bc <[^>]+> f82f 1054 	strh\.w	r1, \[pc, #-84\]	; 0+66c <[^>]+>
 0+6c0 <[^>]+> f8c5 1000 	str\.w	r1, \[r5\]
 0+6c4 <[^>]+> f8c5 1330 	str\.w	r1, \[r5, #816\]
 0+6c8 <[^>]+> f845 1c30 	str\.w	r1, \[r5, #-48\]
@@ -585,8 +585,8 @@ Disassembly of section .text:
 0+6d8 <[^>]+> f845 1d30 	str\.w	r1, \[r5\], #-48
 0+6dc <[^>]+> 5129      	str	r1, \[r5, r4\]
 0+6de <[^>]+> f849 100c 	str\.w	r1, \[r9, ip\]
-0+6e2 <[^>]+> f8cf 1034 	str\.w	r1, \[pc, #52\]
-0+6e6 <[^>]+> f84f 1c7a 	str\.w	r1, \[pc, #-3194\]
+0+6e2 <[^>]+> f8cf 1032 	str\.w	r1, \[pc, #50\]	; 0+716 <[^>]+>
+0+6e6 <[^>]+> f84f 107c 	str\.w	r1, \[pc, #-124\]	; 0+66c <[^>]+>
 0+6ea <[^>]+> f895 f000 	pld	\[r5\]
 0+6ee <[^>]+> f895 f330 	pld	\[r5, #816\]
 0+6f2 <[^>]+> f815 fc30 	pld	\[r5, #-48\]
@@ -596,8 +596,8 @@ Disassembly of section .text:
 0+702 <[^>]+> f815 fd30 	pld	\[r5\], #-48
 0+706 <[^>]+> f815 f000 	pld	\[r5, r0\]
 0+70a <[^>]+> f819 f000 	pld	\[r9, r0\]
-0+70e <[^>]+> f89f f008 	pld	\[pc, #8\]
-0+712 <[^>]+> f81f fca6 	pld	\[pc, #-3238\]
+0+70e <[^>]+> f89f f006 	pld	\[pc, #6\]	; 0+716 <[^>]+>
+0+712 <[^>]+> f81f f0a8 	pld	\[pc, #-168\]	; 0+66c <[^>]+>
 0+716 <[^>]+> e9d5 2300 	ldrd	r2, r3, \[r5\]
 0+71a <[^>]+> e9d5 230c 	ldrd	r2, r3, \[r5, #48\]
 0+71e <[^>]+> e955 230c 	ldrd	r2, r3, \[r5, #-48\]
===================================================================
Index: gas/testsuite/gas/arm/thumb32.s
--- gas/testsuite/gas/arm/thumb32.s	(revision 84)
+++ gas/testsuite/gas/arm/thumb32.s	(working copy)
@@ -194,6 +194,7 @@ branches:
 	bra	bal.n
 	bra	b.n
 	@ bl, blx have no short form.
+	.balign 4
 1:
 	bra	beq
 	bra	bne
@@ -218,9 +219,8 @@ branches:
 	bra	b
 	bra	bl
 	bra	blx
+	.balign 4
 1:
-
-	bx	r0
 	bx	r9
 	blx	r0
 	blx	r9

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Thumb32 assembler (42/69)
  2005-04-26 15:20 ` Paul Brook
  2005-04-29 11:57   ` Zack Weinberg
@ 2005-04-30  0:57   ` Zack Weinberg
  2005-04-30  2:33     ` Zack Weinberg
  1 sibling, 1 reply; 5+ messages in thread
From: Zack Weinberg @ 2005-04-30  0:57 UTC (permalink / raw)
  To: Paul Brook; +Cc: binutils


Here is a less ambitious fix for this bug, which gives responsibility
for the pipeline offset to md_pcrel_from only for the relocations
relevant to this bug.  This works and doesn't break anything else -
tested with both arm-aout and arm-elf cross binutils.

zw

	* gas/config/tc-arm.c (encode_thumb32_addr_mode): Set inst.reloc.pc_rel
	if is_pc.
	(T16_32_TAB): Delete unused entry for BLX.
	(do_t_ldst): Don't offset inst.reloc.exp.X_add_number for PC-relative
	addressing.
	(md_pcrel_from): Report the adjusted PC for
	BFD_RELOC_ARM_THUMB_OFFSET and BFD_RELOC_ARM_T32_OFFSET_IMM.
	(md_apply_fix3): Correct bitmasks for BFD_RELOC_ARM_T32_OFFSET_IMM.
	Do not round up value for PC-relative BFD_RELOC_ARM_THUMB_OFFSET.

	* gas/testsuite/gas/arm/thumb.s: Test PC-relative ldr more thoroughly.
	* gas/testsuite/gas/arm/thumb.d: Update to match.

	* gas/testsuite/gas/arm/thumb32.s: Properly align labels that
	will be targeted by blx instructions.
	* gas/testsuite/gas/arm/thumb32.d: Update to match.  Correct
	expected dissassembly of PC-relative ldr.

	* gas/testsuite/gas/arm/macro1.s: Add leading label and
	trailing padding for a.out compatibility.
	* gas/testsuite/gas/arm/macro1.d: Update to match.
	* gas/testsuite/gas/arm/tcompat2.s: Add trailing padding for a.out
	compatibility.
	* gas/testsuite/gas/arm/tcompat2.d: Update to match.

===================================================================
Index: config/tc-arm.c
--- config/tc-arm.c	(revision 85)
+++ config/tc-arm.c	(working copy)
@@ -5639,6 +5639,7 @@ encode_thumb32_addr_mode (int i, bfd_boo
 	    inst.instruction |= 0x00000100;
 	}
       inst.reloc.type = BFD_RELOC_ARM_T32_OFFSET_IMM;
+      inst.reloc.pc_rel = is_pc;
     }
   else if (inst.operands[i].postind)
     {
@@ -5672,7 +5673,6 @@ encode_thumb32_addr_mode (int i, bfd_boo
   X(asrs,  1000, fa50f000),			\
   X(bic,   4380, ea200000),			\
   X(bics,  4380, ea300000),			\
-  X(blx,   4780, f000c000),			\
   X(cmn,   42c0, eb100f00),			\
   X(cmp,   2800, ebb00f00),			\
   X(cpsie, b660, f3af8400),			\
@@ -6454,8 +6454,6 @@ do_t_ldst (void)
 
       inst.instruction |= inst.operands[0].reg << 8;
       inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
-      if (inst.reloc.pc_rel)
-	inst.reloc.exp.X_add_number -= 4;  /* pipeline offset */
       return;
     }
 
@@ -9664,12 +9662,21 @@ md_pcrel_from (fixS * fixP)
       && fixP->fx_subsy == NULL)
     return 0;
 
-  if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
+  /* PC relative addressing on the Thumb is slightly odd as the bottom
+     two bits of the PC are forced to zero for the calculation.  This
+     happens *after* application of the pipeline offset.  However,
+     Thumb adrl already adjusts for this, so we need not do it again.  */
+  switch (fixP->fx_r_type)
     {
-      /* PC relative addressing on the Thumb is slightly odd
-	 as the bottom two bits of the PC are forced to zero
-	 for the calculation.  */
+    case BFD_RELOC_ARM_THUMB_ADD:
       return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
+
+    case BFD_RELOC_ARM_THUMB_OFFSET:
+    case BFD_RELOC_ARM_T32_OFFSET_IMM:
+      return (fixP->fx_where + fixP->fx_frag->fr_address + 4) & ~3;
+
+    default:
+      break;
     }
 
 #ifdef TE_WINCE
@@ -9866,7 +9873,7 @@ md_apply_fix3 (fixS *	fixP,
 
   /* If this symbol is in a different section then we need to leave it for
      the linker to deal with.  Unfortunately, md_pcrel_from can't tell,
-     so we have to undo it's effects here.  */
+     so we have to undo its effects here.  */
   if (fixP->fx_pcrel)
     {
       if (fixP->fx_addsy != NULL
@@ -10073,7 +10080,7 @@ md_apply_fix3 (fixS *	fixP,
 	    }
 	  newval &= ~0xff;
 	}
-      else if ((newval & 0x0000f000) == 0x0000f0000)
+      else if ((newval & 0x000f0000) == 0x000f0000)
 	{
 	  /* PC-relative, 12-bit offset.  */
 	  if (value >= 0)
@@ -10680,24 +10687,20 @@ md_apply_fix3 (fixS *	fixP,
 	{
 	case 4: /* PC load.  */
 	  /* Thumb PC loads are somewhat odd, bit 1 of the PC is
-	     forced to zero for these loads, so we will need to round
-	     up the offset if the instruction address is not word
-	     aligned (since the final address produced must be, and
-	     we can only describe word-aligned immediate offsets).  */
-
+	     forced to zero for these loads; md_pcrel_from has already
+	     compensated for this.  */
 	  if (value & 3)
 	    as_bad_where (fixP->fx_file, fixP->fx_line,
 			  _("invalid offset, target not word aligned (0x%08lX)"),
 			  (((unsigned int) fixP->fx_frag->fr_address
 			    + (unsigned int) fixP->fx_where) & ~3) + value);
 
-	  if ((value + 2) & ~0x3fe)
+	  if (value & ~0x3fc)
 	    as_bad_where (fixP->fx_file, fixP->fx_line,
 			  _("invalid offset, value too big (0x%08lX)"),
 			  (long) value);
 
-	  /* Round up, since pc will be rounded down.  */
-	  newval |= (value + 2) >> 2;
+	  newval |= value >> 2;
 	  break;
 
 	case 9: /* SP load/store.  */
===================================================================
Index: testsuite/gas/arm/thumb.s
--- testsuite/gas/arm/thumb.s	(revision 84)
+++ testsuite/gas/arm/thumb.s	(working copy)
@@ -192,3 +192,11 @@ forwardonly:
 	.space	(1 << 11)	@ leave space to force long offsets
 .local:
 	bl	.back
+
+	ldr	r0, .target
+	ldr	r0, .target
+	ldr	r0, [pc, #4]
+	ldr	r0, [pc, #4]
+.target:
+	nop	@ pad for a.out
+	nop
===================================================================
Index: testsuite/gas/arm/thumb.d
--- testsuite/gas/arm/thumb.d	(revision 84)
+++ testsuite/gas/arm/thumb.d	(working copy)
@@ -181,3 +181,9 @@ Disassembly of section \.text:
 	\.\.\.
 0+938 <[^>]+> f000 f898 	bl	0+134 <[^>]+>
 			938: R_ARM_THM_CALL	\.text
+0+93c <[^>]+> 4801      	ldr	r0, \[pc, #4\]	\(0+944 <[^>]+>\)
+0+93e <[^>]+> 4801      	ldr	r0, \[pc, #4\]	\(0+944 <[^>]+>\)
+0+940 <[^>]+> 4801      	ldr	r0, \[pc, #4\]	\(0+948 <[^>]+>\)
+0+942 <[^>]+> 4801      	ldr	r0, \[pc, #4\]	\(0+948 <[^>]+>\)
+0+944 <[^>]+> 46c0      	nop			\(mov r8, r8\)
+0+946 <[^>]+> 46c0      	nop			\(mov r8, r8\)
===================================================================
Index: testsuite/gas/arm/thumb32.s
--- testsuite/gas/arm/thumb32.s	(revision 84)
+++ testsuite/gas/arm/thumb32.s	(working copy)
@@ -194,6 +194,7 @@ branches:
 	bra	bal.n
 	bra	b.n
 	@ bl, blx have no short form.
+	.balign 4
 1:
 	bra	beq
 	bra	bne
@@ -218,9 +219,8 @@ branches:
 	bra	b
 	bra	bl
 	bra	blx
+	.balign 4
 1:
-
-	bx	r0
 	bx	r9
 	blx	r0
 	blx	r9
===================================================================
Index: testsuite/gas/arm/thumb32.d
--- testsuite/gas/arm/thumb32.d	(revision 84)
+++ testsuite/gas/arm/thumb32.d	(working copy)
@@ -209,100 +209,100 @@ Disassembly of section .text:
 0+2ce <[^>]+> f3c0 5040 	ubfx	r0, r0, #21, #1
 0+2d2 <[^>]+> f340 0011 	sbfx	r0, r0, #0, #18
 0+2d6 <[^>]+> d0fe      	beq\.n	0+2d6 <[^>]+>
-0+2d8 <[^>]+> d029      	beq\.n	0+32e <[^>]+>
+0+2d8 <[^>]+> d02a      	beq\.n	0+330 <[^>]+>
 0+2da <[^>]+> d1fc      	bne\.n	0+2d6 <[^>]+>
-0+2dc <[^>]+> d127      	bne\.n	0+32e <[^>]+>
+0+2dc <[^>]+> d128      	bne\.n	0+330 <[^>]+>
 0+2de <[^>]+> d2fa      	bcs\.n	0+2d6 <[^>]+>
-0+2e0 <[^>]+> d225      	bcs\.n	0+32e <[^>]+>
+0+2e0 <[^>]+> d226      	bcs\.n	0+330 <[^>]+>
 0+2e2 <[^>]+> d2f8      	bcs\.n	0+2d6 <[^>]+>
-0+2e4 <[^>]+> d223      	bcs\.n	0+32e <[^>]+>
+0+2e4 <[^>]+> d224      	bcs\.n	0+330 <[^>]+>
 0+2e6 <[^>]+> d3f6      	bcc\.n	0+2d6 <[^>]+>
-0+2e8 <[^>]+> d321      	bcc\.n	0+32e <[^>]+>
+0+2e8 <[^>]+> d322      	bcc\.n	0+330 <[^>]+>
 0+2ea <[^>]+> d3f4      	bcc\.n	0+2d6 <[^>]+>
-0+2ec <[^>]+> d31f      	bcc\.n	0+32e <[^>]+>
+0+2ec <[^>]+> d320      	bcc\.n	0+330 <[^>]+>
 0+2ee <[^>]+> d3f2      	bcc\.n	0+2d6 <[^>]+>
-0+2f0 <[^>]+> d31d      	bcc\.n	0+32e <[^>]+>
+0+2f0 <[^>]+> d31e      	bcc\.n	0+330 <[^>]+>
 0+2f2 <[^>]+> d4f0      	bmi\.n	0+2d6 <[^>]+>
-0+2f4 <[^>]+> d41b      	bmi\.n	0+32e <[^>]+>
+0+2f4 <[^>]+> d41c      	bmi\.n	0+330 <[^>]+>
 0+2f6 <[^>]+> d5ee      	bpl\.n	0+2d6 <[^>]+>
-0+2f8 <[^>]+> d519      	bpl\.n	0+32e <[^>]+>
+0+2f8 <[^>]+> d51a      	bpl\.n	0+330 <[^>]+>
 0+2fa <[^>]+> d6ec      	bvs\.n	0+2d6 <[^>]+>
-0+2fc <[^>]+> d617      	bvs\.n	0+32e <[^>]+>
+0+2fc <[^>]+> d618      	bvs\.n	0+330 <[^>]+>
 0+2fe <[^>]+> d7ea      	bvc\.n	0+2d6 <[^>]+>
-0+300 <[^>]+> d715      	bvc\.n	0+32e <[^>]+>
+0+300 <[^>]+> d716      	bvc\.n	0+330 <[^>]+>
 0+302 <[^>]+> d8e8      	bhi\.n	0+2d6 <[^>]+>
-0+304 <[^>]+> d813      	bhi\.n	0+32e <[^>]+>
+0+304 <[^>]+> d814      	bhi\.n	0+330 <[^>]+>
 0+306 <[^>]+> d9e6      	bls\.n	0+2d6 <[^>]+>
-0+308 <[^>]+> d911      	bls\.n	0+32e <[^>]+>
+0+308 <[^>]+> d912      	bls\.n	0+330 <[^>]+>
 0+30a <[^>]+> d7e4      	bvc\.n	0+2d6 <[^>]+>
-0+30c <[^>]+> d70f      	bvc\.n	0+32e <[^>]+>
+0+30c <[^>]+> d710      	bvc\.n	0+330 <[^>]+>
 0+30e <[^>]+> d8e2      	bhi\.n	0+2d6 <[^>]+>
-0+310 <[^>]+> d80d      	bhi\.n	0+32e <[^>]+>
+0+310 <[^>]+> d80e      	bhi\.n	0+330 <[^>]+>
 0+312 <[^>]+> d9e0      	bls\.n	0+2d6 <[^>]+>
-0+314 <[^>]+> d90b      	bls\.n	0+32e <[^>]+>
+0+314 <[^>]+> d90c      	bls\.n	0+330 <[^>]+>
 0+316 <[^>]+> dade      	bge\.n	0+2d6 <[^>]+>
-0+318 <[^>]+> da09      	bge\.n	0+32e <[^>]+>
+0+318 <[^>]+> da0a      	bge\.n	0+330 <[^>]+>
 0+31a <[^>]+> dbdc      	blt\.n	0+2d6 <[^>]+>
-0+31c <[^>]+> db07      	blt\.n	0+32e <[^>]+>
+0+31c <[^>]+> db08      	blt\.n	0+330 <[^>]+>
 0+31e <[^>]+> dcda      	bgt\.n	0+2d6 <[^>]+>
-0+320 <[^>]+> dc05      	bgt\.n	0+32e <[^>]+>
+0+320 <[^>]+> dc06      	bgt\.n	0+330 <[^>]+>
 0+322 <[^>]+> ddd8      	ble\.n	0+2d6 <[^>]+>
-0+324 <[^>]+> dd03      	ble\.n	0+32e <[^>]+>
+0+324 <[^>]+> dd04      	ble\.n	0+330 <[^>]+>
 0+326 <[^>]+> ded6      	bal\.n	0+2d6 <[^>]+>
-0+328 <[^>]+> de01      	bal\.n	0+32e <[^>]+>
+0+328 <[^>]+> de02      	bal\.n	0+330 <[^>]+>
 0+32a <[^>]+> e7d4      	b\.n	0+2d6 <[^>]+>
-0+32c <[^>]+> e7ff      	b\.n	0+32e <[^>]+>
-0+32e <[^>]+> f43f affe 	beq\.w	0+32e <[^>]+>
-0+332 <[^>]+> f000 8058 	beq\.w	0+3e6 <[^>]+>
-0+336 <[^>]+> f47f affa 	bne\.w	0+32e <[^>]+>
-0+33a <[^>]+> f040 8054 	bne\.w	0+3e6 <[^>]+>
-0+33e <[^>]+> f4bf aff6 	bcs\.w	0+32e <[^>]+>
-0+342 <[^>]+> f080 8050 	bcs\.w	0+3e6 <[^>]+>
-0+346 <[^>]+> f4bf aff2 	bcs\.w	0+32e <[^>]+>
-0+34a <[^>]+> f080 804c 	bcs\.w	0+3e6 <[^>]+>
-0+34e <[^>]+> f4ff afee 	bcc\.w	0+32e <[^>]+>
-0+352 <[^>]+> f0c0 8048 	bcc\.w	0+3e6 <[^>]+>
-0+356 <[^>]+> f4ff afea 	bcc\.w	0+32e <[^>]+>
-0+35a <[^>]+> f0c0 8044 	bcc\.w	0+3e6 <[^>]+>
-0+35e <[^>]+> f4ff afe6 	bcc\.w	0+32e <[^>]+>
-0+362 <[^>]+> f0c0 8040 	bcc\.w	0+3e6 <[^>]+>
-0+366 <[^>]+> f53f afe2 	bmi\.w	0+32e <[^>]+>
-0+36a <[^>]+> f100 803c 	bmi\.w	0+3e6 <[^>]+>
-0+36e <[^>]+> f57f afde 	bpl\.w	0+32e <[^>]+>
-0+372 <[^>]+> f140 8038 	bpl\.w	0+3e6 <[^>]+>
-0+376 <[^>]+> f5bf afda 	bvs\.w	0+32e <[^>]+>
-0+37a <[^>]+> f180 8034 	bvs\.w	0+3e6 <[^>]+>
-0+37e <[^>]+> f5ff afd6 	bvc\.w	0+32e <[^>]+>
-0+382 <[^>]+> f1c0 8030 	bvc\.w	0+3e6 <[^>]+>
-0+386 <[^>]+> f63f afd2 	bhi\.w	0+32e <[^>]+>
-0+38a <[^>]+> f200 802c 	bhi\.w	0+3e6 <[^>]+>
-0+38e <[^>]+> f67f afce 	bls\.w	0+32e <[^>]+>
-0+392 <[^>]+> f240 8028 	bls\.w	0+3e6 <[^>]+>
-0+396 <[^>]+> f5ff afca 	bvc\.w	0+32e <[^>]+>
-0+39a <[^>]+> f1c0 8024 	bvc\.w	0+3e6 <[^>]+>
-0+39e <[^>]+> f63f afc6 	bhi\.w	0+32e <[^>]+>
-0+3a2 <[^>]+> f200 8020 	bhi\.w	0+3e6 <[^>]+>
-0+3a6 <[^>]+> f67f afc2 	bls\.w	0+32e <[^>]+>
-0+3aa <[^>]+> f240 801c 	bls\.w	0+3e6 <[^>]+>
-0+3ae <[^>]+> f6bf afbe 	bge\.w	0+32e <[^>]+>
-0+3b2 <[^>]+> f280 8018 	bge\.w	0+3e6 <[^>]+>
-0+3b6 <[^>]+> f6ff afba 	blt\.w	0+32e <[^>]+>
-0+3ba <[^>]+> f2c0 8014 	blt\.w	0+3e6 <[^>]+>
-0+3be <[^>]+> f73f afb6 	bgt\.w	0+32e <[^>]+>
-0+3c2 <[^>]+> f300 8010 	bgt\.w	0+3e6 <[^>]+>
-0+3c6 <[^>]+> f77f afb2 	ble\.w	0+32e <[^>]+>
-0+3ca <[^>]+> f340 800c 	ble\.w	0+3e6 <[^>]+>
-0+3ce <[^>]+> f7ff bfae 	b\.w	0+32e <[^>]+>
-0+3d2 <[^>]+> f000 b808 	b\.w	0+3e6 <[^>]+>
-0+3d6 <[^>]+> f000 f995 	bl	0+32e <[^>]+>
-			3d6: R_ARM_THM_CALL	\.text
-0+3da <[^>]+> f000 f9f1 	bl	0+3e6 <[^>]+>
-			3da: R_ARM_THM_CALL	\.text
-0+3de <[^>]+> f000 e995 	blx	0+32e <[^>]+>
-			3de: R_ARM_THM_XPC22	\.text
-0+3e2 <[^>]+> f000 e9f1 	blx	0+3e6 <[^>]+>
-			3e2: R_ARM_THM_XPC22	\.text
-0+3e6 <[^>]+> 4700      	bx	r0
+0+32c <[^>]+> e000      	b\.n	0+330 <[^>]+>
+0+32e <[^>]+> 46c0      	nop			\(mov r8, r8\)
+0+330 <[^>]+> f43f affe 	beq\.w	0+330 <[^>]+>
+0+334 <[^>]+> f000 8058 	beq\.w	0+3e8 <[^>]+>
+0+338 <[^>]+> f47f affa 	bne\.w	0+330 <[^>]+>
+0+33c <[^>]+> f040 8054 	bne\.w	0+3e8 <[^>]+>
+0+340 <[^>]+> f4bf aff6 	bcs\.w	0+330 <[^>]+>
+0+344 <[^>]+> f080 8050 	bcs\.w	0+3e8 <[^>]+>
+0+348 <[^>]+> f4bf aff2 	bcs\.w	0+330 <[^>]+>
+0+34c <[^>]+> f080 804c 	bcs\.w	0+3e8 <[^>]+>
+0+350 <[^>]+> f4ff afee 	bcc\.w	0+330 <[^>]+>
+0+354 <[^>]+> f0c0 8048 	bcc\.w	0+3e8 <[^>]+>
+0+358 <[^>]+> f4ff afea 	bcc\.w	0+330 <[^>]+>
+0+35c <[^>]+> f0c0 8044 	bcc\.w	0+3e8 <[^>]+>
+0+360 <[^>]+> f4ff afe6 	bcc\.w	0+330 <[^>]+>
+0+364 <[^>]+> f0c0 8040 	bcc\.w	0+3e8 <[^>]+>
+0+368 <[^>]+> f53f afe2 	bmi\.w	0+330 <[^>]+>
+0+36c <[^>]+> f100 803c 	bmi\.w	0+3e8 <[^>]+>
+0+370 <[^>]+> f57f afde 	bpl\.w	0+330 <[^>]+>
+0+374 <[^>]+> f140 8038 	bpl\.w	0+3e8 <[^>]+>
+0+378 <[^>]+> f5bf afda 	bvs\.w	0+330 <[^>]+>
+0+37c <[^>]+> f180 8034 	bvs\.w	0+3e8 <[^>]+>
+0+380 <[^>]+> f5ff afd6 	bvc\.w	0+330 <[^>]+>
+0+384 <[^>]+> f1c0 8030 	bvc\.w	0+3e8 <[^>]+>
+0+388 <[^>]+> f63f afd2 	bhi\.w	0+330 <[^>]+>
+0+38c <[^>]+> f200 802c 	bhi\.w	0+3e8 <[^>]+>
+0+390 <[^>]+> f67f afce 	bls\.w	0+330 <[^>]+>
+0+394 <[^>]+> f240 8028 	bls\.w	0+3e8 <[^>]+>
+0+398 <[^>]+> f5ff afca 	bvc\.w	0+330 <[^>]+>
+0+39c <[^>]+> f1c0 8024 	bvc\.w	0+3e8 <[^>]+>
+0+3a0 <[^>]+> f63f afc6 	bhi\.w	0+330 <[^>]+>
+0+3a4 <[^>]+> f200 8020 	bhi\.w	0+3e8 <[^>]+>
+0+3a8 <[^>]+> f67f afc2 	bls\.w	0+330 <[^>]+>
+0+3ac <[^>]+> f240 801c 	bls\.w	0+3e8 <[^>]+>
+0+3b0 <[^>]+> f6bf afbe 	bge\.w	0+330 <[^>]+>
+0+3b4 <[^>]+> f280 8018 	bge\.w	0+3e8 <[^>]+>
+0+3b8 <[^>]+> f6ff afba 	blt\.w	0+330 <[^>]+>
+0+3bc <[^>]+> f2c0 8014 	blt\.w	0+3e8 <[^>]+>
+0+3c0 <[^>]+> f73f afb6 	bgt\.w	0+330 <[^>]+>
+0+3c4 <[^>]+> f300 8010 	bgt\.w	0+3e8 <[^>]+>
+0+3c8 <[^>]+> f77f afb2 	ble\.w	0+330 <[^>]+>
+0+3cc <[^>]+> f340 800c 	ble\.w	0+3e8 <[^>]+>
+0+3d0 <[^>]+> f7ff bfae 	b\.w	0+330 <[^>]+>
+0+3d4 <[^>]+> f000 b808 	b\.w	0+3e8 <[^>]+>
+0+3d8 <[^>]+> f000 f996 	bl	0+330 <[^>]+>
+			3d8: R_ARM_THM_CALL	\.text
+0+3dc <[^>]+> f000 f9f2 	bl	0+3e8 <[^>]+>
+			3dc: R_ARM_THM_CALL	\.text
+0+3e0 <[^>]+> f000 e996 	blx	0+330 <[^>]+>
+			3e0: R_ARM_THM_XPC22	\.text
+0+3e4 <[^>]+> f000 e9f2 	blx	0+3e8 <[^>]+>
+			3e4: R_ARM_THM_XPC22	\.text
 0+3e8 <[^>]+> 4748      	bx	r9
 0+3ea <[^>]+> 4780      	blx	r0
 0+3ec <[^>]+> 47c8      	blx	r9
@@ -508,8 +508,8 @@ Disassembly of section .text:
 0+5b2 <[^>]+> f815 1d30 	ldrb\.w	r1, \[r5\], #-48
 0+5b6 <[^>]+> 5d29      	ldrb	r1, \[r5, r4\]
 0+5b8 <[^>]+> f819 100c 	ldrb\.w	r1, \[r9, ip\]
-0+5bc <[^>]+> f89f 10b0 	ldrb\.w	r1, \[pc, #176\]
-0+5c0 <[^>]+> f81f 1c26 	ldrb\.w	r1, \[pc, #-3110\]
+0+5bc <[^>]+> f89f 10ac 	ldrb\.w	r1, \[pc, #172\]	; 0+66c <[^>]+>
+0+5c0 <[^>]+> f81f 102a 	ldrb\.w	r1, \[pc, #-42\]	; 0+59a <[^>]+>
 0+5c4 <[^>]+> f995 1000 	ldrsb\.w	r1, \[r5\]
 0+5c8 <[^>]+> f995 1330 	ldrsb\.w	r1, \[r5, #816\]
 0+5cc <[^>]+> f915 1c30 	ldrsb\.w	r1, \[r5, #-48\]
@@ -519,8 +519,8 @@ Disassembly of section .text:
 0+5dc <[^>]+> f915 1d30 	ldrsb\.w	r1, \[r5\], #-48
 0+5e0 <[^>]+> 5729      	ldrsb	r1, \[r5, r4\]
 0+5e2 <[^>]+> f919 100c 	ldrsb\.w	r1, \[r9, ip\]
-0+5e6 <[^>]+> f99f 1086 	ldrsb\.w	r1, \[pc, #134\]
-0+5ea <[^>]+> f91f 1c50 	ldrsb\.w	r1, \[pc, #-3152\]
+0+5e6 <[^>]+> f99f 1084 	ldrsb\.w	r1, \[pc, #132\]	; 0+66c <[^>]+>
+0+5ea <[^>]+> f91f 1052 	ldrsb\.w	r1, \[pc, #-82\]	; 0+59a <[^>]+>
 0+5ee <[^>]+> f8b5 1000 	ldrh\.w	r1, \[r5\]
 0+5f2 <[^>]+> f8b5 1330 	ldrh\.w	r1, \[r5, #816\]
 0+5f6 <[^>]+> f835 1c30 	ldrh\.w	r1, \[r5, #-48\]
@@ -530,8 +530,8 @@ Disassembly of section .text:
 0+606 <[^>]+> f835 1d30 	ldrh\.w	r1, \[r5\], #-48
 0+60a <[^>]+> 5b29      	ldrh	r1, \[r5, r4\]
 0+60c <[^>]+> f839 100c 	ldrh\.w	r1, \[r9, ip\]
-0+610 <[^>]+> f8bf 105c 	ldrh\.w	r1, \[pc, #92\]
-0+614 <[^>]+> f83f 1c7a 	ldrh\.w	r1, \[pc, #-3194\]
+0+610 <[^>]+> f8bf 1058 	ldrh\.w	r1, \[pc, #88\]	; 0+66c <[^>]+>
+0+614 <[^>]+> f83f 107e 	ldrh\.w	r1, \[pc, #-126\]	; 0+59a <[^>]+>
 0+618 <[^>]+> f9b5 1000 	ldrsh\.w	r1, \[r5\]
 0+61c <[^>]+> f9b5 1330 	ldrsh\.w	r1, \[r5, #816\]
 0+620 <[^>]+> f935 1c30 	ldrsh\.w	r1, \[r5, #-48\]
@@ -541,8 +541,8 @@ Disassembly of section .text:
 0+630 <[^>]+> f935 1d30 	ldrsh\.w	r1, \[r5\], #-48
 0+634 <[^>]+> 5f29      	ldrsh	r1, \[r5, r4\]
 0+636 <[^>]+> f939 100c 	ldrsh\.w	r1, \[r9, ip\]
-0+63a <[^>]+> f9bf 1032 	ldrsh\.w	r1, \[pc, #50\]
-0+63e <[^>]+> f93f 1ca4 	ldrsh\.w	r1, \[pc, #-3236\]
+0+63a <[^>]+> f9bf 1030 	ldrsh\.w	r1, \[pc, #48\]	; 0+66c <[^>]+>
+0+63e <[^>]+> f93f 10a6 	ldrsh\.w	r1, \[pc, #-166\]	; 0+59a <[^>]+>
 0+642 <[^>]+> f8d5 1000 	ldr\.w	r1, \[r5\]
 0+646 <[^>]+> f8d5 1330 	ldr\.w	r1, \[r5, #816\]
 0+64a <[^>]+> f855 1c30 	ldr\.w	r1, \[r5, #-48\]
@@ -552,8 +552,8 @@ Disassembly of section .text:
 0+65a <[^>]+> f855 1d30 	ldr\.w	r1, \[r5\], #-48
 0+65e <[^>]+> 5929      	ldr	r1, \[r5, r4\]
 0+660 <[^>]+> f859 100c 	ldr\.w	r1, \[r9, ip\]
-0+664 <[^>]+> f8df 1008 	ldr\.w	r1, \[pc, #8\]
-0+668 <[^>]+> f85f 1cce 	ldr\.w	r1, \[pc, #-3278\]
+0+664 <[^>]+> f8df 1004 	ldr\.w	r1, \[pc, #4\]	; 0+66c <[^>]+>
+0+668 <[^>]+> f85f 10d2 	ldr\.w	r1, \[pc, #-210\]	; 0+59a <[^>]+>
 0+66c <[^>]+> f885 1000 	strb\.w	r1, \[r5\]
 0+670 <[^>]+> f885 1330 	strb\.w	r1, \[r5, #816\]
 0+674 <[^>]+> f805 1c30 	strb\.w	r1, \[r5, #-48\]
@@ -563,8 +563,8 @@ Disassembly of section .text:
 0+684 <[^>]+> f805 1d30 	strb\.w	r1, \[r5\], #-48
 0+688 <[^>]+> 5529      	strb	r1, \[r5, r4\]
 0+68a <[^>]+> f809 100c 	strb\.w	r1, \[r9, ip\]
-0+68e <[^>]+> f88f 1088 	strb\.w	r1, \[pc, #136\]
-0+692 <[^>]+> f80f 1c26 	strb\.w	r1, \[pc, #-3110\]
+0+68e <[^>]+> f88f 1086 	strb\.w	r1, \[pc, #134\]	; 0+716 <[^>]+>
+0+692 <[^>]+> f80f 1028 	strb\.w	r1, \[pc, #-40\]	; 0+66c <[^>]+>
 0+696 <[^>]+> f8a5 1000 	strh\.w	r1, \[r5\]
 0+69a <[^>]+> f8a5 1330 	strh\.w	r1, \[r5, #816\]
 0+69e <[^>]+> f825 1c30 	strh\.w	r1, \[r5, #-48\]
@@ -574,8 +574,8 @@ Disassembly of section .text:
 0+6ae <[^>]+> f825 1d30 	strh\.w	r1, \[r5\], #-48
 0+6b2 <[^>]+> 5329      	strh	r1, \[r5, r4\]
 0+6b4 <[^>]+> f829 100c 	strh\.w	r1, \[r9, ip\]
-0+6b8 <[^>]+> f8af 105e 	strh\.w	r1, \[pc, #94\]
-0+6bc <[^>]+> f82f 1c50 	strh\.w	r1, \[pc, #-3152\]
+0+6b8 <[^>]+> f8af 105a 	strh\.w	r1, \[pc, #90\]	; 0+716 <[^>]+>
+0+6bc <[^>]+> f82f 1054 	strh\.w	r1, \[pc, #-84\]	; 0+66c <[^>]+>
 0+6c0 <[^>]+> f8c5 1000 	str\.w	r1, \[r5\]
 0+6c4 <[^>]+> f8c5 1330 	str\.w	r1, \[r5, #816\]
 0+6c8 <[^>]+> f845 1c30 	str\.w	r1, \[r5, #-48\]
@@ -585,8 +585,8 @@ Disassembly of section .text:
 0+6d8 <[^>]+> f845 1d30 	str\.w	r1, \[r5\], #-48
 0+6dc <[^>]+> 5129      	str	r1, \[r5, r4\]
 0+6de <[^>]+> f849 100c 	str\.w	r1, \[r9, ip\]
-0+6e2 <[^>]+> f8cf 1034 	str\.w	r1, \[pc, #52\]
-0+6e6 <[^>]+> f84f 1c7a 	str\.w	r1, \[pc, #-3194\]
+0+6e2 <[^>]+> f8cf 1032 	str\.w	r1, \[pc, #50\]	; 0+716 <[^>]+>
+0+6e6 <[^>]+> f84f 107c 	str\.w	r1, \[pc, #-124\]	; 0+66c <[^>]+>
 0+6ea <[^>]+> f895 f000 	pld	\[r5\]
 0+6ee <[^>]+> f895 f330 	pld	\[r5, #816\]
 0+6f2 <[^>]+> f815 fc30 	pld	\[r5, #-48\]
@@ -596,8 +596,8 @@ Disassembly of section .text:
 0+702 <[^>]+> f815 fd30 	pld	\[r5\], #-48
 0+706 <[^>]+> f815 f000 	pld	\[r5, r0\]
 0+70a <[^>]+> f819 f000 	pld	\[r9, r0\]
-0+70e <[^>]+> f89f f008 	pld	\[pc, #8\]
-0+712 <[^>]+> f81f fca6 	pld	\[pc, #-3238\]
+0+70e <[^>]+> f89f f006 	pld	\[pc, #6\]	; 0+716 <[^>]+>
+0+712 <[^>]+> f81f f0a8 	pld	\[pc, #-168\]	; 0+66c <[^>]+>
 0+716 <[^>]+> e9d5 2300 	ldrd	r2, r3, \[r5\]
 0+71a <[^>]+> e9d5 230c 	ldrd	r2, r3, \[r5, #48\]
 0+71e <[^>]+> e955 230c 	ldrd	r2, r3, \[r5, #-48\]
===================================================================
Index: testsuite/gas/arm/tcompat2.s
--- testsuite/gas/arm/tcompat2.s	(revision 85)
+++ testsuite/gas/arm/tcompat2.s	(working copy)
@@ -25,3 +25,8 @@ m:
 
 	sbc	r0,r0,r1
 
+	@ section padding for a.out's sake
+	nop
+	nop
+	nop
+	nop
===================================================================
Index: testsuite/gas/arm/tcompat2.d
--- testsuite/gas/arm/tcompat2.d	(revision 85)
+++ testsuite/gas/arm/tcompat2.d	(working copy)
@@ -20,3 +20,7 @@ Disassembly of section .text:
 0+12 <[^>]*> 4308 *	orrs	r0, r1
 0+14 <[^>]*> 4388 *	bics	r0, r1
 0+16 <[^>]*> 4188 *	sbcs	r0, r1
+0+18 <[^>]*> 46c0 *	nop			\(mov r8, r8\)
+0+1a <[^>]*> 46c0 *	nop			\(mov r8, r8\)
+0+1c <[^>]*> 46c0 *	nop			\(mov r8, r8\)
+0+1e <[^>]*> 46c0 *	nop			\(mov r8, r8\)
===================================================================
Index: testsuite/gas/arm/macro1.s
--- testsuite/gas/arm/macro1.s	(revision 85)
+++ testsuite/gas/arm/macro1.s	(working copy)
@@ -3,4 +3,10 @@
 	ldmia sp!, {\regs, pc}
 	.endm
 	.text
+l:
 	popret "r4, r5"
+
+	@ section padding for a.out's sake
+	nop
+	nop
+	nop
===================================================================
Index: testsuite/gas/arm/macro1.d
--- testsuite/gas/arm/macro1.d	(revision 85)
+++ testsuite/gas/arm/macro1.d	(working copy)
@@ -7,3 +7,6 @@
 Disassembly of section .text:
 
 0+0 <[^>]*> e8bd8030 ?	ldmia	sp!, {r4, r5, pc}
+0+4 <[^>]*> e1a00000 ?	nop			\(mov r0,r0\)
+0+8 <[^>]*> e1a00000 ?	nop			\(mov r0,r0\)
+0+c <[^>]*> e1a00000 ?	nop			\(mov r0,r0\)

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Thumb32 assembler (42/69)
  2005-04-30  0:57   ` Zack Weinberg
@ 2005-04-30  2:33     ` Zack Weinberg
  0 siblings, 0 replies; 5+ messages in thread
From: Zack Weinberg @ 2005-04-30  2:33 UTC (permalink / raw)
  To: Paul Brook; +Cc: binutils

Zack Weinberg <zack@codesourcery.com> writes:

> Here is a less ambitious fix for this bug, which gives responsibility
> for the pipeline offset to md_pcrel_from only for the relocations
> relevant to this bug.  This works and doesn't break anything else -
> tested with both arm-aout and arm-elf cross binutils.

Left a piece out.

zw

        * opcodes/arm-dis.c (print_insn_thumb32): Reorganize %a and %A
        handling.  Call info->print_address_func when %a/%A are applied 
        to a PC-relative instruction.

===================================================================
Index: opcodes/arm-dis.c
--- opcodes/arm-dis.c	(revision 86)
+++ opcodes/arm-dis.c	(working copy)
@@ -2278,61 +2278,75 @@ print_insn_thumb32 (pc, info, given)
 		  unsigned int op  = (given & 0x00000f00) >> 8;
 		  unsigned int i12 = (given & 0x00000fff);
 		  unsigned int i8  = (given & 0x000000ff);
+		  bfd_boolean writeback = FALSE, postind = FALSE;
+		  int offset = 0;
 
 		  func (stream, "[%s", arm_regnames[Rn]);
 		  if (U) /* 12-bit positive immediate offset */
+		    offset = i12;
+		  else if (Rn == 15) /* 12-bit negative immediate offset */
+		    offset = -(int)i12;
+		  else if (op == 0x0) /* shifted register offset */
 		    {
-		      if (i12)
-			func (stream, ", #%u", i12);
+		      unsigned int Rm = (i8 & 0x0f);
+		      unsigned int sh = (i8 & 0x30) >> 4;
+		      func (stream, ", %s", arm_regnames[Rm]);
+		      if (sh)
+			func (stream, ", lsl #%u", sh);
 		      func (stream, "]");
+		      break;
 		    }
-		  else if (Rn == 15) /* 12-bit negative immediate offset */
-		    func (stream, ", #-%u]", i12);
 		  else switch (op)
 		    {
-		    case 0x0:  /* shifted register offset */
-		      {
-			unsigned int Rm = (i8 & 0x0f);
-			unsigned int sh = (i8 & 0x30) >> 4;
-			func (stream, ", %s", arm_regnames[Rm]);
-			if (sh)
-			  func (stream, ", lsl #%u", sh);
-			func (stream, "]");
-		      }
-		      break;
-
 		    case 0xE:  /* 8-bit positive immediate offset */
-		      if (i8)
-			func (stream, ", #%u", i8);
-		      func (stream, "]");
+		      offset = i8;
 		      break;
 
 		    case 0xC:  /* 8-bit negative immediate offset */
-		      func (stream, ", #-%u]", i8);
+		      offset = -i8;
 		      break;
 
 		    case 0xB:  /* 8-bit + preindex with wb */
-		      if (i8)
-			func (stream, ", #%u", i8);
-		      func (stream, "]!");
+		      offset = i8;
+		      writeback = TRUE;
 		      break;
 
 		    case 0x9:  /* 8-bit - preindex with wb */
-		      func (stream, ", #-%u]!", i8);
+		      offset = -i8;
+		      writeback = TRUE;
 		      break;
 
 		    case 0xF:  /* 8-bit + postindex */
-		      func (stream, "], #%u", i8);
+		      offset = i8;
+		      postind = TRUE;
 		      break;
 
 		    case 0xD:  /* 8-bit - postindex */
-		      func (stream, "], #-%u", i8);
+		      offset = -i8;
+		      postind = TRUE;
 		      break;
 
 		    default:
 		      func (stream, ", <undefined>]");
+		      goto skip;
+		    }
+
+		  if (postind)
+		    func (stream, "], #%d", offset);
+		  else
+		    {
+		      if (offset)
+			func (stream, ", #%d", offset);
+		      func (stream, writeback ? "]!" : "]");
+		    }
+
+		  if (Rn == 15)
+		    {
+		      func (stream, "\t; ");
+		      info->print_address_func (((pc + 4) & ~3) + offset, info);
 		    }
 		}
+	      skip:
 		break;
 
 	      case 'A':
@@ -2425,7 +2439,7 @@ print_insn_thumb32 (pc, info, given)
 		  unsigned int S = (given & 0x04000000u) >> 26;
 		  unsigned int J1 = (given & 0x00002000u) >> 13;
 		  unsigned int J2 = (given & 0x00000800u) >> 11;
-		  unsigned int offset = 0;
+		  int offset = 0;
 
 		  offset |= !S << 20;
 		  offset |= J2 << 19;
@@ -2434,7 +2448,7 @@ print_insn_thumb32 (pc, info, given)
 		  offset |= (given & 0x000007ff) << 1;
 		  offset -= (1 << 20);
 
-		  info->print_address_func ((bfd_vma)offset + pc + 4, info);
+		  info->print_address_func (pc + 4 + offset, info);
 		}
 		break;
 
@@ -2443,7 +2457,7 @@ print_insn_thumb32 (pc, info, given)
 		  unsigned int S = (given & 0x04000000u) >> 26;
 		  unsigned int I1 = (given & 0x00002000u) >> 13;
 		  unsigned int I2 = (given & 0x00000800u) >> 11;
-		  unsigned int offset = 0;
+		  int offset = 0;
 
 		  offset |= !S << 24;
 		  offset |= !(I1 ^ S) << 23;
@@ -2452,7 +2466,7 @@ print_insn_thumb32 (pc, info, given)
 		  offset |= (given & 0x000007ffu) << 1;
 		  offset -= (1 << 24);
 
-		  info->print_address_func ((bfd_vma)offset + pc + 4, info);
+		  info->print_address_func (pc + 4 + offset, info);
 		}
 		break;
 

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2005-04-30  0:38 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-04-26 10:03 Thumb32 assembler (42/69) Zack Weinberg
2005-04-26 15:20 ` Paul Brook
2005-04-29 11:57   ` Zack Weinberg
2005-04-30  0:57   ` Zack Weinberg
2005-04-30  2:33     ` Zack Weinberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).