[patch] [MIPS] Implement Errata for 24K and 24KE

Catherine Moore clm@codesourcery.com
Sun Apr 19 19:12:00 GMT 2009


Hi Richard,
I saw you original note.  I'm on vacation right now.  Is it okay if I address your issues when I return?
Thanks,
Catherine

Richard Sandiford wrote:
> Sorry for being a pain, but can I ping this?  I wasn't sure if
> anything was happening or not.
> 
> To quote the original message first:
> 
> Richard Sandiford <rdsandiford@googlemail.com> writes:
>> Catherine Moore <clm@codesourcery.com> writes:
>>> This patch implements the errata for the 24K and 24KE.  The errata
>>> calls for a NOP to be emitted after an ERET/DERET instruction followed
>>> by a branch.  If the ERET/DERET is in a noreorder section, then a
>>> warning will be issued instead.  This functionality requires the
>>> -mfix-24k option.
>>>
>>> In addition, there was an error in the delay slot handling in
>>> append_insn.  The code failed to exclude an ERET or DERET instuction
>>> from being moved into a delay slot.  That failure is also corrected
>>> with this patch.
>>>
>>> Does this look okay to install?
>> Other hazards of this kind are handled by insns_between.  Was there
>> a reason why you couldn't use it in this case?
>>
>> I don't like the idea of warning about an ERET at the end of a
>> .set noreorder block.  In general, if you have:
>>
>>    .set noreorder
>>    ...
>>    FOO
>>    ...
>>    .set reorder
>>    ...
>>    BAR
>>
>> and there is a hazard between FOO and BAR, it is perfectly OK to insert
>> nops at any point between the ".set reorder" and BAR.  This is what we
>> do for other hazards, and I think we should be consistent.  Likewise
>> if you have:
>>
>>    FOO
>>    ...
>>    .set noreorder
>>    ...
>>    BAR
>>    ...
>>    .set reorder
>>
>> it is perfectly OK to insert nops between FOO and the ".set noreorder".
>> (FWIW, using insns_between should give you this for free.)
>>
>> Also, ".set neorder" has traditionally meant "trust me!".  If we want
>> to warn about caess where we think the programmer is wrong, I think
>> we need a consistent story.
> 
> ...but I probably wasn't as clear as I should have been.
> 
> -mfix-24k, as implemented by this patch, assumes that the assembler
> should do nothing if the ERET or branch is in a ".set noreorder" block.
> This isn't how the assembler handles other cases where nops are
> needed between instruction A and instruction B.  In these other cases,
> the assembler inserts the required nops unless A and B are in the
> _same_ ".set noreorder" block. 
> 
> (If instruction A and instruction B are not in the same
> ".set noreorder" block, there must be at least one "reorderable
> point" between A and B.  The assembler will insert the nops at one
> such point.)
> 
> I think it would be surprising for users if -mfix-24k hazards were
> treated differently from all other hazards.  Please consider using
> insns_between instead!
> 
> To give a realistic example, suppose we have one function that
> ends in an ERET and a following function that starts with a branch:
> 
> 	.globl	foo
> 	.set	noreorder
> 	.set	nomacro
> foo:
> 	eret
> 	.set	macro
> 	.set	reorder
> 
>         # REORDERABLE POINT
> 
> 	.globl	bar
> 	.set	noreorder
> 	.set	nomacro
> bar:
> 	beq	$4,$0,1f
> 	sw	$0,0($5)
> 	sw	$4,4($5)
> 1:
> 	jr	$31
> 	nop
> 	.set	macro
> 	.set	reorder
> 
> Assemble this with -mfix-24k and you get:
> 
>   foo.s:7: Warning: ERET and DERET must be followed by a NOP on the 24K.
>   foo.s:15: Warning: ERET and DERET must be followed by a NOP on the 24K.
> 
> and no nop is inserted between foo and bar:
> 
> 00000000 <foo>:
>    0:   42000018        eret
> 
> 00000004 <bar>:
>    4:   10800002        beqz    a0,10 <bar+0xc>
>    8:   aca00000        sw      zero,0(a1)
>    c:   aca40004        sw      a0,4(a1)
>   10:   03e00008        jr      ra
>   14:   00000000        nop
> 
> The correct behaviour here (IMO anyway) is not to issue a warning and
> insert a nop at the end of foo.  This is what would happen for other
> cases where a nop is needed.  Like I say, insns_between would give
> you this behaviour for free.
> 
> The patch is also confused by ".ent" and ".end" markers, which is
> why I left them out of the example above.  If you have the following
> code (where bar is intentionally different from before):
> 
> 	.globl	foo
> 	.ent	foo
> foo:
> 	eret
> 	.end	foo
> 
> 	.globl	bar
> 	.ent	bar
> bar:
> 	beq	$4,$0,1f
> 	sw	$4,0($5)
> 1:
> 	jr	$31
> 	.end	bar
> 
> you get neither a warning nor a nop:
> 
> 00000000 <foo>:
>    0:   42000018        eret
> 
> 00000004 <bar>:
>    4:   10800002        beqz    a0,10 <bar+0xc>
>    8:   00000000        nop
>    c:   aca40000        sw      a0,0(a1)
>   10:   03e00008        jr      ra
>   14:   00000000        nop
> 
> As before, I believe the correct behaviour here is to silently insert
> the nop at the end of foo.  insns_between would again give you this
> behaviour for free.
> 
> (I realise that, with insns_between, we currently don't have any code to
> warn about cases where ".set noreorder" stopped us from inserting nops.
> I'm certainly open to adding something though, and I think doing it that
> way rather than the current way would avoid the double warning seen above.
> However, as I said in the earlier message, I think we should be consistent
> in the way we handle warnings as well as the way we handle nop insertion
> itself.)
> 
> Richard



More information about the Binutils mailing list