2007-08-09 Paul Brook <paul@codesourcery.com>
authorPaul Brook <paul@codesourcery.com>
Thu, 9 Aug 2007 15:11:07 +0000 (15:11 +0000)
committerPaul Brook <paul@codesourcery.com>
Thu, 9 Aug 2007 15:11:07 +0000 (15:11 +0000)
gas/
* config/tc-arm.c (relaxed_symbol_addr): Compensate for alignment.

gas/testsuite/
* gas/arm/relax_load_align.d: new test.
* gas/arm/relax_load_align.s: new test.

gas/ChangeLog
gas/config/tc-arm.c
gas/testsuite/ChangeLog
gas/testsuite/gas/arm/relax_load_align.d [new file with mode: 0644]
gas/testsuite/gas/arm/relax_load_align.s [new file with mode: 0644]

index ba546c4..8818688 100644 (file)
@@ -1,3 +1,7 @@
+2007-08-09  Paul Brook  <paul@codesourcery.com>
+
+       * config/tc-arm.c (relaxed_symbol_addr): Compensate for alignment.
+
 2007-08-09  H.J. Lu  <hongjiu.lu@intel.com>
 
        * config/tc-i386.c (check_byte_reg): Support pextrb and pinsrb.
index 82562d7..117fe16 100644 (file)
@@ -16787,7 +16787,31 @@ relaxed_symbol_addr(fragS *fragp, long stretch)
 
   if (stretch != 0
       && sym_frag->relax_marker != fragp->relax_marker)
-    addr += stretch;
+    {
+      fragS *f;
+
+      /* Adjust stretch for any alignment frag.  Note that if have
+        been expanding the earlier code, the symbol may be
+        defined in what appears to be an earlier frag.  FIXME:
+        This doesn't handle the fr_subtype field, which specifies
+        a maximum number of bytes to skip when doing an
+        alignment.  */
+      for (f = fragp; f != NULL && f != sym_frag; f = f->fr_next)
+       {
+         if (f->fr_type == rs_align || f->fr_type == rs_align_code)
+           {
+             if (stretch < 0)
+               stretch = - ((- stretch)
+                            & ~ ((1 << (int) f->fr_offset) - 1));
+             else
+               stretch &= ~ ((1 << (int) f->fr_offset) - 1);
+             if (stretch == 0)
+               break;
+           }
+       }
+      if (f != NULL)
+       addr += stretch;
+    }
 
   return addr;
 }
index 60be6e6..1bbbec1 100644 (file)
@@ -1,3 +1,8 @@
+2007-08-09  Paul Brook  <paul@codesourcery.com>
+
+       * gas/arm/relax_load_align.d: new test.
+       * gas/arm/relax_load_align.s: new test.
+
 2007-08-09  H.J. Lu  <hongjiu.lu@intel.com>
 
        * gas/i386/i386.exp: Run sse4_1-intel, sse4_2-intel,
diff --git a/gas/testsuite/gas/arm/relax_load_align.d b/gas/testsuite/gas/arm/relax_load_align.d
new file mode 100644 (file)
index 0000000..0147b49
--- /dev/null
@@ -0,0 +1,9 @@
+# as: -march=armv6kt2
+# objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0+000 <[^>]+> f510 707a        adds.w  r0, r0, #1000   ; 0x3e8
+0+004 <[^>]+> 4800             ldr     r0, \[pc, #0\]  \(0+008 <[^>]+>\)
+0+006 <[^>]+> 4800             ldr     r0, \[pc, #0\]  \(0+008 <[^>]+>\)
diff --git a/gas/testsuite/gas/arm/relax_load_align.s b/gas/testsuite/gas/arm/relax_load_align.s
new file mode 100644 (file)
index 0000000..e461291
--- /dev/null
@@ -0,0 +1,12 @@
+@ The relaxation algorithm used to not compensate for alignment statements.
+@ The early termination to avoid infinite looping would make the second load
+@ a wide instruction.
+       .text
+       .thumb
+       .syntax unified
+fn:
+       adds r0, r0, #1000
+       ldr r0, 1f
+       ldr r0, 1f
+.align 2
+1: