optabs.h (enum optab_index): Add new OTI_isinf.

* 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
This commit is contained in:
Uros Bizjak 2007-01-31 13:30:20 +01:00 committed by Uros Bizjak
parent 010dc0fdd0
commit 9ed4207fce
9 changed files with 121 additions and 0 deletions

View File

@ -1,3 +1,21 @@
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.

View File

@ -1676,6 +1676,7 @@ mathfn_built_in (tree type, enum built_in_function fn)
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)
@ -2198,6 +2199,8 @@ expand_builtin_interclass_mathfn (tree exp, rtx target, rtx subtarget)
{
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 ();
}
@ -5923,6 +5926,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
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;

View File

@ -122,6 +122,7 @@
(UNSPEC_FIST 66)
(UNSPEC_F2XM1 67)
(UNSPEC_TAN 68)
(UNSPEC_FXAM 69)
; x87 Rounding
(UNSPEC_FRNDINT_FLOOR 70)
@ -17597,6 +17598,43 @@
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;
})
;; Block operation instructions

View File

@ -118,6 +118,7 @@ static const char * const optabs[] =
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$)",

View File

@ -5378,6 +5378,8 @@ init_optabs (void)
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);

View File

@ -204,6 +204,9 @@ enum optab_index
/* Copy sign */
OTI_copysign,
/* Test for infinite value */
OTI_isinf,
/* Compare insn; two operands. */
OTI_cmp,
/* Used only for libcalls for unsigned comparisons. */
@ -370,6 +373,8 @@ extern GTY(()) optab optab_table[OTI_MAX];
#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])

View File

@ -1629,6 +1629,27 @@ subst_stack_regs_pat (rtx insn, stack regstack, rtx pat)
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:

View File

@ -1,3 +1,7 @@
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

View File

@ -0,0 +1,28 @@
/* 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);
}