6 ms·
One trick I used a lot with the Z80 is the conditional return instructions. Instead of doing a jump, structure your functions so you could return early on one
by mark-r 6y ago
One trick I used a lot with the Z80 is the conditional return instructions. Instead of doing a jump, structure your functions so you could return early on one of the condition flags. The jump instructions were 3 bytes, the return instructions were only 1.
- sedatk 6y agoIt was only useful when stack wasn’t involved I presume?
- rusk 6y agoNot sure about Z80 but stack is a bit of a luxury on 6502 ...
- gp2000 6y agoAnd it could also save time. The Z-80 conditional return takes 5 cycles (or "T-States" in Zilog terminology) to execute if the condition is not met and 11 cycles otherwise. Quite worthwhile in testing for uncommon cases. Consider this routine to print a message that is terminated by nul or newline: PMESS LD A,(HL) ; get character from message INC HL ; move message pointer to next character CP 10 ; newline? RET Z ; return if so OR A ; zero? RET Z ; done if so CALL PCHAR ; print character JP PMESS ; keep looping If instead of "RET Z" we had to do a conditional jump to a return it would be 10 cycles for each test instead of 5. CP 10 JP Z,DONE ; 10 cycles, jump taken or not ... JP PMESS DONE: RET ; 10 cycles, BTW The conditional return just happens to be cheaper if not taken because it skips the work of popping the return address off the stack. Though purely an outcome of the implementation you can treat it as sort of a branch prediction. Incidentally, the Z-80 also has relative branches (JR) that differ in execution time whether they are taken or not. The branch offset is a single byte so JR is only 2 bytes compared to JP's 3. A JR is 7 cycles if not taken, 12 otherwise. Again, we can treat it as a hard-coded branch prediction that predicts the branch is not taken. If space or distance to target is not a problem, a JR is faster if taken less than 60% of the time.
- beagle3 6y ago> The jump instructions were 3 bytes Absolute jumps ("JP") were 3 bytes, relative jumps ("JR") were two, whether conditional or not -- but, that's still longer than the 1-byte return instruction...; Though, absolute jumps were the fastest - they did not need to access the stack and adjust SP like "ret", and did not need to do addition like "jr". I used to know the opcodes by heart, but I last wrote Z80 code in 1987, and last wrote x86 machine code in 1997, and nowadays I don't remember all of the binary representations, and sometimes I get the binary representations of the two mixed. I'm getting old ...