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] microMIPS/GAS: Correct the handling of hazard clearance NOPs


Hi,

 This change fixes the handling of NOPs inserted in the microMIPS mode for 
hazard clearance.  Specifically the 32-bit NOP is used where a branch 
delay slot requires it (the instructions are never emitted at this stage, 
but nevertheless I think the same sequence should be used that will 
eventually be produced; also to avoid confusing a reader of this code) and 
compact branches/jumps are recognised.

 I believe none of this code actually triggers now, because the microMIPS 
ASE's instruction set is interlocked enough for GAS not to have or indeed 
be able to intervene and therefore the number of NOPs inserted is always 
zero, but future implementations may change the situation (cf 
mips_fix_24k), so let's not rear these bugs (to grow fatter).  This means 
though, there's no actual way to make a test case to cover this problem.

 OK to apply?

2011-08-02  Maciej W. Rozycki  <macro@codesourcery.com>

	gas/
	* config/tc-mips.c (nops_for_insn_or_target): Handle microMIPS
	branches.

  Maciej

binutils-umips-fix-branch-nops.diff
Index: binutils-fsf-trunk-quilt/gas/config/tc-mips.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/gas/config/tc-mips.c	2011-07-29 22:41:41.000000000 +0100
+++ binutils-fsf-trunk-quilt/gas/config/tc-mips.c	2011-07-29 22:41:52.000000000 +0100
@@ -3562,14 +3562,22 @@ nops_for_insn_or_target (int ignore, con
 			      | INSN_COND_BRANCH_DELAY
 			      | INSN_COND_BRANCH_LIKELY))
     {
+      const struct mips_cl_insn *delay_nop_insn = NOP_INSN;
+
+      if (mips_opts.micromips
+	  && (insn->insn_mo->pinfo2 & INSN2_BRANCH_DELAY_32BIT))
+	delay_nop_insn = &micromips_nop32_insn;
       tmp_nops = nops_for_sequence (2, ignore ? ignore + 2 : 0,
-				    hist, insn, NOP_INSN);
+				    hist, insn, delay_nop_insn);
       if (tmp_nops > nops)
 	nops = tmp_nops;
     }
-  else if (mips_opts.mips16
-	   && (insn->insn_mo->pinfo & (MIPS16_INSN_UNCOND_BRANCH
-				       | MIPS16_INSN_COND_BRANCH)))
+  else if ((mips_opts.mips16
+	    && (insn->insn_mo->pinfo & (MIPS16_INSN_UNCOND_BRANCH
+					| MIPS16_INSN_COND_BRANCH)))
+	   || (mips_opts.micromips
+	       && (insn->insn_mo->pinfo2 & (INSN2_UNCOND_BRANCH
+					    | INSN2_COND_BRANCH))))
     {
       tmp_nops = nops_for_sequence (1, ignore ? ignore + 1 : 0, hist, insn);
       if (tmp_nops > nops)


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