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