While discussing a question about the origin of Zero as value for the default exit code for success, I reflected if there is any Instruction Set Architecture or implementation thereof where testing a byte or word for a value of ONE is favoured over testing for a value of ZERO, but couldn't think of any. All ISA I have meet so far do worst in handling a test for ONE.
Or in a more generic form: is there any ISA treating any discrete value, i.e. a single value, not a range, other then zero, privileged over zero?
(To keep wording simple I'll continue asking about a value of one, but any other than zero will do it)
To give a clear benchmark: The test for ONE must measured against the test for ZERO on these criteria with lower numbers being better:
- number clock cycles
- required memory footprint
- number of instructions
A solution is considered better if it has a lower value on any of these criteria, while not being higher on any of the other. Mixed cases (one higher one lower) might be as well valid after a closer look.
Note, this is about a test of the values of ONE or ZERO of a byte or larger memory unit (like a word), as used for return values. This is not about testing single bit tests (within a byte or word). Of course methods that test for a value of one using on bit test instruction are quite fine. Also, the test must be non-destructive.
So, is there any ISA where testing for a value other than zero performs better than testing for zero?
Bonus: An ISA where testing for any other discrete values is as privileged as testing for zero would already be interesting.
(Note: it still must be privileged over generic compare)
Examples
For example on a 6502 (or 68xx) testing a byte for a one value can be done by loading the value to be tested and compared :
LDA <value>
CMP #1
BEQ was_one
Or, if no longer needed in A decrementing will save a byte (only 65C02)
LDA <value>
DEA
BEQ was_one
In contrast, testing for zero is done by just loading the byte in question:
LDA <value>
BEQ was_zero
This is possible as a load instruction sets the zero flag accordingly. Thus testing for zero will always be one instruction less, at least one byte shorter and two clocks faster than testing for one.
Of course this is a benefit of architectures that set flags during load. Architectures that set their flags/condition codes only due test instruction will usually need more instructions, but still often prefer tests for zero. For example an 8080 needs with
LDA <value>
ORA A
JZ was_zero
6 bytes and 27 cycles, while testing for one will be as well 3 instructions, but 7 bytes and 30 cycles
LDA <value>
CPI 1
JZ was_one
Two address architectures like x86 or /370 will usually perform equal for both cases, as it comes down ot a simple compare - unless the input is already in a register, where a test instruction again prefers test for zero.
P.S.: I'm confident RC.SE patrons will soon find all possible loopholes :))
-1
would have been just as useful for a convention where-1
indicated ... something (either success or error as a status code, or a downward-counting loop that included0
...)1
might be fast on a condition-code ISA if you have a spare register to burn (for some ISAs) or even better if the value being tested is dead after the test. Just subtract 1 and then branch onZ
. Though those ISA probably already have a "free" test against zero as the side effect of loading it in a register or computing it in the first place.== 0
.