Skip to main content

IF

Skip over the next instruction unless a condition is true according to the CPU flags.

OpcodeBytesCyclesFormSatisfied when...
$0211if zeroZF=1
$0311if not zeroZF=0
$0411if negativeNF=1
$0511if not negativeNF=0
$0611if overflowOF=1
$0711if not overflowOF=0
$0811if less unsignedCF=0
$0911if not less unsignedCF=1
$0a11if greater unsignedCF=1 and ZF=0
$0b11if not greater unsignedCF=0 or ZF=1
$0c11if lessNF≠OF
$0d11if not lessNF=OF
$0e11if greaterZF=0 and NF=OF
$0f11if not greaterZF=1 or NF≠OF
Control flagOutput
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