2006-07-18 Paul Brook <paul@codesourcery.com>
authorPaul Brook <paul@codesourcery.com>
Tue, 18 Jul 2006 16:44:47 +0000 (16:44 +0000)
committerPaul Brook <paul@codesourcery.com>
Tue, 18 Jul 2006 16:44:47 +0000 (16:44 +0000)
bfd/
* bfd-in2.h: Regenerate.
* libbfd.h: Regenerate.
* reloc.c: Add BFD_RELOC_ARM_T32_ADD_IMM.

gas/
* tc-arm.c (do_t_add_sub): Use addw/subw when source is PC.
(md_convert_frag): Use correct reloc for add_pc.  Use
BFD_RELOC_ARM_T32_ADD_IMM for normal add/sum.
(md_apply_fix): Handle BFD_RELOC_ARM_T32_ADD_IMM.
(arm_force_relocation): Handle BFD_RELOC_ARM_T32_ADD_IMM.

gas/testsuite/
* gas/arm/thumb2_add.d: New test.
* gas/arm/thumb2_add.s: New test.

bfd/ChangeLog
bfd/bfd-in2.h
bfd/libbfd.h
bfd/reloc.c
gas/ChangeLog
gas/config/tc-arm.c
gas/testsuite/ChangeLog
gas/testsuite/gas/arm/thumb2_add.d [new file with mode: 0644]
gas/testsuite/gas/arm/thumb2_add.s [new file with mode: 0644]

index 6c4773ed28a588e5ee429128c52eca61207a3e19..4ce004e63e2d6c6c23a79e53a02a7dbe1273135c 100644 (file)
@@ -1,3 +1,9 @@
+2006-07-18  Paul Brook  <paul@codesourcery.com>
+
+       * bfd-in2.h: Regenerate.
+       * libbfd.h: Regenerate.
+       * reloc.c: Add BFD_RELOC_ARM_T32_ADD_IMM.
+
 2006-07-18  Nick Clifton  <nickc@redhat.com>
 
        * elfxx-mips.c (_bfd_mips_elf_common_definition): New function.
index df3bae8945c41dea068e04e84958ab8c769584c3..381ae55640f675d337751bd9690db19343ed1dca 100644 (file)
@@ -2966,6 +2966,7 @@ pc-relative or some form of GOT-indirect relocation.  */
   BFD_RELOC_ARM_IMMEDIATE,
   BFD_RELOC_ARM_ADRL_IMMEDIATE,
   BFD_RELOC_ARM_T32_IMMEDIATE,
+  BFD_RELOC_ARM_T32_ADD_IMM,
   BFD_RELOC_ARM_T32_IMM12,
   BFD_RELOC_ARM_T32_ADD_PC12,
   BFD_RELOC_ARM_SHIFT_IMM,
index 0f41f5f2d1b0ba79c94a35b8e419463379da26d2..0aa704604f60ceb60868909a82fc40d9c0887866 100644 (file)
@@ -1263,6 +1263,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_ARM_IMMEDIATE",
   "BFD_RELOC_ARM_ADRL_IMMEDIATE",
   "BFD_RELOC_ARM_T32_IMMEDIATE",
+  "BFD_RELOC_ARM_T32_ADD_IMM",
   "BFD_RELOC_ARM_T32_IMM12",
   "BFD_RELOC_ARM_T32_ADD_PC12",
   "BFD_RELOC_ARM_SHIFT_IMM",
index 414a41cef5f068478cce0f277450e7eb36123965..60ebf36f033ddd9dafc41779b505457cdaa2c258 100644 (file)
@@ -2821,6 +2821,8 @@ ENUMX
   BFD_RELOC_ARM_ADRL_IMMEDIATE
 ENUMX
   BFD_RELOC_ARM_T32_IMMEDIATE
+ENUMX
+  BFD_RELOC_ARM_T32_ADD_IMM
 ENUMX
   BFD_RELOC_ARM_T32_IMM12
 ENUMX
index 80c46cd276cd2f791328318d2b1a17344a78b27b..6b414dc1f2c35ef0b9153b88cfadaeaf011f14ba 100644 (file)
@@ -1,3 +1,11 @@
+2006-07-18  Paul Brook  <paul@codesourcery.com>
+
+       * tc-arm.c (do_t_add_sub): Use addw/subw when source is PC.
+       (md_convert_frag): Use correct reloc for add_pc.  Use
+       BFD_RELOC_ARM_T32_ADD_IMM for normal add/sum.
+       (md_apply_fix): Handle BFD_RELOC_ARM_T32_ADD_IMM.
+       (arm_force_relocation): Handle BFD_RELOC_ARM_T32_ADD_IMM.
+
 2006-07-17  Mat Hostetter  <mat@lcs.mit.edu>
 
        * symbols.c (report_op_error): Fix pasto.  Don't use as_bad_where
index 1bfe5b307a3d5f67f1bc939646a3847685936d8a..fe9d77521fc733e2893642204752c69a1cf216b7 100644 (file)
@@ -8186,13 +8186,13 @@ do_t_add_sub (void)
        narrow = (current_it_mask != 0);
       if (!inst.operands[2].isreg)
        {
+         int add;
+
+         add = (inst.instruction == T_MNEM_add
+                || inst.instruction == T_MNEM_adds);
          opcode = 0;
          if (inst.size_req != 4)
            {
-             int add;
-
-             add = (inst.instruction == T_MNEM_add
-                    || inst.instruction == T_MNEM_adds);
              /* Attempt to use a narrow opcode, with relaxation if
                 appropriate.  */
              if (Rd == REG_SP && Rs == REG_SP && !flags)
@@ -8222,12 +8222,24 @@ do_t_add_sub (void)
          if (inst.size_req == 4
              || (inst.size_req != 2 && !opcode))
            {
-             /* ??? Convert large immediates to addw/subw.  */
-             inst.instruction = THUMB_OP32 (inst.instruction);
-             inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
+             if (Rs == REG_PC)
+               {
+                 /* Always use addw/subw.  */
+                 inst.instruction = add ? 0xf20f0000 : 0xf2af0000;
+                 inst.reloc.type = BFD_RELOC_ARM_T32_IMM12;
+               }
+             else
+               {
+                 inst.instruction = THUMB_OP32 (inst.instruction);
+                 inst.instruction = (inst.instruction & 0xe1ffffff)
+                                    | 0x10000000;
+                 if (flags)
+                   inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
+                 else
+                   inst.reloc.type = BFD_RELOC_ARM_T32_ADD_IMM;
+               }
              inst.instruction |= inst.operands[0].reg << 8;
              inst.instruction |= inst.operands[1].reg << 16;
-             inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
            }
        }
       else
@@ -16136,7 +16148,10 @@ md_convert_frag (bfd *abfd, segT asec ATTRIBUTE_UNUSED, fragS *fragp)
          insn = THUMB_OP32 (opcode);
          insn |= (old_op & 0xf0) << 4;
          put_thumb32_insn (buf, insn);
-         reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
+         if (opcode == T_MNEM_add_pc)
+           reloc_type = BFD_RELOC_ARM_T32_IMM12;
+         else
+           reloc_type = BFD_RELOC_ARM_T32_ADD_IMM;
        }
       else
        reloc_type = BFD_RELOC_ARM_THUMB_ADD;
@@ -16153,7 +16168,10 @@ md_convert_frag (bfd *abfd, segT asec ATTRIBUTE_UNUSED, fragS *fragp)
          insn |= (old_op & 0xf0) << 4;
          insn |= (old_op & 0xf) << 16;
          put_thumb32_insn (buf, insn);
-         reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
+         if (insn & (1 << 20))
+           reloc_type = BFD_RELOC_ARM_T32_ADD_IMM;
+         else
+           reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
        }
       else
        reloc_type = BFD_RELOC_ARM_THUMB_ADD;
@@ -17561,6 +17579,7 @@ md_apply_fix (fixS *    fixP,
       break;
 
     case BFD_RELOC_ARM_T32_IMMEDIATE:
+    case BFD_RELOC_ARM_T32_ADD_IMM:
     case BFD_RELOC_ARM_T32_IMM12:
     case BFD_RELOC_ARM_T32_ADD_PC12:
       /* We claim that this fixup has been processed here,
@@ -17581,15 +17600,21 @@ md_apply_fix (fixS *  fixP,
       newval <<= 16;
       newval |= md_chars_to_number (buf+2, THUMB_SIZE);
 
-      /* FUTURE: Implement analogue of negate_data_op for T32.  */
-      if (fixP->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE)
+      newimm = FAIL;
+      if (fixP->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
+         || fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
        {
          newimm = encode_thumb32_immediate (value);
          if (newimm == (unsigned int) FAIL)
            newimm = thumb32_negate_data_op (&newval, value);
        }
-      else
+      if (fixP->fx_r_type != BFD_RELOC_ARM_T32_IMMEDIATE
+         && newimm == (unsigned int) FAIL)
        {
+         /* Turn add/sum into addw/subw.  */
+         if (fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
+           newval = (newval & 0xfeffffff) | 0x02000000;
+
          /* 12 bit immediate for addw/subw.  */
          if (value < 0)
            {
@@ -18608,6 +18633,7 @@ arm_force_relocation (struct fix * fixp)
   if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
       || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
       || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE
+      || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM
       || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
       || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMM12
       || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_PC12)
index 327364b152fc2f2a77914af616c44745b2cfb10e..16b48ac8a802b27cd4d68f6ec5617eab51e7610a 100644 (file)
@@ -1,3 +1,8 @@
+2006-07-18  Paul Brook  <paul@codesourcery.com>
+
+       * gas/arm/thumb2_add.d: New test.
+       * gas/arm/thumb2_add.s: New test.
+
 2006-07-18  Maciej W. Rozycki  <macro@mips.com>
 
        * gas/mips/mips4.s, gas/mips/mips4.d: Enable the "pref" test.  Change
diff --git a/gas/testsuite/gas/arm/thumb2_add.d b/gas/testsuite/gas/arm/thumb2_add.d
new file mode 100644 (file)
index 0000000..6331acf
--- /dev/null
@@ -0,0 +1,18 @@
+# as: -march=armv6kt2
+# objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0+000 <[^>]+> f60f 0000        addw    r0, pc, #2048   ; 0x800
+0+004 <[^>]+> f20f 0900        addw    r9, pc, #0      ; 0x0
+0+008 <[^>]+> f20f 4900        addw    r9, pc, #1024   ; 0x400
+0+00c <[^>]+> f509 6880        add.w   r8, r9, #1024   ; 0x400
+0+010 <[^>]+> f209 1801        addw    r8, r9, #257    ; 0x101
+0+014 <[^>]+> f201 1301        addw    r3, r1, #257    ; 0x101
+0+018 <[^>]+> f6af 0000        subw    r0, pc, #2048   ; 0x800
+0+01c <[^>]+> f2af 0900        subw    r9, pc, #0      ; 0x0
+0+020 <[^>]+> f2af 4900        subw    r9, pc, #1024   ; 0x400
+0+024 <[^>]+> f5a9 6880        sub.w   r8, r9, #1024   ; 0x400
+0+028 <[^>]+> f2a9 1801        subw    r8, r9, #257    ; 0x101
+0+02c <[^>]+> f2a1 1301        subw    r3, r1, #257    ; 0x101
diff --git a/gas/testsuite/gas/arm/thumb2_add.s b/gas/testsuite/gas/arm/thumb2_add.s
new file mode 100644 (file)
index 0000000..72d1bb1
--- /dev/null
@@ -0,0 +1,20 @@
+       .syntax unified
+       .text
+       .align  2
+       .global thumb2_add
+       .thumb
+       .thumb_func
+       .type   thumb2_add, %function
+thumb2_add:
+       add r0, pc, #0x800
+       add r9, pc, #0
+       add r9, pc, #0x400
+       add r8, r9, #0x400
+       add r8, r9, #0x101
+       add r3, r1, #0x101
+       sub r0, pc, #0x800
+       sub r9, pc, #0
+       sub r9, pc, #0x400
+       sub r8, r9, #0x400
+       sub r8, r9, #0x101
+       sub r3, r1, #0x101
This page took 0.062136 seconds and 4 git commands to generate.