I'm using the CCmode model for condition-code handling in a 4.6.1 based compiler. Every other port I've done used the CC0 model, so I'm probably doing something misguided here.
I'm down to just 170 failures in the check-gcc testsuites, so it's looking pretty solid; of the failures about 30 are tests with delay-slots being filled incorrectly. The situation I see is where we have source that looks like if (x != 0) count++; if (y != z) ..... RTL (without delay slot considerations looks like) jeq $1 add r1,1 $1: cmp r2,r3 jeq $2 branches have delay slots, and are not annullable. When reorg runs, it realizes that it can't put the add into the delay slot, but it hoists the cmp instruction into the first branch slot, ala jeq $1 cmp r2,r3 add r1,1 $1: jeq $r2 ...... So, if the first branch is not taken, we set the condition codes needed for the second branch and clobber them with the add instruction then fall to the conditional branch using the wrong condition codes. I emit (clobber (reg:CC CCreg)) with every instruction that can set condition codes, but it appears that nearly all of them are removed before we reach reorg where mark_referenced_resources() or mark_set_resources() would detect a conflict of the CCreg's. So, am I constructing my RTL incorrectly? Do I need to be making the clobbers inside a parallel instead of just emitting them sequentially? Or should I just fall back to a cc0 model where this shouldn't be a problem? The define_expand pattern for add looks like (define_expand "add<S:mode>3" [(set (match_operand:S 0 "nonimmediate_operand") (plus:S (match_operand:S 1 "general_operand") (match_operand:S 2 "general_operand"))) (clobber (reg:CC CC_REGNUM))] "" ..... }) has corresponding define_insn's are (define_insn "*addsi" [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm,rS,rm") (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0, 0, 0,rm") (match_operand:SI 2 "general_operand" "QI, K, i,rm")))] ,........ ) (define_insn "*addsi_cc" [(set (reg:CC CC_REGNUM) (compare:CC (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0, 0, 0,rm") (match_operand:SI 2 "general_operand" "QI, K, i,rm")) (const_int 0))) (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm,rS,rm") (plus:SI (match_dup 1) (match_dup 2)))]