This is the mail archive of the binutils@sources.redhat.com 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]

On the RM9000 convert jal to bal if in range


Now the point of RM9000 identification.  The RM9000 has branch
prediction hardware which can predict the destination of the bal
instruction.  However, the branch prediction hardware does not work
for jal.  Therefore, bal is slightly more efficient than jal.  But, of
course, the range of bal (signed 18 offset) is quite limited compared
to the range of jal.

This patch will convert a jal instruction to a bal instruction if
possible when linking a file which was compiled for the RM9000.  I am
about to commit this patch.  I will follow it up with a test case.

Ian


2004-12-09  Ian Lance Taylor  <ian@wasabisystems.com>

	* elfxx-mips.c (mips_elf_calculate_relocation): For R_MIPS_JALR,
	return a real value, unless it is a PLT symbol.
	(mips_elf_perform_relocation): On the RM9000, turn a jal into a
	bal if possible.


Index: elfxx-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-mips.c,v
retrieving revision 1.115
diff -u -r1.115 elfxx-mips.c
--- elfxx-mips.c	9 Dec 2004 06:08:45 -0000	1.115
+++ elfxx-mips.c	9 Dec 2004 07:07:52 -0000
@@ -3523,12 +3523,16 @@
       value &= howto->dst_mask;
       break;
 
-    case R_MIPS_PJUMP:
     case R_MIPS_JALR:
-      /* Both of these may be ignored.  R_MIPS_JALR is an optimization
-	 hint; we could improve performance by honoring that hint.  */
-      return bfd_reloc_continue;
+      /* This relocation is only a hint.  In some cases, we optimize
+	 it into a bal instruction.  But we don't try to optimize
+	 branches to the PLT; that will wind up wasting time.  */
+      if (h != NULL && h->root.plt.offset != (bfd_vma) -1)
+	return bfd_reloc_continue;
+      value = symbol + addend;
+      break;
 
+    case R_MIPS_PJUMP:
     case R_MIPS_GNU_VTINHERIT:
     case R_MIPS_GNU_VTENTRY:
       /* We don't do anything with these at present.  */
@@ -3730,6 +3734,33 @@
       x = (x & ~(0x3f << 26)) | (jalx_opcode << 26);
     }
 
+  /* On the RM9000, bal is faster than jal, because bal uses branch
+     prediction hardware.  If we are linking for the RM9000, and we
+     see jal, and bal fits, use it instead.  Note that this
+     transformation should be safe for all architectures.  */
+  if (bfd_get_mach (input_bfd) == bfd_mach_mips9000
+      && !info->relocatable
+      && !require_jalx
+      && ((r_type == R_MIPS_26 && (x >> 26) == 0x3)	    /* jal addr */
+	  || (r_type == R_MIPS_JALR && x == 0x0320f809)))   /* jalr t9 */
+    {
+      bfd_vma addr;
+      bfd_vma dest;
+      bfd_signed_vma off;
+
+      addr = (input_section->output_section->vma
+	      + input_section->output_offset
+	      + relocation->r_offset
+	      + 4);
+      if (r_type == R_MIPS_26)
+	dest = (value << 2) | ((addr >> 28) << 28);
+      else
+	dest = value;
+      off = dest - addr;
+      if (off <= 0x1ffff && off >= -0x20000)
+	x = 0x04110000 | (((bfd_vma) off >> 2) & 0xffff);   /* bal addr */
+    }
+
   /* Swap the high- and low-order 16 bits on little-endian systems
      when doing a MIPS16 relocation.  */
   if ((r_type == R_MIPS16_GPREL || r_type == R_MIPS16_26)


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