This is the mail archive of the
mailing list for the binutils project.
Re: [MIPS] avoiding certain instruction in delay slots
- From: Richard Sandiford <rdsandiford at googlemail dot com>
- To: Sven Anderson <sven at anderson dot de>
- Cc: binutils at sourceware dot org
- Date: Mon, 03 Feb 2014 14:57:31 +0000
- Subject: Re: [MIPS] avoiding certain instruction in delay slots
- Authentication-results: sourceware.org; auth=none
- References: <52EF785C dot 7010509 at anderson dot de>
Sven Anderson <firstname.lastname@example.org> writes:
> I'm working with an 24kc-based SoC for which - because of an errata -
> certain instructions must not appear in branch delay slots (mainly lw
> and sw). I could generally use gcc's -fno-delayed-branch to compile for
> the target. But this has the two disadvantages that, 1. I additionally
> have to manually patch assembler code, and 2. I disable more
> optimization than necessary. Therefore I tried to patch gas to produce
> according code by adapting the fix-24kc code in tc-mips.c, but it didn't
> work as expected. It's probably because I have no clue how exactly the
> process of assembling really works, that is when and if the delay slots
> are filled by gas, for instance.
> Therefore I want to kindly ask to give me some advice how to implement
> this correctly. Would it even be possible to apply the constrain even to
> noreorder assembly-code or at least give a warning about it? If this is
> of general interest, I would be happy to submit a patch.
It depends on what sort of errata it is. Is the problem specific to
delay slots? Or is it a case of "instruction X must not be followed
by instruction Y in certain situations"?
Most of the existing -mfix-* options are of the latter kind. E.g.
the -mfix-24k one is avoiding certain sequences of stores and certain
sequences of (D)ERET and branch instructions. For these the idea is
that branches are handled optimistically, assuming the best for the
target, while labels are handled pessimistically and assume the worst
for what came before. So it's perfectly OK for GCC and GAS to put a
store in a delay slot, even with -mfix-24k, since the onus is on the
target code to insert nops where necessary.
These kinds of option are handled by having GCC emit the function in
".set reorder" mode (except for filled delay branches) and leaving
everything up to the assembler. Using ".set reorder" is important
because it allows the assembler to insert nops after any label.
(In answer to your question, the assembler really does need to honour
".set noreorder"; we can never insert fixup nops while that's in effect.)
If this particular errata applies specifically to delay slots though,
you'd need to handle it differently from -mfix-24k. You'd need to teach
both GCC and GAS about the restrictions. In the GCC case this would be
by setting the "can_delay" attribute to "no" for the problem cases,
while for GAS it would be making can_swap_branch_p return false.