optabs.h (enum optab_index): Add new OTI_expm1.
authorUros Bizjak <uros@kss-loka.si>
Mon, 3 May 2004 05:31:45 +0000 (07:31 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Mon, 3 May 2004 05:31:45 +0000 (07:31 +0200)
2004-05-03  Uros Bizjak  <uros@kss-loka.si>

* optabs.h (enum optab_index): Add new OTI_expm1.
(expm1_optab): Define corresponding macro.
* optabs.c (init_optabs): Initialize expm1_optab.
* genopinit.c (optabs): Implement expm1_optab using expm1?f2
patterns.
* builtins.c (expand_builtin_mathfn): Handle BUILT_IN_EXPM1{,F,L}
using expm1_optab.
(expand_builtin): Expand BUILT_IN_EXPM1{,F,L} using
expand_builtin_mathfn if flag_unsafe_math_optimizations is set.

* config/i386/i386.md (expm1df2, expm1sf2, expm1xf2): New expanders
to implement expm1, expm1f and expm1l built-ins as inline x87
intrinsics.

testsuite:

        * gcc.dg/builtins-34.c: Also check expm1*.

From-SVN: r81425

gcc/ChangeLog
gcc/builtins.c
gcc/config/i386/i386.md
gcc/genopinit.c
gcc/optabs.c
gcc/optabs.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/builtins-34.c

index 9a2374792e5532073bfe4958a1718bca4414ac16..e907ac3a52d29676c6112dec21a2f79b4edfd21c 100644 (file)
@@ -1,3 +1,19 @@
+2004-05-03  Uros Bizjak  <uros@kss-loka.si>
+
+       * optabs.h (enum optab_index): Add new OTI_expm1.
+       (expm1_optab): Define corresponding macro.
+       * optabs.c (init_optabs): Initialize expm1_optab.
+       * genopinit.c (optabs): Implement expm1_optab using expm1?f2
+       patterns.
+       * builtins.c (expand_builtin_mathfn): Handle BUILT_IN_EXPM1{,F,L}
+       using expm1_optab.
+       (expand_builtin): Expand BUILT_IN_EXPM1{,F,L} using
+       expand_builtin_mathfn if flag_unsafe_math_optimizations is set.
+
+       * config/i386/i386.md (expm1df2, expm1sf2, expm1xf2): New expanders
+       to implement expm1, expm1f and expm1l built-ins as inline x87
+       intrinsics.
+
 2004-05-02  Alexandre Oliva  <aoliva@redhat.com>
 
        2003-11-19  Richard Sandiford  <rsandifo@redhat.com>
index 96d365ababb305cff1783837da9d182fce798a2d..c42a42392df495deb92e3b5ca6d018ee4216c8cf 100644 (file)
@@ -1600,6 +1600,10 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
     case BUILT_IN_EXP2F:
     case BUILT_IN_EXP2L:
       errno_set = true; builtin_optab = exp2_optab; break;
+    case BUILT_IN_EXPM1:
+    case BUILT_IN_EXPM1F:
+    case BUILT_IN_EXPM1L:
+      errno_set = true; builtin_optab = expm1_optab; break;
     case BUILT_IN_LOGB:
     case BUILT_IN_LOGBF:
     case BUILT_IN_LOGBL:
@@ -5292,6 +5296,9 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
     case BUILT_IN_EXP2:
     case BUILT_IN_EXP2F:
     case BUILT_IN_EXP2L:
+    case BUILT_IN_EXPM1:
+    case BUILT_IN_EXPM1F:
+    case BUILT_IN_EXPM1L:
     case BUILT_IN_LOGB:
     case BUILT_IN_LOGBF:
     case BUILT_IN_LOGBL:
index e258559d18893007b3c24ebc61bafdcdc8c3872d..75d153d6c5995089396e1b0bddc43496cad4d430 100644 (file)
     operands[i] = gen_reg_rtx (XFmode);
   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
 })
+
+(define_expand "expm1df2"
+  [(set (match_dup 2)
+       (float_extend:XF (match_operand:DF 1 "register_operand" "")))
+   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
+   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
+   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
+   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
+   (parallel [(set (match_dup 8)
+                  (unspec:XF [(match_dup 7) (match_dup 5)]
+                             UNSPEC_FSCALE_FRACT))
+                  (set (match_dup 9)
+                  (unspec:XF [(match_dup 7) (match_dup 5)]
+                             UNSPEC_FSCALE_EXP))])
+   (parallel [(set (match_dup 11)
+                  (unspec:XF [(match_dup 10) (match_dup 9)]
+                             UNSPEC_FSCALE_FRACT))
+             (set (match_dup 12)
+                  (unspec:XF [(match_dup 10) (match_dup 9)]
+                             UNSPEC_FSCALE_EXP))])
+   (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
+   (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
+   (set (match_operand:DF 0 "register_operand" "")
+       (float_truncate:DF (match_dup 14)))]
+  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+   && flag_unsafe_math_optimizations"
+{
+  rtx temp;
+  int i;
+
+  for (i=2; i<15; i++)
+    operands[i] = gen_reg_rtx (XFmode);
+  temp = standard_80387_constant_rtx (5); /* fldl2e */
+  emit_move_insn (operands[3], temp);
+  emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
+})
+
+(define_expand "expm1sf2"
+  [(set (match_dup 2)
+       (float_extend:XF (match_operand:SF 1 "register_operand" "")))
+   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
+   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
+   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
+   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
+   (parallel [(set (match_dup 8)
+                  (unspec:XF [(match_dup 7) (match_dup 5)]
+                             UNSPEC_FSCALE_FRACT))
+                  (set (match_dup 9)
+                  (unspec:XF [(match_dup 7) (match_dup 5)]
+                             UNSPEC_FSCALE_EXP))])
+   (parallel [(set (match_dup 11)
+                  (unspec:XF [(match_dup 10) (match_dup 9)]
+                             UNSPEC_FSCALE_FRACT))
+             (set (match_dup 12)
+                  (unspec:XF [(match_dup 10) (match_dup 9)]
+                             UNSPEC_FSCALE_EXP))])
+   (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
+   (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
+   (set (match_operand:SF 0 "register_operand" "")
+       (float_truncate:SF (match_dup 14)))]
+  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+   && flag_unsafe_math_optimizations"
+{
+  rtx temp;
+  int i;
+
+  for (i=2; i<15; i++)
+    operands[i] = gen_reg_rtx (XFmode);
+  temp = standard_80387_constant_rtx (5); /* fldl2e */
+  emit_move_insn (operands[3], temp);
+  emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
+})
+
+(define_expand "expm1xf2"
+  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
+                              (match_dup 2)))
+   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
+   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
+   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
+   (parallel [(set (match_dup 7)
+                  (unspec:XF [(match_dup 6) (match_dup 4)]
+                             UNSPEC_FSCALE_FRACT))
+                  (set (match_dup 8)
+                  (unspec:XF [(match_dup 6) (match_dup 4)]
+                             UNSPEC_FSCALE_EXP))])
+   (parallel [(set (match_dup 10)
+                  (unspec:XF [(match_dup 9) (match_dup 8)]
+                             UNSPEC_FSCALE_FRACT))
+             (set (match_dup 11)
+                  (unspec:XF [(match_dup 9) (match_dup 8)]
+                             UNSPEC_FSCALE_EXP))])
+   (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
+   (set (match_operand:XF 0 "register_operand" "")
+       (plus:XF (match_dup 12) (match_dup 7)))]
+  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+   && flag_unsafe_math_optimizations"
+{
+  rtx temp;
+  int i;
+
+  for (i=2; i<13; i++)
+    operands[i] = gen_reg_rtx (XFmode);
+  temp = standard_80387_constant_rtx (5); /* fldl2e */
+  emit_move_insn (operands[2], temp);
+  emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
+})
 \f
 ;; Block operation instructions
 
index 95d53107ae277f7fa943c8f012e1a7cf3d022dc8..87934496b766bfbcdf88cfbfb50201460b0b9b50 100644 (file)
@@ -130,6 +130,7 @@ static const char * const optabs[] =
   "exp_optab->handlers[$A].insn_code = CODE_FOR_$(exp$a2$)",
   "exp10_optab->handlers[$A].insn_code = CODE_FOR_$(exp10$a2$)",
   "exp2_optab->handlers[$A].insn_code = CODE_FOR_$(exp2$a2$)",
+  "expm1_optab->handlers[$A].insn_code = CODE_FOR_$(expm1$a2$)",
   "logb_optab->handlers[$A].insn_code = CODE_FOR_$(logb$a2$)",
   "ilogb_optab->handlers[$A].insn_code = CODE_FOR_$(ilogb$a2$)",
   "log_optab->handlers[$A].insn_code = CODE_FOR_$(log$a2$)",
index 8d2a232a469a4ab24719c81a95b3fd8aa8fae6b6..1632ecfe8c9100148c3e7ea530520be9424dcb7c 100644 (file)
@@ -5386,6 +5386,7 @@ init_optabs (void)
   exp_optab = init_optab (UNKNOWN);
   exp10_optab = init_optab (UNKNOWN);
   exp2_optab = init_optab (UNKNOWN);
+  expm1_optab = init_optab (UNKNOWN);
   logb_optab = init_optab (UNKNOWN);
   ilogb_optab = init_optab (UNKNOWN);
   log_optab = init_optab (UNKNOWN);
index 2e0a47ab9e9411bf6758db745c9a650518ea84b2..a7aac1934f3e2dcd54406bb61971aae3f4ff57fe 100644 (file)
@@ -164,6 +164,8 @@ enum optab_index
   OTI_exp10,
   /* Base-2 Exponential */
   OTI_exp2,
+  /* Exponential - 1*/
+  OTI_expm1,
   /* Radix-independent exponent */
   OTI_logb,
   OTI_ilogb,
@@ -281,6 +283,7 @@ extern GTY(()) optab optab_table[OTI_MAX];
 #define exp_optab (optab_table[OTI_exp])
 #define exp10_optab (optab_table[OTI_exp10])
 #define exp2_optab (optab_table[OTI_exp2])
+#define expm1_optab (optab_table[OTI_expm1])
 #define logb_optab (optab_table[OTI_logb])
 #define ilogb_optab (optab_table[OTI_ilogb])
 #define log_optab (optab_table[OTI_log])
index 822cb30f7c0ed4d1d34bd7b8a31886c16eb7a643..5735a6c55483a2b52ec894ad977a70c4ecc7fc22 100644 (file)
@@ -1,3 +1,7 @@
+2004-05-03  Uros Bizjak  <uros@kss-loka.si>
+
+        * gcc.dg/builtins-34.c: Also check expm1*.
+
 2004-05-01  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * gcc.dg/torture/builtin-integral-1.c: Reorg and add more cases.
index d2bf4d412195a17a2ca61bf9c41b48ff25ad6cf6..0055f329dd532c7fa9c6ce57f04d4063f11b36bd 100644 (file)
@@ -1,7 +1,7 @@
 /* Copyright (C) 2004 Free Software Foundation.
 
-   Check that exp10, exp10f, exp10l, exp2, exp2f, exp2l, pow10, pow10f
-   and pow10l built-in functions compile.
+   Check that exp10, exp10f, exp10l, exp2, exp2f, exp2l, pow10, pow10f,
+   pow10l, expm1, expm1f and expm1l built-in functions compile.
 
    Written by Uros Bizjak, 13th February 2004.  */
 
 extern double exp10(double);
 extern double exp2(double);
 extern double pow10(double);
+extern double expm1(double);
 extern float exp10f(float);
 extern float exp2f(float);
 extern float pow10f(float);
+extern float expm1f(float);
 extern long double exp10l(long double);
 extern long double exp2l(long double);
 extern long double pow10l(long double);
+extern long double expm1l(long double);
 
 
 double test1(double x)
@@ -34,6 +37,11 @@ double test3(double x)
   return pow10(x);
 }
 
+double test4(double x)
+{
+  return expm1(x);
+}
+
 float test1f(float x)
 {
   return exp10f(x);
@@ -49,6 +57,11 @@ float test3f(float x)
   return pow10f(x);
 }
 
+float test4f(float x)
+{
+  return expm1f(x);
+}
+
 long double test1l(long double x)
 {
   return exp10l(x);
@@ -64,3 +77,8 @@ long double test3l(long double x)
   return pow10l(x);
 }
 
+long double test4l(long double x)
+{
+  return expm1l(x);
+}
+