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)))]
 

Reply via email to