* optabs.h (enum optab_index): Add new OTI_isinf.
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 31 Jan 2007 12:30:20 +0000 (12:30 +0000)
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 31 Jan 2007 12:30:20 +0000 (12:30 +0000)
(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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@121419 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/builtins.c
gcc/config/i386/i386.md
gcc/genopinit.c
gcc/optabs.c
gcc/optabs.h
gcc/reg-stack.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/builtins-63.c [new file with mode: 0644]

index 8c0bbcb..ba55b7c 100644 (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.
index 5ba1eae..777206c 100644 (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;
index a9620e2..cfe48c4 100644 (file)
    (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
 
index ad72637..1e70c6d 100644 (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$)",
index c7f16c2..e66c115 100644 (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);
index 85d9ca7..d3cfd74 100644 (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])
index 0df425e..f21d833 100644 (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:
index d28f8e6..97bf5f1 100644 (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
diff --git a/gcc/testsuite/gcc.dg/builtins-63.c b/gcc/testsuite/gcc.dg/builtins-63.c
new file mode 100644 (file)
index 0000000..8fcbc68
--- /dev/null
@@ -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);
+}
+