When looking at IF, ELSE, ELSIF, and ENDIF, don't overlook the RJMP macro which is where the "real" work is going on. IF, ELSE, ELSIF, and ENDIF are mostly for providing nesting, context control, and a friendly syntax around the RJMP macro.
%imacro RJMP 2.nolist
; This macro preforms the opposite conditional jump
; than what the value suggests, it's used internally
; by other macros
%ifidni %1, ==
jne %2
%elifidni %1, >
jle %2
%elifidni %1, <
jge %2
%elifidni %1, >=
jl %2
%elifidni %1, <=
jg %2
%elifidni %1, !=
je %2
%elifidni %1, !>
jg %2
%elifidni %1, !<
jl %2
%elifidni %1, CARRY
jnc %2
%elifidni %1, BELOW
jnb %2
%elifidni %1, ABOVE
jna %2
%elifidni %1, PARITY
jnp %2
%elifidni %1, SIGNED
jns %2
%elifidni %1, OVERFLOW
jno %2
%elifidni %1, !CARRY
jc %2
%elifidni %1, !BELOW
jb %2
%elifidni %1, !ABOVE
ja %2
%elifidni %1, !PARITY
jp %2
%elifidni %1, !SIGNED
js %2
%elifidni %1, !OVERFLOW
jo %2
%endif
%endmacro
I know it seems odd that we JNE on an "==" in %1, but the internal use of this macro is to generate a branch instruction over the code associated with the truth condition, so we need the opposite of the truth condition.