[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