(define_expand "copysign<mode>3"
[(use (match_operand:IEEE128 0 "altivec_register_operand"))
(use (match_operand:IEEE128 1 "altivec_register_operand"))
- (use (match_operand:IEEE128 2 "altivec_register_operand"))]
+ (use (match_operand:IEEE128 2 "any_operand"))]
"FLOAT128_IEEE_P (<MODE>mode)"
{
+ /* Middle-end canonicalizes -fabs (x) to copysign (x, -1),
+ but PowerPC prefers -fabs (x). */
+ if (CONST_DOUBLE_AS_FLOAT_P (operands[2]))
+ {
+ if (real_isneg (CONST_DOUBLE_REAL_VALUE (operands[2])))
+ {
+ rtx abs_res = gen_reg_rtx (<MODE>mode);
+ emit_insn (gen_abs<mode>2 (abs_res, operands[1]));
+ emit_insn (gen_neg<mode>2 (operands[0], abs_res));
+ }
+ else
+ emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
+ DONE;
+ }
+
+ if (!altivec_register_operand (operands[2], <MODE>mode))
+ operands[2] = copy_to_mode_reg (<MODE>mode, operands[2]);
+
if (TARGET_FLOAT128_HW)
emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
operands[2]));