Here are my notes for x86 code generation for some of the IR primitives. Note that the code generation logic contains optimizations (for example testing equality with 0, moving a register to itself, etc) and also some required tests (in sub_ovf the case where the destination register is the same as the second operand, to avoid clobbering the second operand). Marc ------------------------------------------------------------------------------- rptr $t_1 = get_ctx; no-op. register allocator should assign context register to $t_1 ------------------------------------------------------------------------------- box $t_1 = load_box $t_2, K; movq K( %REG($t_2) ), %REG($t_1) ------------------------------------------------------------------------------- i64 $t_1 = and_box_i64 $t_2, K; if K = 0 then xorq %REG($t_1), %REG($t_1) else if %REG($t_1) != %REG($t_2) then movq %REG($t_2), %REG($t_1) endif andq $K, %REG($t_1) endif ------------------------------------------------------------------------------- i64 $t_1 = and_box_i64 $t_2, $t_3; if %REG($t_2) = %REG($t_3) then if %REG($t_1) != %REG($t_2) then movq %REG($t_2), %REG($t_1) endif elsif %REG($t_1) = %REG($t_2) then andq %REG($t_3), %REG($t_1) elseif %REG($t_1) = %REG($t_3) then andq %REG($t_2), %REG($t_1) else movq %REG($t_2), %REG($t_1) andq %REG($t_3), %REG($t_1) endif ------------------------------------------------------------------------------- i8 $t_1 = eq_i64 $t_2, K; if K = 0 then testq %REG($t_2), %REG($t_2) else cmpq $K, %REG($t_2) endif movb $0, %REG($t_1) cmoveb $1, %REG($t_1) ------------------------------------------------------------------------------- i8 $t_1 = eq_i64 $t_2, $t_3; cmpq %REG($t_2), %REG($t_3) movb $0, %REG($t_1) cmoveb $1, %REG($t_1) ------------------------------------------------------------------------------- if_i8 $t_1 then lbl1 else lbl2; testb %REG($t_1), %REG($t_1) if the if_i8 instruction is immediately followed by lbl1 then je lbl2 elsif the if_i8 instruction is immediately followed by lbl2 then jne lbl1 else jne lbl1 jmp lbl2 endif ------------------------------------------------------------------------------- box $t_1 = add_ovf $t_2, K normal lbl1 overflow lbl2; if %REG($t_1) != %REG($t_2) then movq %REG($t_2), %REG($t_1) endif if K = 1 then incq %REG($t_1) else addq $K, %REG($t_1) endif if the add_ovf instruction is immediately followed by lbl1 then jo lbl2 elsif the add_ovf instruction is immediately followed by lbl2 then jno lbl1 else jno lbl1 jmp lbl2 endif ------------------------------------------------------------------------------- box $t_1 = add_ovf $t_2, $t_3 normal lbl1 overflow lbl2; if %REG($t_1) != %REG($t_2) then movq %REG($t_2), %REG($t_1) endif addq %REG($t_3), %REG($t_1) if the add_ovf instruction is immediately followed by lbl1 then jo lbl2 elsif the add_ovf instruction is immediately followed by lbl2 then jno lbl1 else jno lbl1 jmp lbl2 endif ------------------------------------------------------------------------------- box $t_1 = sub_ovf $t_2, K normal lbl1 overflow lbl2; if %REG($t_1) != %REG($t_2) then movq %REG($t_2), %REG($t_1) endif if K = 1 then decq %REG($t_1) else subq $K, %REG($t_1) endif if the sub_ovf instruction is immediately followed by lbl1 then jo lbl2 elsif the sub_ovf instruction is immediately followed by lbl2 then jno lbl1 else jno lbl1 jmp lbl2 endif ------------------------------------------------------------------------------- box $t_1 = sub_ovf $t_2, $t_3 normal lbl1 overflow lbl2; if %REG($t_2) = %REG($t_3) then xorq %REG($t_1), %REG($t_1) else if %REG($t_1) = %REG($t_3) then movq %REG($t_3), %TEMP movq %REG($t_2), %REG($t_1) subq %TEMP, %REG($t_1) // note: %TEMP can be a free register, stack or context slot else if %REG($t_1) != %REG($t_2) then movq %REG($t_2), %REG($t_1) endif subq %REG($t_3), %REG($t_1) endif if the sub_ovf instruction is immediately followed by lbl1 then jo lbl2 elsif the sub_ovf instruction is immediately followed by lbl2 then jno lbl1 else jno lbl1 jmp lbl2 endif endif -------------------------------------------------------------------------------