On Fri, Jul 13, 2001 at 04:01:29PM +0200, Maciej W. Rozycki wrote:
> Sure, but sometimes ".set reorder" allows you to achieve better
> optimization across various ISAs without a need to resort to the
> preprocessor. Consider the following code:
>
> lw $1,($2)
> addu $3,$1
>
> You need an instruction between the two for a MIPS I CPU but MIPS II+ CPUs
> interlock here if no instruction is placed. Assuming no real instruction
> can be reordered here, a nop must be inserted if the code gets compiled
> for a MIPS I CPU but no instruction is preferred otherwise. The assembler
> does it automatically if the ".set reorder" directive is active, but you
> need to decide yourself if it is not.
>
> Actually with mfc0 there is no problem -- you need a nop in the case like
> the above one as coprocessor transfers never interlock; at least docs
> state so. But who believes docs without a grain of salt, so please
> correct me if I am wrong (I don't have appropriate hardware to perform a
> test).
Real wild pig hackers on R3000 were writing code which knows that in the
load delay slot they still have the old register value available. So you
can implement var1++; var2++ as:
.set noreorder
lw $reg, var1($gp)
nop
addiu $reg, $reg, 1
lw $reg, var2($gp)
sw $reg, var1($gp)
addiu $reg, $reg, 1
sw $reg, var2($gp)
.common var1, 4, 4
.common var2, 4, 4
Of course only safe with interrupts disabled. So in a sense introducing
the load interlock broke semantics of MIPS machine code ;-)
Ralf
|