On 12/18/2009 03:18 PM, Michael Eager wrote:
MicroBlaze has a bit unusual compare and branch architecture. There are no condition flags; comparison results are stored in a result register.
This like Alpha or MIPS then.
There's one branch instruction, which compares a register with zero and branches based on condition (eq, ne, lt, gt, etc.).
Yep,
There are a number of different instructions which can be used for comparisons. Regular instructions like sub or xor can be used in some cases. There are also cmp/cmpu instructions which do a modified subtraction of signed and unsigned integers.
Yep,
For comparisons, I'm generating insns like: (set (reg:CC rD) (eq:CC (reg:SI rA) (reg:SI rB)) followed by a branch: (if_then_else (eq:CC (reg:CC rD) (const_int 0)) (label_ref xx) (pc)))
There's no need to use CCmode; SImode will work just fine. Your cmp instruction is a bit weird, in that only bit 0 is set for the comparison, and the rest of the register still contains the result of the subtraction. You may well want to model this with (define_insn_and_split "*cmp" [(set (match_operand:SI 0 "register_operand" "=r") (lt:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "register_operand" "r")))] "" "cmp %0,%1,%2\;andi $0,$0,1" "" [(set (match_dup 0) (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_CMP)) (set (match_dup 0) (and:SI (match_dup 0) (const_int 1)))] "") If your cmp instruction cleared bits 31:1, then this would be exactly the MIPS SLT instruction. I think all your problems will just Go Away if you stop using CCmode, and model your branch instructions like MIPS does. r~