On 8/14/20 4:16 AM, Senthil Kumar Selvaraj via Gcc wrote:
Hi,

   I'm working on porting AVR to MODE_CC, and there are quite a few
   patterns that clobber the condition code reg only for certain
   constraint alternatives. For e.g.,

(define_insn "mov<mode>_insn"
   [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r    ,d    ,Qm   ,r 
,q,r,*r")
         (match_operand:ALL1 1 "nox_general_operand"   "r Y00,n Ynn,r 
Y00,Qm,r,q,i"))]
  "register_operand (operands[0], <MODE>mode)
  || reg_or_0_operand (operands[1], <MODE>mode)"
  {
       return output_movqi (insn, operands, NULL);
  }
  [(set_attr "length" "1,1,5,5,1,1,4")
  (set_attr "adjust_len" "mov8")
  (set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")])

As you can deduce from the (set_attr "cc" ..), only constraint
alternatives 0,2,3 and 6 clobber CC - others leave it unchanged.

My first version of the port adds a post-reload splitter that adds a
(clobber (reg:CC REG_CC)) unconditionally, and it appears to work. If I
do want to add the clobber conditionally, would something like the below
be a good way to do it (get_cc_reg_clobber_rtx returns either const0_rtx
or cc_reg_rtx based on get_attr_cc (insn))? Or is there a better/cleaner way?

(define_insn_and_split "mov<mode>_insn"
   [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r    ,d    ,Qm   ,r 
,q,r,*r")
         (match_operand:ALL1 1 "nox_general_operand"   "r Y00,n Ynn,r 
Y00,Qm,r,q,i"))]
   "register_operand (operands[0], <MODE>mode)
     || reg_or_0_operand (operands[1], <MODE>mode)"
   "#"
   "&& reload_completed"
   [(parallel [(set (match_dup 0)
                    (match_dup 1))
               (clobber (match_dup 2))])]
   {
     operands[2] = get_cc_reg_clobber_rtx (curr_insn);
   }
   [(set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")])

(define_insn "*mov<mode>_insn_clobber_flags"
   [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r    ,Qm   ,r ,*r")
         (match_operand:ALL1 1 "nox_general_operand"   "r Y00,r Y00,Qm,i"))
    (clobber (reg:CC REG_CC))]
   "(register_operand (operands[0], <MODE>mode)
     || reg_or_0_operand (operands[1], <MODE>mode))
    && reload_completed"
   {
     return output_movqi (insn, operands, NULL);
   }
   [(set_attr "length" "1,5,5,4")
    (set_attr "adjust_len" "mov8")])

(define_insn "*mov<mode>_insn_noclobber_flags"
   [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r,d   ,q,r")
         (match_operand:ALL1 1 "nox_general_operand"   "r,n Ynn,r,q"))
    (clobber (const_int 0))]
   "(register_operand (operands[0], <MODE>mode)
     || reg_or_0_operand (operands[1], <MODE>mode))
    && reload_completed"
   {
     return output_movqi (insn, operands, NULL);
   }
   [(set_attr "length" "1,1,1,1")
    (set_attr "adjust_len" "mov8")])

Regards
Senthil

Happy to see someone working this.   Are you starting with one CC mode?
I noticed that the current CC0 implementation seems to effectively use
several modes.  For example, one for use of the t flag.  I'm sure it will be easier
to start with one mode.

Matt

Reply via email to