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~

Reply via email to