This is the mail archive of the binutils-cvs@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]

[binutils-gdb] Optimise PowerPC64 r2 adjusting stubs


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=a7c4979727e13498b8d4d85c72ddf65611c532a9

commit a7c4979727e13498b8d4d85c72ddf65611c532a9
Author: Alan Modra <amodra@gmail.com>
Date:   Mon Aug 31 17:55:14 2015 +0930

    Optimise PowerPC64 r2 adjusting stubs
    
    Sometimes these stubs don't need to change the low 16-bits of r2, so in
    that case omit a useless addi r2,r2,0 insn.  Also, change the get_r2off
    error return from 0 to -1 since 0 is a valid return for ELFv2 -R objects.
    
    	* elf64-ppc.c (get_r2off): Return -1 on error.
    	(ppc_build_one_stub): Adjust for get_r2off change.  Don't emit
    	addi r2,r2,0 on r2off stubs when the low 16-bit delta is zero.
    	(ppc_size_one_stub): Corresponding size changes for r2off stubs.
    	Add condition in test for -R objects.

Diff:
---
 bfd/ChangeLog   |  8 ++++++++
 bfd/elf64-ppc.c | 32 ++++++++++++++++++++------------
 2 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 58d2359..5742aa3 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,13 @@
 2015-08-31  Alan Modra  <amodra@gmail.com>
 
+	* elf64-ppc.c (get_r2off): Return -1 on error.
+	(ppc_build_one_stub): Adjust for get_r2off change.  Don't emit
+	addi r2,r2,0 on r2off stubs when the low 16-bit delta is zero.
+	(ppc_size_one_stub): Corresponding size changes for r2off stubs.
+	Add condition in test for -R objects.
+
+2015-08-31  Alan Modra  <amodra@gmail.com>
+
 	* section.c (section_id): Make file scope.
 	(bfd_get_next_section_id): New function.
 	* elf64-ppc.c (struct map_stub): Remove toc_off field.  Move decl.
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index efa124e..810b227 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -10540,10 +10540,10 @@ get_r2off (struct bfd_link_info *info,
 	  info->callbacks->einfo (_("%P: cannot find opd entry toc for `%T'\n"),
 				  stub_entry->h->elf.root.root.string);
 	  bfd_set_error (bfd_error_bad_value);
-	  return 0;
+	  return (bfd_vma) -1;
 	}
       if (!bfd_get_section_contents (opd->owner, opd, buf, opd_off + 8, 8))
-	return 0;
+	return (bfd_vma) -1;
       r2off = bfd_get_64 (opd->owner, buf);
       r2off -= elf_gp (info->output_bfd);
     }
@@ -10599,23 +10599,28 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
 	{
 	  bfd_vma r2off = get_r2off (info, stub_entry);
 
-	  if (r2off == 0)
+	  if (r2off == (bfd_vma) -1)
 	    {
 	      htab->stub_error = TRUE;
 	      return FALSE;
 	    }
 	  bfd_put_32 (htab->params->stub_bfd, STD_R2_0R1 + STK_TOC (htab), loc);
 	  loc += 4;
-	  size = 12;
+	  size = 8;
 	  if (PPC_HA (r2off) != 0)
 	    {
-	      size = 16;
 	      bfd_put_32 (htab->params->stub_bfd,
 			  ADDIS_R2_R2 | PPC_HA (r2off), loc);
 	      loc += 4;
+	      size += 4;
+	    }
+	  if (PPC_LO (r2off) != 0)
+	    {
+	      bfd_put_32 (htab->params->stub_bfd,
+			  ADDI_R2_R2 | PPC_LO (r2off), loc);
+	      loc += 4;
+	      size += 4;
 	    }
-	  bfd_put_32 (htab->params->stub_bfd, ADDI_R2_R2 | PPC_LO (r2off), loc);
-	  loc += 4;
 	  off -= size - 4;
 	}
       bfd_put_32 (htab->params->stub_bfd, B_DOT | (off & 0x3fffffc), loc);
@@ -10796,7 +10801,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
 	{
 	  bfd_vma r2off = get_r2off (info, stub_entry);
 
-	  if (r2off == 0 && htab->opd_abi)
+	  if (r2off == (bfd_vma) -1)
 	    {
 	      htab->stub_error = TRUE;
 	      return FALSE;
@@ -11062,14 +11067,16 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
       if (stub_entry->stub_type == ppc_stub_long_branch_r2off)
 	{
 	  r2off = get_r2off (info, stub_entry);
-	  if (r2off == 0 && htab->opd_abi)
+	  if (r2off == (bfd_vma) -1)
 	    {
 	      htab->stub_error = TRUE;
 	      return FALSE;
 	    }
-	  size = 12;
+	  size = 8;
 	  if (PPC_HA (r2off) != 0)
-	    size = 16;
+	    size += 4;
+	  if (PPC_LO (r2off) != 0)
+	    size += 4;
 	  off -= size - 4;
 	}
 
@@ -11079,7 +11086,8 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
 	 Do the same for -R objects without function descriptors.  */
       if (off + (1 << 25) >= (bfd_vma) (1 << 26) - local_off
 	  || (stub_entry->stub_type == ppc_stub_long_branch_r2off
-	      && r2off == 0))
+	      && r2off == 0
+	      && htab->sec_info[stub_entry->target_section->id].toc_off == 0))
 	{
 	  struct ppc_branch_hash_entry *br_entry;


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