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]

RE: MIPS PLT entry


> > 
> >  ... it's trivial to implement it flexibly, so that both MIPS 
> > I support is 
> > retained and newer platforms benefit from a faster sequence, 
> > and I plan to 
> > do so unless Chao-Ying beats me, ;) so I see no point in doing it 
> > otherwise.
> 
Hi Maciej,

  I didn't see your patch, so I made a patch.  Do you think
this patch does what you plan to do?  Thanks a lot!

Regards,
Chao-ying

2009-07-15  Chao-ying Fu  <fu@mips.com>

	* elfxx-mips.c (mips_exec_fast_plt_entry): New table.
	(_bfd_mips_elf_size_dynamic_sections): For MIPS1, the last PLT
	entry needs a nop in the branch delay slot.
	(_bfd_mips_elf_finish_dynamic_symbol): For non-MIPS1 CPUs,
	we can use the fast PLT entry that don't need the 5th instruction.

Index: src/bfd/elfxx-mips.c
===================================================================
--- src.orig/bfd/elfxx-mips.c	2009-05-21 11:59:36.000000000 -0700
+++ src/bfd/elfxx-mips.c	2009-07-15 15:55:52.366101000 -0700
@@ -923,6 +923,14 @@ static const bfd_vma mips_exec_plt_entry
   0x03200008	/* jr $25					*/
 };
 
+/* This plt entry is for non-MIPS1 CPUs that have load interlocking.  */
+static const bfd_vma mips_exec_fast_plt_entry[] = {
+  0x3c0f0000,	/* lui $15, %hi(.got.plt entry)			*/
+  0x01f90000,	/* l[wd] $25, %lo(.got.plt entry)($15)		*/
+  0x03200008,	/* jr $25					*/
+  0x25f80000	/* addiu $24, $15, %lo(.got.plt entry)		*/
+};
+
 /* The format of the first PLT entry in a VxWorks executable.  */
 static const bfd_vma mips_vxworks_exec_plt0_entry[] = {
   0x3c190000,	/* lui t9, %hi(_GLOBAL_OFFSET_TABLE_)		*/
@@ -8630,10 +8638,12 @@ _bfd_mips_elf_size_dynamic_sections (bfd
 	s->size += mips_elf_hash_table (info)->compact_rel_size;
       else if (s == htab->splt)
 	{
-	  /* If the last PLT entry has a branch delay slot, allocate
+	  /* For MIPS1, if the last PLT entry has a branch delay slot, allocate
 	     room for an extra nop to fill the delay slot.  */
-	  if (!htab->is_vxworks && s->size > 0)
-	    s->size += 4;
+	  if (((elf_elfheader (output_bfd)->e_flags & EF_MIPS_ARCH)
+	       == E_MIPS_ARCH_1)
+	      && !htab->is_vxworks && s->size > 0)
+	      s->size += 4;
 	}
       else if (! CONST_STRNEQ (name, ".init")
 	       && s != htab->sgot
@@ -9352,11 +9362,26 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd
       load = MIPS_ELF_LOAD_WORD (output_bfd);
 
       /* Fill in the PLT entry itself.  */
-      plt_entry = mips_exec_plt_entry;
+      if ((elf_elfheader (output_bfd)->e_flags & EF_MIPS_ARCH)
+	  == E_MIPS_ARCH_1)
+	plt_entry = mips_exec_plt_entry;
+      else
+	/* We can use the fast PLT entry for non-MIPS1 CPUs.  */
+	plt_entry = mips_exec_fast_plt_entry;
       bfd_put_32 (output_bfd, plt_entry[0] | got_address_high, loc);
       bfd_put_32 (output_bfd, plt_entry[1] | got_address_low | load, loc + 4);
-      bfd_put_32 (output_bfd, plt_entry[2] | got_address_low, loc + 8);
-      bfd_put_32 (output_bfd, plt_entry[3], loc + 12);
+
+      if ((elf_elfheader (output_bfd)->e_flags & EF_MIPS_ARCH)
+	  == E_MIPS_ARCH_1)
+	{
+	  bfd_put_32 (output_bfd, plt_entry[2] | got_address_low, loc + 8);
+	  bfd_put_32 (output_bfd, plt_entry[3], loc + 12);
+	}
+      else
+	{
+	  bfd_put_32 (output_bfd, plt_entry[2], loc + 8);
+	  bfd_put_32 (output_bfd, plt_entry[3] | got_address_low, loc + 12);
+	}
 
       /* Emit an R_MIPS_JUMP_SLOT relocation against the .got.plt entry.  */
       mips_elf_output_dynamic_relocation (output_bfd, htab->srelplt,


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