The reason for this is because I have not implemented any convenient instruction to convert a non-zero value to one. So the code for the return statement in the code below
void showcase_compare(int a){
return a == 42;
}
is converted to the assembly snippet show below (a is R2, 42 in r3)
load flags,#alu_cmp ; binop(==)
alu r2,r3,r2
beq post_0003 ; equal
move r2,0,0
bra post_0004
post_0003:
move r2,0,1
post_0004:
So in order to get a proper one or zero we always have to branch.
Seteq and setne
To prevent this kind of unnecessary branching I added two new instructions to the Robin cpu: seteq and setne that set the contents of a register to either zero or one depending on the zero flag. The compiler can now use these instructions to simplify the code to:
load flags,#alu_cmp ; binop(==)
alu r2,r3,r2
seteq r2
This saves not only 3 instructions in code size, but also 2 or 3 instructions being executed (2 if equal, 3 if not equal).Setpos and setmin
To complete the set and make it easier to produce code for the < <= > and >= operators the setpos and setmin instructions are also implemented.