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]

PATCH: Account for alignment relocs when relaxing mn10300 jump instructions


Hi Guys,

  I am checking in the attached patch to add code to the mn10300's
  linker relaxation code to allow for alignment relocs when deciding
  if 16-bit branch and jump instructions can be relaxed.  The patch
  also adds a linker testcase to check the code.

Cheers
  Nick

bfd/ChangeLog
2007-11-21  Nick Clifton  <nickc@redhat.com>

	* elf-m10300.c (mn10300_elf_relax_section): Allow for alignment
	relocs when computing whether instructions can be relaxed.

ld/testsuite/ChangeLog
2007-11-21  Nick Clifton  <nickc@redhat.com>

	* ld-mn10300/i135409-4.s: New test case.  Check for relaxation to
	a 16-bit jump instruction.
	* ld-mn10300/i135409-4.t: Linker script for the new test.
	* ld-mn10300/i135409-4.d: Expected disassembly of new test.
	* ld-mn10300/mn10300.exp: Run the new test.

Index: bfd/elf-m10300.c
===================================================================
RCS file: /cvs/src/src/bfd/elf-m10300.c,v
retrieving revision 1.91
diff -c -3 -p -r1.91 elf-m10300.c
*** bfd/elf-m10300.c	16 Nov 2007 09:48:05 -0000	1.91
--- bfd/elf-m10300.c	21 Nov 2007 11:58:22 -0000
*************** mn10300_elf_relax_section (bfd *abfd,
*** 2105,2110 ****
--- 2105,2111 ----
    Elf_Internal_Sym *isymbuf = NULL;
    struct elf32_mn10300_link_hash_table *hash_table;
    asection *section = sec;
+   bfd_vma align_gap_adjustment;
  
    /* Assume nothing changes.  */
    *again = FALSE;
*************** mn10300_elf_relax_section (bfd *abfd,
*** 2718,2723 ****
--- 2719,2751 ----
    if (internal_relocs == NULL)
      goto error_return;
  
+   /* Scan for worst case alignment gap changes.  Note that this logic
+      is not ideal; what we should do is run this scan for every
+      opcode/address range and adjust accordingly, but that's
+      expensive.  Worst case is that for an alignment of N bytes, we
+      move by 2*N-N-1 bytes, assuming we have aligns of 1, 2, 4, 8, etc
+      all before it.  Plus, this still doesn't cover cross-section
+      jumps with section alignment.  */
+   irelend = internal_relocs + sec->reloc_count;
+   align_gap_adjustment = 0;
+   for (irel = internal_relocs; irel < irelend; irel++)
+     {
+       if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_ALIGN)
+ 	{
+ 	  bfd_vma adj = 1 << irel->r_addend;
+ 	  bfd_vma aend = irel->r_offset;
+ 
+ 	  aend = BFD_ALIGN (aend, 1 << irel->r_addend);
+ 	  adj = 2*adj - adj - 1;
+ 
+ 	  /* Record the biggest adjustmnet.  Skip any alignment at the
+ 	     end of our section.  */
+ 	  if (align_gap_adjustment < adj
+ 	      && aend < sec->output_section->vma + sec->output_offset + sec->size)
+ 	    align_gap_adjustment = adj;
+ 	}
+     }
+ 
    /* Walk through them looking for relaxing opportunities.  */
    irelend = internal_relocs + sec->reloc_count;
    for (irel = internal_relocs; irel < irelend; irel++)
*************** mn10300_elf_relax_section (bfd *abfd,
*** 2933,2939 ****
  	  /* See if the value will fit in 16 bits, note the high value is
  	     0x7fff + 2 as the target will be two bytes closer if we are
  	     able to relax.  */
! 	  if ((long) value < 0x8001 && (long) value > -0x8000)
  	    {
  	      unsigned char code;
  
--- 2961,2970 ----
  	  /* See if the value will fit in 16 bits, note the high value is
  	     0x7fff + 2 as the target will be two bytes closer if we are
  	     able to relax.  */
! 	  /* Account for jumps across alignment boundaries using
! 	     align_gap_adjustment.  */
! 	  if (value < 0x8001 - align_gap_adjustment
! 	      && ((bfd_signed_vma) value > -0x8000 + (bfd_signed_vma) align_gap_adjustment))
  	    {
  	      unsigned char code;
  
Index: ld/testsuite/ld-mn10300/mn10300.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-mn10300/mn10300.exp,v
retrieving revision 1.4
diff -c -3 -p -r1.4 mn10300.exp
*** ld/testsuite/ld-mn10300/mn10300.exp	16 Nov 2007 09:48:04 -0000	1.4
--- ld/testsuite/ld-mn10300/mn10300.exp	21 Nov 2007 12:00:03 -0000
*************** set mn10300_tests {
*** 79,84 ****
--- 79,92 ----
  	{ {objdump -d i135409-3.d} }
  	"i135409-3.x"
      }
+     {
+ 	"adjusting a 16 bit branch"
+ 	"-Ti135409-4.t -relax"
+ 	""
+ 	{ "i135409-4.s" }
+ 	{ {objdump -d i135409-4.d} }
+ 	"i135409-4.x"
+     }
  }
  
  run_ld_link_tests $mn10300_tests
*** /dev/null	2007-11-21 09:54:40.711827624 +0000
--- ld/testsuite/ld-mn10300/i135409-4.s	2007-11-21 10:24:20.000000000 +0000
***************
*** 0 ****
--- 1,8 ----
+ 	.text
+         .global _start
+ _start:
+         jmp     L001
+ 
+         .section        .text1
+ L001:
+         nop
*** /dev/null	2007-11-21 09:54:40.711827624 +0000
--- ld/testsuite/ld-mn10300/i135409-4.t	2007-11-21 10:24:20.000000000 +0000
***************
*** 0 ****
--- 1,23 ----
+ SECTIONS
+ {
+         . = 0x0;
+         .text :
+         {
+                 *(.text)
+         }
+ 
+         . = 0x700;
+         .text1 :
+         {
+                 *(.text1)
+         }
+         . = 0x8100;
+         .bss :
+         {
+                 *(.bss)
+         }
+         .data :
+         {
+                 *(.data)
+         }
+ }
*** /dev/null	2007-11-21 09:54:40.711827624 +0000
--- ld/testsuite/ld-mn10300/i135409-4.d	2007-11-21 10:24:20.000000000 +0000
***************
*** 0 ****
--- 1,7 ----
+ 
+ tmpdir/i135409-4.x:     file format elf32-.*
+ 
+ Disassembly of section .text:
+ 
+ 0+0 <_start>:
+    0:[ 	]+cc 00 07[ 	]+jmp[ 	]+700 \<L001\>

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]