IF
Skip over the next instruction unless a condition is true according to the CPU flags.
| Opcode | Bytes | Cycles | Form | Satisfied when... |
|---|---|---|---|---|
| $02 | 1 | 1 | if zero | ZF=1 |
| $03 | 1 | 1 | if not zero | ZF=0 |
| $04 | 1 | 1 | if negative | NF=1 |
| $05 | 1 | 1 | if not negative | NF=0 |
| $06 | 1 | 1 | if overflow | OF=1 |
| $07 | 1 | 1 | if not overflow | OF=0 |
| $08 | 1 | 1 | if less unsigned | CF=0 |
| $09 | 1 | 1 | if not less unsigned | CF=1 |
| $0a | 1 | 1 | if greater unsigned | CF=1 and ZF=0 |
| $0b | 1 | 1 | if not greater unsigned | CF=0 or ZF=1 |
| $0c | 1 | 1 | if less | NF≠OF |
| $0d | 1 | 1 | if not less | NF=OF |
| $0e | 1 | 1 | if greater | ZF=0 and NF=OF |
| $0f | 1 | 1 | if not greater | ZF=1 or NF≠OF |
| Control flag | Output |
|---|---|
| skip (SF) | If the condition is not satisfied, then SF is 1; otherwise it is 0. |
Notes
-
If the condition is false, then the subsequent instruction will be skipped by setting the skip flag (SF).
-
Skipped instructions only require 1 CPU cycle.
Examples
math::sign()
Here's how the Hybrix compiler implements math::sign(), which returns 1 if i:0 is positive, -1 if it is negative, or returns 0 if i:0 is zero. Since move does not alter the flags, a single compare operation can set the flags for two different if instructions:
compare i:0, 0
if greater
move i:0, 1
if not greater
shift right signed i:0, 31
kernel::memset_byte()
if instructions are very often used with jump to implement loops. Here's an example from the Hybrix framework:
module kernel
. . .
func memset_byte(target: int, value: byte, num_bytes: int)
chombit
end func
. . .
end module
Here, if jumps out of the loop when the target register reaches target_end:
@kernel.kernel.memset_byte:
push fp
move fp, sp
add sp, 8
# i:-17 arg_target
# b:-13 arg_value
# i:-12 arg_num_bytes
# i:-8 return ip
# i:-4 fp
# i:0 target
# i:4 target_end
move i:0, i:-17
move i:4, i:-17
add i:4, i:-12
@kernel.kernel.memset_byte.l_2:
compare i:0, i:4
if not less
jump @kernel.kernel.memset_byte.l_3
store [i:0], b:-13
add i:0, 1
jump @kernel.kernel.memset_byte.l_2
@kernel.kernel.memset_byte.l_3:
add sp, -8
pop fp
pop ip
fill 4