In ARM, (almost) any instruction can be predicated. In thumb mode, that requires an it instruction to encode the predicate and pattern of negated or not for the next few instructions.
But in unified syntax the assembler can do that for you, without an explict it, I think.
e.g. movle r0, #1 sets r0 = 1 if the LE condition is true in flags, otherwise leaving it unchanged. So you'd need a mov r0, #0 first.
ARM32 doesn't have a set-from-condition instruction like x86's setcc.
AArch64 does: turning a flag condition into an integer only takes a single cset instruction.
This C source:
int booleanize(int x, int y) { return x<y; }
int booleanize_u(unsigned a, unsigned b) { return a<b; }
compiles for ARM32 thumb with clang -O3 (on the Godbolt compiler explorer), revealing some stupid missed optimizations. gcc is similar, making branchy code with no -mcpu or even worse than clang with -mcpu=cortex-a53. Branchy is maybe not totally unreasonable on a simple microcontroller.
@@ BAD EXAMPLE, compiler missed optimizations
@ clang7.0 -target arm -mthumb -mcpu=cortex-a53
booleanize(int, int):
movs r2, #0 @ movs is 16-bit, mov is a 32-bit instruction, I think.
cmp r0, r1
it lt
movlt r2, #1
mov r0, r2 @ wasted instruction because the compiler wanted to mov #0 before cmp
bx lr
booleanize_u(unsigned int, unsigned int):
movs r2, #0
cmp r0, r1
it lo
movlo r2, #1
mov r0, r2
bx lr
This is pretty definitely worse than ite le / movle / movgt from @fuz's answer, with 2 predicated instructions.
ARM-mode code-gen is more or less fine, where every 32-bit instruction word has 4 bits in the encoding for a predicate condition. (The default with no suffix in the asm source is al = always.)
@ gcc8.2 -O3 -mcpu=cortex-a53
booleanize(int, int):
cmp r0, r1
movge r0, #0 @ a simple mov without predication or flag-setting would work
movlt r0, #1
bx lr
booleanize_u(unsigned int, unsigned int):
cmp r0, r1
movcs r0, #0
movcc r0, #1
bx lr
AArch64 has cset, booleanization in a can.
@ clang and gcc make the same efficient code
booleanize(int, int):
cmp w0, w1
cset w0, lt @ signed less-than
ret
booleanize_u(unsigned int, unsigned int):
cmp w0, w1
cset w0, lo @ unsigned lower
ret