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