public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] MIPS/BFD: Convert jalr/jr to jal/j, if possible
@ 2017-06-13  5:43 r
  0 siblings, 0 replies; only message in thread
From: r @ 2017-06-13  5:43 UTC (permalink / raw)
  To: binutils; +Cc: Chao-ying.Fu, Heiher

From: Heiher <r@hev.cc>

2017-06-13  Heiher <r@hev.cc>

	* elfxx-mips.c (JALR_TO_JAL_P): New define to transform JALR to JAL.
	(JR_TO_J_P): New define to transform JR to J.
	It is true for all CPUs.
	Convert "jalr t9" to "jal", if possible.
	Convert "jr t9" to "j", if possible.
	Convert "jalr zero, t9" to "j", if possible.
---
 bfd/ChangeLog    |  9 ++++++
 bfd/elfxx-mips.c | 93 ++++++++++++++++++++++++++++++++++++++++----------------
 2 files changed, 76 insertions(+), 26 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index daea1732bc..10edcb8d6f 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,12 @@
+2017-06-13  Heiher <r@hev.cc>
+
+	* elfxx-mips.c (JALR_TO_JAL_P): New define to transform JALR to JAL.
+	(JR_TO_J_P): New define to transform JR to J.
+	It is true for all CPUs.
+	Convert "jalr t9" to "jal", if possible.
+	Convert "jr t9" to "j", if possible.
+	Convert "jalr zero, t9" to "j", if possible.
+
 2017-06-12  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* elf-bfd.h (elf_backend_data): Add struct bfd_link_info *
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index 830207ad6a..308b8d76ad 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -777,6 +777,16 @@ static bfd *reldyn_sorting_bfd;
    all CPUs.  */
 #define JR_TO_B_P(abfd) 1
 
+/* True if ABFD is for CPUs that are faster if JALR is converted to JAL.
+   This should be safe for all architectures.  We enable this predicate for
+   all CPUs.  */
+#define JALR_TO_JAL_P(abfd) 1
+
+/* True if ABFD is for CPUs that are faster if JR is converted to J.
+   This should be safe for all architectures.  We enable this predicate for
+   all CPUs.  */
+#define JR_TO_J_P(abfd) 1
+
 /* True if ABFD is a PIC object.  */
 #define PIC_OBJECT_P(abfd) \
   ((elf_elfheader (abfd)->e_flags & EF_MIPS_PIC) != 0)
@@ -6459,11 +6469,14 @@ mips_elf_perform_relocation (struct bfd_link_info *info,
 	}
     }
 
-  /* Try converting JAL to BAL and J(AL)R to B(AL), if the target is in
-     range.  */
   if (!bfd_link_relocatable (info)
-      && !cross_mode_jump_p
-      && ((JAL_TO_BAL_P (input_bfd)
+      && !cross_mode_jump_p)
+    {
+      bfd_boolean skip_to_j_p = FALSE;
+
+      /* Try converting JAL to BAL and J(AL)R to B(AL), if the target is in
+         range.  */
+      if ((JAL_TO_BAL_P (input_bfd)
 	   && r_type == R_MIPS_26
 	   && (x >> 26) == 0x3)			/* jal addr */
 	  || (JALR_TO_BAL_P (input_bfd)
@@ -6471,28 +6484,56 @@ mips_elf_perform_relocation (struct bfd_link_info *info,
 	      && x == 0x0320f809)		/* jalr t9 */
 	  || (JR_TO_B_P (input_bfd)
 	      && r_type == R_MIPS_JALR
-	      && (x & ~1) == 0x03200008)))	/* jr t9 / jalr zero, 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)
-	{
-	  if ((x & ~1) == 0x03200008)		/* jr t9 / jalr zero, t9 */
-	    x = 0x10000000 | (((bfd_vma) off >> 2) & 0xffff);   /* b addr */
-	  else
-	    x = 0x04110000 | (((bfd_vma) off >> 2) & 0xffff);   /* bal addr */
-	}
+	      && (x & ~1) == 0x03200008))	/* jr t9 / jalr zero, 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)
+	    {
+	      if ((x & ~1) == 0x03200008)		/* jr t9 / jalr zero, t9 */
+	        x = 0x10000000 | (((bfd_vma) off >> 2) & 0xffff);   /* b addr */
+	      else
+	        x = 0x04110000 | (((bfd_vma) off >> 2) & 0xffff);   /* bal addr */
+	      skip_to_j_p = TRUE;
+	    }
+        }
+
+      /* Try converting J(AL)R to J(AL), if the target is in range. */
+      if (!bfd_link_pic (info)
+	  && !skip_to_j_p
+	  && ((JALR_TO_JAL_P (input_bfd)
+	         && r_type == R_MIPS_JALR
+	         && x == 0x0320f809)		/* jalr t9 */
+	     || (JR_TO_J_P (input_bfd)
+	         && r_type == R_MIPS_JALR
+	         && (x & ~1) == 0x03200008)))	/* jr t9 / jalr zero, t9 */
+        {
+          bfd_vma addr;
+          bfd_vma dest = value;
+
+          addr = (input_section->output_section->vma
+	          + input_section->output_offset
+	          + relocation->r_offset
+	          + 4);
+          if (((addr >> 28) << 28) == ((dest >> 28) << 28))
+	    {
+	      if ((x & ~1) == 0x03200008)		/* jr t9 / jalr zero, t9 */
+	        x = 0x08000000 | ((dest >> 2) & 0x3ffffff);   /* j addr */
+	      else
+	        x = 0x0c000000 | ((dest >> 2) & 0x3ffffff);   /* jal addr */
+	    }
+        }
     }
 
   /* Put the value into the output.  */
-- 
2.13.1

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2017-06-13  5:43 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-13  5:43 [PATCH] MIPS/BFD: Convert jalr/jr to jal/j, if possible r

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).