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: [PATCH] MIPS: microMIPS ASE support


Continuing this thread from March:

Richard Sandiford <rdsandiford@googlemail.com> writes:
> "Maciej W. Rozycki" <macro@codesourcery.com> writes:
>>  As it has turned out in the course of sorting out some earlier concerns 
>> the microMIPS change needs a couple of updates.  For your reference I'm 
>> sending the current version of the original patch as it had to be 
>> regenerated.  On top of this I'm sending the following updates:
>
> Everything except binutils-gas-umips-swap.diff is OK (as one commit,
> like you say), with the changes below.

It seemed a shame to get to the point of an approved version and not
actually commit it.  I've now updated and regenerated the patch series,
made the changes from this approval, and applied a few other things I
noticed.  I've attached the three patches separately.

Tested on 

  mips64-elf mips64el-unknown-kfreebsd-gnu mips64-linux-gnu
  mips64octeon-linux-gnu mips64-unknown-kfreebsd-gnu
  mipsel-unknown-kfreebsd-gnu mipsisa32el-linux-gnu mipsisa64-elf
  mips-linux-gnu mips-unknown-kfreebsd-gnu mips-wrs-vxworks

Applied to trunk along with:

  http://sourceware.org/ml/binutils/2010-12/msg00399.html
  http://sourceware.org/ml/binutils/2011-02/msg00318.html

Maciej: I regenerated and updated each of your patches separately,
so if you'd like a copy of those individual patches, I can send them
privately.

I went on to say:

> If you don't agree with some of the requested changes, let me know.

and I gather from an off-list discussion a couple of months ago that
there were indeed some things that you didn't like.  But I think it'd
be easier to deal with them as follow-ups.  Please feel free to send
patches against trunk.  Or, if you tell me what it is you disagree with,
I can try to fix it myself.

I'm sure there are things that we've both missed, but again,
we can deal with them as follow-ups.

Last, but not least, thanks for all your hard work on this series.
Thanks especially for perservering in the face of all my annoying
niggles. :-)

Richard


The regenerated version of your patch series (excluding umips-swap,
as per above):

Attachment: combined.diff.bz2
Description: Binary data

The changes I asked for:

Index: bfd/elfxx-mips.c
===================================================================
--- bfd/elfxx-mips.c	2011-07-24 15:06:40.000000000 +0100
+++ bfd/elfxx-mips.c	2011-07-24 15:07:48.000000000 +0100
@@ -5162,7 +5162,7 @@ mips_elf_calculate_relocation (bfd *abfd
       target_is_16_bit_code_p = ELF_ST_IS_MIPS16 (h->root.other);
       /* If the output section is the PLT section,
          then the target is not microMIPS.  */
-      target_is_micromips_code_p = ((htab->splt != sec)
+      target_is_micromips_code_p = (htab->splt != sec
 				    && ELF_ST_IS_MICROMIPS (h->root.other));
     }
 
@@ -11910,18 +11910,9 @@ mips_elf_relax_delete_bytes (bfd *abfd,
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   isym = (Elf_Internal_Sym *) symtab_hdr->contents;
   for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
-    {
-      bfd_vma value;
-
-      if (isym->st_shndx != sec_shndx)
-	continue;
-
-      value = isym->st_value;
-      if (ELF_ST_IS_MICROMIPS (isym->st_other))
-	value &= MINUS_TWO;
-      if (value > addr)
-	isym->st_value -= count;
-    }
+    if (isym->st_shndx == sec_shndx
+	&& isym->st_value > addr)
+      isym->st_value -= count;
 
   /* Now adjust the global symbols defined in this section.  */
   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
@@ -11932,18 +11923,19 @@ mips_elf_relax_delete_bytes (bfd *abfd,
   for (; sym_hashes < end_hashes; sym_hashes++)
     {
       struct elf_link_hash_entry *sym_hash = *sym_hashes;
-      bfd_vma value;
-
-      if ((sym_hash->root.type != bfd_link_hash_defined
-	   && sym_hash->root.type != bfd_link_hash_defweak)
-	  || sym_hash->root.u.def.section != sec)
-	continue;
 
-      value = sym_hash->root.u.def.value;
-      if (ELF_ST_IS_MICROMIPS (sym_hash->other))
-	value &= MINUS_TWO;
-      if (value > addr)
-	sym_hash->root.u.def.value -= count;
+      if ((sym_hash->root.type == bfd_link_hash_defined
+	   || sym_hash->root.type == bfd_link_hash_defweak)
+	  && sym_hash->root.u.def.section == sec)
+	{
+	  bfd_vma value;
+
+	  value = sym_hash->root.u.def.value;
+	  if (ELF_ST_IS_MICROMIPS (sym_hash->other))
+	    value &= MINUS_TWO;
+	  if (value > addr)
+	    sym_hash->root.u.def.value -= count;
+	}
     }
 
   return TRUE;
@@ -12279,6 +12271,27 @@ #define IS_BITSIZE(val, N)						\
   (((((val) & ((1ULL << (N)) - 1)) ^ (1ULL << ((N) - 1)))		\
     - (1ULL << ((N) - 1))) == (val))
 
+/* See if relocations [INTERNAL_RELOCS, IRELEND) confirm that there
+   is a 4-byte branch at offset OFFSET.  */
+
+static bfd_boolean
+check_4byte_branch (Elf_Internal_Rela *internal_relocs,
+		    Elf_Internal_Rela *irelend, bfd_vma offset)
+{
+  Elf_Internal_Rela *irel;
+  unsigned long r_type;
+
+  for (irel = internal_relocs; irel < irelend; irel++)
+    if (irel->r_offset == offset)
+      {
+	r_type = ELF32_R_TYPE (irel->r_info);
+	if (r_type == R_MICROMIPS_26_S1
+	    || r_type == R_MICROMIPS_PC16_S1
+	    || r_type == R_MICROMIPS_JALR)
+	  return TRUE;
+      }
+  return FALSE;
+}
 
 bfd_boolean
 _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
@@ -12439,12 +12452,8 @@ _bfd_mips_elf_relax_section (bfd *abfd,
          out the offset).  */
       if (r_type == R_MICROMIPS_HI16 && MATCH (opcode, lui_insn))
 	{
-	  Elf_Internal_Rela *ibrrel;
-	  bfd_boolean brc = FALSE;
-	  unsigned int br_r_type;
 	  unsigned long nextopc;
 	  unsigned long reg;
-	  int bdsize = -1;
 	  bfd_vma offset;
 
 	  /* Give up if the previous reloc was a HI16 against this symbol
@@ -12466,58 +12475,20 @@ _bfd_mips_elf_relax_section (bfd *abfd,
 	      && ELF32_R_SYM (irel[2].r_info) == r_symndx)
 	    continue;
 
-	  /* See if there is a jump or a branch reloc preceding the
-	     LUI instruction immediately.  */
-	  for (ibrrel = internal_relocs; ibrrel < irelend; ibrrel++)
-	    {
-	      offset = irel->r_offset - ibrrel->r_offset;
-	      if (offset != 2 && offset != 4)
-		continue;
-
-	      br_r_type = ELF32_R_TYPE (ibrrel->r_info);
-	      if (offset == 2
-		  && (br_r_type == R_MICROMIPS_PC7_S1
-		      || br_r_type == R_MICROMIPS_PC10_S1
-		      || br_r_type == R_MICROMIPS_JALR))
-		break;
-	      if (offset == 4
-		  && (br_r_type == R_MICROMIPS_26_S1
-		      || br_r_type == R_MICROMIPS_PC16_S1
-		      || br_r_type == R_MICROMIPS_JALR))
-		{
-		  bfd_byte *ptr = contents + ibrrel->r_offset;
-		  unsigned long bropc;
-
-		  bropc   = bfd_get_16 (abfd, ptr);
-		  bropc <<= 16;
-		  bropc  |= bfd_get_16 (abfd, ptr + 2);
-		  /* Compact branches are OK.  */
-		  if (find_match (opcode, bzc_insns_32) >= 0)
-		    brc = TRUE;
-		  break;
-		}
-	    }
-	  /* A delay slot was found, give up, sigh...  */
-	  if (!brc && ibrrel < irelend)
+	  /* See if the LUI instruction *might* be in a branch delay slot.  */
+	  if (irel->r_offset >= 2
+	      && check_br16_dslot (abfd, contents + irel->r_offset - 2) > 0
+	      && !(irel->r_offset >= 4
+		   /* If the instruction is actually a 4-byte branch,
+		      the value of check_br16_dslot doesn't matter.
+		      We should use check_br32_dslot to check whether
+		      the branch has a delay slot.  */
+		   && check_4byte_branch (internal_relocs, irelend,
+					  irel->r_offset - 4)))
+	    continue;
+	  if (irel->r_offset >= 4
+	      && check_br32_dslot (abfd, contents + irel->r_offset - 4) > 0)
 	    continue;
-
-	  /* Otherwise see if the LUI instruction *might* be in a
-	     branch delay slot.  */
-	  if (!brc)
-	    {
-	      bfd_byte *ptr = contents + irel->r_offset;
-
-	      if (irel->r_offset >= 2)
-		bdsize = check_br16_dslot (abfd, ptr - 2);
-	      /* A branch possibly found, give up, sigh...  */
-	      if (bdsize > 0)
-		continue;
-	      if (irel->r_offset >= 4)
-		bdsize = check_br32_dslot (abfd, ptr - 4);
-	      /* A branch possibly found, give up, sigh...  */
-	      if (bdsize > 0)
-		continue;
-	    }
 
 	  reg = OP32_SREG (opcode);
 
@@ -12545,7 +12516,8 @@ _bfd_mips_elf_relax_section (bfd *abfd,
 	  nextopc  = bfd_get_16 (abfd, contents + irel[1].r_offset    ) << 16;
 	  nextopc |= bfd_get_16 (abfd, contents + irel[1].r_offset + 2);
 
-	  /* Give up unless the same register used with both relocations.  */
+	  /* Give up unless the same register is used with both
+	     relocations.  */
 	  if (OP32_SREG (nextopc) != reg)
 	    continue;
 
Index: gas/config/tc-mips.c
===================================================================
--- gas/config/tc-mips.c	2011-07-24 15:07:45.000000000 +0100
+++ gas/config/tc-mips.c	2011-07-24 15:07:48.000000000 +0100
@@ -2150,7 +2150,7 @@ reglist_lookup (char **s, unsigned int t
   unsigned int regmask;
   unsigned int regno;
   char *s_reset = *s;
-  char *s_comma = *s;
+  char *s_end_of_list = *s;
 
   while (reg_lookup (s, types, &regno))
     {
@@ -2175,14 +2175,14 @@ reglist_lookup (char **s, unsigned int t
       regmask ^= (1 << regno) - 1;
       reglist |= regmask;
 
-      s_comma = *s;
+      s_end_of_list = *s;
       if (**s != ',')
 	break;
       (*s)++;
     }
 
   if (ok)
-    *s = s_comma;
+    *s = s_end_of_list;
   else
     *s = s_reset;
   if (reglistp)
@@ -2663,24 +2663,41 @@ micromips_reloc_p (bfd_reloc_code_real_t
 static inline bfd_boolean
 got16_reloc_p (bfd_reloc_code_real_type reloc)
 {
-  return (reloc == BFD_RELOC_MIPS_GOT16 || reloc == BFD_RELOC_MIPS16_GOT16
+  return (reloc == BFD_RELOC_MIPS_GOT16
+	  || reloc == BFD_RELOC_MIPS16_GOT16
 	  || reloc == BFD_RELOC_MICROMIPS_GOT16);
 }
 
 static inline bfd_boolean
 hi16_reloc_p (bfd_reloc_code_real_type reloc)
 {
-  return (reloc == BFD_RELOC_HI16_S || reloc == BFD_RELOC_MIPS16_HI16_S
+  return (reloc == BFD_RELOC_HI16_S
+	  || reloc == BFD_RELOC_MIPS16_HI16_S
 	  || reloc == BFD_RELOC_MICROMIPS_HI16_S);
 }
 
 static inline bfd_boolean
 lo16_reloc_p (bfd_reloc_code_real_type reloc)
 {
-  return (reloc == BFD_RELOC_LO16 || reloc == BFD_RELOC_MIPS16_LO16
+  return (reloc == BFD_RELOC_LO16
+	  || reloc == BFD_RELOC_MIPS16_LO16
 	  || reloc == BFD_RELOC_MICROMIPS_LO16);
 }
 
+static inline bfd_boolean
+jmp_reloc_p (bfd_reloc_code_real_type reloc)
+{
+  return (reloc == BFD_RELOC_MIPS_JMP
+	  || reloc == BFD_RELOC_MICROMIPS_JMP);
+}
+
+static inline bfd_boolean
+jalr_reloc_p (bfd_reloc_code_real_type reloc)
+{
+  return (reloc == BFD_RELOC_MIPS_JALR
+	  || reloc == BFD_RELOC_MICROMIPS_JALR);
+}
+
 /* Return true if the given relocation might need a matching %lo().
    This is only "might" because SVR4 R_MIPS_GOT16 relocations only
    need a matching %lo() when applied to local symbols.  */
@@ -3761,7 +3778,7 @@ can_swap_branch_p (struct mips_cl_insn *
     return FALSE;
 
   /* If the previous instruction has an incorrect size for a fixed
-     branch delay slot in the microMIPS mode, we cannot swap.  */
+     branch delay slot in microMIPS mode, we cannot swap.  */
   if (mips_opts.micromips)
     {
       pinfo2 = ip->insn_mo->pinfo;
@@ -4030,11 +4047,9 @@ append_insn (struct mips_cl_insn *ip, ex
 
 	case BFD_RELOC_MIPS_JMP:
 	  {
-	    bfd_reloc_code_real_type reloc;
 	    int shift;
 
-	    reloc = micromips_map_reloc (*reloc_type);
-	    shift = reloc == BFD_RELOC_MICROMIPS_JMP ? 1 : 2;
+	    shift = mips_opts.micromips ? 1 : 2;
 	    if ((address_expr->X_add_number & ((1 << shift) - 1)) != 0)
 	      as_bad (_("jump to misaligned address (0x%lx)"),
 		      (unsigned long) address_expr->X_add_number);
@@ -4057,11 +4072,9 @@ append_insn (struct mips_cl_insn *ip, ex
 
 	case BFD_RELOC_16_PCREL_S2:
 	  {
-	    bfd_reloc_code_real_type reloc;
 	    int shift;
 
-	    reloc = micromips_map_reloc (*reloc_type);
-	    shift = reloc == BFD_RELOC_MICROMIPS_16_PCREL_S1 ? 1 : 2;
+	    shift = mips_opts.micromips ? 1 : 2;
 	    if ((address_expr->X_add_number & ((1 << shift) - 1)) != 0)
 	      as_bad (_("branch to misaligned address (0x%lx)"),
 		      (unsigned long) address_expr->X_add_number);
@@ -4313,32 +4326,32 @@ append_insn (struct mips_cl_insn *ip, ex
 
   if (!ip->complete_p && *reloc_type < BFD_RELOC_UNUSED)
     {
-      bfd_reloc_code_real_type reloc;
+      bfd_reloc_code_real_type final_type[3];
       reloc_howto_type *howto;
       int i;
 
+      /* Perform any necessary conversion to microMIPS relocations
+	 and find out how many relocations there actually are.  */
+      for (i = 0; i < 3 && reloc_type[i] != BFD_RELOC_UNUSED; i++)
+	final_type[i] = micromips_map_reloc (reloc_type[i]);
+
       /* In a compound relocation, it is the final (outermost)
 	 operator that determines the relocated field.  */
-      for (i = 1; i < 3; i++)
-	if (reloc_type[i] == BFD_RELOC_UNUSED)
-	  break;
-
-      reloc = micromips_map_reloc (reloc_type[i - 1]);
-      howto = bfd_reloc_type_lookup (stdoutput, reloc);
+      howto = bfd_reloc_type_lookup (stdoutput, final_type[i - 1]);
       if (howto == NULL)
 	{
 	  /* To reproduce this failure try assembling gas/testsuites/
 	     gas/mips/mips16-intermix.s with a mips-ecoff targeted
 	     assembler.  */
-	  as_bad (_("Unsupported MIPS relocation number %d"), reloc);
+	  as_bad (_("Unsupported MIPS relocation number %d"),
+		  final_type[i - 1]);
 	  howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
 	}
 	  
       ip->fixp[0] = fix_new_exp (ip->frag, ip->where,
 				 bfd_get_reloc_size (howto),
 				 address_expr,
-				 howto->pc_relative,
-				 micromips_map_reloc (reloc_type[0]));
+				 howto->pc_relative, final_type[0]);
 
       /* Tag symbols that have a R_MIPS16_26 relocation against them.  */
       if (reloc_type[0] == BFD_RELOC_MIPS16_JMP
@@ -4352,7 +4365,6 @@ append_insn (struct mips_cl_insn *ip, ex
 	  && (reloc_type[0] == BFD_RELOC_16
 	      || reloc_type[0] == BFD_RELOC_32
 	      || reloc_type[0] == BFD_RELOC_MIPS_JMP
-	      || reloc_type[0] == BFD_RELOC_MICROMIPS_JMP
 	      || reloc_type[0] == BFD_RELOC_GPREL16
 	      || reloc_type[0] == BFD_RELOC_MIPS_LITERAL
 	      || reloc_type[0] == BFD_RELOC_GPREL32
@@ -4401,8 +4413,8 @@ append_insn (struct mips_cl_insn *ip, ex
 	if (reloc_type[i] != BFD_RELOC_UNUSED)
 	  {
 	    ip->fixp[i] = fix_new (ip->frag, ip->where,
-				   ip->fixp[0]->fx_size, NULL, 0, FALSE,
-				   micromips_map_reloc (reloc_type[i]));
+				   ip->fixp[0]->fx_size, NULL, 0,
+				   FALSE, final_type[i]);
 
 	    /* Use fx_tcbit to mark compound relocs.  */
 	    ip->fixp[0]->fx_tcbit = 1;
@@ -17323,7 +17335,7 @@ md_estimate_size_before_relax (fragS *fr
 	length = relaxed_micromips_16bit_branch_length (fragp, segtype, FALSE);
       if (length == 4 && RELAX_MICROMIPS_RELAX32 (fragp->fr_subtype))
 	length = relaxed_micromips_32bit_branch_length (fragp, segtype, FALSE);
-      fragp->fr_var= length;
+      fragp->fr_var = length;
 
       return length;
     }
@@ -17385,9 +17397,7 @@ mips_fix_adjustable (fixS *fixp)
      the in-place relocatable field if recalculated against the start
      address of the symbol's containing section.  */
   if (HAVE_IN_PLACE_ADDENDS
-      && (fixp->fx_pcrel
-	  || fixp->fx_r_type == BFD_RELOC_MIPS_JALR
-	  || fixp->fx_r_type == BFD_RELOC_MICROMIPS_JALR))
+      && (fixp->fx_pcrel || jalr_reloc_p (fixp->fx_r_type)))
     return 0;
 
 #ifdef OBJ_ELF
@@ -17439,8 +17449,7 @@ mips_fix_adjustable (fixS *fixp)
 	  || *symbol_get_tc (fixp->fx_addsy)
 	  || (HAVE_IN_PLACE_ADDENDS
 	      && ELF_ST_IS_MICROMIPS (S_GET_OTHER (fixp->fx_addsy))
-	      && (fixp->fx_r_type == BFD_RELOC_MIPS_JMP
-		  || fixp->fx_r_type == BFD_RELOC_MICROMIPS_JMP))))
+	      && jmp_reloc_p (fixp->fx_r_type))))
     return 0;
 #endif
 
@@ -17781,12 +17790,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNU
       bfd_boolean compact = RELAX_MICROMIPS_COMPACT (fragp->fr_subtype);
       bfd_boolean al = RELAX_MICROMIPS_LINK (fragp->fr_subtype);
       int type = RELAX_MICROMIPS_TYPE (fragp->fr_subtype);
-
-      /* Default to the long-delay-slot versions.  */
-      unsigned long jal = 0xf4000000;			/* jal  */
-      unsigned long jalr = 0x45c0;			/* jalr  */
-
-      unsigned long jr = compact ? 0x45a0 : 0x4580;	/* jr/c  */
+      unsigned long jal, jalr, jr;
 
       unsigned long insn;
       expressionS exp;
@@ -17798,7 +17802,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNU
 
       fragp->fr_fix += fragp->fr_var;
 
-      /* Handle 16-bit branches that fit or forced to fit.  */
+      /* Handle 16-bit branches that fit or are forced to fit.  */
       if (type != 0 && !RELAX_MICROMIPS_TOOFAR16 (fragp->fr_subtype))
 	{
 	  /* We generate a fixup instead of applying it right now,
@@ -17906,6 +17910,12 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNU
 	  jal = 0x74000000;				/* jals  */
 	  jalr = 0x45e0;				/* jalrs  */
 	}
+      else
+	{
+	  jal = 0xf4000000;				/* jal  */
+	  jalr = 0x45c0;				/* jalr  */
+	}
+      jr = compact ? 0x45a0 : 0x4580;			/* jr/c  */
 
       if (!RELAX_MICROMIPS_UNCOND (fragp->fr_subtype))
 	{
Index: include/opcode/mips.h
===================================================================
--- include/opcode/mips.h	2011-07-24 15:06:40.000000000 +0100
+++ include/opcode/mips.h	2011-07-24 15:07:48.000000000 +0100
@@ -1330,7 +1330,7 @@ #define MIPS16_INSN_COND_BRANCH		    0x0
 extern const int bfd_mips16_num_opcodes;
 
 /* These are the bitmasks and shift counts used for the different
-   fields in the instruction formats.  Other than OP, no masks are
+   fields in the instruction formats.  Other than MAJOR, no masks are
    provided for the fixed portions of an instruction, since they are
    not needed.  */
 
The other stuff I noticed while testing:

Index: gas/config/tc-mips.c
===================================================================
--- gas/config/tc-mips.c	2011-07-24 15:07:48.000000000 +0100
+++ gas/config/tc-mips.c	2011-07-24 15:07:51.000000000 +0100
@@ -203,9 +203,6 @@ static bfd_boolean mips_in_shared = TRUE
    pseudo-op.  We use a struct so that .set push and .set pop are more
    reliable.  */
 
-/* Whether or not we emit branch likely macros.  */
-static bfd_boolean emit_branch_likely_macro = FALSE;
-
 struct mips_set_options
 {
   /* MIPS ISA (Instruction Set Architecture) level.  This is set to -1
@@ -644,7 +641,7 @@ static struct hash_control *op_hash = NU
 /* The opcode hash table we use for the mips16.  */
 static struct hash_control *mips16_op_hash = NULL;
 
-/* The opcode hash table we use for the micromips.  */
+/* The opcode hash table we use for the microMIPS ASE.  */
 static struct hash_control *micromips_op_hash = NULL;
 
 /* This array holds the chars that always start a comment.  If the
@@ -745,7 +742,7 @@ #define MAX_NOPS 4
 #define NOP_INSN (mips_opts.mips16 ? &mips16_nop_insn \
 		  : (mips_opts.micromips ? &micromips_nop16_insn : &nop_insn))
 
-/* The number of bytes NOP takes for the current mode.  */
+/* The size of NOP_INSN in bytes.  */
 #define NOP_INSN_SIZE (HAVE_CODE_COMPRESSION ? 2 : 4)
 
 /* If this is set, it points to a frag holding nop instructions which
@@ -1251,6 +1248,9 @@ #define MIPS16_EXTRACT_OPERAND(FIELD, IN
 		MIPS16OP_MASK_##FIELD, \
 		MIPS16OP_SH_##FIELD)
 
+/* Whether or not we are emitting a branch-likely macro.  */
+static bfd_boolean emit_branch_likely_macro = FALSE;
+
 /* Global variables used when generating relaxable macros.  See the
    comment above RELAX_ENCODE for more details about how relaxation
    is used.  */
@@ -1292,12 +1292,14 @@ #define MIPS16_EXTRACT_OPERAND(FIELD, IN
      is the length of the first instruction of the second alternative.
      For non-relaxable macros, both elements give the length of the first
      instruction in bytes.
+
      Set to zero if we haven't yet seen the first instruction.  */
   unsigned int first_insn_sizes[2];
 
   /* For relaxable macros, insns[0] is the number of instructions for the
      first alternative and insns[1] is the number of instructions for the
      second alternative.
+
      For non-relaxable macros, both elements give the number of
      instructions for the macro.  */
   unsigned int insns[2];
@@ -1542,10 +1544,11 @@ mips_clear_insn_labels (void)
     }
 }
 
+/* Mark instruction labels in MIPS16/microMIPS mode.  */
+
 static inline void
 mips_mark_labels (void)
 {
-  /* Mark instruction labels in MIPS16/microMIPS mode.  */
   if (HAVE_CODE_COMPRESSION)
     mips_compressed_mark_labels ();
 }
@@ -2071,7 +2074,6 @@ static const struct regname reg_names_n3
   {0, 0}
 };
 
-
 /* Check if S points at a valid register specifier according to TYPES.
    If so, then return 1, advance S to consume the specifier and store
    the register's number in REGNOP, otherwise return 0.  */
@@ -3973,7 +3975,8 @@ micromips_map_reloc (bfd_reloc_code_real
 
 /* Output an instruction.  IP is the instruction information.
    ADDRESS_EXPR is an operand of the instruction to be used with
-   RELOC_TYPE.  */
+   RELOC_TYPE.  EXPANSIONP is true if the instruction is part of
+   a macro expansion.  */
 
 static void
 append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
@@ -4209,12 +4212,12 @@ append_insn (struct mips_cl_insn *ip, ex
 	        16-bit/32-bit instructions.  */
 	     && !forced_insn_length);
 
-  if (address_expr
+  if (!HAVE_CODE_COMPRESSION
+      && address_expr
       && relax32
       && *reloc_type == BFD_RELOC_16_PCREL_S2
       && (pinfo & INSN_UNCOND_BRANCH_DELAY || pinfo & INSN_COND_BRANCH_DELAY
-	  || pinfo & INSN_COND_BRANCH_LIKELY)
-      && !HAVE_CODE_COMPRESSION)
+	  || pinfo & INSN_COND_BRANCH_LIKELY))
     {
       relaxed_branch = TRUE;
       add_relaxed_insn (ip, (relaxed_branch_length
@@ -4232,14 +4235,14 @@ append_insn (struct mips_cl_insn *ip, ex
 			address_expr->X_add_number);
       *reloc_type = BFD_RELOC_UNUSED;
     }
-  else if (address_expr
+  else if (mips_opts.micromips
+	   && address_expr
 	   && ((relax32 && *reloc_type == BFD_RELOC_16_PCREL_S2)
 	       || *reloc_type > BFD_RELOC_UNUSED)
 	   && (pinfo & INSN_UNCOND_BRANCH_DELAY
 	       || pinfo & INSN_COND_BRANCH_DELAY
 	       || (pinfo2 & ~INSN2_ALIAS) == INSN2_UNCOND_BRANCH
-	       || pinfo2 & INSN2_COND_BRANCH)
-	   && mips_opts.micromips)
+	       || pinfo2 & INSN2_COND_BRANCH))
     {
       bfd_boolean relax16 = *reloc_type > BFD_RELOC_UNUSED;
       int type = relax16 ? *reloc_type - BFD_RELOC_UNUSED : 0;
@@ -4348,6 +4351,7 @@ append_insn (struct mips_cl_insn *ip, ex
 	  howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
 	}
 	  
+      howto = bfd_reloc_type_lookup (stdoutput, final_type[0]);
       ip->fixp[0] = fix_new_exp (ip->frag, ip->where,
 				 bfd_get_reloc_size (howto),
 				 address_expr,
@@ -4503,12 +4507,10 @@ append_insn (struct mips_cl_insn *ip, ex
 	  && (history[0].insn_mo->pinfo & MIPS16_INSN_UNCOND_BRANCH)))
     mips_no_prev_insn ();
 
-  /* For branch likely macro, we need to emit a label at the end.  */
+  /* We need to emit a label at the end of branch-likely macros.  */
   if (emit_branch_likely_macro)
     {
       emit_branch_likely_macro = FALSE;
-
-      /* We need to generate a label.  */
       micromips_add_label ();
     }
 
@@ -4723,8 +4725,7 @@ macro_end (void)
       relax_substateT s;
       const char *msg;
 
-      s = (subtype
-	   & (RELAX_SECOND_LONGER | RELAX_NOMACRO | RELAX_DELAY_SLOT));
+      s = subtype & (RELAX_SECOND_LONGER | RELAX_NOMACRO | RELAX_DELAY_SLOT);
       msg = macro_warning (s);
       if (msg != NULL)
 	as_warn ("%s", msg);
@@ -5259,7 +5260,7 @@ macro_build_jalr (expressionS *ep, int c
   static const bfd_reloc_code_real_type jalr_relocs[2]
     = { BFD_RELOC_MIPS_JALR, BFD_RELOC_MICROMIPS_JALR };
   bfd_reloc_code_real_type jalr_reloc = jalr_relocs[mips_opts.micromips];
-  const char *jalr = mips_opts.noreorder && !cprestore ? "jalr" : "jalrs";
+  const char *jalr;
   char *f = NULL;
 
   if (MIPS_JALR_HINT_P (ep))
@@ -5269,10 +5270,14 @@ macro_build_jalr (expressionS *ep, int c
     }
   if (!mips_opts.micromips)
     macro_build (NULL, "jalr", "d,s", RA, PIC_CALL_REG);
-  else if (MIPS_JALR_HINT_P (ep))
-    macro_build (NULL, jalr, "t,s", RA, PIC_CALL_REG);
   else
-    macro_build (NULL, jalr, "mj", PIC_CALL_REG);
+    {
+      jalr = mips_opts.noreorder && !cprestore ? "jalr" : "jalrs";
+      if (MIPS_JALR_HINT_P (ep))
+	macro_build (NULL, jalr, "t,s", RA, PIC_CALL_REG);
+      else
+	macro_build (NULL, jalr, "mj", PIC_CALL_REG);
+    }
   if (MIPS_JALR_HINT_P (ep))
     fix_new_exp (frag_now, f - frag_now->fr_literal, 4, ep, FALSE, jalr_reloc);
 }
@@ -6031,23 +6036,28 @@ add_got_offset_hilo (int dest, expressio
 /* Emit a sequence of instructions to emulate a branch likely operation.
    BR is an ordinary branch corresponding to one to be emulated.  BRNEG
    is its complementing branch with the original condition negated.
-   CALL is set if the original branch specified the link operation.  EP,
-   FMT, SREG and TREG specify the usual macro_build() parameters.
+   CALL is set if the original branch specified the link operation.
+   EP, FMT, SREG and TREG specify the usual macro_build() parameters.
 
    Code like this is produced in the noreorder mode:
+
 	BRNEG	<args>, 1f
 	 nop
 	b	<sym>
 	 delay slot (executed only if branch taken)
     1:
-   or:
+
+   or, if CALL is set:
+
 	BRNEG	<args>, 1f
 	 nop
 	bal	<sym>
 	 delay slot (executed only if branch taken)
     1:
-   if CALL is set.  In the reorder mode the delay slot would be filled
-   with a nop anyway, so code produced is simply:
+
+   In the reorder mode the delay slot would be filled with a nop anyway,
+   so code produced is simply:
+
 	BR	<args>, <sym>
 	 nop
 
Index: gas/testsuite/gas/mips/dli.s
===================================================================
--- gas/testsuite/gas/mips/dli.s	2011-07-24 15:01:44.000000000 +0100
+++ gas/testsuite/gas/mips/dli.s	2011-07-24 15:07:51.000000000 +0100
@@ -62,6 +62,4 @@ foo:
 	dli	$4,0x003ffc03ffffc000
 
 # Round to a 16 byte boundary, for ease in testing multiple targets.
-	nop
-	nop
-	nop
+	.p2align 4
Index: gas/testsuite/gas/mips/micromips-trap.d
===================================================================
--- gas/testsuite/gas/mips/micromips-trap.d	2011-07-24 15:05:46.000000000 +0100
+++ gas/testsuite/gas/mips/micromips-trap.d	2011-07-24 15:07:52.000000000 +0100
@@ -1,6 +1,6 @@
 #objdump: -dr --show-raw-insn
 #name: microMIPS for MIPS32r2 (w/traps)
-#as: -mips32r2 -32 -trap -mfp64
+#as: -mips32r2 -32 -trap -mfp64 -EB
 #stderr: micromips.l
 #source: micromips.s
 
Index: gas/testsuite/gas/mips/micromips.d
===================================================================
--- gas/testsuite/gas/mips/micromips.d	2011-07-24 15:05:46.000000000 +0100
+++ gas/testsuite/gas/mips/micromips.d	2011-07-24 15:07:52.000000000 +0100
@@ -1,6 +1,6 @@
 #objdump: -dr --show-raw-insn
 #name: microMIPS for MIPS32r2
-#as: -mips32r2 -32 -mfp64
+#as: -mips32r2 -32 -mfp64 -EB
 #stderr: micromips.l
 #source: micromips.s
 
Index: gas/testsuite/gas/mips/micromips@dli.d
===================================================================
--- gas/testsuite/gas/mips/micromips@dli.d	2011-07-24 15:05:46.000000000 +0100
+++ gas/testsuite/gas/mips/micromips@dli.d	2011-07-24 15:07:51.000000000 +0100
@@ -113,7 +113,4 @@ Disassembly of section \.text:
 [0-9a-f]+ <[^>]*> 5084 ffff 	ori	a0,a0,0xffff
 [0-9a-f]+ <[^>]*> 5884 8000 	dsll	a0,a0,0x10
 [0-9a-f]+ <[^>]*> 5084 c000 	ori	a0,a0,0xc000
-[0-9a-f]+ <[^>]*> 0c00      	nop
-[0-9a-f]+ <[^>]*> 0c00      	nop
-[0-9a-f]+ <[^>]*> 0c00      	nop
-[0-9a-f]+ <[^>]*> 0c00      	nop
+	\.\.\.
Index: gas/testsuite/gas/mips/micromips@elfel-rel2.d
===================================================================
--- /dev/null	2011-07-24 10:34:17.994719526 +0100
+++ gas/testsuite/gas/mips/micromips@elfel-rel2.d	2011-07-24 15:07:52.000000000 +0100
@@ -0,0 +1,28 @@
+#objdump: -sr -j .text
+#name: MIPS ELF reloc 2
+#source: elf-rel2.s
+#as: -mabi=o64
+
+# Test the GPREL and LITERAL generation (microMIPS).
+# FIXME: really this should check that the contents of .sdata, .lit4,
+# and .lit8 are correct too.
+
+.*: +file format .*mips.*
+
+RELOCATION RECORDS FOR \[\.text\]:
+OFFSET [ ]+ TYPE              VALUE 
+0+0000000 R_MICROMIPS_LITERAL  \.lit8
+0+0000004 R_MICROMIPS_LITERAL  \.lit8
+0+0000008 R_MICROMIPS_LITERAL  \.lit8
+0+000000c R_MICROMIPS_LITERAL  \.lit4
+0+0000010 R_MICROMIPS_LITERAL  \.lit4
+0+0000014 R_MICROMIPS_LITERAL  \.lit4
+0+0000018 R_MICROMIPS_GPREL16  \.sdata
+0+000001c R_MICROMIPS_GPREL16  \.sdata
+0+0000020 R_MICROMIPS_GPREL16  \.sdata
+
+
+Contents of section \.text:
+ 0000 5cbc0000 5cbc0800 5cbc1000 5c9c0000  .*
+ 0010 5c9c0400 5c9c0800 5cfc0000 5cfc0400  .*
+ 0020 5cfc0800 .*
Index: gas/testsuite/gas/mips/micromips@mips4-branch-likely.d
===================================================================
--- gas/testsuite/gas/mips/micromips@mips4-branch-likely.d	2011-07-24 15:05:46.000000000 +0100
+++ gas/testsuite/gas/mips/micromips@mips4-branch-likely.d	2011-07-24 15:07:51.000000000 +0100
@@ -1,6 +1,7 @@
 #objdump: -dr --prefix-addresses --show-raw-insn
 #name: MIPS mips4 branch-likely instructions
 #source: mips4-branch-likely.s
+#as: -32
 
 # Test mips4 branch-likely instructions (microMIPS).
 
Index: gas/testsuite/gas/mips/micromips@mips4-fp.d
===================================================================
--- gas/testsuite/gas/mips/micromips@mips4-fp.d	2011-07-24 15:05:46.000000000 +0100
+++ gas/testsuite/gas/mips/micromips@mips4-fp.d	2011-07-24 15:07:51.000000000 +0100
@@ -1,6 +1,7 @@
 #objdump: -dr --prefix-addresses --show-raw-insn
 #name: MIPS mips4 fp
 #source: mips4-fp.s
+#as: -32
 
 # Test mips4 fp instructions (microMIPS).
 
Index: gas/testsuite/gas/mips/mips.exp
===================================================================
--- gas/testsuite/gas/mips/mips.exp	2011-07-24 15:06:40.000000000 +0100
+++ gas/testsuite/gas/mips/mips.exp	2011-07-24 15:07:51.000000000 +0100
@@ -489,21 +489,31 @@ if { [istarget mips*-*-vxworks*] } {
     run_dump_test "eret-1"
     run_dump_test "eret-2"
     run_dump_test "eret-3"
-    run_dump_test_arches "24k-branch-delay-1" [mips_arch_list_matching mips1]
+    run_dump_test_arches "24k-branch-delay-1" \
+	[mips_arch_list_matching mips1 !micromips]
     run_dump_test_arches "24k-triple-stores-1" \
-				    [mips_arch_list_matching mips32r2 !octeon]
-    run_dump_test_arches "24k-triple-stores-2" [mips_arch_list_matching mips2]
-    run_dump_test_arches "24k-triple-stores-3" [mips_arch_list_matching mips3]
-    run_dump_test_arches "24k-triple-stores-4" [mips_arch_list_matching mips2]
-    run_dump_test_arches "24k-triple-stores-5" [mips_arch_list_matching mips1]
-    run_dump_test_arches "24k-triple-stores-6" [mips_arch_list_matching mips2]
-    run_dump_test_arches "24k-triple-stores-7" [mips_arch_list_matching mips2]
-    run_dump_test_arches "24k-triple-stores-8" [mips_arch_list_matching mips1]
-    run_dump_test_arches "24k-triple-stores-9" [mips_arch_list_matching mips1]
-    run_dump_test_arches "24k-triple-stores-10" [mips_arch_list_matching mips1]
+	[mips_arch_list_matching mips32r2 !octeon !micromips]
+    run_dump_test_arches "24k-triple-stores-2" \
+	[mips_arch_list_matching mips2 !micromips]
+    run_dump_test_arches "24k-triple-stores-3" \
+	[mips_arch_list_matching mips3 !micromips]
+    run_dump_test_arches "24k-triple-stores-4" \
+	[mips_arch_list_matching mips2 !micromips]
+    run_dump_test_arches "24k-triple-stores-5" \
+	[mips_arch_list_matching mips1 !micromips]
+    run_dump_test_arches "24k-triple-stores-6" \
+	[mips_arch_list_matching mips2 !micromips]
+    run_dump_test_arches "24k-triple-stores-7" \
+	[mips_arch_list_matching mips2 !micromips]
+    run_dump_test_arches "24k-triple-stores-8" \
+	[mips_arch_list_matching mips1 !micromips]
+    run_dump_test_arches "24k-triple-stores-9" \
+	[mips_arch_list_matching mips1 !micromips]
+    run_dump_test_arches "24k-triple-stores-10" \
+	[mips_arch_list_matching mips1 !micromips]
     if $elf {
 	run_dump_test_arches "24k-triple-stores-11" \
-	    [mips_arch_list_matching mips1]
+	    [mips_arch_list_matching mips1 !micromips]
     }
 
     if $elf {
Index: gas/testsuite/gas/mips/mipsel16-e.d
===================================================================
--- gas/testsuite/gas/mips/mipsel16-e.d	2011-07-24 15:01:44.000000000 +0100
+++ gas/testsuite/gas/mips/mipsel16-e.d	2011-07-24 15:07:52.000000000 +0100
@@ -1,4 +1,4 @@
-#objdump: -rst -mips16
+#objdump: -rst --special-syms -mips16
 #name: MIPS16 reloc
 #as: -32 -mips16
 #source: mips16-e.s
Index: gas/testsuite/gas/mips/tmipsel16-e.d
===================================================================
--- gas/testsuite/gas/mips/tmipsel16-e.d	2011-07-24 15:01:44.000000000 +0100
+++ gas/testsuite/gas/mips/tmipsel16-e.d	2011-07-24 15:07:52.000000000 +0100
@@ -1,4 +1,4 @@
-#objdump: -rst -mips16
+#objdump: -rst --special-syms -mips16
 #name: MIPS16 reloc
 #as: -32 -mips16
 #source: mips16-e.s
Index: ld/testsuite/ld-mips-elf/mips-elf.exp
===================================================================
--- ld/testsuite/ld-mips-elf/mips-elf.exp	2011-07-24 15:05:46.000000000 +0100
+++ ld/testsuite/ld-mips-elf/mips-elf.exp	2011-07-24 15:07:51.000000000 +0100
@@ -129,19 +129,19 @@ run_dump_test "jalx-1"
 if { $linux_gnu } {
     run_ld_link_tests [list \
 	[list "Dummy shared library for JALX test 2" \
-	      "-shared -nostdlib" \
+	      "-shared -nostdlib -melf32btsmip" \
 	      "-G0 -EB -mmicromips -no-mdebug -mabi=32 -march=mips32r2 -KPIC" \
 	      { jalx-2-printf.s } \
 	      {} \
 	      "libjalx-2.so"] \
 	[list "Dummy external function for JALX test 2" \
-	      "-r" \
+	      "-r -melf32btsmip" \
 	      "-G0 -EB -no-mdebug -mabi=32 -march=mips32r2 -mno-shared -call_nonpic" \
 	      { jalx-2-ex.s } \
 	      {} \
 	      "jalx-2-ex.o.r"] \
 	[list "MIPS JALX test 2" \
-	      "-nostdlib -T jalx-2.ld tmpdir/libjalx-2.so tmpdir/jalx-2-ex.o.r" \
+	      "-nostdlib -T jalx-2.ld tmpdir/libjalx-2.so tmpdir/jalx-2-ex.o.r -melf32btsmip" \
 	      "-G0 -EB -mmicromips -no-mdebug -mabi=32 -march=mips32r2 -mno-shared -call_nonpic" \
 	      { jalx-2-main.s } \
 	      { { objdump -d jalx-2.dd } } \

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