[PATCH] microMIPS/GAS: Correct the handling of hazard clearance NOPs
Maciej W. Rozycki
macro@codesourcery.com
Tue Aug 2 15:38:00 GMT 2011
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 = µmips_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)
More information about the Binutils
mailing list