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~