Hi Richard, On 16 January 2013 06:58, Richard Henderson <r...@redhat.com> wrote: > > You could, however, use two CCmodes for the result of the compares: > > (set (reg:CC r) (compare:CC (reg:SI x) (reg:SI y))) > => cmp r, x, y > > (set (reg:CCU r) (compare:CCU (reg:SI x) (reg:SI y))) > => cmpu r, x, y > > and then the branch insns consume CC and CCU mode inputs: > > (set (pc) > (if_then_else > (match_operator 1 "mb_signed_cmp_op" // eq, lt, le > [(match_operand:CC 2 "register_operand" "r") > (const_int 0)]0 > (label_ref (match_operand 0)) > (pc))) > > and similar for "mb_unsigned_cmp_op" (eq, ltu, leu) with CCUmode. > > I believe you'll find that MODE_CC modes default to word size > already, so if you arrange for mov{cc,ccu} patterns, reload will > spill/reload these values as required and everything will Just Work. >
Thanks for the reply and suggestion - I had implemented a combined branch_compare insns as I had indicated worked for us in the past with our out of tree gcc 4.1.2, and can confirm that unrolling of loops was successful. I've also tried using CCmode / CCUmodes method, and while it works and produces correct code, passing the testsuite with no regressions, it unfortunately doesnt unroll loops - it appears to be due to the get_condition check in loop-iv.c:check_simple_exit, which has allow_cc_mode=false, which means we return 0 from canonicalize_condition; /* If OP0 is the result of a comparison, we weren't able to find what was really being compared, so fail. */ if (!allow_cc_mode && GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC) return 0; and mark the loop as 'not simple'. I'm still looking, but these are the instructions as I implemented them; (define_insn "signed_compare" [(set (match_operand:CC 0 "register_operand" "=d") (compare:CC (match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "register_operand" "d")))] "" "cmp\t%0,%1,%2" [(set_attr "type" "arith") (set_attr "mode" "SI") (set_attr "length" "4")]) (define_insn "unsigned_compare" [(set (match_operand:CCU 0 "register_operand" "=d") (compare:CCU (match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "register_operand" "d")))] "" "cmpu\t%0,%1,%2" [(set_attr "type" "arith") (set_attr "mode" "SI") (set_attr "length" "4")]) and branches; (define_insn "signed_condbranch" [(set (pc) (if_then_else (match_operator: 0 "signed_cmp_op" [(match_operand:CC 1 "register_operand" "d") (const_int 0)]) (label_ref (match_operand 2)) (pc)))] "" "b%C0i%?\t%z1,%2" [(set_attr "type" "branch") (set_attr "mode" "none") (set_attr "length" "4")] ) (define_insn "unsigned_condbranch" [(set (pc) (if_then_else (match_operator: 0 "unsigned_cmp_op" [(match_operand:CCU 1 "register_operand" "d") (const_int 0)]) (label_ref (match_operand 2)) (pc)))] "" "b%C0i%?\t%z1,%2" [(set_attr "type" "branch") (set_attr "mode" "none") (set_attr "length" "4")] ) thanks, David