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] MIPS/BFD: Add microMIPS instruction access helpers


Hi,

 It has struck me it makes little sense to handle all the microMIPS 32-bit 
instruction piecewise throughout where the same access pattern repeats 
throughout.  I have therefore decided to wrap all these places into little 
instruction access helpers, making the code more readable and less error 
prone.  Here's the result.

 Regression-tested successfully, for the mips-linux-gnu and mips-sde-elf 
targets.  OK to apply?

2011-10-25  Maciej W. Rozycki  <macro@codesourcery.com>

	bfd/
	* elfxx-mips.c (LA25_LUI_MICROMIPS_1, LA25_LUI_MICROMIPS_2):
	Remove macros, folding them into...
	(LA25_LUI_MICROMIPS): ... this new macro.
	(LA25_J_MICROMIPS_1, LA25_J_MICROMIPS_2): Likewise into...
	(LA25_J_MICROMIPS): ... this new macro.
	(LA25_ADDIU_MICROMIPS_1, LA25_ADDIU_MICROMIPS_2): Likewise
	into...
	(LA25_ADDIU_MICROMIPS): ... this new macro.
	(bfd_put_micromips_32, bfd_get_micromips_32): New functions.
	(mips_elf_create_la25_stub): Use them.
	(check_br32_dslot, check_br32, check_relocated_bzc): Likewise.
	(_bfd_mips_elf_relax_section): Likewise.


  Maciej

binutils-umips-bfd-get-32.diff
Index: binutils-fsf-trunk-quilt/bfd/elfxx-mips.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/bfd/elfxx-mips.c	2011-10-24 22:15:55.585928160 +0100
+++ binutils-fsf-trunk-quilt/bfd/elfxx-mips.c	2011-10-24 23:03:23.505571286 +0100
@@ -306,12 +306,12 @@ struct mips_elf_la25_stub {
 #define LA25_LUI(VAL) (0x3c190000 | (VAL))	/* lui t9,VAL */
 #define LA25_J(VAL) (0x08000000 | (((VAL) >> 2) & 0x3ffffff)) /* j VAL */
 #define LA25_ADDIU(VAL) (0x27390000 | (VAL))	/* addiu t9,t9,VAL */
-#define LA25_LUI_MICROMIPS_1(VAL) (0x41b9)	/* lui t9,VAL */
-#define LA25_LUI_MICROMIPS_2(VAL) (VAL)
-#define LA25_J_MICROMIPS_1(VAL) (0xd400 | (((VAL) >> 17) & 0x3ff)) /* j VAL */
-#define LA25_J_MICROMIPS_2(VAL) ((VAL) >> 1)
-#define LA25_ADDIU_MICROMIPS_1(VAL) (0x3339)	/* addiu t9,t9,VAL */
-#define LA25_ADDIU_MICROMIPS_2(VAL) (VAL)
+#define LA25_LUI_MICROMIPS(VAL)						\
+  (0x41b90000 | (VAL))				/* lui t9,VAL */
+#define LA25_J_MICROMIPS(VAL)						\
+  (0xd4000000 | (((VAL) >> 1) & 0x3ffffff))	/* j VAL */
+#define LA25_ADDIU_MICROMIPS(VAL)					\
+  (0x33390000 | (VAL))				/* addiu t9,t9,VAL */
 
 /* This structure is passed to mips_elf_sort_hash_table_f when sorting
    the dynamic symbols.  */
@@ -1002,6 +1002,23 @@ static const bfd_vma mips_vxworks_shared
   0x24180000	/* li t8, <pltindex>	*/
 };
 
+/* microMIPS 32-bit opcode helper installer.  */
+
+static void
+bfd_put_micromips_32 (const bfd *abfd, bfd_vma opcode, bfd_byte *ptr)
+{
+  bfd_put_16 (abfd, (opcode >> 16) & 0xffff, ptr);
+  bfd_put_16 (abfd,  opcode        & 0xffff, ptr + 2);
+}
+
+/* microMIPS 32-bit opcode helper retriever.  */
+
+static bfd_vma
+bfd_get_micromips_32 (const bfd *abfd, const bfd_byte *ptr)
+{
+  return (bfd_get_16 (abfd, ptr) << 16) | bfd_get_16 (abfd, ptr + 2);
+}
+
 /* Look up an entry in a MIPS ELF linker hash table.  */
 
 #define mips_elf_link_hash_lookup(table, string, create, copy, follow)	\
@@ -9627,14 +9644,12 @@ mips_elf_create_la25_stub (void **slot, 
       loc += offset;
       if (ELF_ST_IS_MICROMIPS (stub->h->root.other))
 	{
-	  bfd_put_16 (hti->output_bfd, LA25_LUI_MICROMIPS_1 (target_high),
-		      loc);
-	  bfd_put_16 (hti->output_bfd, LA25_LUI_MICROMIPS_2 (target_high),
-		      loc + 2);
-	  bfd_put_16 (hti->output_bfd, LA25_ADDIU_MICROMIPS_1 (target_low),
-		      loc + 4);
-	  bfd_put_16 (hti->output_bfd, LA25_ADDIU_MICROMIPS_2 (target_low),
-		      loc + 6);
+	  bfd_put_micromips_32 (hti->output_bfd,
+				LA25_LUI_MICROMIPS (target_high),
+				loc);
+	  bfd_put_micromips_32 (hti->output_bfd,
+				LA25_ADDIU_MICROMIPS (target_low),
+				loc + 4);
 	}
       else
 	{
@@ -9648,16 +9663,12 @@ mips_elf_create_la25_stub (void **slot, 
       loc += offset;
       if (ELF_ST_IS_MICROMIPS (stub->h->root.other))
 	{
-	  bfd_put_16 (hti->output_bfd, LA25_LUI_MICROMIPS_1 (target_high),
-		      loc);
-	  bfd_put_16 (hti->output_bfd, LA25_LUI_MICROMIPS_2 (target_high),
-		      loc + 2);
-	  bfd_put_16 (hti->output_bfd, LA25_J_MICROMIPS_1 (target), loc + 4);
-	  bfd_put_16 (hti->output_bfd, LA25_J_MICROMIPS_2 (target), loc + 6);
-	  bfd_put_16 (hti->output_bfd, LA25_ADDIU_MICROMIPS_1 (target_low),
-		      loc + 8);
-	  bfd_put_16 (hti->output_bfd, LA25_ADDIU_MICROMIPS_2 (target_low),
-		      loc + 10);
+	  bfd_put_micromips_32 (hti->output_bfd,
+				LA25_LUI_MICROMIPS (target_high), loc);
+	  bfd_put_micromips_32 (hti->output_bfd,
+				LA25_J_MICROMIPS (target), loc + 4);
+	  bfd_put_micromips_32 (hti->output_bfd,
+				LA25_ADDIU_MICROMIPS (target_low), loc + 8);
 	  bfd_put_32 (hti->output_bfd, 0, loc + 12);
 	}
       else
@@ -12198,7 +12209,7 @@ check_br32_dslot (bfd *abfd, bfd_byte *p
   unsigned long opcode;
   int bdsize;
 
-  opcode = (bfd_get_16 (abfd, ptr) << 16) | bfd_get_16 (abfd, ptr + 2);
+  opcode = bfd_get_micromips_32 (abfd, ptr);
   if (find_match (opcode, ds_insns_32_bd32) >= 0)
     /* 32-bit branch/jump with a 32-bit delay slot.  */
     bdsize = 4;
@@ -12243,7 +12254,7 @@ check_br32 (bfd *abfd, bfd_byte *ptr, un
 {
   unsigned long opcode;
 
-  opcode = (bfd_get_16 (abfd, ptr) << 16) | bfd_get_16 (abfd, ptr + 2);
+  opcode = bfd_get_micromips_32 (abfd, ptr);
   if (MATCH (opcode, j_insn_32)
 						/* J  */
       || MATCH (opcode, bc_insn_32)
@@ -12275,9 +12286,7 @@ check_relocated_bzc (bfd *abfd, const bf
   const Elf_Internal_Rela *irel;
   unsigned long opcode;
 
-  opcode   = bfd_get_16 (abfd, ptr);
-  opcode <<= 16;
-  opcode  |= bfd_get_16 (abfd, ptr + 2);
+  opcode = bfd_get_micromips_32 (abfd, ptr);
   if (find_match (opcode, bzc_insns_32) < 0)
     return FALSE;
 
@@ -12435,8 +12444,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, 
       if (irel->r_offset + 4 > sec->size)
 	continue;
 
-      opcode  = bfd_get_16 (abfd, ptr    ) << 16;
-      opcode |= bfd_get_16 (abfd, ptr + 2);
+      opcode = bfd_get_micromips_32 (abfd, ptr);
 
       /* This is the pc-relative distance from the instruction the
          relocation is applied to, to the symbol referred.  */
@@ -12518,8 +12526,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, 
 	      continue;
 	    }
 
-	  nextopc  = bfd_get_16 (abfd, contents + irel[1].r_offset    ) << 16;
-	  nextopc |= bfd_get_16 (abfd, contents + irel[1].r_offset + 2);
+	  nextopc = bfd_get_micromips_32 (abfd, contents + irel[1].r_offset);
 
 	  /* Give up unless the same register is used with both
 	     relocations.  */
@@ -12560,10 +12567,8 @@ _bfd_mips_elf_relax_section (bfd *abfd, 
 	      nextopc = (addiupc_insn.match
 			 | ADDIUPC_REG_FIELD (OP32_TREG (nextopc)));
 
-	      bfd_put_16 (abfd, (nextopc >> 16) & 0xffff,
-			  contents + irel[1].r_offset);
-	      bfd_put_16 (abfd,  nextopc        & 0xffff,
-			  contents + irel[1].r_offset + 2);
+	      bfd_put_micromips_32 (abfd, nextopc,
+				    contents + irel[1].r_offset);
 	    }
 
 	  /* Can't do anything, give up, sigh...  */
@@ -12597,8 +12602,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, 
 		    | BZC32_REG_FIELD (reg)
 		    | (opcode & 0xffff));		/* Addend value.  */
 
-	  bfd_put_16 (abfd, (opcode >> 16) & 0xffff, ptr);
-	  bfd_put_16 (abfd,  opcode        & 0xffff, ptr + 2);
+	  bfd_put_micromips_32 (abfd, opcode, ptr);
 
 	  /* Delete the 16-bit delay slot NOP: two bytes from
 	     irel->offset + 4.  */
@@ -12663,8 +12667,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, 
 	  unsigned long n32opc;
 	  bfd_boolean relaxed = FALSE;
 
-	  n32opc  = bfd_get_16 (abfd, ptr + 4) << 16;
-	  n32opc |= bfd_get_16 (abfd, ptr + 6);
+	  n32opc = bfd_get_micromips_32 (abfd, ptr + 4);
 
 	  if (MATCH (n32opc, nop_insn_32))
 	    {
@@ -12691,10 +12694,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, 
 	    {
 	      /* JAL with 32-bit delay slot that is changed to a JALS
 	         with 16-bit delay slot.  */
-	      bfd_put_16 (abfd, (jal_insn_32_bd16.match >> 16) & 0xffff,
-			  ptr);
-	      bfd_put_16 (abfd,  jal_insn_32_bd16.match        & 0xffff,
-			  ptr + 2);
+	      bfd_put_micromips_32 (abfd, jal_insn_32_bd16.match, ptr);
 
 	      /* Delete 2 bytes from irel->r_offset + 6.  */
 	      delcnt = 2;


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