[PATCH] MIPS: microMIPS and MCU ASE instruction set support

Maciej W. Rozycki macro@codesourcery.com
Tue Jun 1 14:21:00 GMT 2010


Hi Richard,

> Big patch, so this review is only for the gas and ld/testsuite bits.

 Thanks for the review, especially as I know it must have taken a lot of 
effort.  I hope we'll be able to sort out all issues gradually.

 I'm placing notes throughout and I'll be asking people for explanations 
where applicable.  Chao-ying, would you please look into the few pieces of 
code below I am a bit uncertain about?  Catherine, there's one question 
for you at the end as well.

> Generally looks good.  It would have been better to submit the
> ACE, m14kc and microMIPS support as three separate changes though.
> Please can you do that for the follow-up?

 I have done it now; the next version will comprise microMIPS ASE changes 
only (the MCU ASE adds to both the MIPS ISA and the microMIPS ASE, so it 
should be applied on top of the microMIPS change).

 Stricly speaking some changes, while related, can be split off too (e.g. 
some MIPS16 or testsuite changes), so I'll look into separating them too 
-- perhaps that'll make the thing rolling sooner.

> From a usability perspective, it's a shame that:
> 
> 	.set	micromips
> 	.ent	foo
> foo:
> 	b	1f
> 	nop
> 	.end	foo
> 	.ent	bar
> bar:
> 1:	nop
> 	.end	bar
> 
> disassembles as:
> 
> 00000000 <foo>:
>    0:   cfff            b       0 <foo>
>                         0: R_MICROMIPS_PC10_S1  .L11
>    2:   0c00            nop
>    4:   0c00            nop
> 
> 00000006 <bar>:
>    6:   0c00            nop
> 
> leaving the poor user with no idea what .L11 is.

 Indeed.  This is a general limitation of `objdump' it would seem.  This 
is no different to what you get with:

$ cat b.s
	.globl	baz
	.ent	foo
foo:
	b	baz
	nop
	.end	foo
	.ent	bar
baz:
bar:
1:	nop
	.end	bar
$ mips-sde-elf-objdump -dr b.o

b.o:     file format elf32-tradbigmips


Disassembly of section .text:

00000000 <foo>:
   0:	1000ffff 	b	0 <foo>
			0: R_MIPS_PC16	baz
   4:	00000000 	nop
   8:	00000000 	nop

0000000c <bar>:
   c:	00000000 	nop

I'd just recommend peeking at the symbol table (back to the first 
program):

$ mips-sde-elf-objdump -t b.o

b.o:     file format elf32-tradbigmips

SYMBOL TABLE:
00000000 l    d  .text	00000000 .text
00000000 l    d  .data	00000000 .data
00000000 l    d  .bss	00000000 .bss
00000000 l    d  .reginfo	00000000 .reginfo
00000000 l    d  .pdr	00000000 .pdr
00000000 l     F .text	00000006 0x80 foo
00000006 l     F .text	00000002 0x80 bar
00000006 l       .text	00000000 0x80 .L11

Any other ideas, anyone?

> The following:
> 
> 	.set	micromips
> 	.ent	foo
> foo:
> 	ld	$10,0x1000($11)
> 	.end	foo
> 
> generates an assertion failure:
> 
> Assertion failure in micromips_macro_build at gas/config/tc-mips.c line 19466.
> Please report this bug.
> 
> on mipsisa64-elf with "-mips1 -mabi=32".

 I can't reproduce it, sorry:

$ cat ld.s
	.set	micromips
	.ent	foo
foo:
	ld	$10,0x1000($11)
	.end	foo
$ mipsisa64-elf-as -mips1 -mabi=32 -o ld.o ld.s
$ mipsisa64-elf-objdump -d ld.o

ld.o:     file format elf32-bigmips


Disassembly of section .text:

00000000 <foo>:
   0:	fd4b 1000 	lw	t2,4096(t3)
   4:	fd6b 1004 	lw	t3,4100(t3)

The assertion you're referring to is this piece of code from 
micromips_macro_build():

	case 'i':
	case 'j':
	case 'o':
	  macro_read_relocs (&args, r);
	  gas_assert (*r == BFD_RELOC_MICROMIPS_GPREL16
		  || *r == BFD_RELOC_MICROMIPS_LITERAL
		  || *r == BFD_RELOC_MICROMIPS_HIGHER
		  || *r == BFD_RELOC_MICROMIPS_HI16_S
		  || *r == BFD_RELOC_MICROMIPS_LO16
		  || *r == BFD_RELOC_MICROMIPS_GOT16
		  || *r == BFD_RELOC_MICROMIPS_CALL16
		  || *r == BFD_RELOC_MICROMIPS_GOT_DISP
		  || *r == BFD_RELOC_MICROMIPS_GOT_PAGE
		  || *r == BFD_RELOC_MICROMIPS_GOT_OFST
		  || *r == BFD_RELOC_MICROMIPS_GOT_LO16
		  || *r == BFD_RELOC_MICROMIPS_CALL_LO16);
	  continue;

(indentation is wrong after s/assert/gas_assert/ it would seem, I have 
fixed it up; this has to be done in upstream HEAD in a couple of places 
too).

 Can you debug it and see what the relocation type is that's causing it?  
I wonder if that might be related to the varargs issue you referring to 
below and depend on the host architecture, hmm...

> > gas/
> > 2010-05-18  Chao-ying Fu  <fu@mips.com>
> >             Maciej W. Rozycki  <macro@codesourcery.com>
> >             Daniel Jacobowitz  <dan@codesourcery.com>
> >
> > 	* config/tc-mips.h (mips_segment_info): Add one bit for
> > 	microMIPS.
> > 	* config/tc-mips.c
> 
> How about having something like:
> 
>   #define OOD_TEXT_LABELS (mips_opts.mips16 || mips_opts.micromips)
> 
> ?

 It sounds reasonable to me, except that condition is used in some other 
contexts as well.  I have made it HAVE_CODE_COMPRESSION thus and took the 
opportunity to optimise code around mips16_micromips_mark_labels() too.  
Finally I have renamed the function to mips_compressed_mark_labels() for 
as the other sounds too complicated to me.

> > 	(A_BFD_RELOC_HI16_S, A_BFD_RELOC_HI16, A_BFD_RELOC_LO16): New
> > 	relocation wrapper macros.
> > 	(A_BFD_RELOC_GPREL16): Likewise.
> > 	(A_BFD_RELOC_MIPS_GOT16, A_BFD_RELOC_MIPS_GOT_HI16): Likewise.
> > 	(A_BFD_RELOC_MIPS_GOT_LO16, A_BFD_RELOC_MIPS_HIGHEST): Likewise.
> > 	(A_BFD_RELOC_MIPS_HIGHER, A_BFD_RELOC_MIPS_GOT_DISP): Likewise.
> > 	(A_BFD_RELOC_MIPS_GOT_PAGE, A_BFD_RELOC_MIPS_GOT_OFST): Likewise.
> > 	(A_BFD_RELOC_MIPS_SUB, A_BFD_RELOC_MIPS_JALR): Likewise.
> 
> Did you consider doing the translation from non-microMIPS to
> microMIPS in the macro_* functions, rather than in their callers?
> I fear it'll be too easy to accidentally forget to use A_BFD_* in future.

 Agreed, I didn't like the new macros from the very beginning.  Chao-ying 
-- any thoughts?

> > 	(mips_macro_warning): Add delay_slot_16bit_p, delay_slot_32bit_p,
> > 	and num_insns.
> > 	(micromips_16, micromips_32): New variables.
> > 	(is_micromips_16bit_p, is_micromips_32bit_p): New functions.
> > 	(insn_length): Return the length of microMIPS instructions.
> > 	(mips_record_mips16_mode): Rename to...
> > 	(mips_record_mips16_micromips_mode): ... this.  Handle microMIPS.
> > 	(install_insn): Handle microMIPS.
> > 	(is_opcode_valid): Likewise.
> > 	(md_begin): Likewise.
> 
> +	      if (micromips_nop16_insn.insn_mo == NULL
> +		  && strcmp (name, "nop") == 0)
> +		{
> +		  create_insn (&micromips_nop16_insn, micromips_opcodes + i);
> +		  micromips_nop16_insn.fixed_p = 1;
> +		}
> +	      else if (micromips_nop32_insn.insn_mo == NULL
> +		  && strcmp (name, "nop") == 0)
> +		{
> +		  create_insn (&micromips_nop32_insn, micromips_opcodes + i);
> +		  micromips_nop32_insn.fixed_p = 1;
> +		}
> 
> You seem to rely on the 16-bit nop being first.  Wouldn't it be more
> robust to call is_micromips_16bit_p and is_micromips_32bit_p?

 Agreed.  I rewrote this piece entirely.

> > 	(MICROMIPS_TARGET, MICROMIPS_TARGET_LABEL): New macros.
> > 	(micromips_add_number_label): New function.
> 
> +/* For microMIPS macros, we need to generate a local number label
> +   as the target of branches.  */
> +#define MICROMIPS_TARGET	"2147483647f"
> +#define MICROMIPS_TARGET_LABEL	2147483647
> +
> +static void
> +micromips_add_number_label (void)
> +{
> +  symbolS *s;
> +  fb_label_instance_inc (MICROMIPS_TARGET_LABEL);
> +  s = colon (fb_label_name (MICROMIPS_TARGET_LABEL, 0));
> +  S_SET_OTHER (s, ELF_ST_SET_MICROMIPS (S_GET_OTHER (s)));
> +}
> +
> 
> Ugh, this is a bit hackish.  There's nothing stopping a user using
> 2147483647f themselves.

 A local symbol with some magic characters would be better indeed.  I'll 
see if any existing approach could be reused.

> > 	(append_insn): Handle microMIPS.
> 
> +  if (mips_opts.micromips)
> +    {
> +      if ((prev_pinfo2 & INSN2_BRANCH_DELAY_16BIT)
> +	  && !is_micromips_16bit_p (ip->insn_mo))
> +	as_warn (_("instruction with wrong size in a branch delay slot that"
> +		   " requires a 16-bit instruction"));
> +      if ((prev_pinfo2 & INSN2_BRANCH_DELAY_32BIT)
> +	  && !is_micromips_32bit_p (ip->insn_mo))
> +	as_warn (_("instruction with wrong size in a branch delay slot that"
> +		   " requires a 32-bit instruction"));
> +    }
> +  
> 
> Although not enforced as often as it should be, GAS convention is for
> errors to start with a capital letter.

 I'll be fixing these up as I come across them.  If to be effective, then 
upstream HEAD should be fixed up or otherwise people have no way not to 
get confused.  I didn't know of this rule for one.  That shouldn't be a 
lot effort, should it?

 Some have to stay for now actually, because .l testsuite patterns are 
commonly shared between standard MIPS and microMIPS tests, and should be 
fixed separately.

> +      if (pinfo & INSN_COP)
> +	{
> +	  /* We don't keep enough information to sort these cases out.
> +	     The itbl support does keep this information however, although
> +	     we currently don't support itbl fprmats as part of the cop
> +	     instruction.  May want to add this support in the future.  */
> +	}
> 
> Assert?

 Well, that's no different to the standard MIPS variant.

> +	      /* For microMIPS, disable reordering.  */
> +	      || (mips_opts.micromips)
> 
> Redundant (...)

 Fixed.

> -	      if (mips_relax.sequence)
> -		mips_relax.sizes[mips_relax.sequence - 1] += 4;
> +	      /* MicroMIPS nop is 2 bytes.  */
> +  	      if (mips_relax.sequence)
> +		mips_relax.sizes[mips_relax.sequence - 1] +=
> +		  mips_opts.micromips ? micromips_nop_size : 4;
> 
> Confusing comment: the microMIPS nop may be 2 or 4 bytes.
> Better to say nothing IMO.

 Fixed.

> > 	(start_noreorder, end_noreorder): Likewise.
> 
> +	      frag_grow ((mips_opts.mips16 | mips_opts.micromips) ? nops * 2
> +								  : nops * 4);
> 
> How about a NOP_INSN_SIZE macro?  (Or similar.)

 Added.  And found the third place where needed while making the 
replacement.

> > 	(macro_start, macro_warning, macro_end): Likewise.
> 
> +  else if ((subtype & RELAX_DELAY_SLOT_SIZE_ERROR_FIRST)
> +	   || (subtype & RELAX_DELAY_SLOT_SIZE_ERROR_SECOND))
> +    return _("Macro instruction of the wrong size in a branch delay slot"
> +	     " that requires a 16-bit or 32-bit instruction");
> 
> Did you consider adding a flag to distinguish the 32-bit and 16-bit cases?
> It'd be nice to be consistent with the non-relaxed error if possible.

 Chao-ying?  I've had a look actually and flag may not be necessary to get 
the functionality.  I'm fixing this up elsewhere already.

> +  /* If either one implementation contains one instruction, we need to check
> +     the delay slot size requirement.  */
> 
> "If either implementation"

 Fixed.

> +  /* If either one implementation contains one instruction, we need to check
> +     the delay slot size requirement.  */
> +  if (mips_macro_warning.num_insns[0] == 1
> +      || mips_macro_warning.num_insns[1] == 1)
> +    {
> +      if (mips_macro_warning.num_insns[0] == mips_macro_warning.num_insns[1]
> +	  && mips_macro_warning.sizes[0] == mips_macro_warning.sizes[1])
> +	{
> +	  /* Either the macro has a single implementation or both
> +	     implementations are 1 instruction with the same size.
> +	     Emit the warning now.  */
> +	  if ((mips_macro_warning.delay_slot_16bit_p
> +	       && mips_macro_warning.sizes[0] != 2)
> +	      || (mips_macro_warning.delay_slot_32bit_p
> +		  && mips_macro_warning.sizes[0] != 4))
> +	    {
> +	      const char *msg;
> +	      msg = macro_warning (RELAX_DELAY_SLOT_SIZE_ERROR_FIRST);
> +	      if (msg != 0)
> +		as_warn (msg);
> +	    }
> +	}
> +      else
> +	{
> +	  relax_substateT subtype;
> +
> +	  /* Set up the relaxation warning flags.  */
> +	  subtype = 0;
> +	  if (mips_macro_warning.delay_slot_16bit_p)
> +	    {
> +	      if (mips_macro_warning.num_insns[0] != 1
> +		  || mips_macro_warning.sizes[0] != 2)
> +		subtype |= RELAX_DELAY_SLOT_SIZE_ERROR_FIRST;
> +	      if (mips_macro_warning.num_insns[1] != 1
> +		  || mips_macro_warning.sizes[1] != 2)
> +		subtype |= RELAX_DELAY_SLOT_SIZE_ERROR_SECOND;
> +	    }
> +	  if (mips_macro_warning.delay_slot_32bit_p)
> +	    {
> +	      if (mips_macro_warning.num_insns[0] != 1
> +		  || mips_macro_warning.sizes[0] != 4)
> +		subtype |= RELAX_DELAY_SLOT_SIZE_ERROR_FIRST;
> +	      if (mips_macro_warning.num_insns[1] != 1
> +		  || mips_macro_warning.sizes[1] != 4)
> +		subtype |= RELAX_DELAY_SLOT_SIZE_ERROR_SECOND;
> +	    }
> +
> +	  /* One implementation might need a warning but the other
> +	     definitely doesn't.  */
> +	  mips_macro_warning.first_frag->fr_subtype |= subtype;
> +	}
> +    }
> 
> Why not work out the subtype, then check whether both ERROR_FIRST and
> ERROR_SECOND are set?

 Chao-ying?

> +	  if (mips_macro_warning.delay_slot_p)
> +	    {
> +	      if (mips_macro_warning.num_insns[0] > 1)
> +		subtype |= RELAX_DELAY_SLOT_SIZE_ERROR_FIRST;
> +	      if (mips_macro_warning.num_insns[1] > 1)
> +		subtype |= RELAX_DELAY_SLOT_SIZE_ERROR_SECOND;
> +	    }
> 
> I don't get why this hunk is needed.  I thought ERROR_FIRST and ERROR_SECOND
> controlled cases where a macro has a single-insn expansion that is the
> wrong size, which ought to be handled by the block above.  If the code
> really is needed, you should add a comment explaining why.

 Chao-ying?

> > 	(macro_build): Likewise.
> 
> +  if (mips_opts.micromips)
> +    {
> +      if (strcmp (name, "lui") == 0)
> +	micromips_macro_build (ep, name, "s,u", args);
> +      else if (strcmp (fmt, "d,w,<") == 0)
> +	micromips_macro_build (ep, name, "t,r,<", args);
> +      else
> +	micromips_macro_build (ep, name, fmt, args);
> +      va_end (args);
> +      return;
> +    }
> 
> A bit of commentary might help explain the letter switch here.

 Chao-ying?

> > 	(macro_build_jalr): Likewise.
> 
> +  if (mips_opts.micromips)
> +    {
> +      if (HAVE_NEWABI)
> +	macro_build (NULL, "jalr", "t,s", RA, PIC_CALL_REG);
> +      else
> +	macro_build (NULL, "jalr", "mj", PIC_CALL_REG);
> +    }
> +  else
> +    macro_build (NULL, "jalr", "d,s", RA, PIC_CALL_REG);
> 
> Why HAVE_NEWABI?  Do you want a 32-bit insn for R_MIPS_JALR?

 Chao-ying?

> If so, you should check MIPS_JALR_HINT_P (ep) instead.

 I may have missed that while updating the change for the recent JALR hint 
support, let me see...

> -	      macro_build (&tmp, "ori", "t,r,i", reg, 0, BFD_RELOC_LO16);
> +	      macro_build (&tmp, "ori", "t,r,i", reg, 0, A_BFD_RELOC_LO16);
>  	      macro_build (NULL, (shift >= 32) ? "dsll32" : "dsll", "d,w,<",
> -			   reg, reg, (shift >= 32) ? shift - 32 : shift);
> +				  reg, reg, (shift >= 32) ? shift - 32 : shift);
> 
> Last change looks bogus.

 Fixed.

> -  gas_assert (fixP->fx_size == 4
> +  gas_assert (fixP->fx_size == 2
> +	  || fixP->fx_size == 4
>  	  || fixP->fx_r_type == BFD_RELOC_16
> +	  || fixP->fx_r_type == BFD_RELOC_MICROMIPS_16
>  	  || fixP->fx_r_type == BFD_RELOC_64
>  	  || fixP->fx_r_type == BFD_RELOC_CTOR
>  	  || fixP->fx_r_type == BFD_RELOC_MIPS_SUB
> +	  || fixP->fx_r_type == BFD_RELOC_MICROMIPS_SUB
>  	  || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
>  	  || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY
>  	  || fixP->fx_r_type == BFD_RELOC_MIPS_TLS_DTPREL64);
>  
> +
>    buf = (bfd_byte *) (fixP->fx_frag->fr_literal + fixP->fx_where);
> 
> Last change is bogus.

 Fixed.

> +    case BFD_RELOC_MICROMIPS_7_PCREL_S1:
> +    case BFD_RELOC_MICROMIPS_10_PCREL_S1:
> +    case BFD_RELOC_MICROMIPS_16_PCREL_S1:
> +      /* We adjust the offset back to even.  */
> +      if ((*valP & 0x1) != 0)
> +	--(*valP);
> +
> +      if (! fixP->fx_done)
> +	break;
> +
> +      /* Should never visit here, because we keep the relocation.  */
> +      abort ();
> +      break;
> 
> I suppose this silently ignores branches to non-microMIPS code,
> but there again, so does the MIPS16 equivalent...

 Neither can work, so some diagnostics would be useful.

> > 	(mips_relax_frag): Handle microMIPS.
> 
> +     gas_assert (fixp->fx_r_type == BFD_RELOC_16_PCREL_S2
> +	      || fixp->fx_r_type == BFD_RELOC_MICROMIPS_7_PCREL_S1
> +	      || fixp->fx_r_type == BFD_RELOC_MICROMIPS_10_PCREL_S1
> +	      || fixp->fx_r_type == BFD_RELOC_MICROMIPS_16_PCREL_S1);
> +
> +      /* For 7/10 PCREL_S1, we just need to use fixp->fx_addnumber.  */
> +      if (fixp->fx_r_type == BFD_RELOC_MICROMIPS_7_PCREL_S1
> +	  || fixp->fx_r_type == BFD_RELOC_MICROMIPS_10_PCREL_S1)
> +	reloc->addend = fixp->fx_addnumber;
> +      else
> +	/* At this point, fx_addnumber is "symbol offset - pcrel address".
> +	   Relocations want only the symbol offset.  */
> +	reloc->addend = fixp->fx_addnumber + reloc->address;
> 
> A better comment is needed.  _Why_ do you just need fx_addnumber?

 Thanks, Chao-ying and Richard, for the feedback on this -- I'll see if I 
can make something up from it.

> > 	(md_convert_frag): Likewise.
> 
> -      /* Possibly emit a warning if we've chosen the longer option.  */
> -      if (((fragp->fr_subtype & RELAX_USE_SECOND) != 0)
> -	  == ((fragp->fr_subtype & RELAX_SECOND_LONGER) != 0))
> +      if (!(fragp->fr_subtype & RELAX_USE_SECOND))
> +  	{
> +	  /* Check if the size in branch delay slot is ok.  */
> +	  if (fragp->fr_subtype & RELAX_DELAY_SLOT_SIZE_ERROR_FIRST)
> +	    {
> +	      const char *msg = macro_warning (fragp->fr_subtype);
> +	      if (msg != 0)
> +		as_warn_where (fragp->fr_file, fragp->fr_line, msg);
> +	    }
> +	}
> +      else
>  	{
> -	  const char *msg = macro_warning (fragp->fr_subtype);
> -	  if (msg != 0)
> -	    as_warn_where (fragp->fr_file, fragp->fr_line, "%s", msg);
> +	  /* Check if the size in branch delay slot is ok.
> +	     Possibly emit a warning if we've chosen the longer option.  */
> +	  if ((fragp->fr_subtype & RELAX_DELAY_SLOT_SIZE_ERROR_SECOND)
> +	      || (fragp->fr_subtype & RELAX_SECOND_LONGER))
> +	    {
> +	      const char *msg = macro_warning (fragp->fr_subtype);
> +	      if (msg != 0)
> +		as_warn_where (fragp->fr_file, fragp->fr_line, msg);
> +	    }
>  	}
> 
> This doesn't accurately preserve the previous:
> 
>       if (((fragp->fr_subtype & RELAX_USE_SECOND) != 0)
> 	  == ((fragp->fr_subtype & RELAX_SECOND_LONGER) != 0))
> 
> behaviour.

 Chao-ying?

> > 	(mips_handle_align): Likewise.
> 
>        /* If we're not inserting a whole number of instructions,
> -	 pad the end of the fixed part of the frag with zeros.  */
> -      memset (p, 0, excess);
> +         pad the end of the fixed part of the frag with zeros.
> +         But try to fit a short microMIPS nop too if applicable.  */
> +      if (excess < 2 || *p != 2)
> +	memset (p, 0, excess);
> +      else
> +	{
> +	  memset (p, 0, excess - 2);
> +	  md_number_to_chars (p + excess - 2,
> +			      micromips_nop16_insn.insn_opcode, 2);
> +	}
> 
> Not how it'd be written from scratch; the comment makes microMIPS sound
> like an afterthought.  Please handle the microMIPS case first and make
> the comment treat it as a first-class citizen.

 It was an afterthought indeed. :)  I noticed this piece of code was 
horrible just before submission while resolving a conflict with the recent 
Loongson 2F erratum workaround.  Now the result assembled is better, but I 
think you're right this is not my best artwork. ;)

 Calling memset() for a variable count (i.e. one that cannot be inlined) 
that is at most three bytes seems an overkill to me; I have rewritten it 
now with a switch() statement.

> > 	(micromips_ip): New function.
> 
> +      /* Try to search "16" or "32" in the str.  */
> +      if ((t = strstr (str, "16")) != NULL && t < save_s)
> +	{
> +	  /* Make sure "16" is before the first '.' if '.' exists.  */
> +	  if ((s = strchr (str, '.')) != NULL && (t + 2 != s))
> +	    {
> +	      insn_error = "unrecognized opcode";
> +	      return;
> +	    }
> +
> +	  /* Make sure "16" is at the end of insn name, if no '.'.  */
> +	  if ((s = strchr (str, '.')) == NULL
> +	      && (!ISSPACE (*(t + 2)) && *(t + 2) != '\0'))
> +	    {
> +	      insn_error = "unrecognized opcode";
> +	      return;
> +	    }
> +
> +	  micromips_16 = TRUE;
> +	  for (s = t + 2; *s != '\0'; ++s)
> +	    *(s - 2) = *s;
> +	  *(s - 2) = '\0';
> +
> +	  for (s = t; *s != '\0' && !ISSPACE (*s); ++s)
> +	    continue;
> +
> +	  if (ISSPACE (*s))
> +	    {
> +	      save_c = *s;
> +	      *s++ = '\0';
> +	    }
> +
> +	  if ((insn = (struct mips_opcode *) hash_find (micromips_op_hash, str))
> +	      == NULL)
> +	    {
> +	      int i;
> +	      int length;
> +	      micromips_16 = FALSE;
> +
> +	      /* Restore the character we overwrite above (if any).  */
> +	      if (save_c)
> +		*(--s) = save_c;
> +
> +	      length = strlen (str);
> +	      for (i = length - 1; &str[i] >= t; i--)
> +		{
> +		  str[i + 2] = str[i];
> +		  if (t == &str[i])
> +		    {
> +		      str[i + 1] = '6';
> +		      str[i] = '1';
> +		      str[length + 2] = '\0';
> +		      break;
> +		    }
> +		}
> +
> +	      insn_error = "unrecognized 16-bit version of microMIPS opcode";
> +	      return;
> +	    }
> +	}
> +      else if ((t = strstr (str, "32")) != NULL && t < save_s)
> +	{
> +	  /* For some instruction names, we already have 32, so we need
> +	     to seek the second 32 to process.  Ex: bposge3232, dsra3232.  */
> +	  char *new_t;
> +	  if ((new_t = strstr (t + 2, "32")) != NULL && new_t < save_s)
> +	    t = new_t;
> +
> +	  /* Make sure "32" is before the first '.' if '.' exists.  */
> +	  if ((s = strchr (str, '.')) != NULL && (t + 2 != s))
> +	    {
> +	      insn_error = "unrecognized opcode";
> +	      return;
> +	    }
> +
> +	  /* Make sure "32" is at the end of the name, if no '.'.  */
> +	  if ((s = strchr (str, '.')) == NULL
> +	      && (!ISSPACE (*(t + 2)) && *(t + 2) != '\0'))
> +	    {
> +	      insn_error = "unrecognized opcode";
> +	      return;
> +	    }
> +
> +	  micromips_32 = TRUE;
> +	  for (s = t + 2; *s != '\0'; ++s)
> +	    *(s - 2) = *s;
> +	  *(s - 2) = '\0';
> +
> +	  for (s = t; *s != '\0' && !ISSPACE (*s); ++s)
> +	    continue;
> +
> +	  if (ISSPACE (*s))
> +	    {
> +	      save_c = *s;
> +	      *s++ = '\0';
> +	    }
> +
> +	  if ((insn = (struct mips_opcode *) hash_find (micromips_op_hash, str))
> +	      == NULL)
> +	    {
> +	      int i;
> +	      int length;
> +	      micromips_32 = FALSE;
> +
> +	      /* Restore the character we overwrite above (if any).  */
> +	      if (save_c)
> +		*(--s) = save_c;
> +
> +	      length = strlen (str);
> +	      for (i = length - 1; &str[i] >= t; i--)
> +		{
> +		  str[i + 2] = str[i];
> +		  if (t == &str[i])
> +		    {
> +		      str[i + 1] = '2';
> +		      str[i] = '3';
> +		      str[length + 2] = '\0';
> +		      break;
> +		    }
> +		}
> +
> +	      insn_error = "unrecognized 32-bit version of microMIPS opcode";
> +	      return;
> +	    }
> 
> Far too much cut-&-paste between the "16" and "32" cases.  Also:
> 
> +      if ((t = strstr (str, "16")) != NULL && t < save_s)
> 
> t < save_s must surely be true, since save_s is the null terminator.
> 
> +	  /* Make sure "16" is before the first '.' if '.' exists.  */
> +	  if ((s = strchr (str, '.')) != NULL && (t + 2 != s))
> +	    {
> +	      insn_error = "unrecognized opcode";
> +	      return;
> +	    }
> +
> +	  /* Make sure "16" is at the end of insn name, if no '.'.  */
> +	  if ((s = strchr (str, '.')) == NULL
> +	      && (!ISSPACE (*(t + 2)) && *(t + 2) != '\0'))
> +	    {
> +	      insn_error = "unrecognized opcode";
> +	      return;
> +	    }
> 
> Don't call strchr (str, '.') twice like that.  Better would be:
> 
> 	s = strchr (str, '.');
> 
> followed by the two checks.  Isn't the ISSPACE check redundant though,
> given that you've terminated the string at the first space?  I would
> have thought:
> 
>         if (t + 2 != (s ? s : save_s))
> 
> would be enough.  Errors should start with a capital letter.  Missing
> internationalisation.

 Chao-ying?

> You could use alloca to create an opcode without the "16" or "32",
> which would make the error-reporting code simpler.  It's best not
> to change the user's source line if we can help it.

 Agreed.

> +	      if (!insn_error)
> +		{
> +		  static char buf[100];
> +		  sprintf (buf,
> +			   _("opcode not supported on this processor: %s (%s)"),
> +			   mips_cpu_info_from_arch (mips_opts.arch)->name,
> +			   mips_cpu_info_from_isa (mips_opts.isa)->name);
> +		  insn_error = buf;
> +		}
> +	      if (save_c)
> +		*(--s) = save_c;
> +
> +	      if (micromips_16 || micromips_32)
> +		{
> +		  int i;
> +		  int length;
> +
> +		  length = strlen (str);
> +		  for (i = length - 1; i >= 0; i--)
> +		    {
> +		      str[i + 2] = str[i];
> +		      if (t == &str[i])
> +			break;
> +		    }
> +		  if (micromips_16)
> +		    {
> +		      insn_error =
> +			"unrecognized 16-bit version of microMIPS opcode";
> +		      str[i + 1] = '6';
> +		      str[i] = '1';
> +		    }
> +		  else
> +		    {
> +		      insn_error =
> +			"unrecognized 32-bit version of microMIPS opcode";
> +		      str[i + 1] = '2';
> +		      str[i] = '3';
> +		    }
> +		  str[length + 2] = '\0';
> +		}
> +	      return;
> 
> Why override the insn_error unconditionally like this?  E.g.:
> 
> 	jar16	$30,$26
> 
>     Error: unrecognized 16-bit version of microMIPS opcode `jar16 $30,$26'
> 
> implies there's a 32-bit opcode.  I'd also have thought that the
> "opcode not supported on this processor" would triumph if it applies.

 The error you've seen comes from the previous hunk above rather than this 
one which I think is unnecessary code duplication.  It's all rather 
over-complicated and I'm working on getting it polished.  I've fixed this 
piece of code:

	.set	micromips
	.set	noreorder
	bltzall	$2, bar
	 addiusp 256

producing this nonsense:

bltzall.s: Assembler messages:
bltzall.s:4: Error: opcode not supported on this processor: mips1 (mips1) `addiusp 256'

too.  Also the original loop seems ill-formed to me, with most of code 
intended to be executed at most once, after the loop's terminating 
condition triggered -- i.e. that shouldn't be in the loop in the first 
place.

> +do_lsb:
> 
> Not properly indented.  A few other instances.

 Like the respective originals in mips_ip().  I have fixed up the new 
labels, but upstream HEAD code should be adjusted the same way.

> +			}
> +		    }
> +	/* Now that we have assembled one operand, we use the args string
> +	 * to figure out where it goes in the instruction.  */
> +		  switch (c)
> +		    {
> 
> Bogus indentation.

 Fixed.

> > 	(micromips_macro_build): Likewise.
> > 	(micromips_macro): Likewise.
> 
> I'll look at micromips_ip and these two in more detail later.

 Me too. ;)

> > 	* ld-mips-elf/jalx-2-main.s: New.
> > 	* ld-mips-elf/jalx-2.dd: New.
> > 	* ld-mips-elf/jalx-2-ex.s: New.
> > 	* ld-mips-elf/jalx-2-printf.s: New.
> > 	* ld-mips-elf/mips-elf.exp: Run new test.
> 
> Please make the .dd output less susceptible to things like the number
> of sections, size of program headers, etc.  One way is to use a linker
> script to place each section at a nice round address.  Another is to
> ".*" out the addresses and instruction encodings and just reply on
> the symbolic part of the disassembly.  I think the former's better
> here.  There are quite a few existing examples.

 Catherine, I reckon you were working on these?

 I'll look into whatever's left yet.  Here's the current version for a 
reference, in case you or anyone else wanted to comment on what I have 
modified so far (no obligation, of course!).

  Maciej

bfd/
2010-06-01  Chao-ying Fu  <fu@mips.com>
            Ilie Garbacea  <ilie@mips.com>
            Maciej W. Rozycki  <macro@codesourcery.com>
            Joseph Myers  <joseph@codesourcery.com>
            Catherine Moore  <clm@codesourcery.com>

	* archures.c (bfd_mach_mips_micromips): New macro.
	* cpu-mips.c (I_micromips): New enum value.
	(arch_info_struct): Add bfd_mach_mips_micromips.
	* elf32-mips.c (elf_micromips_howto_table_rel): New variable.
	(_bfd_mips_elf32_gprel16_reloc): Handle microMIPS.
	(mips_elf_gprel32_reloc): Update comment.
	(micromips_reloc_map): New variable.
	(bfd_elf32_bfd_reloc_type_lookup): Handle microMIPS.
	(mips_elf32_rtype_to_howto): Likewise.
	(mips_info_to_howto_rel): Likewise.
	(elf32_mips_relax_delete_bytes): New function.
	(opcode_descriptor): New structure.
	(b_insns_32, b_insn_16): New variables.
	(BZ32_REG, BZ32_REG_FIELD): New macros.
	(bz_insns_32, bzc_insns_32, bz_insns_16): New variables.
	(BZ16_VALID_REG, BZ16_REG_FIELD): New macros.
	(jal_insn_32_bd16, jal_insn_32_bd32): New variables.
	(jalr_insn_32_bd16, jalr_insn_32_bd32): Likewise.
	(ds_insns_32_bd16, ds_insns_32_bd32): Likewise.
	(jalr_insn_16_bd16, jalr_insn_16_bd32): Likewise.
	(ds_insns_16_bd16): Likewise.
	(lui_insn, addiu_insn, addiupc_insn): Likewise.
	(ADDIU_REG, ADDIUPC_VALID_REG, ADDIUPC_REG_FIELD): New macros.
	(lwgp_insn_32, lwgp_insn_16): New functions.
	(LWGP32_REG, LWGP16_VALID_REG, LWGP16_REG_FIELD): New macros.
	(MOVE32_RD, MOVE32_RS): Likewise.
	(MOVE16_RD_FIELD, MOVE16_RS_FIELD): Likewise.
	(move_insns_32, move_insns_16): New variables.
	(nop_insn_32, nop_insn_16): Likewise.
	(MATCH): New macro.
	(find_match): New function.
	(relax_delay_slot): Likewise.
	(IS_BITSIZE): New macro.
	(elf32_mips_relax_section): New function.
	(bfd_elf32_bfd_relax_section): Define.
	* elf64-mips.c (micromips_elf64_howto_table_rel): New variable.
	(micromips_elf64_howto_table_rela): Likewise.
	(micromips_reloc_map): Likewise.
	(bfd_elf64_bfd_reloc_type_lookup): Handle microMIPS.
	(bfd_elf64_bfd_reloc_name_lookup): Likewise.
	(mips_elf64_rtype_to_howto): Likewise.
	* elfn32-mips.c (elf_micromips_howto_table_rel): New variable.
	(elf_micromips_howto_table_rela): Likewise.
	(micromips_reloc_map): Likewise.
	(bfd_elf32_bfd_reloc_type_lookup): Handle microMIPS.
	(bfd_elf32_bfd_reloc_name_lookup): Likewise.
	(mips_elf_n32_rtype_to_howto): Likewise.
	* elfxx-mips.c (micromips_reloc_shuffle_p): New function.
	(TLS_RELOC_P): Handle microMIPS.
	(got16_reloc_p, call16_reloc_p): Likewise.
	(hi16_reloc_p, lo16_reloc_p): Likewise.
	(_bfd_mips16_elf_reloc_unshuffle): Likewise.
	(_bfd_mips16_elf_reloc_shuffle): Likewise.
	(_bfd_mips_elf_lo16_reloc): Likewise.
	(mips_tls_got_index, mips_elf_got_page): Likewise.
	(mips_elf_create_local_got_entry): Likewise.
	(mips_elf_relocation_needs_la25_stub): Likewise.
	(mips_elf_calculate_relocation): Likewise.
	(mips_elf_perform_relocation): Likewise.
	(_bfd_mips_elf_symbol_processing): Likewise.
	(_bfd_mips_elf_add_symbol_hook): Likewise.
	(_bfd_mips_elf_link_output_symbol_hook): Likewise.
	(mips_elf_add_lo16_rel_addend): Likewise.
	(_bfd_mips_elf_check_relocs): Likewise.
	(mips_elf_adjust_addend): Likewise.
	(_bfd_mips_elf_relocate_section): Likewise.
	(_bfd_mips_vxworks_finish_dynamic_symbol): Likewise.
	(_bfd_mips_elf_gc_sweep_hook): Likewise.
	(_bfd_mips_elf_print_private_bfd_data):	Likewise.
	* reloc.c (BFD_RELOC_MICROMIPS_16): New relocation.
	(BFD_RELOC_MICROMIPS_7_PCREL_S1): Likewise.
	(BFD_RELOC_MICROMIPS_10_PCREL_S1): Likewise.
	(BFD_RELOC_MICROMIPS_16_PCREL_S1): Likewise.
	(BFD_RELOC_MICROMIPS_GPREL16): Likewise.
	(BFD_RELOC_MICROMIPS_JMP, BFD_RELOC_MICROMIPS_HI16): Likewise.
	(BFD_RELOC_MICROMIPS_HI16_S): Likewise.
	(BFD_RELOC_MICROMIPS_LO16): Likewise.
	(BFD_RELOC_MICROMIPS_LITERAL): Likewise.
	(BFD_RELOC_MICROMIPS_GOT16): Likewise.
	(BFD_RELOC_MICROMIPS_CALL16): Likewise.
	(BFD_RELOC_MICROMIPS_GOT_HI16): Likewise.
	(BFD_RELOC_MICROMIPS_GOT_LO16): Likewise.
	(BFD_RELOC_MICROMIPS_CALL_HI16): Likewise.
	(BFD_RELOC_MICROMIPS_CALL_LO16): Likewise.
	(BFD_RELOC_MICROMIPS_SUB): Likewise.
	(BFD_RELOC_MICROMIPS_GOT_PAGE): Likewise.
	(BFD_RELOC_MICROMIPS_GOT_OFST): Likewise.
	(BFD_RELOC_MICROMIPS_GOT_DISP): Likewise.
	(BFD_RELOC_MICROMIPS_HIGHEST): Likewise.
	(BFD_RELOC_MICROMIPS_HIGHER): Likewise.
	(BFD_RELOC_MICROMIPS_SCN_DISP): Likewise.
	(BFD_RELOC_MICROMIPS_JALR): Likewise.
	(BFD_RELOC_MICROMIPS_TLS_GD): Likewise.
	(BFD_RELOC_MICROMIPS_TLS_LDM): Likewise.
	(BFD_RELOC_MICROMIPS_TLS_DTPREL_HI16): Likewise.
	(BFD_RELOC_MICROMIPS_TLS_DTPREL_LO16): Likewise.
	(BFD_RELOC_MICROMIPS_TLS_GOTTPREL): Likewise.
	(BFD_RELOC_MICROMIPS_TLS_TPREL_HI16): Likewise.
	(BFD_RELOC_MICROMIPS_TLS_TPREL_LO16): Likewise.
	* bfd-in2.h: Regenerate.
	* libbfd.h: Regenerate.

	* elfxx-mips.c (mips_elf_calculate_relocation): Do not mark
	calls to undefined weak functions as needing jalx.

	* elfxx-mips.c (LA25_LUI_MICROMIPS_1, LA25_LUI_MICROMIPS_2,
	LA25_J_MICROMIPS_1, LA25_J_MICROMIPS_2, LA25_ADDIU_MICROMIPS_1,
	LA25_ADDIU_MICROMIPS_2): Define.
	(mips_elf_add_la25_intro, mips_elf_add_la25_trampoline): Adjust
	value of stub symbol if target is a microMIPS function.
	(mips_elf_create_la25_stub): Create microMIPS stub if target is
	a microMIPS function.

	* elfxx-mips.c (mips_elf_calculate_relocation): Expect low bit
	of $t9 to be set of microMIPS _gp_disp relocations.

binutils/
2010-06-01  Chao-ying Fu  <fu@mips.com>

	* readelf.c (get_machine_flags): Handle microMIPS.
	(get_mips_symbol_other): Likewise.

gas/
2010-06-01  Chao-ying Fu  <fu@mips.com>
            Maciej W. Rozycki  <macro@codesourcery.com>

	* config/tc-mips.h (mips_segment_info): Add one bit for
	microMIPS.
	* config/tc-mips.c (emit_branch_likely_macro): New variable.
	(mips_set_options): Add micromips.
	(mips_opts): Initialise micromips to -1.
	(file_ase_micromips): New variable.
	(CPU_HAS_MICROMIPS): New macro.
	(HAVE_CODE_COMPRESSION): Likewise.
	(micromips_op_hash): New variable.
	(micromips_nop16_insn, micromips_nop32_insn): New variables.
	(NOP_INSN): Handle microMIPS.
	(mips32_to_micromips_reg_b_map): New macro.
	(mips32_to_micromips_reg_c_map): Likewise.
	(mips32_to_micromips_reg_d_map): Likewise.
	(mips32_to_micromips_reg_e_map): Likewise.
	(mips32_to_micromips_reg_f_map): Likewise.
	(mips32_to_micromips_reg_g_map): Likewise.
	(mips32_to_micromips_reg_l_map): Likewise.
	(mips32_to_micromips_reg_q_map): New variable.
	(micromips_to_32_reg_b_map): New macro.
	(micromips_to_32_reg_c_map): Likewise.
	(micromips_to_32_reg_d_map): Likewise.
	(micromips_to_32_reg_e_map): Likewise.
	(micromips_to_32_reg_f_map): Likewise.
	(micromips_to_32_reg_g_map): Likewise.
	(micromips_to_32_reg_l_map): Likewise.
	(micromips_to_32_reg_q_map): New variable.
	(micromips_imm_b_map, micromips_imm_c_map): New macros.
	(RELAX_DELAY_SLOT_SIZE_ERROR_FIRST): New macro.
	(RELAX_DELAY_SLOT_SIZE_ERROR_SECOND): Likewise.
	(RELAX_MICROMIPS_ENCODE, RELAX_MICROMIPS_P): New macros.
	(RELAX_MICROMIPS_TYPE, RELAX_MICROMIPS_USER_16BIT): Likewise.
	(RELAX_MICROMIPS_UNCOND, RELAX_MICROMIPS_LINK): Likewise.
	(RELAX_MICROMIPS_TOOFAR, RELAX_MICROMIPS_MARK_TOOFAR): Likewise.
	(RELAX_MICROMIPS_CLEAR_TOOFAR): Likewise.
	(RELAX_MICROMIPS_EXTENDED): Likewise.
	(RELAX_MICROMIPS_MARK_EXTENDED): Likewise.
	(RELAX_MICROMIPS_CLEAR_EXTENDED): Likewise.
	(MICROMIPS_INSERT_OPERAND, MICROMIPS_EXTRACT_OPERAND): New
	macros.
	(A_BFD_RELOC_HI16_S, A_BFD_RELOC_HI16, A_BFD_RELOC_LO16): New
	relocation wrapper macros.
	(A_BFD_RELOC_GPREL16): Likewise.
	(A_BFD_RELOC_MIPS_GOT16, A_BFD_RELOC_MIPS_GOT_HI16): Likewise.
	(A_BFD_RELOC_MIPS_GOT_LO16, A_BFD_RELOC_MIPS_HIGHEST): Likewise.
	(A_BFD_RELOC_MIPS_HIGHER, A_BFD_RELOC_MIPS_GOT_DISP): Likewise.
	(A_BFD_RELOC_MIPS_GOT_PAGE, A_BFD_RELOC_MIPS_GOT_OFST): Likewise.
	(A_BFD_RELOC_MIPS_SUB, A_BFD_RELOC_MIPS_JALR): Likewise.
	(mips_macro_warning): Add delay_slot_16bit_p, delay_slot_32bit_p,
	and num_insns.
	(micromips_16, micromips_32): New variables.
	(is_micromips_16bit_p, is_micromips_32bit_p): New functions.
	(insn_length): Return the length of microMIPS instructions.
	(mips_record_mips16_mode): Rename to...
	(mips_record_mips16_micromips_mode): ... this.  Handle microMIPS.
	(install_insn): Handle microMIPS.
	(is_size_valid, is_delay_slot_valid): New functions.
	(md_begin): Handle microMIPS.
	(md_assemble): Likewise.
	(micromips_reloc_p): New function.
	(got16_reloc_p): Handle microMIPS.
	(hi16_reloc_p): Likewise.
	(lo16_reloc_p): Likewise.
	(matching_lo_reloc): Likewise.
	(mips_move_labels): Likewise.
	(mips_mark_labels): New function.
	(mips16_mark_labels): Rename to...
	(mips_compressed_mark_labels): ... this.  Handle microMIPS.
	(insns_between): Handle microMIPS.
	(MICROMIPS_TARGET, MICROMIPS_TARGET_LABEL): New macros.
	(micromips_add_number_label): New function.
	(append_insn): Handle microMIPS.
	(start_noreorder, end_noreorder): Likewise.
	(macro_start, macro_warning, macro_end): Likewise.
	(macro_build): Likewise.
	(macro_build_jalr): Likewise.
	(macro_build_lui): Likewise.
	(macro_build_ldst_constoffset): Use relocation wrappers.
	(set_at): Likewise.
	(load_register): Likewise.
	(load_address): Likewise.
	(move_register): Handle microMIPS.
	(load_got_offset): Use relocation wrappers.
	(add_got_offset): Likewise.
	(add_got_offset_hilo): Likewise.
	(macro): Handle microMIPS.
	(validate_micromips_insn): New function.
	(micromips_percent_op): New variable.
	(parse_relocation): Handle microMIPS.
	(my_getExpression): Likewise.
	(options): Add OPTION_MICROMIPS and OPTION_NO_MICROMIPS.
	(md_longopts): Add mmicromips and mno-micromips.
	(md_parse_option): Handle OPTION_MICROMIPS and
	OPTION_NO_MICROMIPS.
	(mips_after_parse_args): Handle microMIPS.
	(md_pcrel_from): Handle microMIPS relocations.
	(mips_force_relocation): Likewise.
	(md_apply_fix): Likewise.
	(mips_align): Handle microMIPS.
	(s_mipsset): Likewise.
	(s_cpload, s_cpsetup, s_cpreturn): Use relocation wrappers.
	(s_dtprel_internal): Likewise.
	(s_gpword, s_gpdword): Likewise.
	(s_insn): Handle microMIPS.
	(s_mips_stab): Likewise.
	(relaxed_micromips_32bit_branch_length): New function.
	(relaxed_micromips_16bit_branch_length): New function.
	(md_estimate_size_before_relax): Handle microMIPS.
	(mips_fix_adjustable): Likewise.
	(tc_gen_reloc): Handle microMIPS relocations.
	(mips_relax_frag): Handle microMIPS.
	(md_convert_frag): Likewise.
	(mips_frob_file_after_relocs): Likewise.
	(mips_elf_final_processing): Likewise.
	(mips_nop_opcode): Likewise.
	(mips_handle_align): Likewise.
	(md_show_usage): Handle microMIPS options.
	(micromips_ip): New function.
	(micromips_macro_build): Likewise.
	(micromips_macro): Likewise.

	* doc/as.texinfo (Target MIPS options): Add -mmicromips and
	-mno-micromips.
	(-mmicromips, -mno-micromips): New options.
	* doc/c-mips.texi (-mmicromips, -mno-micromips): New options.
	(MIPS ISA): Document .set micromips and .set nomicromips.

	* config/tc-mips.c (nops_for_insn_or_target): Replace
	MIPS16_INSN_BRANCH with MIPS16_INSN_UNCOND_BRANCH and
	MIPS16_INSN_COND_BRANCH.

	* config/tc-mips.c (append_insn): Replace INSN2_MOD_31 with
	INSN2_READ_GPR_31.  Merge with code to handle INSN_WRITE_GPR_31.

	* config/tc-mips.c (mips32_to_micromips_reg_h_map): New
	variable.
	(mips32_to_micromips_reg_m_map): Likewise.
	(mips32_to_micromips_reg_n_map): New macro.
	(micromips_to_32_reg_h_map): New variable.
	(micromips_to_32_reg_i_map): Likewise.
	(micromips_to_32_reg_m_map): Likewise.
	(micromips_to_32_reg_n_map): New macro.
	(append_insn): Handle microMIPS "mh", "mi", "mm" and "mn"
	operands.

gas/testsuite/
2010-06-01  Maciej W. Rozycki  <macro@codesourcery.com>
            Chao-ying Fu  <fu@mips.com>

	* gas/mips/beq.d: Reformat.
	* gas/mips/bge.d, gas/mips/bgeu.d: Likewise.
	* gas/mips/blt.d, gas/mips/bltu.d: Likewise.

	* gas/mips/mips4-fp.d: Reformat.

	* gas/mips/beq.d, gas/mips/beq.s: Remove checks for
	branch-likely instructions and place them...
	* gas/mips/bge.d, gas/mips/bge.s: Likewise.
	* gas/mips/bgeu.d, gas/mips/bgeu.s: Likewise.
	* gas/mips/blt.d, gas/mips/blt.s: Likewise.
	* gas/mips/bltu.d, gas/mips/bltu.s: Likewise.
	* gas/mips/branch-likely.d, gas/mips/branch-likely.s: ... in
	this new test.
	* gas/mips/mips.exp: Run the new test and update the
	constraints for the upated tests to include MIPS I.

	* gas/mips/mips4-fp.d, gas/mips/mips4-fp.s: Remove checks for
	branch-likely instructions and place them...
	* gas/mips/mips4-fp.l: Update accordingly.
	* gas/mips/mips4-branch-likely.d, gas/mips/mips4-branch-likely.s:
	... in this new test.
	* gas/mips/mips4-branch-likely.l: New stderr output for the new
	test.
	* gas/mips/mips.exp (mips4-branch-likely): Run a dump test and
	list tests matching branch-likely and mips4-fp tests
	appropriately.

	* gas/mips/micromips.d: New test.
	* gas/mips/micromips-trap.d: Likewise.
	* gas/mips/micromips-branch-relax-pic.d: Likewise.
	* gas/mips/micromips-branch-relax-pic.d: Likewise.
	* gas/mips/micromips.l: New stderr output.
	* gas/mips/micromips-branch-relax.l: Likewise.
	* gas/mips/micromips-branch-relax-pic.l: Likewise.
	* gas/mips/micromips.s: New test source.
	* gas/mips/micromips-branch-relax.s: Likewise.
	* gas/mips/mips.exp: Run the new tests.

	* gas/mips/mips.exp (run_dump_test_arch): Check for the presence
	of an architecture-specific test first and use it if found,
	before falling back to the generic one.

	* gas/mips/micromips@abs.d: New test.
	* gas/mips/micromips@add.d: Likewise.
	* gas/mips/micromips@and.d: Likewise.
	* gas/mips/micromips@beq.d: Likewise.
	* gas/mips/micromips@bge.d: Likewise.
	* gas/mips/micromips@bgeu.d: Likewise.
	* gas/mips/micromips@blt.d: Likewise.
	* gas/mips/micromips@bltu.d: Likewise.
	* gas/mips/micromips@branch-likely.d: Likewise.
	* gas/mips/micromips@branch-misc-1.d: Likewise.
	* gas/mips/micromips@branch-misc-2-64.d: Likewise.
	* gas/mips/micromips@branch-misc-2.d: Likewise.
	* gas/mips/micromips@branch-misc-2pic-64.d: Likewise.
	* gas/mips/micromips@branch-misc-2pic.d: Likewise.
	* gas/mips/micromips@dli.d: Likewise.
	* gas/mips/micromips@elf-jal.d: Likewise.
	* gas/mips/micromips@elf-rel2.d: Likewise.
	* gas/mips/micromips@elf-rel4.d: Likewise.
	* gas/mips/micromips@lb-svr4pic-ilocks.d: Likewise.
	* gas/mips/micromips@li.d: Likewise.
	* gas/mips/micromips@mips1-fp.d: Likewise.
	* gas/mips/micromips@mips32-cp2.d: Likewise.
	* gas/mips/micromips@mips32-imm.d: Likewise.
	* gas/mips/micromips@mips32-sf32.d: Likewise.
	* gas/mips/micromips@mips32.d: Likewise.
	* gas/mips/micromips@mips32r2-cp2.d: Likewise.
	* gas/mips/micromips@mips32r2-fp32.d: Likewise.
	* gas/mips/micromips@mips32r2.d: Likewise.
	* gas/mips/micromips@mips4-branch-likely.d: Likewise.
	* gas/mips/micromips@mips4-fp.d: Likewise.
	* gas/mips/micromips@mips4.d: Likewise.
	* gas/mips/micromips@mips5.d: Likewise.
	* gas/mips/micromips@mips64-cp2.d: Likewise.
	* gas/mips/micromips@mips64.d: Likewise.
	* gas/mips/micromips@mips64r2.d: Likewise.
	* gas/mips/micromips@rol-hw.d: Likewise.
	* gas/mips/micromips@uld2-eb.d: Likewise.
	* gas/mips/micromips@uld2-el.d: Likewise.
	* gas/mips/micromips@ulh2-eb.d: Likewise.
	* gas/mips/micromips@ulh2-el.d: Likewise.
	* gas/mips/micromips@ulw2-eb-ilocks.d: Likewise.
	* gas/mips/micromips@ulw2-el-ilocks.d: Likewise.
	* gas/mips/mips32-imm.d: Likewise.
	* gas/mips/mips32.d: Update immediates.
	* gas/mips/micromips@mips32-cp2.s: New test source.
	* gas/mips/micromips@mips32-imm.s: Likewise.
	* gas/mips/micromips@mips32r2-cp2.s: Likewise.
	* gas/mips/micromips@mips64-cp2.s: Likewise.
	* gas/mips/mips32-imm.s: Likewise.
	* gas/mips/mips32.s: Handle microMIPS.
	* gas/mips/mips.exp: Add the micromips arch.  Exclude mips16e
	from micromips.  Run mips32-imm.

	* gas/mips/jal-mask-11.d: New test.
	* gas/mips/jal-mask-12.d: Likewise.
	* gas/mips/micromips@jal-mask-11.d: Likewise.
	* gas/mips/jal-mask-1.s: Source for the new tests.
	* gas/mips/jal-mask-21.d: New test.
	* gas/mips/jal-mask-22.d: Likewise.
	* gas/mips/micromips@jal-mask-12.d: Likewise.
	* gas/mips/jal-mask-2.s: Source for the new tests.
	* gas/mips/mips.exp: Run the new tests.

include/elf/
2010-06-01  Chao-ying Fu  <fu@mips.com>

	* mips.h (R_MICROMIPS_min, R_MICROMIPS_16): New relocations.
	(R_MICROMIPS_26_S1): Likewise.
	(R_MICROMIPS_HI16, R_MICROMIPS_LO16): Likewise.
	(R_MICROMIPS_GPREL16, R_MICROMIPS_LITERAL): Likewise.
	(R_MICROMIPS_GOT16, R_MICROMIPS_PC7_S1): Likewise.
	(R_MICROMIPS_PC10_S1, R_MICROMIPS_PC16_S1): Likewise.
	(R_MICROMIPS_CALL16, R_MICROMIPS_GOT_DISP): Likewise.
	(R_MICROMIPS_GOT_PAGE, R_MICROMIPS_GOT_OFST): Likewise.
	(R_MICROMIPS_GOT_HI16, R_MICROMIPS_GOT_LO16): Likewise.
	(R_MICROMIPS_SUB, R_MICROMIPS_HIGHER): Likewise.
	(R_MICROMIPS_HIGHEST, R_MICROMIPS_CALL_HI16): Likewise.
	(R_MICROMIPS_CALL_LO16, R_MICROMIPS_SCN_DISP): Likewise.
	(R_MICROMIPS_JALR, R_MICROMIPS_HI0_LO16): Likewise.
	(R_MICROMIPS_TLS_GD, R_MICROMIPS_TLS_LDM): Likewise.
	(R_MICROMIPS_TLS_DTPREL_HI, R_MICROMIPS_TLS_DTPREL_LO): Likewise.
	(R_MICROMIPS_TLS_GOTTPREL): Likewise.
	(R_MICROMIPS_TLS_TPREL_HI16): Likewise.
	(R_MICROMIPS_TLS_TPREL_LO16): Likewise.
	(R_MICROMIPS_GPREL7_S2, R_MICROMIPS_PC23_S2): Likewise.
	(R_MICROMIPS_max): Likewise.
	(EF_MIPS_ARCH_ASE_MICROMIPS): New macro.
	(ELF_ST_IS_MIPS_PLT): Likewise.
	(STO_MICROMIPS): Likewise.
	(ELF_ST_IS_MICROMIPS, ELF_ST_MICROMIPS, ELF_ST_SET_MICROMIPS):
	Likewise.
	(ELF_ST_IS_MIPS_PIC, ELF_ST_SET_MIPS_PIC): Handle microMIPS.

include/opcode/
2010-06-01  Chao-ying Fu  <fu@mips.com>
            Maciej W. Rozycki  <macro@codesourcery.com>

	* mips.h
	(INSN2_BRANCH_DELAY_16BIT, INSN2_BRANCH_DELAY_32BIT): New macros.
	(INSN2_WRITE_GPR_S, INSN2_READ_FPR_D): Likewise.
	(INSN2_MOD_GPR_MB, INSN2_MOD_GPR_MC, INSN2_MOD_GPR_MD): Likewise.
	(INSN2_MOD_GPR_ME, INSN2_MOD_GPR_MF, INSN2_MOD_GPR_MG): Likewise.
	(INSN2_MOD_GPR_MJ, INSN2_MOD_GPR_MP, INSN2_MOD_GPR_MQ): Likewise.
	(INSN2_MOD_SP, INSN2_MOD_31): Likewise.
	(INSN2_READ_GP, INSN2_READ_PC): Likewise.
	(CPU_MICROMIPS): New macro.
	(M_BC1FL, M_BC1TL, M_BC2FL, M_BC2TL, M_BEQL, M_BGEZL): New enum
	values.
	(M_BGEZALL, M_BGTZL, M_BLEZL, M_BLTZL, M_BLTZALL): Likewise.
	(M_CACHE_OB, M_LDC2_OB, M_LDL_OB, M_LDM_AB, M_LDM_OB): Likewise.
	(M_LDP_AB, M_LDP_OB, M_LDR_OB, M_LL_OB, M_LLD_OB): Likewise.
	(M_LWC2_OB, M_LWL_OB, M_LWM_AB, M_LWP_AB, M_LWP_OB): Likewise.
	(M_LWR_OB, M_LWU_OB, M_PREF_OB, M_SC_OB, M_SCD_OB): Likewise.
	(M_SDC2_OB, M_SDL_OB, M_SDM_AB, M_SDM_OB, M_SDP_AB): Likewise.
	(M_SDP_OB, M_SDR_OB, M_SWC2_OB, M_SWL_OB, M_SWM_AB): Likewise.
	(M_SWM_OB, M_SWP_AB, M_SWP_OB, M_SWR_OB): Likewise.
	(MICROMIPSOP_MASK_MAJOR, MICROMIPSOP_SH_MAJOR): New macros.
	(MICROMIPSOP_MASK_IMMEDIATE, MICROMIPSOP_SH_IMMEDIATE): Likewise.
	(MICROMIPSOP_MASK_DELTA, MICROMIPSOP_SH_DELTA): Likewise.
	(MICROMIPSOP_MASK_CODE10, MICROMIPSOP_SH_CODE10): Likewise.
	(MICROMIPSOP_MASK_TRAP, MICROMIPSOP_SH_TRAP): Likewise.
	(MICROMIPSOP_MASK_SHAMT, MICROMIPSOP_SH_SHAMT): Likewise.
	(MICROMIPSOP_MASK_TARGET, MICROMIPSOP_SH_TARGET): Likewise.
	(MICROMIPSOP_MASK_EXTLSB, MICROMIPSOP_SH_EXTLSB): Likewise.
	(MICROMIPSOP_MASK_EXTMSBD, MICROMIPSOP_SH_EXTMSBD): Likewise.
	(MICROMIPSOP_MASK_INSMSB, MICROMIPSOP_SH_INSMSB): Likewise.
	(MICROMIPSOP_MASK_BREAKCODE, MICROMIPSOP_SH_BREAKCODE): Likewise.
	(MICROMIPSOP_SH_BREAKCODE2): Likewise.
	(MICROMIPSOP_MASK_CACHEOP, MICROMIPSOP_SH_CACHEOP): Likewise.
	(MICROMIPSOP_MASK_COPSEL, MICROMIPSOP_SH_COPSEL): Likewise.
	(MICROMIPSOP_MASK_OFFSET12, MICROMIPSOP_SH_OFFSET12): Likewise.
	(MICROMIPSOP_MASK_3BITPOS, MICROMIPSOP_SH_3BITPOS): Likewise.
	(MICROMIPSOP_MASK_STYPE, MICROMIPSOP_SH_STYPE): Likewise.
	(MICROMIPSOP_MASK_OFFSET10, MICROMIPSOP_SH_OFFSET10): Likewise.
	(MICROMIPSOP_MASK_RS, MICROMIPSOP_SH_RS): Likewise.
	(MICROMIPSOP_MASK_RT, MICROMIPSOP_SH_RT): Likewise.
	(MICROMIPSOP_MASK_RD, MICROMIPSOP_SH_RD): Likewise.
	(MICROMIPSOP_MASK_FS, MICROMIPSOP_SH_FS): Likewise.
	(MICROMIPSOP_MASK_FT, MICROMIPSOP_SH_FT): Likewise.
	(MICROMIPSOP_MASK_FD, MICROMIPSOP_SH_FD): Likewise.
	(MICROMIPSOP_MASK_FR, MICROMIPSOP_SH_FR): Likewise.
	(MICROMIPSOP_MASK_RS3, MICROMIPSOP_SH_RS3): Likewise.
	(MICROMIPSOP_MASK_PREFX, MICROMIPSOP_SH_PREFX): Likewise.
	(MICROMIPSOP_MASK_BCC, MICROMIPSOP_SH_BCC): Likewise.
	(MICROMIPSOP_MASK_CCC, MICROMIPSOP_SH_CCC): Likewise.
	(MICROMIPSOP_MASK_COPZ, MICROMIPSOP_SH_COPZ): Likewise.
	(MICROMIPSOP_MASK_MB, MICROMIPSOP_SH_MB): Likewise.
	(MICROMIPSOP_MASK_MC, MICROMIPSOP_SH_MC): Likewise.
	(MICROMIPSOP_MASK_MD, MICROMIPSOP_SH_MD): Likewise.
	(MICROMIPSOP_MASK_ME, MICROMIPSOP_SH_ME): Likewise.
	(MICROMIPSOP_MASK_MF, MICROMIPSOP_SH_MF): Likewise.
	(MICROMIPSOP_MASK_MG, MICROMIPSOP_SH_MG): Likewise.
	(MICROMIPSOP_MASK_MJ, MICROMIPSOP_SH_MJ): Likewise.
	(MICROMIPSOP_MASK_ML, MICROMIPSOP_SH_ML): Likewise.
	(MICROMIPSOP_MASK_MP, MICROMIPSOP_SH_MP): Likewise.
	(MICROMIPSOP_MASK_MQ, MICROMIPSOP_SH_MQ): Likewise.
	(MICROMIPSOP_MASK_MZ, MICROMIPSOP_SH_MZ): Likewise.
	(MICROMIPSOP_MASK_IMMA, MICROMIPSOP_SH_IMMA): Likewise.
	(MICROMIPSOP_MASK_IMMB, MICROMIPSOP_SH_IMMB): Likewise.
	(MICROMIPSOP_MASK_IMMC, MICROMIPSOP_SH_IMMC): Likewise.
	(MICROMIPSOP_MASK_IMMD, MICROMIPSOP_SH_IMMD): Likewise.
	(MICROMIPSOP_MASK_IMME, MICROMIPSOP_SH_IMME): Likewise.
	(MICROMIPSOP_MASK_IMMF, MICROMIPSOP_SH_IMMF): Likewise.
	(MICROMIPSOP_MASK_IMMG, MICROMIPSOP_SH_IMMG): Likewise.
	(MICROMIPSOP_MASK_IMMH, MICROMIPSOP_SH_IMMH): Likewise.
	(MICROMIPSOP_MASK_IMMI, MICROMIPSOP_SH_IMMI): Likewise.
	(MICROMIPSOP_MASK_IMMJ, MICROMIPSOP_SH_IMMJ): Likewise.
	(MICROMIPSOP_MASK_IMML, MICROMIPSOP_SH_IMML): Likewise.
	(MICROMIPSOP_MASK_IMMM, MICROMIPSOP_SH_IMMM): Likewise.
	(MICROMIPSOP_MASK_IMMN, MICROMIPSOP_SH_IMMN): Likewise.
	(MICROMIPSOP_MASK_IMMO, MICROMIPSOP_SH_IMMO): Likewise.
	(MICROMIPSOP_MASK_IMMP, MICROMIPSOP_SH_IMMP): Likewise.
	(MICROMIPSOP_MASK_IMMQ, MICROMIPSOP_SH_IMMQ): Likewise.
	(MICROMIPSOP_MASK_IMMU, MICROMIPSOP_SH_IMMU): Likewise.
	(MICROMIPSOP_MASK_IMMW, MICROMIPSOP_SH_IMMW): Likewise.
	(MICROMIPSOP_MASK_IMMX, MICROMIPSOP_SH_IMMX): Likewise.
	(MICROMIPSOP_MASK_IMMY, MICROMIPSOP_SH_IMMY): Likewise.
	(micromips_opcodes): New declaration.
	(bfd_micromips_num_opcodes): Likewise.

	* mips.h (MIPS16_INSN_UNCOND_BRANCH): New macro.
	(MIPS16_INSN_BRANCH): Rename to...
	(MIPS16_INSN_COND_BRANCH): ... this.

	* mips.h (INSN2_MOD_31): Rename to...
	(INSN2_READ_GPR_31): ... this.
	(INSN2_UNCOND_BRANCH, INSN2_COND_BRANCH): New macros.

	* mips.h (INSN2_MOD_GPR_MHI): New macro.
	(INSN2_MOD_GPR_MM, INSN2_MOD_GPR_MN): Likewise.
	(MICROMIPSOP_MASK_MH, MICROMIPSOP_SH_MH): Likewise.
	(MICROMIPSOP_MASK_MI, MICROMIPSOP_SH_MI): Likewise.
	(MICROMIPSOP_MASK_MM, MICROMIPSOP_SH_MM): Likewise.
	(MICROMIPSOP_MASK_MN, MICROMIPSOP_SH_MN): Likewise.

ld/testsuite/
2010-06-01  Catherine Moore  <clm@codesourcery.com>
            Chao-ying Fu  <fu@mips.com>
            Maciej W. Rozycki  <macro@codesourcery.com>

	* ld-mips-elf/jalx-1.s: New test.
	* ld-mips-elf/jalx-1.d: New test output.
	* ld-mips-elf/jalx-1.ld: New test linker script.
	* ld-mips-elf/mips-elf.exp: Run new test.

	* ld-mips-elf/jalx-2-main.s: New.
	* ld-mips-elf/jalx-2.dd: New.
	* ld-mips-elf/jalx-2-ex.s: New.
	* ld-mips-elf/jalx-2-printf.s: New.
	* ld-mips-elf/mips-elf.exp: Run new test.

opcodes/
2010-06-01  Chao-ying Fu  <fu@mips.com>
            Maciej W. Rozycki  <macro@codesourcery.com>

	* micromips-opc.c: New file.
	* mips-dis.c (micromips_to_32_reg_b_map): New array.
	(micromips_to_32_reg_c_map, micromips_to_32_reg_d_map): Likewise.
	(micromips_to_32_reg_e_map, micromips_to_32_reg_f_map): Likewise.
	(micromips_to_32_reg_g_map, micromips_to_32_reg_l_map): Likewise.
	(micromips_to_32_reg_q_map): Likewise.
	(micromips_imm_b_map, micromips_imm_c_map): Likewise.
	(print_insn_micromips): New function.
	(is_micromips_mode_p): New function.
	(_print_insn_mips): Handle microMIPS instructions.
	* Makefile.am (CFILES): Add micromips-opc.c.
	* configure.in (bfd_mips_arch): Add micromips-opc.lo.
	* Makefile.in: Regenerate.
	* configure: Regenerate.

	* mips-dis.c (print_mips16_insn_arg): Remove branch instruction
	type and delay slot determination.
	(print_insn_mips16): Extend branch instruction type and delay
	slot determination to cover all instructions.
	* mips16-opc.c (BR): Remove macro.
	(UBR, CBR): New macros.
	(mips16_opcodes): Update branch annotation for "b", "beqz",
	"bnez", "bteqz" and "btnez".  Add branch annotation for "jalrc"
	and "jrc".

	* mips-dis.c (print_insn_mips): Correct branch instruction type
	determination.

	* mips-dis.c (micromips_to_32_reg_h_map): New variable.
	(micromips_to_32_reg_i_map): Likewise.
	(micromips_to_32_reg_m_map): Likewise.
	(micromips_to_32_reg_n_map): New macro.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: binutils-fsf-2.20.51-20100601-umips-16.patch.bz2
Type: application/octet-stream
Size: 128412 bytes
Desc: 
URL: <https://sourceware.org/pipermail/binutils/attachments/20100601/32ae19b7/attachment.obj>


More information about the Binutils mailing list