case CODE_FOR_xsiexpqpf_kf:
icode = CODE_FOR_xsiexpqpf_tf;
break;
- case CODE_FOR_xststdcqp_kf:
- icode = CODE_FOR_xststdcqp_tf;
+ case CODE_FOR_xststdc_kf:
+ icode = CODE_FOR_xststdc_tf;
break;
case CODE_FOR_xscmpexpqp_eq_kf:
icode = CODE_FOR_xscmpexpqp_eq_tf;
const signed int \
__builtin_vsx_scalar_test_data_class_dp (double, const int<7>);
- VSTDCDP xststdcdp {}
+ VSTDCDP xststdc_df {}
const signed int \
__builtin_vsx_scalar_test_data_class_sp (float, const int<7>);
- VSTDCSP xststdcsp {}
+ VSTDCSP xststdc_sf {}
const signed int __builtin_vsx_scalar_test_neg_dp (double);
VSTDCNDP xststdcnegdp {}
const signed int __builtin_vsx_scalar_test_data_class_qp (_Float128, \
const int<7>);
- VSTDCQP xststdcqp_kf {}
+ VSTDCQP xststdc_kf {}
const signed int __builtin_vsx_scalar_test_neg_qp (_Float128);
VSTDCNQP xststdcnegqp_kf {}
(FRAME_POINTER_REGNUM 110)
])
+;;
+;; Test data class mask bits
+;;
+
+(define_constants
+ [(VSX_TEST_DATA_CLASS_NAN 0x40)
+ (VSX_TEST_DATA_CLASS_POS_INF 0x20)
+ (VSX_TEST_DATA_CLASS_NEG_INF 0x10)
+ (VSX_TEST_DATA_CLASS_POS_ZERO 0x8)
+ (VSX_TEST_DATA_CLASS_NEG_ZERO 0x4)
+ (VSX_TEST_DATA_CLASS_POS_DENORMAL 0x2)
+ (VSX_TEST_DATA_CLASS_NEG_DENORMAL 0x1)
+ ])
+
;;
;; UNSPEC usage
;;
(define_mode_attr sd [(SF "s") (DF "d")
(V4SF "s") (V2DF "d")])
+; A generic s/d/q attribute, for sp/dp/qp for example.
+(define_mode_attr sdq [(SF "s") (DF "d")
+ (TF "q") (KF "q")])
+
; "s" or nothing, for fmuls/fmul for example.
(define_mode_attr s [(SF "s") (DF "")])
(define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
(TF "FLOAT128_IEEE_P (TFmode)")])
+; Iterator for IEEE floating point
+(define_mode_iterator IEEE_FP [SFDF IEEE128])
+
+; "vsx/altivec_register_operand", for IEEE_FP predicates
+(define_mode_attr fp_register_op [(SF "vsx_register_operand")
+ (DF "vsx_register_operand")
+ (TF "altivec_register_operand")
+ (KF "altivec_register_operand")])
+
+; "wa" or "v", for IEEE_FP constraints
+(define_mode_attr wa_v [(SF "wa") (DF "wa")
+ (TF "v") (KF "v")])
+
+; "x" or nothing, for IEEE_FP
+(define_mode_attr x [(SF "x") (DF "x")
+ (TF "") (KF "")])
+
; Iterator for 128-bit floating point
(define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
(IF "TARGET_FLOAT128_TYPE")
"xscmpexpqp %0,%1,%2"
[(set_attr "type" "fpcompare")])
-;; VSX Scalar Test Data Class Quad-Precision
-;; (Expansion for scalar_test_data_class (__ieee128, int))
-;; (Has side effect of setting the lt bit if operand 1 is negative,
-;; setting the eq bit if any of the conditions tested by operand 2
-;; are satisfied, and clearing the gt and undordered bits to zero.)
-(define_expand "xststdcqp_<mode>"
- [(set (match_dup 3)
- (compare:CCFP
- (unspec:IEEE128
- [(match_operand:IEEE128 1 "altivec_register_operand" "v")
- (match_operand:SI 2 "u7bit_cint_operand" "n")]
- UNSPEC_VSX_STSTDC)
- (const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=r")
- (eq:SI (match_dup 3)
- (const_int 0)))]
- "TARGET_P9_VECTOR"
-{
- operands[3] = gen_reg_rtx (CCFPmode);
-})
-
-;; VSX Scalar Test Data Class Double- and Single-Precision
+;; VSX Scalar Test Data Class Quad-/Double-/Single-Precision
;; (The lt bit is set if operand 1 is negative. The eq bit is set
;; if any of the conditions tested by operand 2 are satisfied.
;; The gt and unordered bits are cleared to zero.)
-(define_expand "xststdc<sd>p"
+(define_expand "xststdc_<mode>"
[(set (match_dup 3)
(compare:CCFP
- (unspec:SFDF
- [(match_operand:SFDF 1 "vsx_register_operand" "wa")
+ (unspec:IEEE_FP
+ [(match_operand:IEEE_FP 1 "<fp_register_op>" "<wa_v>")
(match_operand:SI 2 "u7bit_cint_operand" "n")]
UNSPEC_VSX_STSTDC)
(match_dup 4)))
operands[4] = CONST0_RTX (SImode);
})
+(define_expand "isinf<mode>2"
+ [(use (match_operand:SI 0 "gpc_reg_operand"))
+ (use (match_operand:IEEE_FP 1 "<fp_register_op>"))]
+ "TARGET_HARD_FLOAT && TARGET_P9_VECTOR"
+{
+ int mask = VSX_TEST_DATA_CLASS_POS_INF | VSX_TEST_DATA_CLASS_NEG_INF;
+ emit_insn (gen_xststdc_<mode> (operands[0], operands[1], GEN_INT (mask)));
+ DONE;
+})
+
;; The VSX Scalar Test Negative Quad-Precision
(define_expand "xststdcnegqp_<mode>"
[(set (match_dup 2)
operands[3] = CONST0_RTX (SImode);
})
-(define_insn "*xststdcqp_<mode>"
+(define_insn "*xststdc_<mode>"
[(set (match_operand:CCFP 0 "" "=y")
(compare:CCFP
- (unspec:IEEE128
- [(match_operand:IEEE128 1 "altivec_register_operand" "v")
+ (unspec:IEEE_FP
+ [(match_operand:IEEE_FP 1 "<fp_register_op>" "<wa_v>")
(match_operand:SI 2 "u7bit_cint_operand" "n")]
UNSPEC_VSX_STSTDC)
(const_int 0)))]
"TARGET_P9_VECTOR"
- "xststdcqp %0,%1,%2"
- [(set_attr "type" "fpcompare")])
-
-(define_insn "*xststdc<sd>p"
- [(set (match_operand:CCFP 0 "" "=y")
- (compare:CCFP
- (unspec:SFDF [(match_operand:SFDF 1 "vsx_register_operand" "wa")
- (match_operand:SI 2 "u7bit_cint_operand" "n")]
- UNSPEC_VSX_STSTDC)
- (match_operand:SI 3 "zero_constant" "j")))]
- "TARGET_P9_VECTOR"
- "xststdc<sd>p %0,%x1,%2"
+ "xststdc<sdq>p %0,%<x>1,%2"
[(set_attr "type" "fpcompare")])
;; VSX Vector Extract Exponent Double and Single Precision
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
+/* { dg-require-effective-target powerpc_vsx } */
+
+int test1 (double x)
+{
+ return __builtin_isinf (x);
+}
+
+int test2 (float x)
+{
+ return __builtin_isinf (x);
+}
+
+int test3 (float x)
+{
+ return __builtin_isinff (x);
+}
+
+/* { dg-final { scan-assembler-not {\mfcmp} } } */
+/* { dg-final { scan-assembler-times {\mxststdcsp\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mxststdcdp\M} 1 } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-require-effective-target ppc_float128_hw } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9 -mabi=ieeelongdouble -Wno-psabi" } */
+/* { dg-require-effective-target powerpc_vsx } */
+
+int test1 (long double x)
+{
+ return __builtin_isinf (x);
+}
+
+int test2 (long double x)
+{
+ return __builtin_isinfl (x);
+}
+
+/* { dg-final { scan-assembler-not {\mxscmpuqp\M} } } */
+/* { dg-final { scan-assembler-times {\mxststdcqp\M} 2 } } */