* optabs.h (enum optab_index): Add new OTI_isinf.
(isinf_optab): Define corresponding macro.
* optabs.c (init_optabs): Initialize isinf_optab.
* genopinit.c (optabs): Implement isinf_optab using isinf?f2
patterns.
* builtins.c (mathfn_built_in): Handle BUILT_IN_ISINF{,F,L}.
(expand_builtin_interclass_mathfn): Expand BUILT_IN_ISINF{,F,L}
using isinf_optab.
(expand_builtin): Expand BUILT_IN_ISINF{,F,L} using
expand_builtin_interclass_mathfn.
* reg_stack.c (subst_stack_regs_pat): Handle UNSPEC_FXAM.
* config/i386/i386.md (UNSPEC_FXAM): New constant.
(fxam<mode>2_i387): New insn pattern.
(isinf<mode>2) New expander to implement isinf, isinff and isinfl
built-in functions as x87 inline asm.
testsuite/ChangeLog:
* gcc.dg/builtins-63.c: New test.
From-SVN: r121419
+2007-01-31 Uros Bizjak <ubizjak@gmail.com>
+
+ * optabs.h (enum optab_index): Add new OTI_isinf.
+ (isinf_optab): Define corresponding macro.
+ * optabs.c (init_optabs): Initialize isinf_optab.
+ * genopinit.c (optabs): Implement isinf_optab using isinf?f2
+ patterns.
+ * builtins.c (mathfn_built_in): Handle BUILT_IN_ISINF{,F,L}.
+ (expand_builtin_interclass_mathfn): Expand BUILT_IN_ISINF{,F,L}
+ using isinf_optab.
+ (expand_builtin): Expand BUILT_IN_ISINF{,F,L} using
+ expand_builtin_interclass_mathfn.
+ * reg_stack.c (subst_stack_regs_pat): Handle UNSPEC_FXAM.
+ * config/i386/i386.md (UNSPEC_FXAM): New constant.
+ (fxam<mode>2_i387): New insn pattern.
+ (isinf<mode>2) New expander to implement isinf, isinff and isinfl
+ built-in functions as x87 inline asm.
+
2007-01-31 Kazu Hirata <kazu@codesourcery.com>
* gcc/config/arm/unwind-arm.h (_sleb128_t, _uleb128_t): New.
CASE_MATHFN (BUILT_IN_HYPOT)
CASE_MATHFN (BUILT_IN_ILOGB)
CASE_MATHFN (BUILT_IN_INF)
+ CASE_MATHFN (BUILT_IN_ISINF)
CASE_MATHFN (BUILT_IN_J0)
CASE_MATHFN (BUILT_IN_J1)
CASE_MATHFN (BUILT_IN_JN)
{
CASE_FLT_FN (BUILT_IN_ILOGB):
errno_set = true; builtin_optab = ilogb_optab; break;
+ CASE_FLT_FN (BUILT_IN_ISINF):
+ builtin_optab = isinf_optab; break;
default:
gcc_unreachable ();
}
CASE_FLT_FN (BUILT_IN_ILOGB):
if (! flag_unsafe_math_optimizations)
break;
+ CASE_FLT_FN (BUILT_IN_ISINF):
target = expand_builtin_interclass_mathfn (exp, target, subtarget);
if (target)
return target;
(UNSPEC_FIST 66)
(UNSPEC_F2XM1 67)
(UNSPEC_TAN 68)
+ (UNSPEC_FXAM 69)
; x87 Rounding
(UNSPEC_FRNDINT_FLOOR 70)
DONE;
})
+(define_insn "fxam<mode>2_i387"
+ [(set (match_operand:HI 0 "register_operand" "=a")
+ (unspec:HI
+ [(match_operand:X87MODEF 1 "register_operand" "f")]
+ UNSPEC_FXAM))]
+ "TARGET_USE_FANCY_MATH_387"
+ "fxam\n\tfnstsw\t%0"
+ [(set_attr "type" "multi")
+ (set_attr "unit" "i387")
+ (set_attr "mode" "<MODE>")])
+
+(define_expand "isinf<mode>2"
+ [(use (match_operand:SI 0 "register_operand" ""))
+ (use (match_operand:X87MODEF 1 "register_operand" ""))]
+ "TARGET_USE_FANCY_MATH_387
+ && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
+ || TARGET_MIX_SSE_I387)"
+{
+ rtx mask = GEN_INT (0x45);
+ rtx val = GEN_INT (0x05);
+
+ rtx cond;
+
+ rtx scratch = gen_reg_rtx (HImode);
+ rtx res = gen_reg_rtx (QImode);
+
+ emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
+ emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
+ emit_insn (gen_cmpqi_ext_3 (scratch, val));
+ cond = gen_rtx_fmt_ee (EQ, QImode,
+ gen_rtx_REG (CCmode, FLAGS_REG),
+ const0_rtx);
+ emit_insn (gen_rtx_SET (VOIDmode, res, cond));
+ emit_insn (gen_zero_extendqisi2 (operands[0], res));
+ DONE;
+})
+
\f
;; Block operation instructions
abs_optab->handlers[$A].insn_code = CODE_FOR_$(abs$F$a2$)",
"absv_optab->handlers[$A].insn_code = CODE_FOR_$(absv$I$a2$)",
"copysign_optab->handlers[$A].insn_code = CODE_FOR_$(copysign$F$a3$)",
+ "isinf_optab->handlers[$A].insn_code = CODE_FOR_$(isinf$a2$)",
"sqrt_optab->handlers[$A].insn_code = CODE_FOR_$(sqrt$a2$)",
"floor_optab->handlers[$A].insn_code = CODE_FOR_$(floor$a2$)",
"lfloor_optab->handlers[$B][$A].insn_code = CODE_FOR_$(lfloor$F$a$I$b2$)",
atan_optab = init_optab (UNKNOWN);
copysign_optab = init_optab (UNKNOWN);
+ isinf_optab = init_optab (UNKNOWN);
+
strlen_optab = init_optab (UNKNOWN);
cbranch_optab = init_optab (UNKNOWN);
cmov_optab = init_optab (UNKNOWN);
/* Copy sign */
OTI_copysign,
+ /* Test for infinite value */
+ OTI_isinf,
+
/* Compare insn; two operands. */
OTI_cmp,
/* Used only for libcalls for unsigned comparisons. */
#define atan_optab (optab_table[OTI_atan])
#define copysign_optab (optab_table[OTI_copysign])
+#define isinf_optab (optab_table[OTI_isinf])
+
#define cmp_optab (optab_table[OTI_cmp])
#define ucmp_optab (optab_table[OTI_ucmp])
#define tst_optab (optab_table[OTI_tst])
replace_reg (src1, FIRST_STACK_REG);
break;
+ case UNSPEC_FXAM:
+
+ /* This insn only operate on the top of the stack. */
+
+ src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
+ emit_swap_insn (insn, regstack, *src1);
+
+ src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
+
+ replace_reg (src1, FIRST_STACK_REG);
+
+ if (src1_note)
+ {
+ remove_regno_note (insn, REG_DEAD,
+ REGNO (XEXP (src1_note, 0)));
+ emit_pop_insn (insn, regstack, XEXP (src1_note, 0),
+ EMIT_AFTER);
+ }
+
+ break;
+
case UNSPEC_SIN:
case UNSPEC_COS:
case UNSPEC_FRNDINT:
+2007-01-31 Uros Bizjak <ubizjak@gmail.com>
+
+ * gcc.dg/builtins-63.c: New test.
+
2007-01-31 Tobias Burnus <burnus@net-b.de>
PR fortran/27588
--- /dev/null
+/* Copyright (C) 2007 Free Software Foundation.
+
+ Check that isinf, isinff and isinfl built-in functions compile.
+
+ Written by Uros Bizjak, 31st January 2007. */
+
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+extern int isinf(double);
+extern int isinff(float);
+extern int isinfl(long double);
+
+int test1(double x)
+{
+ return isinf(x);
+}
+
+int test1f(float x)
+{
+ return isinff(x);
+}
+
+int test1l(long double x)
+{
+ return isinfl(x);
+}
+