aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorUros Bizjak <uros@gcc.gnu.org>2007-06-07 20:31:40 +0200
committerUros Bizjak <uros@gcc.gnu.org>2007-06-07 20:31:40 +0200
commitedc5bbcd8f2becdd035195f0a4e6e0e880b3d28d (patch)
tree443622ba397e46afad2dd19365e5275d03f2304c /gcc
parent125253d945a40bc7e56a40dc45b7cf1af77fba53 (diff)
downloadgcc-edc5bbcd8f2becdd035195f0a4e6e0e880b3d28d.zip
gcc-edc5bbcd8f2becdd035195f0a4e6e0e880b3d28d.tar.gz
gcc-edc5bbcd8f2becdd035195f0a4e6e0e880b3d28d.tar.bz2
i386.md (standard sse constant splitter): Handle TFmode.
* config/i386/i386.md (standard sse constant splitter): Handle TFmode. (negtf2, abstf2, *absnegtf2_sse): New insn patterns. (CSGNMODE): New mode macro. (CSGNVMODE): New mode attribute. (copysign<mode>3): Rename from copysingsf3 and copysigndf3. Macroize expander using CSGNMODE mode macro. Handle TFmode. (copysign<mode>3_const): Rename from copysignsf3_const and copysigndf3_const. Macroize pattern using CSGNMODE mode macro. Handle TFmode. (copysign<mode>3_var): Rename from copysignsf3_var and copysigndf3_var. Macroize pattern using CSGNMODE mode macro. Handle TFmode. (copysign<mode>3_var splitter): Macroize pattern using CSGNMODE mode macro. Handle TFmode. * config/i386/sse.md (andtf3, *andtf3, *nandtf3): New insn patterns. (iortf3, *iortf3): Ditto. (xortf3, *xortf3): Ditto. * config/i386/i386.c (ix86_build_signbit_mask): Create scalar TFmode and TImode masks. (ix86_expand_copysign): Expand TFmode copysign insn. (IX86_BUILTIN_INFQ): New. (IX86_BUILTIN_FABSQ): Ditto. (IX86_BUILTIN_COPYSIGNQ): Ditto. (ix86_init_mmx_sse_builtins) [__builtin_infq]: New builtin definition. [__builtin_fabsq]: Ditto. [__builtin_copysignq]: Ditto. (ix86_expand_builtin) [IX86_BUILTIN_INFQ]: Expand builtin. [IX86_BUILTIN_FABSQ]: Expand builtin using ix86_expand_unop_builtin(). [IX86_BUILTIN_COPYSIGNQ]: Expand builtin using ix86_expand_unop_builtin(). testsuite/ChangeLog: * gcc.target/i386/builtin-copysign.c: New test. From-SVN: r125535
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog33
-rw-r--r--gcc/config/i386/i386.c123
-rw-r--r--gcc/config/i386/i386.md197
-rw-r--r--gcc/config/i386/sse.md67
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-copysign.c16
6 files changed, 306 insertions, 136 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b5c5300..dbd3526 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,36 @@
+2007-06-07 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.md (standard sse constant splitter): Handle TFmode.
+ (negtf2, abstf2, *absnegtf2_sse): New insn patterns.
+ (CSGNMODE): New mode macro.
+ (CSGNVMODE): New mode attribute.
+ (copysign<mode>3): Rename from copysingsf3 and copysigndf3. Macroize
+ expander using CSGNMODE mode macro. Handle TFmode.
+ (copysign<mode>3_const): Rename from copysignsf3_const and
+ copysigndf3_const. Macroize pattern using CSGNMODE mode macro.
+ Handle TFmode.
+ (copysign<mode>3_var): Rename from copysignsf3_var and
+ copysigndf3_var. Macroize pattern using CSGNMODE mode macro.
+ Handle TFmode.
+ (copysign<mode>3_var splitter): Macroize pattern using CSGNMODE
+ mode macro. Handle TFmode.
+ * config/i386/sse.md (andtf3, *andtf3, *nandtf3): New insn patterns.
+ (iortf3, *iortf3): Ditto.
+ (xortf3, *xortf3): Ditto.
+ * config/i386/i386.c (ix86_build_signbit_mask): Create scalar
+ TFmode and TImode masks.
+ (ix86_expand_copysign): Expand TFmode copysign insn.
+ (IX86_BUILTIN_INFQ): New.
+ (IX86_BUILTIN_FABSQ): Ditto.
+ (IX86_BUILTIN_COPYSIGNQ): Ditto.
+ (ix86_init_mmx_sse_builtins) [__builtin_infq]: New builtin definition.
+ [__builtin_fabsq]: Ditto.
+ [__builtin_copysignq]: Ditto.
+ (ix86_expand_builtin) [IX86_BUILTIN_INFQ]: Expand builtin.
+ [IX86_BUILTIN_FABSQ]: Expand builtin using ix86_expand_unop_builtin().
+ [IX86_BUILTIN_COPYSIGNQ]: Expand builtin using
+ ix86_expand_unop_builtin().
+
2007-06-07 Bob Wilson <bob.wilson@acm.org>
* config/xtensa/lib1funcs.asm: Clean up whitespace.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index c23b5b7..c893900 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -10632,6 +10632,14 @@ ix86_build_signbit_mask (enum machine_mode mode, bool vect, bool invert)
lo = 0, hi = (HOST_WIDE_INT)1 << (shift - HOST_BITS_PER_WIDE_INT);
break;
+ case TImode:
+ case TFmode:
+ imode = TImode;
+ vec_mode = VOIDmode;
+ gcc_assert (HOST_BITS_PER_WIDE_INT >= 64);
+ lo = 0, hi = (HOST_WIDE_INT)1 << shift;
+ break;
+
default:
gcc_unreachable ();
}
@@ -10643,6 +10651,9 @@ ix86_build_signbit_mask (enum machine_mode mode, bool vect, bool invert)
mask = immed_double_const (lo, hi, imode);
mask = gen_lowpart (mode, mask);
+ if (vec_mode == VOIDmode)
+ return force_reg (mode, mask);
+
v = ix86_build_const_vector (mode, vect, mask);
return force_reg (vec_mode, v);
}
@@ -10664,6 +10675,8 @@ ix86_expand_fp_absneg_operator (enum rtx_code code, enum machine_mode mode,
elt_mode = GET_MODE_INNER (mode);
use_sse = true;
}
+ else if (mode == TFmode)
+ use_sse = true;
else if (TARGET_SSE_MATH)
use_sse = SSE_FLOAT_MODE_P (mode);
@@ -10732,39 +10745,54 @@ ix86_expand_copysign (rtx operands[])
if (GET_CODE (op0) == CONST_DOUBLE)
{
- rtvec v;
+ rtx (*copysign_insn)(rtx, rtx, rtx, rtx);
if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
op0 = simplify_unary_operation (ABS, mode, op0, mode);
- if (op0 == CONST0_RTX (mode))
- op0 = CONST0_RTX (vmode);
- else
- {
- if (mode == SFmode)
- v = gen_rtvec (4, op0, CONST0_RTX (SFmode),
- CONST0_RTX (SFmode), CONST0_RTX (SFmode));
+ if (mode == SFmode || mode == DFmode)
+ {
+ if (op0 == CONST0_RTX (mode))
+ op0 = CONST0_RTX (vmode);
else
- v = gen_rtvec (2, op0, CONST0_RTX (DFmode));
- op0 = force_reg (vmode, gen_rtx_CONST_VECTOR (vmode, v));
+ {
+ rtvec v;
+
+ if (mode == SFmode)
+ v = gen_rtvec (4, op0, CONST0_RTX (SFmode),
+ CONST0_RTX (SFmode), CONST0_RTX (SFmode));
+ else
+ v = gen_rtvec (2, op0, CONST0_RTX (DFmode));
+ op0 = force_reg (vmode, gen_rtx_CONST_VECTOR (vmode, v));
+ }
}
mask = ix86_build_signbit_mask (mode, 0, 0);
if (mode == SFmode)
- emit_insn (gen_copysignsf3_const (dest, op0, op1, mask));
+ copysign_insn = gen_copysignsf3_const;
+ else if (mode == DFmode)
+ copysign_insn = gen_copysigndf3_const;
else
- emit_insn (gen_copysigndf3_const (dest, op0, op1, mask));
+ copysign_insn = gen_copysigntf3_const;
+
+ emit_insn (copysign_insn (dest, op0, op1, mask));
}
else
{
+ rtx (*copysign_insn)(rtx, rtx, rtx, rtx, rtx, rtx);
+
nmask = ix86_build_signbit_mask (mode, 0, 1);
mask = ix86_build_signbit_mask (mode, 0, 0);
if (mode == SFmode)
- emit_insn (gen_copysignsf3_var (dest, NULL, op0, op1, nmask, mask));
+ copysign_insn = gen_copysignsf3_var;
+ else if (mode == DFmode)
+ copysign_insn = gen_copysigndf3_var;
else
- emit_insn (gen_copysigndf3_var (dest, NULL, op0, op1, nmask, mask));
+ copysign_insn = gen_copysigntf3_var;
+
+ emit_insn (copysign_insn (dest, NULL_RTX, op0, op1, nmask, mask));
}
}
@@ -16808,6 +16836,11 @@ enum ix86_builtins
IX86_BUILTIN_PCMPGTQ,
+ /* TFmode support builtins. */
+ IX86_BUILTIN_INFQ,
+ IX86_BUILTIN_FABSQ,
+ IX86_BUILTIN_COPYSIGNQ,
+
IX86_BUILTIN_MAX
};
@@ -17706,9 +17739,6 @@ ix86_init_mmx_sse_builtins (void)
V16QI_type_node,
integer_type_node,
NULL_TREE);
-
- tree float80_type;
- tree float128_type;
tree ftype;
/* The __float80 type. */
@@ -17718,18 +17748,38 @@ ix86_init_mmx_sse_builtins (void)
else
{
/* The __float80 type. */
- float80_type = make_node (REAL_TYPE);
- TYPE_PRECISION (float80_type) = 80;
- layout_type (float80_type);
- (*lang_hooks.types.register_builtin_type) (float80_type, "__float80");
+ tree float80_type_node = make_node (REAL_TYPE);
+
+ TYPE_PRECISION (float80_type_node) = 80;
+ layout_type (float80_type_node);
+ (*lang_hooks.types.register_builtin_type) (float80_type_node,
+ "__float80");
}
if (TARGET_64BIT)
{
- float128_type = make_node (REAL_TYPE);
- TYPE_PRECISION (float128_type) = 128;
- layout_type (float128_type);
- (*lang_hooks.types.register_builtin_type) (float128_type, "__float128");
+ tree float128_type_node = make_node (REAL_TYPE);
+
+ TYPE_PRECISION (float128_type_node) = 128;
+ layout_type (float128_type_node);
+ (*lang_hooks.types.register_builtin_type) (float128_type_node,
+ "__float128");
+
+ /* TFmode support builtins. */
+ ftype = build_function_type (float128_type_node,
+ void_list_node);
+ def_builtin_const (OPTION_MASK_ISA_64BIT, "__builtin_infq", ftype, IX86_BUILTIN_INFQ);
+
+ ftype = build_function_type_list (float128_type_node,
+ float128_type_node,
+ NULL_TREE);
+ def_builtin_const (OPTION_MASK_ISA_64BIT, "__builtin_fabsq", ftype, IX86_BUILTIN_FABSQ);
+
+ ftype = build_function_type_list (float128_type_node,
+ float128_type_node,
+ float128_type_node,
+ NULL_TREE);
+ def_builtin (OPTION_MASK_ISA_64BIT, "__builtin_copysignq", ftype, IX86_BUILTIN_COPYSIGNQ);
}
/* Add all SSE builtins that are more or less simple operations on
@@ -19687,6 +19737,29 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
case IX86_BUILTIN_VEC_SET_V16QI:
return ix86_expand_vec_set_builtin (exp);
+ case IX86_BUILTIN_INFQ:
+ {
+ REAL_VALUE_TYPE inf;
+ rtx tmp;
+
+ real_inf (&inf);
+ tmp = CONST_DOUBLE_FROM_REAL_VALUE (inf, mode);
+
+ tmp = validize_mem (force_const_mem (mode, tmp));
+
+ if (target == 0)
+ target = gen_reg_rtx (mode);
+
+ emit_move_insn (target, tmp);
+ return target;
+ }
+
+ case IX86_BUILTIN_FABSQ:
+ return ix86_expand_unop_builtin (CODE_FOR_abstf2, exp, target, 0);
+
+ case IX86_BUILTIN_COPYSIGNQ:
+ return ix86_expand_binop_builtin (CODE_FOR_copysigntf3, exp, target);
+
default:
break;
}
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 43e58ae..641b6a1 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -3035,7 +3035,8 @@
(match_operand 1 "memory_operand" ""))]
"reload_completed
&& MEM_P (operands[1])
- && (GET_MODE (operands[0]) == XFmode
+ && (GET_MODE (operands[0]) == TFmode
+ || GET_MODE (operands[0]) == XFmode
|| GET_MODE (operands[0]) == SFmode
|| GET_MODE (operands[0]) == DFmode)
&& (operands[2] = find_constant_src (insn))"
@@ -9651,60 +9652,6 @@
&& ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
"#")
-(define_expand "copysignsf3"
- [(match_operand:SF 0 "register_operand" "")
- (match_operand:SF 1 "nonmemory_operand" "")
- (match_operand:SF 2 "register_operand" "")]
- "TARGET_SSE_MATH"
-{
- ix86_expand_copysign (operands);
- DONE;
-})
-
-(define_insn_and_split "copysignsf3_const"
- [(set (match_operand:SF 0 "register_operand" "=x")
- (unspec:SF
- [(match_operand:V4SF 1 "vector_move_operand" "xmC")
- (match_operand:SF 2 "register_operand" "0")
- (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
- UNSPEC_COPYSIGN))]
- "TARGET_SSE_MATH"
- "#"
- "&& reload_completed"
- [(const_int 0)]
-{
- ix86_split_copysign_const (operands);
- DONE;
-})
-
-(define_insn "copysignsf3_var"
- [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
- (unspec:SF
- [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
- (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
- (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
- (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
- UNSPEC_COPYSIGN))
- (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
- "TARGET_SSE_MATH"
- "#")
-
-(define_split
- [(set (match_operand:SF 0 "register_operand" "")
- (unspec:SF
- [(match_operand:SF 2 "register_operand" "")
- (match_operand:SF 3 "register_operand" "")
- (match_operand:V4SF 4 "" "")
- (match_operand:V4SF 5 "" "")]
- UNSPEC_COPYSIGN))
- (clobber (match_scratch:V4SF 1 ""))]
- "TARGET_SSE_MATH && reload_completed"
- [(const_int 0)]
-{
- ix86_split_copysign_var (operands);
- DONE;
-})
-
(define_expand "negdf2"
[(set (match_operand:DF 0 "nonimmediate_operand" "")
(neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
@@ -9747,60 +9694,6 @@
&& ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
"#")
-(define_expand "copysigndf3"
- [(match_operand:DF 0 "register_operand" "")
- (match_operand:DF 1 "nonmemory_operand" "")
- (match_operand:DF 2 "register_operand" "")]
- "TARGET_SSE2 && TARGET_SSE_MATH"
-{
- ix86_expand_copysign (operands);
- DONE;
-})
-
-(define_insn_and_split "copysigndf3_const"
- [(set (match_operand:DF 0 "register_operand" "=x")
- (unspec:DF
- [(match_operand:V2DF 1 "vector_move_operand" "xmC")
- (match_operand:DF 2 "register_operand" "0")
- (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
- UNSPEC_COPYSIGN))]
- "TARGET_SSE2 && TARGET_SSE_MATH"
- "#"
- "&& reload_completed"
- [(const_int 0)]
-{
- ix86_split_copysign_const (operands);
- DONE;
-})
-
-(define_insn "copysigndf3_var"
- [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
- (unspec:DF
- [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
- (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
- (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
- (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
- UNSPEC_COPYSIGN))
- (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
- "TARGET_SSE2 && TARGET_SSE_MATH"
- "#")
-
-(define_split
- [(set (match_operand:DF 0 "register_operand" "")
- (unspec:DF
- [(match_operand:DF 2 "register_operand" "")
- (match_operand:DF 3 "register_operand" "")
- (match_operand:V2DF 4 "" "")
- (match_operand:V2DF 5 "" "")]
- UNSPEC_COPYSIGN))
- (clobber (match_scratch:V2DF 1 ""))]
- "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
- [(const_int 0)]
-{
- ix86_split_copysign_var (operands);
- DONE;
-})
-
(define_expand "negxf2"
[(set (match_operand:XF 0 "nonimmediate_operand" "")
(neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
@@ -9823,6 +9716,28 @@
&& ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
"#")
+(define_expand "negtf2"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "")
+ (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
+ "TARGET_64BIT"
+ "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
+
+(define_expand "abstf2"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "")
+ (abs:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
+ "TARGET_64BIT"
+ "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
+
+(define_insn "*absnegtf2_sse"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x,m")
+ (match_operator:TF 3 "absneg_operator"
+ [(match_operand:TF 1 "nonimmediate_operand" "0, x,0")]))
+ (use (match_operand:TF 2 "nonimmediate_operand" "xm,0,X"))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_64BIT
+ && ix86_unary_operator_ok (GET_CODE (operands[3]), TFmode, operands)"
+ "#")
+
;; Splitters for fp abs and neg.
(define_split
@@ -10080,6 +9995,70 @@
"fabs"
[(set_attr "type" "fsgn")
(set_attr "mode" "XF")])
+
+;; Copysign instructions
+
+(define_mode_macro CSGNMODE [SF DF TF])
+(define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
+
+(define_expand "copysign<mode>3"
+ [(match_operand:CSGNMODE 0 "register_operand" "")
+ (match_operand:CSGNMODE 1 "nonmemory_operand" "")
+ (match_operand:CSGNMODE 2 "register_operand" "")]
+ "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
+ || (TARGET_64BIT && (<MODE>mode == TFmode))"
+{
+ ix86_expand_copysign (operands);
+ DONE;
+})
+
+(define_insn_and_split "copysign<mode>3_const"
+ [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
+ (unspec:CSGNMODE
+ [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
+ (match_operand:CSGNMODE 2 "register_operand" "0")
+ (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
+ UNSPEC_COPYSIGN))]
+ "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
+ || (TARGET_64BIT && (<MODE>mode == TFmode))"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+{
+ ix86_split_copysign_const (operands);
+ DONE;
+})
+
+(define_insn "copysign<mode>3_var"
+ [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
+ (unspec:CSGNMODE
+ [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
+ (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
+ (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
+ (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
+ UNSPEC_COPYSIGN))
+ (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
+ "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
+ || (TARGET_64BIT && (<MODE>mode == TFmode))"
+ "#")
+
+(define_split
+ [(set (match_operand:CSGNMODE 0 "register_operand" "")
+ (unspec:CSGNMODE
+ [(match_operand:CSGNMODE 2 "register_operand" "")
+ (match_operand:CSGNMODE 3 "register_operand" "")
+ (match_operand:<CSGNVMODE> 4 "" "")
+ (match_operand:<CSGNVMODE> 5 "" "")]
+ UNSPEC_COPYSIGN))
+ (clobber (match_scratch:<CSGNVMODE> 1 ""))]
+ "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
+ || (TARGET_64BIT && (<MODE>mode == TFmode)))
+ && reload_completed"
+ [(const_int 0)]
+{
+ ix86_split_copysign_var (operands);
+ DONE;
+})
;; One complement instructions
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 042146e..deb3c43 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -3677,7 +3677,7 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
-;; Parallel integral logical operations
+;; Parallel bitwise logical operations
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -3725,6 +3725,35 @@
(set_attr "prefix_data16" "1")
(set_attr "mode" "TI")])
+(define_expand "andtf3"
+ [(set (match_operand:TF 0 "register_operand" "")
+ (and:TF (match_operand:TF 1 "nonimmediate_operand" "")
+ (match_operand:TF 2 "nonimmediate_operand" "")))]
+ "TARGET_64BIT"
+ "ix86_fixup_binary_operands_no_copy (AND, TFmode, operands);")
+
+(define_insn "*andtf3"
+ [(set (match_operand:TF 0 "register_operand" "=x")
+ (and:TF
+ (match_operand:TF 1 "nonimmediate_operand" "%0")
+ (match_operand:TF 2 "nonimmediate_operand" "xm")))]
+ "TARGET_64BIT && ix86_binary_operator_ok (AND, TFmode, operands)"
+ "pand\t{%2, %0|%0, %2}"
+ [(set_attr "type" "sselog")
+ (set_attr "prefix_data16" "1")
+ (set_attr "mode" "TI")])
+
+(define_insn "*nandtf3"
+ [(set (match_operand:TF 0 "register_operand" "=x")
+ (and:TF
+ (not:TF (match_operand:TF 1 "register_operand" "0"))
+ (match_operand:TF 2 "nonimmediate_operand" "xm")))]
+ "TARGET_64BIT"
+ "pandn\t{%2, %0|%0, %2}"
+ [(set_attr "type" "sselog")
+ (set_attr "prefix_data16" "1")
+ (set_attr "mode" "TI")])
+
(define_expand "ior<mode>3"
[(set (match_operand:SSEMODEI 0 "register_operand" "")
(ior:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
@@ -3743,6 +3772,24 @@
(set_attr "prefix_data16" "1")
(set_attr "mode" "TI")])
+(define_expand "iortf3"
+ [(set (match_operand:TF 0 "register_operand" "")
+ (ior:TF (match_operand:TF 1 "nonimmediate_operand" "")
+ (match_operand:TF 2 "nonimmediate_operand" "")))]
+ "TARGET_64BIT"
+ "ix86_fixup_binary_operands_no_copy (IOR, TFmode, operands);")
+
+(define_insn "*iortf3"
+ [(set (match_operand:TF 0 "register_operand" "=x")
+ (ior:TF
+ (match_operand:TF 1 "nonimmediate_operand" "%0")
+ (match_operand:TF 2 "nonimmediate_operand" "xm")))]
+ "TARGET_64BIT && ix86_binary_operator_ok (IOR, TFmode, operands)"
+ "por\t{%2, %0|%0, %2}"
+ [(set_attr "type" "sselog")
+ (set_attr "prefix_data16" "1")
+ (set_attr "mode" "TI")])
+
(define_expand "xor<mode>3"
[(set (match_operand:SSEMODEI 0 "register_operand" "")
(xor:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
@@ -3761,6 +3808,24 @@
(set_attr "prefix_data16" "1")
(set_attr "mode" "TI")])
+(define_expand "xortf3"
+ [(set (match_operand:TF 0 "register_operand" "")
+ (xor:TF (match_operand:TF 1 "nonimmediate_operand" "")
+ (match_operand:TF 2 "nonimmediate_operand" "")))]
+ "TARGET_64BIT"
+ "ix86_fixup_binary_operands_no_copy (XOR, TFmode, operands);")
+
+(define_insn "*xortf3"
+ [(set (match_operand:TF 0 "register_operand" "=x")
+ (xor:TF
+ (match_operand:TF 1 "nonimmediate_operand" "%0")
+ (match_operand:TF 2 "nonimmediate_operand" "xm")))]
+ "TARGET_64BIT && ix86_binary_operator_ok (XOR, TFmode, operands)"
+ "pxor\t{%2, %0|%0, %2}"
+ [(set_attr "type" "sselog")
+ (set_attr "prefix_data16" "1")
+ (set_attr "mode" "TI")])
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Parallel integral element swizzling
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 746e3db..0ee92f6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2007-06-07 Uros Bizjak <ubizjak@gmail.com>
+
+ * gcc.target/i386/builtin-copysign.c: New test.
+
2007-06-07 Zdenek Dvorak <dvorakz@suse.cz>
PR tree-optimization/32220
@@ -365,7 +369,7 @@
* gcc.target/arm/long-calls-4.c: Likewise.
2007-05-25 Richard Guenther <rguenther@suse.de>
- Andrew Pinski <andrew_pinski@playstation.sony.com>
+ Andrew Pinski <andrew_pinski@playstation.sony.com>
PR tree-optimization/31982
* gcc.dg/tree-ssa/forwprop-2.c: New testcase.
diff --git a/gcc/testsuite/gcc.target/i386/builtin-copysign.c b/gcc/testsuite/gcc.target/i386/builtin-copysign.c
new file mode 100644
index 0000000..c20a0b6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-copysign.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+#define TEST_SET(MODE, CEXT) \
+MODE test1##CEXT(MODE a) { return -a; } \
+MODE test2##CEXT(MODE a) { return __builtin_fabs##CEXT(a); } \
+MODE test3##CEXT(MODE a) { return __builtin_copysign##CEXT(a, 0.0); } \
+MODE test4##CEXT(MODE a) { return __builtin_copysign##CEXT(a, -1.0); } \
+MODE test5##CEXT(MODE a, MODE b) { return __builtin_copysign##CEXT(a, b); }
+
+TEST_SET (float, f)
+TEST_SET (double, )
+TEST_SET (long double, l)
+#if defined (__LP64__)
+TEST_SET (__float128, q)
+#endif