This uses new rtx code copysign instead of an unspec.
It also allows const_double as 2nd operand because gcc
does not optimize code like

__builtin_copysignf (x, -1.0f);

Ok for trunk?

Johann

--

    AVR: Use rtx code copysign.

    gcc/
            * config/avr/avr.md (UNSPEC_COPYSIGN): Remove define_enum.
            (copysignsf3): Use copysign instead of UNSPEC_COPYSIGN.
            Allow const_double for operand 2.

diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 429f537b7d4..2abf3c38d83 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -87,7 +87,6 @@ (define_c_enum "unspec"
    UNSPEC_FMUL
    UNSPEC_FMULS
    UNSPEC_FMULSU
-   UNSPEC_COPYSIGN
    UNSPEC_INSERT_BITS
    UNSPEC_ROUND
    ])
@@ -9272,12 +9271,18 @@ (define_insn "*ffssihi2.libgcc"
 ;; Copysign

 (define_insn "copysignsf3"
-  [(set (match_operand:SF 0 "register_operand"             "=r")
-        (unspec:SF [(match_operand:SF 1 "register_operand"  "0")
-                    (match_operand:SF 2 "register_operand"  "r")]
-                   UNSPEC_COPYSIGN))]
+  [(set (match_operand:SF 0 "register_operand"              "=r")
+        (copysign:SF (match_operand:SF 1 "register_operand"  "0")
+                     (match_operand:SF 2 "nonmemory_operand" "rF")))]
   ""
-  "bst %D2,7\;bld %D0,7"
+  {
+    if (const_double_operand (operands[2], SFmode))
+      {
+        rtx xmsb = simplify_gen_subreg (QImode, operands[2], SFmode, 3);
+        return INTVAL (xmsb) < 0 ? "set\;bld %D0,7" : "clt\;bld %D0,7";
+      }
+    return "bst %D2,7\;bld %D0,7";
+  }
   [(set_attr "length" "2")])

Reply via email to