This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Improve Thumb-2 relaxation algorithm.


The Thumb-2 assembly relaxation code contains logic to terminate relaxation if 
it looks like conflicting alignment requirements may cause an infinite loop.

However the code to calculate offsets during relaxation does not compensate 
for alignment directives, which leads to false positives if previous 
relaxations changes moved the target symbol.

The patch below borrows code from the mips assembler to help maintain proper 
alignment during relaxation.  The old behaviour isn't wrong per se, just 
generated unnecessarily large code.

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

Paul

2007-08-09  Paul Brook  <paul@codesourcery.com>

	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.

Index: gas/testsuite/gas/arm/relax_load_align.d
===================================================================
--- gas/testsuite/gas/arm/relax_load_align.d	(revision 0)
+++ gas/testsuite/gas/arm/relax_load_align.d	(revision 0)
@@ -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 <[^>]+>\)
Index: gas/testsuite/gas/arm/relax_load_align.s
===================================================================
--- gas/testsuite/gas/arm/relax_load_align.s	(revision 0)
+++ gas/testsuite/gas/arm/relax_load_align.s	(revision 0)
@@ -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:
Index: gas/config/tc-arm.c
===================================================================
--- gas/config/tc-arm.c	(revision 178502)
+++ gas/config/tc-arm.c	(working copy)
@@ -16771,7 +16771,31 @@ relaxed_symbol_addr(fragS *fragp, long s
 
   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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]