* optabs.h (enum optab_index): Add new OTI_scalb.
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 20 Feb 2007 13:33:51 +0000 (13:33 +0000)
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 20 Feb 2007 13:33:51 +0000 (13:33 +0000)
(scalb_optab): Define corresponding macro.
* optabs.c (init_optabs): Initialize scalb_optab.
* genopinit.c (optabs): Implement scalb_optab using scalb?f3
patterns.
* builtins.c (expand_builtin_mathfn_2, expand_builtin): Handle
BUILT_IN_SCALB{,F,L}, BUILT_IN_SCALBN{,F,L} and BUILT_IN_SCALBLN{,F,L}.
(expand_builtin): Expand BUILT_IN_SCALB{,F,L}, BUILT_IN_SCALBN{,F,L}
and BUILT_IN_SCALBLN{,F,L} using expand_builtin_mathfn_2 if
flag_unsafe_math_optimizations is set.

* config/i386/i386.md (scalbxf3, scalb<mode>3): New expanders
to implement scalbf, scalb and scalbl built-ins as inline x87
intrinsics.

testsuite/ChangeLog

* gcc.dg/builtins-34.c: Add scalb/scalbn/scalbln cases.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@122162 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/testsuite/ChangeLog
gcc/testsuite/gcc.dg/builtins-34.c

index ebceb40..292bfbc 100644 (file)
@@ -1,3 +1,21 @@
+2007-02-20  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
+           Uros Bizjak  <ubizjak@gmail.com>
+
+       * optabs.h (enum optab_index): Add new OTI_scalb.
+       (scalb_optab): Define corresponding macro.
+       * optabs.c (init_optabs): Initialize scalb_optab.
+       * genopinit.c (optabs): Implement scalb_optab using scalb?f3
+       patterns.
+       * builtins.c (expand_builtin_mathfn_2, expand_builtin): Handle
+       BUILT_IN_SCALB{,F,L}, BUILT_IN_SCALBN{,F,L} and BUILT_IN_SCALBLN{,F,L}.
+       (expand_builtin): Expand BUILT_IN_SCALB{,F,L}, BUILT_IN_SCALBN{,F,L}
+       and BUILT_IN_SCALBLN{,F,L} using expand_builtin_mathfn_2 if
+       flag_unsafe_math_optimizations is set.
+
+       * config/i386/i386.md (scalbxf3, scalb<mode>3): New expanders
+       to implement scalbf, scalb and scalbl built-ins as inline x87
+       intrinsics.
+
 2007-02-20  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
             DJ Delorie <dj@redhat.com>
 
index 67d9bf6..e1c2dee 100644 (file)
@@ -1973,10 +1973,15 @@ expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
   bool errno_set = true;
   bool stable = true;
 
-  if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP
-      || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF
-      || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL)
-    op1_type = INTEGER_TYPE;
+  switch (DECL_FUNCTION_CODE (fndecl))
+    {
+    CASE_FLT_FN (BUILT_IN_SCALBN):
+    CASE_FLT_FN (BUILT_IN_SCALBLN):
+    CASE_FLT_FN (BUILT_IN_LDEXP):
+      op1_type = INTEGER_TYPE;
+    default:
+      break;
+    }
 
   if (!validate_arglist (exp, REAL_TYPE, op1_type, VOID_TYPE))
     return NULL_RTX;
@@ -1990,6 +1995,15 @@ expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
       builtin_optab = pow_optab; break;
     CASE_FLT_FN (BUILT_IN_ATAN2):
       builtin_optab = atan2_optab; break;
+    CASE_FLT_FN (BUILT_IN_SCALB):
+      if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
+       return 0;
+      builtin_optab = scalb_optab; break;
+    CASE_FLT_FN (BUILT_IN_SCALBN):
+    CASE_FLT_FN (BUILT_IN_SCALBLN):
+      if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
+       return 0;
+    /* Fall through... */
     CASE_FLT_FN (BUILT_IN_LDEXP):
       builtin_optab = ldexp_optab; break;
     CASE_FLT_FN (BUILT_IN_FMOD):
@@ -5963,6 +5977,9 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
 
     CASE_FLT_FN (BUILT_IN_ATAN2):
     CASE_FLT_FN (BUILT_IN_LDEXP):
+    CASE_FLT_FN (BUILT_IN_SCALB):
+    CASE_FLT_FN (BUILT_IN_SCALBN):
+    CASE_FLT_FN (BUILT_IN_SCALBLN):
       if (! flag_unsafe_math_optimizations)
        break;
 
index 7dae8e1..920b9dd 100644 (file)
   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
   DONE;
 })
+
+(define_expand "scalbxf3"
+  [(parallel [(set (match_operand:XF 0 " register_operand" "")
+                  (unspec:XF [(match_operand:XF 1 "register_operand" "")
+                              (match_operand:XF 2 "register_operand" "")]
+                             UNSPEC_FSCALE_FRACT))
+             (set (match_dup 3)
+                  (unspec:XF [(match_dup 1) (match_dup 2)]
+                             UNSPEC_FSCALE_EXP))])]
+  "TARGET_USE_FANCY_MATH_387
+   && flag_unsafe_math_optimizations && !optimize_size"
+{
+  operands[3] = gen_reg_rtx (XFmode);
+})
+
+(define_expand "scalb<mode>3"
+  [(use (match_operand:X87MODEF12 0 "register_operand" ""))
+   (use (match_operand:X87MODEF12 1 "general_operand" ""))
+   (use (match_operand:X87MODEF12 2 "register_operand" ""))]
+ "TARGET_USE_FANCY_MATH_387
+   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
+       || TARGET_MIX_SSE_I387)
+   && flag_unsafe_math_optimizations && !optimize_size"
+{
+  rtx op0 = gen_reg_rtx (XFmode);
+  rtx op1 = gen_reg_rtx (XFmode);
+  rtx op2 = gen_reg_rtx (XFmode);
+
+  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
+  emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
+  emit_insn (gen_scalbxf3 (op0, op1, op2));
+  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+  DONE;
+})
 \f
 
 (define_insn "frndintxf2"
index 1e70c6d..3c06639 100644 (file)
@@ -140,6 +140,7 @@ static const char * const optabs[] =
   "exp2_optab->handlers[$A].insn_code = CODE_FOR_$(exp2$a2$)",
   "expm1_optab->handlers[$A].insn_code = CODE_FOR_$(expm1$a2$)",
   "ldexp_optab->handlers[$A].insn_code = CODE_FOR_$(ldexp$a3$)",
+  "scalb_optab->handlers[$A].insn_code = CODE_FOR_$(scalb$a3$)",
   "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 6a78b37..51c84c8 100644 (file)
@@ -5449,6 +5449,7 @@ init_optabs (void)
   exp2_optab = init_optab (UNKNOWN);
   expm1_optab = init_optab (UNKNOWN);
   ldexp_optab = init_optab (UNKNOWN);
+  scalb_optab = init_optab (UNKNOWN);
   logb_optab = init_optab (UNKNOWN);
   ilogb_optab = init_optab (UNKNOWN);
   log_optab = init_optab (UNKNOWN);
index d3cfd74..0f8c796 100644 (file)
@@ -179,6 +179,8 @@ enum optab_index
   OTI_expm1,
   /* Load exponent of a floating point number */
   OTI_ldexp,
+  /* Multiply floating-point number by integral power of radix */
+  OTI_scalb,
   /* Radix-independent exponent */
   OTI_logb,
   OTI_ilogb,
@@ -357,6 +359,7 @@ extern GTY(()) optab optab_table[OTI_MAX];
 #define exp2_optab (optab_table[OTI_exp2])
 #define expm1_optab (optab_table[OTI_expm1])
 #define ldexp_optab (optab_table[OTI_ldexp])
+#define scalb_optab (optab_table[OTI_scalb])
 #define logb_optab (optab_table[OTI_logb])
 #define ilogb_optab (optab_table[OTI_ilogb])
 #define log_optab (optab_table[OTI_log])
index b5f91c5..80c712c 100644 (file)
@@ -1,3 +1,7 @@
+2007-02-20  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
+
+       * gcc.dg/builtins-34.c: Add scalb/scalbn/scalbln cases.
+
 2007-02-20  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
             DJ Delorie <dj@redhat.com>
 
@@ -76,7 +80,7 @@
 
 2007-02-18  Roger Sayle  <roger@eyesopen.com>
 
-        * gfortran.dg/forall_10.f90: New test case.
+       * gfortran.dg/forall_10.f90: New test case.
 
 2007-02-18  Eric Botcazou  <ebotcazou@adacore.com>
 
 
 2007-01-06  Lee Millward  <lee.millward@codesourcery.com>
 
-       PR c++/19439
-       * g++.dg/template/duplicate1.C: New test
-       * g++.dg/template/memfriend6.C: Adjust error markers.
+       PR c++/19439
+       * g++.dg/template/duplicate1.C: New test
+       * g++.dg/template/memfriend6.C: Adjust error markers.
        
 2007-01-05  Andrew Pinski  <Andrew_Pinski@playstation.sony.com>
 
index f2625d5..ee8d751 100644 (file)
@@ -13,16 +13,25 @@ extern double exp2(double);
 extern double pow10(double);
 extern double expm1(double);
 extern double ldexp(double, int);
+extern double scalb(double, double);
+extern double scalbn(double, int);
+extern double scalbln(double, long);
 extern float exp10f(float);
 extern float exp2f(float);
 extern float pow10f(float);
 extern float expm1f(float);
 extern float ldexpf(float, int);
+extern float scalbf(float, float);
+extern float scalbnf(float, int);
+extern float scalblnf(float, long);
 extern long double exp10l(long double);
 extern long double exp2l(long double);
 extern long double pow10l(long double);
 extern long double expm1l(long double);
 extern long double ldexpl(long double, int);
+extern long double scalbl(long double, long double);
+extern long double scalbnl(long double, int);
+extern long double scalblnl(long double, long);
 
 
 double test1(double x)
@@ -50,6 +59,21 @@ double test5(double x, int exp)
   return ldexp(x, exp);
 }
 
+double test6(double x, double exp)
+{
+  return scalb(x, exp);
+}
+
+double test7(double x, int exp)
+{
+  return scalbn(x, exp);
+}
+
+double test8(double x, long exp)
+{
+  return scalbln(x, exp);
+}
+
 float test1f(float x)
 {
   return exp10f(x);
@@ -75,6 +99,21 @@ float test5f(float x, int exp)
   return ldexpf(x, exp);
 }
 
+float test6f(float x, float exp)
+{
+  return scalbf(x, exp);
+}
+
+float test7f(float x, int exp)
+{
+  return scalbnf(x, exp);
+}
+
+float test8f(float x, long exp)
+{
+  return scalblnf(x, exp);
+}
+
 long double test1l(long double x)
 {
   return exp10l(x);
@@ -99,3 +138,18 @@ long double test5l(long double x, int exp)
 {
   return ldexpl(x, exp);
 }
+
+long double test6l(long double x, long double exp)
+{
+  return scalbl(x, exp);
+}
+
+long double test7l(long double x, int exp)
+{
+  return scalbnl(x, exp);
+}
+
+long double test8l(long double x, long exp)
+{
+  return scalblnl(x, exp);
+}