OSDN Git Service

* optabs.h (enum optab_index): Add new OTI_ldexp.
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 12 Feb 2005 11:34:24 +0000 (11:34 +0000)
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 12 Feb 2005 11:34:24 +0000 (11:34 +0000)
(ldexp_optab): Define corresponding macro.
* optabs.c (init_optabs): Initialize ldexp_optab.
* genopinit.c (optabs): Implement ldexp_optab using ldexp?f3
patterns.
* builtins.c (expand_builtin_mathfn_2): Handle BUILT_IN_LDEXP{,F,L}
using ldexp_optab.
(expand_builtin): Expand BUILT_IN_LDEXP{,F,L} using
expand_builtin_mathfn_2 if flag_unsafe_math_optimizations is set.

* config/i386/i386.md (ldexpsf3, ldexpdf3, ldexpxf3): New expanders
to implement ldexpf, ldexp and ldexpl built-ins as inline x87
intrinsics.

testsuite:

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

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@94931 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 e8e8a80..bfaa691 100644 (file)
@@ -1,3 +1,19 @@
+2005-02-12  Uros Bizjak  <uros@kss-loka.si>
+
+       * optabs.h (enum optab_index): Add new OTI_ldexp.
+       (ldexp_optab): Define corresponding macro.
+       * optabs.c (init_optabs): Initialize ldexp_optab.
+       * genopinit.c (optabs): Implement ldexp_optab using ldexp?f3
+       patterns.
+       * builtins.c (expand_builtin_mathfn_2): Handle BUILT_IN_LDEXP{,F,L}
+       using ldexp_optab.
+       (expand_builtin): Expand BUILT_IN_LDEXP{,F,L} using
+       expand_builtin_mathfn_2 if flag_unsafe_math_optimizations is set.
+
+       * config/i386/i386.md (ldexpsf3, ldexpdf3, ldexpxf3): New expanders
+       to implement ldexpf, ldexp and ldexpl built-ins as inline x87
+       intrinsics.
+
 2005-02-13  Ira Rosen  <irar@il.ibm.com>
 
        * tree-vectorizer.h (struct _stmt_vec_info): Rename a field: base
index 420e5de..afeb9bc 100644 (file)
@@ -1862,6 +1862,7 @@ expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
 {
   optab builtin_optab;
   rtx op0, op1, insns;
+  int op1_type = REAL_TYPE;
   tree fndecl = get_callee_fndecl (exp);
   tree arglist = TREE_OPERAND (exp, 1);
   tree arg0, arg1, temp, narg;
@@ -1869,7 +1870,12 @@ expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
   bool errno_set = true;
   bool stable = true;
 
-  if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
+  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;
+
+  if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE))
     return 0;
 
   arg0 = TREE_VALUE (arglist);
@@ -1885,6 +1891,10 @@ expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
     case BUILT_IN_ATAN2F:
     case BUILT_IN_ATAN2L:
       builtin_optab = atan2_optab; break;
+    case BUILT_IN_LDEXP:
+    case BUILT_IN_LDEXPF:
+    case BUILT_IN_LDEXPL:
+      builtin_optab = ldexp_optab; break;
     case BUILT_IN_FMOD:
     case BUILT_IN_FMODF:
     case BUILT_IN_FMODL:
@@ -5259,6 +5269,9 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
     case BUILT_IN_ATAN2:
     case BUILT_IN_ATAN2F:
     case BUILT_IN_ATAN2L:
+    case BUILT_IN_LDEXP:
+    case BUILT_IN_LDEXPF:
+    case BUILT_IN_LDEXPL:
     case BUILT_IN_FMOD:
     case BUILT_IN_FMODF:
     case BUILT_IN_FMODL:
index 3fdf441..d9a4ce5 100644 (file)
   emit_move_insn (operands[2], temp);
   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
 })
+
+(define_expand "ldexpdf3"
+  [(set (match_dup 3)
+       (float_extend:XF (match_operand:DF 1 "register_operand" "")))
+   (set (match_dup 4)
+       (float:XF (match_operand:SI 2 "register_operand" "")))
+   (parallel [(set (match_dup 5)
+                  (unspec:XF [(match_dup 3) (match_dup 4)]
+                             UNSPEC_FSCALE_FRACT))
+             (set (match_dup 6)
+                  (unspec:XF [(match_dup 3) (match_dup 4)]
+                             UNSPEC_FSCALE_EXP))])
+   (set (match_operand:DF 0 "register_operand" "")
+       (float_truncate:DF (match_dup 5)))]
+  "TARGET_USE_FANCY_MATH_387
+   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
+   && flag_unsafe_math_optimizations"
+{
+  int i;
+
+  for (i=3; i<7; i++)
+    operands[i] = gen_reg_rtx (XFmode);
+})
+
+(define_expand "ldexpsf3"
+  [(set (match_dup 3)
+       (float_extend:XF (match_operand:SF 1 "register_operand" "")))
+   (set (match_dup 4)
+       (float:XF (match_operand:SI 2 "register_operand" "")))
+   (parallel [(set (match_dup 5)
+                  (unspec:XF [(match_dup 3) (match_dup 4)]
+                             UNSPEC_FSCALE_FRACT))
+             (set (match_dup 6)
+                  (unspec:XF [(match_dup 3) (match_dup 4)]
+                             UNSPEC_FSCALE_EXP))])
+   (set (match_operand:SF 0 "register_operand" "")
+       (float_truncate:SF (match_dup 5)))]
+  "TARGET_USE_FANCY_MATH_387
+   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
+   && flag_unsafe_math_optimizations"
+{
+  int i;
+
+  for (i=3; i<7; i++)
+    operands[i] = gen_reg_rtx (XFmode);
+})
+
+(define_expand "ldexpxf3"
+  [(set (match_dup 3)
+       (float:XF (match_operand:SI 2 "register_operand" "")))
+   (parallel [(set (match_operand:XF 0 " register_operand" "")
+                  (unspec:XF [(match_operand:XF 1 "register_operand" "")
+                              (match_dup 3)]
+                             UNSPEC_FSCALE_FRACT))
+             (set (match_dup 4)
+                  (unspec:XF [(match_dup 1) (match_dup 3)]
+                             UNSPEC_FSCALE_EXP))])]
+  "TARGET_USE_FANCY_MATH_387
+   && flag_unsafe_math_optimizations"
+{
+  int i;
+
+  for (i=3; i<5; i++)
+    operands[i] = gen_reg_rtx (XFmode);
+})
 \f
 
 (define_insn "frndintxf2"
index f56f13c..e52ca06 100644 (file)
@@ -133,6 +133,7 @@ static const char * const optabs[] =
   "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$)",
+  "ldexp_optab->handlers[$A].insn_code = CODE_FOR_$(ldexp$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 75c78cd..9525620 100644 (file)
@@ -5027,6 +5027,7 @@ init_optabs (void)
   exp10_optab = init_optab (UNKNOWN);
   exp2_optab = init_optab (UNKNOWN);
   expm1_optab = init_optab (UNKNOWN);
+  ldexp_optab = init_optab (UNKNOWN);
   logb_optab = init_optab (UNKNOWN);
   ilogb_optab = init_optab (UNKNOWN);
   log_optab = init_optab (UNKNOWN);
index 621136b..e0a7985 100644 (file)
@@ -171,6 +171,8 @@ enum optab_index
   OTI_exp2,
   /* Exponential - 1*/
   OTI_expm1,
+  /* Load exponent of a floating point number */
+  OTI_ldexp,
   /* Radix-independent exponent */
   OTI_logb,
   OTI_ilogb,
@@ -302,6 +304,7 @@ extern GTY(()) optab optab_table[OTI_MAX];
 #define exp10_optab (optab_table[OTI_exp10])
 #define exp2_optab (optab_table[OTI_exp2])
 #define expm1_optab (optab_table[OTI_expm1])
+#define ldexp_optab (optab_table[OTI_ldexp])
 #define logb_optab (optab_table[OTI_logb])
 #define ilogb_optab (optab_table[OTI_ilogb])
 #define log_optab (optab_table[OTI_log])
index 02ac9f4..408e128 100644 (file)
@@ -1,3 +1,7 @@
+2005-02-12  Uros Bizjak  <uros@kss-loka.si>
+
+       * gcc.dg/builtins-34.c: Also check ldexp*.
+
 2005-02-12  Hans-Peter Nilsson  <hp@bitrange.com>
 
        * gcc.dg/tree-ssa/20040703-1.c: Quote decimal dot.
index 0055f32..f2625d5 100644 (file)
@@ -12,14 +12,17 @@ extern double exp10(double);
 extern double exp2(double);
 extern double pow10(double);
 extern double expm1(double);
+extern double ldexp(double, int);
 extern float exp10f(float);
 extern float exp2f(float);
 extern float pow10f(float);
 extern float expm1f(float);
+extern float ldexpf(float, int);
 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);
 
 
 double test1(double x)
@@ -42,6 +45,11 @@ double test4(double x)
   return expm1(x);
 }
 
+double test5(double x, int exp)
+{
+  return ldexp(x, exp);
+}
+
 float test1f(float x)
 {
   return exp10f(x);
@@ -62,6 +70,11 @@ float test4f(float x)
   return expm1f(x);
 }
 
+float test5f(float x, int exp)
+{
+  return ldexpf(x, exp);
+}
+
 long double test1l(long double x)
 {
   return exp10l(x);
@@ -82,3 +95,7 @@ long double test4l(long double x)
   return expm1l(x);
 }
 
+long double test5l(long double x, int exp)
+{
+  return ldexpl(x, exp);
+}