Fix adr pseudo op for Thumb.
authorNick Clifton <nickc@redhat.com>
Fri, 17 Mar 2000 22:12:08 +0000 (22:12 +0000)
committerNick Clifton <nickc@redhat.com>
Fri, 17 Mar 2000 22:12:08 +0000 (22:12 +0000)
gas/ChangeLog
gas/config/tc-arm.c

index 4b10a7bae511ce884a4a0b10c991bc6cb1b9ea83..02bcb959e9500d8a9ae85ebbaa360e13a49c2ffc 100644 (file)
@@ -1,3 +1,11 @@
+2000-03-17 Thomas de Lellis <tdel@windriver.com>
+
+        * config/tc-arm.c (do_t_adr): Flag "adr Rd,label"
+        instruction operand bad if Rd > 7 when generating
+        thumb instructions. Prevents for example,
+        "adr r12,label" from silently failing and generating
+        the wrong instruction.
+        
 2000-03-17  Nick Clifton  <nickc@cygnus.com>
 
        * config/tc-arm.c (md_apply_fix3): Handle same-section relocations
index 57f8faa21b102ef6bf2a305b8851be303fb213ac..58dd3cfec38794d3b2e24e432ebad32be6d6c5b6 100644 (file)
@@ -2642,8 +2642,7 @@ do_adr (str, flags)
      unsigned long flags;
 {
   /* This is a pseudo-op of the form "adr rd, label" to be converted
-     into a relative address of the form "add rd, pc, #label-.-8" */
-
+     into a relative address of the form "add rd, pc, #label-.-8".  */
   skip_whitespace (str);
 
   if (reg_required_here (&str, 12) == FAIL
@@ -2654,10 +2653,11 @@ do_adr (str, flags)
        inst.error = BAD_ARGS;
       return;
     }
+  
   /* Frag hacking will turn this into a sub instruction if the offset turns
      out to be negative.  */
   inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
-  inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
+  inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
   inst.reloc.pc_rel = 1;
   inst.instruction |= flags;
   end_of_line (str);
@@ -4905,11 +4905,15 @@ static void
 do_t_adr (str)
      char * str;
 {
+  int reg;
+
   /* This is a pseudo-op of the form "adr rd, label" to be converted
-     into a relative address of the form "add rd, pc, #label-.-4" */
+     into a relative address of the form "add rd, pc, #label-.-4" */
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 4) == FAIL  /* Store Rd in temporary location inside instruction.  */
+  /* Store Rd in temporary location inside instruction.  */
+  if ((reg = reg_required_here (&str, 4)) == FAIL
+      || (reg > 7)  /* For Thumb reg must be r0..r7.  */
       || skip_past_comma (&str) == FAIL
       || my_get_expression (&inst.reloc.exp, &str))
     {
@@ -4919,9 +4923,10 @@ do_t_adr (str)
     }
 
   inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
-  inst.reloc.exp.X_add_number -= 4; /* PC relative adjust */
+  inst.reloc.exp.X_add_number -= 4; /* PC relative adjust */
   inst.reloc.pc_rel = 1;
-  inst.instruction |= REG_PC; /* Rd is already placed into the instruction */
+  inst.instruction |= REG_PC; /* Rd is already placed into the instruction.  */
+  
   end_of_line (str);
 }