Michael Stellmann via llvm-dev
2018-Jul-18 04:28 UTC
[llvm-dev] Lowering SEXT (and ZEXT) efficiently on Z80
I'm working on a Z80 backend and am trying to efficiently lower SEXT, specifically 8 to 16 bit, in LowerOperation() according to the following rules: The Z80 has 8 bit registers and 16 bit registers, which are aliased versions of two 8 bit registers. 8 bit registers are named A, H, L, D, E and some more. 16 bit registers are HL (composed of H + L), DE (D + E) - and some more - with L and E being the low bits (LSB). For SEXT from 8 to 16 bit, here are the rules to do it efficiently: 8 bit reg -> 16 bit reg Fast extension: L HL, by making MSB (H) = 0/255 E DE, by making MSB (D) = 0/255 Slow (costly) extension: H HL or DE, by making LSB (D or L) = H and MSB (H) = 0/255 D same as above Reg "A" doesn't have a 16 bit register pair, so SEXT must always done as a "slow" operation. For the fast extension, how could an efficient lowering be done so L prefers being extended into HL and E into DE (and saving any previous content of H or D somewhere else)? And for the slow extension, would creating a virtual 16 bit register pair for the destination also include a register pair that is composed of the source reg, i.e. H into HL - or even prefer it, if all are used? Thanks, Michael
Bruce Hoult via llvm-dev
2018-Jul-18 06:22 UTC
[llvm-dev] Lowering SEXT (and ZEXT) efficiently on Z80
On Tue, Jul 17, 2018 at 9:28 PM, Michael Stellmann via llvm-dev < llvm-dev at lists.llvm.org> wrote:> I'm working on a Z80 backend and am trying to efficiently lower SEXT, > specifically 8 to 16 bit, in LowerOperation() according to the following > rules: > > The Z80 has 8 bit registers and 16 bit registers, which are aliased > versions of two 8 bit registers. > > 8 bit registers are named A, H, L, D, E and some more. > 16 bit registers are HL (composed of H + L), DE (D + E) - and some more - > with L and E being the low bits (LSB). > > For SEXT from 8 to 16 bit, here are the rules to do it efficiently: > > 8 bit reg -> 16 bit reg > Fast extension: > L HL, by making MSB (H) = 0/255 > E DE, by making MSB (D) = 0/255 > > Slow (costly) extension: > H HL or DE, by making LSB (D or L) = H and MSB (H) = 0/255 > D same as above > > Reg "A" doesn't have a 16 bit register pair, so SEXT must always done as a > "slow" operation.I'm not sure it's a useful thing to insist on putting the high and low bytes into a 16 bit register pair. Maybe that's the path of least resistance with LLVM. I don't think there's any particularly fast or slow places to start with the value. In the place where you want the low half to end up is ideal of course, but if not then it changes little. I don't think you can do better than this? LO -> HI || LO: ld a, LO rla sbc a, a ld HI, a If the value starts in a, reverse the first instruction. If the value starts somewhere else (even in HI) then move it to both LO and a. One more instruction. Nothing else changes.> >For the fast extension, how could an efficient lowering be done so L> prefers being extended into HL and E into DE (and saving any previous > content of H or D somewhere else)? >Again, you don't need to do that. If LLVM allocates the result into a 16 bit register, it will make sure by itself that nothing else useful is already there. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180717/a86dfc77/attachment.html>
Michael Stellmann via llvm-dev
2018-Jul-18 10:54 UTC
[llvm-dev] Lowering SEXT (and ZEXT) efficiently on Z80
<html><head></head><body><div style="font-family: Verdana;font-size: 12.0px;"><div> <div>Thank you very much Bruce!</div> <div> </div> <div>Very well explained! I'm slowly getting the hang of how lowering is supposed to work in LLVM.</div> <div> </div> <div> </div> <div>P.S. The code you posted is expert level, you are sure knowledgeable about the Z80! ;-)</div> </div></div></body></html>