[llvm-dev] [SPARC]: leon2 and leon3: not respecting delayed-write to Y-register
Patrick Boettcher via llvm-dev
llvm-dev at lists.llvm.org
Wed Nov 16 02:29:18 PST 2016
Hi,
in section B.29. (Write State Register Instructions) of 'The SPARC
Architecture Manual Version 8' it is said that the "The write state
register instructions are delayed-write instructions."
The Y-register is a state-register.
Furthermore in the B.29-secion there is a programming note saying:
MULScc, RDY, SDIV, SDIVcc, UDIV, and UDIVcc implicitly read the Y
register. If any of these instructions execute within three
instructions after a WRY which changed the contents of the Y
register, its results are undefined.
This currently is not respected with LLVM. I'm using 3.9 and checked
whether any commit on the master-branch handles this case, I haven't
seen anything - but I might be wrong.
Unfortunately I'm not (yet) qualified enough to implement a solution
for this problem.
IMHO the best solution could be to add a pass which checks
whether there are read-hazards after any state-register-writes (Y,
PSR, ASR, WIM, TBR) and which adds NOPs if necessary or even reschedules
other instructions. (Some years ago, there was this
HazardRecognition-class in the scheduler which could be used for
that.)
The easy solution would be to simply add three NOPs the moment where
the WRY instruction is added:
https://github.com/llvm-mirror/llvm/blob/master/lib/Target/Sparc/SparcISelDAGToDAG.cpp#L357
I'd appreciate any help and guidances of how to fix this problem.
Starting with adding NOPs and maybe adding a pass to the LEONPasses.
(There is the Filler-pass, is this the right one?)
--- Code example:
clang compiles the following c-code:
int main(void)
{
int *a = (int *) 0x80000000;
int *b = (int *) 0x80000004;
return *a / *b;
}
to
[...]
49c: b5 3e 60 1f sra %i1, 0x1f, %i2
4a0: 81 80 00 1a wr %i2, %y
4a4: b0 7e 40 18 sdiv %i1, %i0, %i0
4a8: 81 c7 e0 08 ret
gcc does:
[...]
4a0: 87 38 60 1f sra %g1, 0x1f, %g3
4a4: 81 80 e0 00 wr %g3, %y
4a8: 01 00 00 00 nop
4ac: 01 00 00 00 nop
4b0: 01 00 00 00 nop
4b4: 82 78 40 02 sdiv %g1, %g2, %g1
4b8: b0 10 00 01 mov %g1, %i0
4bc: 81 e8 00 00 restore
4c0: 81 c3 e0 08 retl
---
regards,
--
Patrick.
More information about the llvm-dev
mailing list