This is a regression present on mainline and 4.6/4.5 branch. We generate wrong code for the movcc patterns if the operands of the comparison have TFmode and TARGET_HARD_QUAD is not set, because we fail to update the comparison code after going through the comparison routine.
Tested on SPARC/Solaris, applied to mainline and 4.6/4.5 branch. 2011-10-11 Eric Botcazou <ebotca...@adacore.com> PR target/49965 * config/sparc/sparc.md (mov<I:mode>cc): Do not save comparison code. (mov<F:mode>cc): Likewise. -- Eric Botcazou
Index: config/sparc/sparc.md =================================================================== --- config/sparc/sparc.md (revision 179736) +++ config/sparc/sparc.md (working copy) @@ -2614,11 +2614,9 @@ (define_expand "mov<I:mode>cc" (match_operand:I 3 "arith10_operand" "")))] "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)" { - enum rtx_code code = GET_CODE (operands[1]); rtx cc_reg; - if (GET_MODE (XEXP (operands[1], 0)) == DImode - && ! TARGET_ARCH64) + if (GET_MODE (XEXP (operands[1], 0)) == DImode && !TARGET_ARCH64) FAIL; if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD) @@ -2629,12 +2627,14 @@ (define_expand "mov<I:mode>cc" if (XEXP (operands[1], 1) == const0_rtx && GET_CODE (XEXP (operands[1], 0)) == REG && GET_MODE (XEXP (operands[1], 0)) == DImode - && v9_regcmp_p (code)) + && v9_regcmp_p (GET_CODE (operands[1]))) cc_reg = XEXP (operands[1], 0); else cc_reg = gen_compare_reg (operands[1]); - operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx); + operands[1] + = gen_rtx_fmt_ee (GET_CODE (operands[1]), GET_MODE (cc_reg), cc_reg, + const0_rtx); }) (define_expand "mov<F:mode>cc" @@ -2644,11 +2644,9 @@ (define_expand "mov<F:mode>cc" (match_operand:F 3 "register_operand" "")))] "TARGET_V9 && TARGET_FPU" { - enum rtx_code code = GET_CODE (operands[1]); rtx cc_reg; - if (GET_MODE (XEXP (operands[1], 0)) == DImode - && ! TARGET_ARCH64) + if (GET_MODE (XEXP (operands[1], 0)) == DImode && !TARGET_ARCH64) FAIL; if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD) @@ -2659,12 +2657,14 @@ (define_expand "mov<F:mode>cc" if (XEXP (operands[1], 1) == const0_rtx && GET_CODE (XEXP (operands[1], 0)) == REG && GET_MODE (XEXP (operands[1], 0)) == DImode - && v9_regcmp_p (code)) + && v9_regcmp_p (GET_CODE (operands[1]))) cc_reg = XEXP (operands[1], 0); else cc_reg = gen_compare_reg (operands[1]); - operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx); + operands[1] + = gen_rtx_fmt_ee (GET_CODE (operands[1]), GET_MODE (cc_reg), cc_reg, + const0_rtx); }) ;; Conditional move define_insns