This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Confusion about delay slots and using condition-code register


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]