This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] microMIPS/GAS: Correct the handling of hazard clearance NOPs
- From: "Maciej W. Rozycki" <macro at codesourcery dot com>
- To: Richard Sandiford <rdsandiford at googlemail dot com>
- Cc: binutils at sourceware dot org, Chao-ying Fu <fu at mips dot com>, Rich Fuhler <rich at mips dot com>, David Lau <davidlau at mips dot com>, Kevin Mills <kevinm at mips dot com>, Ilie Garbacea <ilie at mips dot com>, Catherine Moore <clm at codesourcery dot com>, Nathan Sidwell <nathan at codesourcery dot com>, Joseph Myers <joseph at codesourcery dot com>
- Date: Tue, 2 Aug 2011 16:38:13 +0100 (BST)
- Subject: [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 = µ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)