Bit Shifting

Optimising bit shifting

Bit shifting, be it rotating left or right is so common it's easy to create slow code if you are not careful.

Shift BC, DE or HL left one bit

This is a 16 bit shift left operation. The first thought would be, especially if you have a 6502 background like myself, is to shift L left 1 bit, clearing bit 0 with carry set to the original bit 7 state, then shift H left 1 bit pulling in carry into bit 0:

CB25SLALShift L left, set bit 0 to 0
CB14RLHShift H left, set bit 0 to original bit 7 from L

However any shift left operation is the same as multiplying the value by 2 or just adding to itself, and the Z80 has a single byte operation to do this.

29ADDHL,HLShift HL left 1 bit

The same applies for BC or DE. If you need to shift a 16-bit register left one bit then always use ADD.

Shift 8-bit register left one bit

This might seem odd but the same optimisation can be done for any of the 8-bit registers. You can either use SLA or you can just add the register to itself.

Shift A left one bit, set bit 0 to 0
CB27SLAA2 bytes 8 t-states
87ADDA,A1 byte 4 t-states

Here we can halve both the code size and the time taken to perform the shift.

The downside with ADD is that the original bit 7 of the register is lost. SLA will preserve it in the Carry flag.

Other than that it's identical, with Z set if the register is now 0 and S set if the new bit 7 is set.

Last modified November 14, 2021: Rename tips to optimization (8743ec0)