invoke.texi (-msselibm): Document.
authorRichard Guenther <rguenther@suse.de>
Tue, 31 Jan 2006 15:34:52 +0000 (15:34 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 31 Jan 2006 15:34:52 +0000 (15:34 +0000)
2006-01-31  Richard Guenther  <rguenther@suse.de>

* doc/invoke.texi (-msselibm): Document.
* target.h (expand_library_builtin): New target hook.
* builtins.c (expand_builtin): Use expand_library_builtin.
(default_expand_library_builtin): New function.
* gcc.c (LINK_GCC_MATH_SPEC): Define.
(LINK_COMMAND_SPEC): Handle %(link_gcc_math).
(link_gcc_math_spec): Declare.
(static_specs): Add link_gcc_math_spec.
* expr.h (default_expand_library_builtin): Declare.
* target-def.h (TARGET_EXPAND_LIBRARY_BUILTIN): Define.
(TARGET_INITIALIZER): Add TARGET_EXPAND_LIBRARY_BUILTIN.
* config/i386/i386.h: Provide LINK_GCC_MATH_SPEC.
* config/i386/i386.opt (msselibm): New target option.
* config/i386/i386.c (ix86_builtin_function_variants): New array.
(ix86_init_sse_abi_builtins): New function.
(ix86_expand_library_builtin): Likewise.
(TARGET_EXPAND_LIBRARY_BUILTIN): Define.
(override_options): Handle error conditions wrt -msselibm.
(ix86_builtins): Add function codes for SSE2 ABI builtins.
(ix86_init_builtins): Call ix86_init_sse_abi_builtins.
* doc/extend.texi (__builtin_sse2_*): Document new target specific
builtins.

* gcc.target/i386/sselibm-1.c: New testcase.
* gcc.target/i386/sselibm-2.c: Likewise.
* gcc.target/i386/sselibm-3.c: Likewise.
* gcc.target/i386/sselibm-4.c: Likewise.
* gcc.target/i386/sselibm-5.c: Likewise.

From-SVN: r110439

17 files changed:
gcc/ChangeLog
gcc/builtins.c
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/i386/i386.opt
gcc/doc/extend.texi
gcc/doc/invoke.texi
gcc/expr.h
gcc/gcc.c
gcc/target-def.h
gcc/target.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/sselibm-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sselibm-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sselibm-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sselibm-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sselibm-5.c [new file with mode: 0644]

index 58a53d8..03b7cfe 100644 (file)
@@ -1,4 +1,29 @@
 2006-01-31  Richard Guenther  <rguenther@suse.de>
 2006-01-31  Richard Guenther  <rguenther@suse.de>
+
+       * doc/invoke.texi (-msselibm): Document.
+       * target.h (expand_library_builtin): New target hook.
+       * builtins.c (expand_builtin): Use expand_library_builtin.
+       (default_expand_library_builtin): New function.
+       * gcc.c (LINK_GCC_MATH_SPEC): Define.
+       (LINK_COMMAND_SPEC): Handle %(link_gcc_math).
+       (link_gcc_math_spec): Declare.
+       (static_specs): Add link_gcc_math_spec.
+       * expr.h (default_expand_library_builtin): Declare.
+       * target-def.h (TARGET_EXPAND_LIBRARY_BUILTIN): Define.
+       (TARGET_INITIALIZER): Add TARGET_EXPAND_LIBRARY_BUILTIN.
+       * config/i386/i386.h: Provide LINK_GCC_MATH_SPEC.
+       * config/i386/i386.opt (msselibm): New target option.
+       * config/i386/i386.c (ix86_builtin_function_variants): New array.
+       (ix86_init_sse_abi_builtins): New function.
+       (ix86_expand_library_builtin): Likewise.
+       (TARGET_EXPAND_LIBRARY_BUILTIN): Define.
+       (override_options): Handle error conditions wrt -msselibm.
+       (ix86_builtins): Add function codes for SSE2 ABI builtins.
+       (ix86_init_builtins): Call ix86_init_sse_abi_builtins.
+       * doc/extend.texi (__builtin_sse2_*): Document new target specific
+       builtins.
+
+2006-01-31  Richard Guenther  <rguenther@suse.de>
        Paolo Bonzini  <bonzini@gnu.org>
 
        * doc/install.texi (--disable-libgcc-math): Document.
        Paolo Bonzini  <bonzini@gnu.org>
 
        * doc/install.texi (--disable-libgcc-math): Document.
index bb113dc..fd551da 100644 (file)
@@ -5560,6 +5560,14 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
 
   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
     return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
 
   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
     return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
+  else
+    {
+      /* Try expanding the builtin via the generic target hook.  */
+      rtx tmp = targetm.expand_library_builtin (exp, target, subtarget,
+                                               mode, ignore);
+      if (tmp != NULL_RTX)
+       return tmp;
+    }
 
   /* When not optimizing, generate calls to library functions for a certain
      set of builtins.  */
 
   /* When not optimizing, generate calls to library functions for a certain
      set of builtins.  */
@@ -8913,6 +8921,18 @@ default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
   return NULL_RTX;
 }
 
   return NULL_RTX;
 }
 
+/* Default target-specific library builtin expander that does nothing.  */
+
+rtx
+default_expand_library_builtin (tree exp ATTRIBUTE_UNUSED,
+                       rtx target ATTRIBUTE_UNUSED,
+                       rtx subtarget ATTRIBUTE_UNUSED,
+                       enum machine_mode mode ATTRIBUTE_UNUSED,
+                       int ignore ATTRIBUTE_UNUSED)
+{
+  return NULL_RTX;
+}
+
 /* Returns true is EXP represents data that would potentially reside
    in a readonly section.  */
 
 /* Returns true is EXP represents data that would potentially reside
    in a readonly section.  */
 
index c9029f0..ed23c86 100644 (file)
@@ -1050,6 +1050,9 @@ int ix86_section_threshold = 65536;
 /* Prefix built by ASM_GENERATE_INTERNAL_LABEL.  */
 char internal_label_prefix[16];
 int internal_label_prefix_len;
 /* Prefix built by ASM_GENERATE_INTERNAL_LABEL.  */
 char internal_label_prefix[16];
 int internal_label_prefix_len;
+
+/* Table for BUILT_IN_NORMAL to BUILT_IN_MD mapping.  */
+static GTY(()) tree ix86_builtin_function_variants[(int) END_BUILTINS];
 \f
 static bool ix86_handle_option (size_t, const char *, int);
 static void output_pic_addr_const (FILE *, rtx, int);
 \f
 static bool ix86_handle_option (size_t, const char *, int);
 static void output_pic_addr_const (FILE *, rtx, int);
@@ -1084,6 +1087,7 @@ static int ix86_issue_rate (void);
 static int ix86_adjust_cost (rtx, rtx, rtx, int);
 static int ia32_multipass_dfa_lookahead (void);
 static void ix86_init_mmx_sse_builtins (void);
 static int ix86_adjust_cost (rtx, rtx, rtx, int);
 static int ia32_multipass_dfa_lookahead (void);
 static void ix86_init_mmx_sse_builtins (void);
+static void ix86_init_sse_abi_builtins (void);
 static rtx x86_this_parameter (tree);
 static void x86_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
                                 HOST_WIDE_INT, tree);
 static rtx x86_this_parameter (tree);
 static void x86_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
                                 HOST_WIDE_INT, tree);
@@ -1140,6 +1144,7 @@ static bool ix86_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
                                    tree, bool);
 static void ix86_init_builtins (void);
 static rtx ix86_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
                                    tree, bool);
 static void ix86_init_builtins (void);
 static rtx ix86_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
+static rtx ix86_expand_library_builtin (tree, rtx, rtx, enum machine_mode, int);
 static const char *ix86_mangle_fundamental_type (tree);
 static tree ix86_stack_protect_fail (void);
 static rtx ix86_internal_arg_pointer (void);
 static const char *ix86_mangle_fundamental_type (tree);
 static tree ix86_stack_protect_fail (void);
 static rtx ix86_internal_arg_pointer (void);
@@ -1204,6 +1209,8 @@ static section *x86_64_elf_select_section (tree decl, int reloc,
 #define TARGET_INIT_BUILTINS ix86_init_builtins
 #undef TARGET_EXPAND_BUILTIN
 #define TARGET_EXPAND_BUILTIN ix86_expand_builtin
 #define TARGET_INIT_BUILTINS ix86_init_builtins
 #undef TARGET_EXPAND_BUILTIN
 #define TARGET_EXPAND_BUILTIN ix86_expand_builtin
+#undef TARGET_EXPAND_LIBRARY_BUILTIN
+#define TARGET_EXPAND_LIBRARY_BUILTIN ix86_expand_library_builtin
 
 #undef TARGET_ASM_FUNCTION_EPILOGUE
 #define TARGET_ASM_FUNCTION_EPILOGUE ix86_output_function_epilogue
 
 #undef TARGET_ASM_FUNCTION_EPILOGUE
 #define TARGET_ASM_FUNCTION_EPILOGUE ix86_output_function_epilogue
@@ -1886,6 +1893,16 @@ override_options (void)
       && ! TARGET_SSE)
     error ("-msseregparm used without SSE enabled");
 
       && ! TARGET_SSE)
     error ("-msseregparm used without SSE enabled");
 
+  /* Accept -msselibm only if at least SSE support is enabled.  */
+  if (TARGET_SSELIBM
+      && ! TARGET_SSE2)
+    error ("-msselibm used without SSE2 enabled");
+
+  /* Ignore -msselibm on 64bit targets.  */
+  if (TARGET_SSELIBM
+      && TARGET_64BIT)
+    error ("-msselibm used on a 64bit target");
+
   ix86_fpmath = TARGET_FPMATH_DEFAULT;
 
   if (ix86_fpmath_string != 0)
   ix86_fpmath = TARGET_FPMATH_DEFAULT;
 
   if (ix86_fpmath_string != 0)
@@ -14235,6 +14252,28 @@ enum ix86_builtins
   IX86_BUILTIN_VEC_SET_V8HI,
   IX86_BUILTIN_VEC_SET_V4HI,
 
   IX86_BUILTIN_VEC_SET_V8HI,
   IX86_BUILTIN_VEC_SET_V4HI,
 
+  /* SSE2 ABI functions.  */
+  IX86_BUILTIN_SSE2_ACOS,
+  IX86_BUILTIN_SSE2_ACOSF,
+  IX86_BUILTIN_SSE2_ASIN,
+  IX86_BUILTIN_SSE2_ASINF,
+  IX86_BUILTIN_SSE2_ATAN,
+  IX86_BUILTIN_SSE2_ATANF,
+  IX86_BUILTIN_SSE2_ATAN2,
+  IX86_BUILTIN_SSE2_ATAN2F,
+  IX86_BUILTIN_SSE2_COS,
+  IX86_BUILTIN_SSE2_COSF,
+  IX86_BUILTIN_SSE2_EXP,
+  IX86_BUILTIN_SSE2_EXPF,
+  IX86_BUILTIN_SSE2_LOG10,
+  IX86_BUILTIN_SSE2_LOG10F,
+  IX86_BUILTIN_SSE2_LOG,
+  IX86_BUILTIN_SSE2_LOGF,
+  IX86_BUILTIN_SSE2_SIN,
+  IX86_BUILTIN_SSE2_SINF,
+  IX86_BUILTIN_SSE2_TAN,
+  IX86_BUILTIN_SSE2_TANF,
+
   IX86_BUILTIN_MAX
 };
 
   IX86_BUILTIN_MAX
 };
 
@@ -14616,6 +14655,8 @@ ix86_init_builtins (void)
 {
   if (TARGET_MMX)
     ix86_init_mmx_sse_builtins ();
 {
   if (TARGET_MMX)
     ix86_init_mmx_sse_builtins ();
+  if (TARGET_SSE2)
+    ix86_init_sse_abi_builtins ();
 }
 
 /* Set up all the MMX/SSE builtins.  This is not called if TARGET_MMX
 }
 
 /* Set up all the MMX/SSE builtins.  This is not called if TARGET_MMX
@@ -15255,6 +15296,70 @@ ix86_init_mmx_sse_builtins (void)
   def_builtin (MASK_SSE | MASK_3DNOW_A, "__builtin_ia32_vec_set_v4hi",
               ftype, IX86_BUILTIN_VEC_SET_V4HI);
 }
   def_builtin (MASK_SSE | MASK_3DNOW_A, "__builtin_ia32_vec_set_v4hi",
               ftype, IX86_BUILTIN_VEC_SET_V4HI);
 }
+#undef def_builtin
+
+/* Set up all the SSE ABI builtins that we may use to override
+   the normal builtins.  */
+static void
+ix86_init_sse_abi_builtins (void)
+{
+  tree dbl, flt, dbl2, flt2;
+
+  /* Bail out in case the template definitions are not available.  */
+  if (! built_in_decls [BUILT_IN_SIN]
+      || ! built_in_decls [BUILT_IN_SINF]
+      || ! built_in_decls [BUILT_IN_ATAN2]
+      || ! built_in_decls [BUILT_IN_ATAN2F])
+    return;
+
+  /* Build the function types as variants of the existing ones.  */
+  dbl = build_variant_type_copy (TREE_TYPE (built_in_decls [BUILT_IN_SIN]));
+  TYPE_ATTRIBUTES (dbl)
+    = tree_cons (get_identifier ("sseregparm"),
+                 NULL_TREE, TYPE_ATTRIBUTES (dbl));
+  flt = build_variant_type_copy (TREE_TYPE (built_in_decls [BUILT_IN_SINF]));
+  TYPE_ATTRIBUTES (flt)
+    = tree_cons (get_identifier ("sseregparm"),
+                 NULL_TREE, TYPE_ATTRIBUTES (flt));
+  dbl2 = build_variant_type_copy (TREE_TYPE (built_in_decls [BUILT_IN_ATAN2]));
+  TYPE_ATTRIBUTES (dbl2)
+    = tree_cons (get_identifier ("sseregparm"),
+                 NULL_TREE, TYPE_ATTRIBUTES (dbl2));
+  flt2 = build_variant_type_copy (TREE_TYPE (built_in_decls [BUILT_IN_ATAN2F]));
+  TYPE_ATTRIBUTES (flt2)
+    = tree_cons (get_identifier ("sseregparm"),
+                 NULL_TREE, TYPE_ATTRIBUTES (flt2));
+
+#define def_builtin(capname, name, type) \
+  ix86_builtin_function_variants [BUILT_IN_ ## capname]                        \
+    = lang_hooks.builtin_function ("__builtin_sse2_" # name, type,     \
+                                  IX86_BUILTIN_SSE2_ ## capname,       \
+                                  BUILT_IN_NORMAL,                     \
+                                  "__libm_sse2_" # name, NULL_TREE)
+  def_builtin (ACOS, acos, dbl);
+  def_builtin (ACOSF, acosf, flt);
+  def_builtin (ASIN, asin, dbl);
+  def_builtin (ASINF, asinf, flt);
+  def_builtin (ATAN, atan, dbl);
+  def_builtin (ATANF, atanf, flt);
+  def_builtin (ATAN2, atan2, dbl2);
+  def_builtin (ATAN2F, atan2f, flt2);
+  def_builtin (COS, cos, dbl);
+  def_builtin (COSF, cosf, flt);
+  def_builtin (EXP, exp, dbl);
+  def_builtin (EXPF, expf, flt);
+  def_builtin (LOG10, log10, dbl);
+  def_builtin (LOG10F, log10f, flt);
+  def_builtin (LOG, log, dbl);
+  def_builtin (LOGF, logf, flt);
+  def_builtin (SIN, sin, dbl);
+  def_builtin (SINF, sinf, flt);
+  def_builtin (TAN, tan, dbl);
+  def_builtin (TANF, tanf, flt);
+
+#undef def_builtin
+}
 
 /* Errors in the source file can cause expand_expr to return const0_rtx
    where we expect a vector.  To avoid crashing, use one of the vector
 
 /* Errors in the source file can cause expand_expr to return const0_rtx
    where we expect a vector.  To avoid crashing, use one of the vector
@@ -16089,6 +16194,39 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
   gcc_unreachable ();
 }
 
   gcc_unreachable ();
 }
 
+/* Expand an expression EXP that calls a built-in library function,
+   with result going to TARGET if that's convenient
+   (and in mode MODE if that's convenient).
+   SUBTARGET may be used as the target for computing one of EXP's operands.
+   IGNORE is nonzero if the value is to be ignored.  */
+
+static rtx
+ix86_expand_library_builtin (tree exp, rtx target,
+                            rtx subtarget ATTRIBUTE_UNUSED,
+                            enum machine_mode mode ATTRIBUTE_UNUSED,
+                            int ignore)
+{
+  enum built_in_function fncode;
+  tree fndecl, newfn, call;
+
+  /* Try expanding builtin math functions to the SSE2 ABI variants.  */
+  if (!TARGET_SSELIBM)
+      return NULL_RTX;
+
+  fncode = builtin_mathfn_code (exp);
+  if (!ix86_builtin_function_variants [(int)fncode])
+    return NULL_RTX;
+
+  fndecl = get_callee_fndecl (exp);
+  if (DECL_RTL_SET_P (fndecl))
+    return NULL_RTX;
+
+  /* Build the redirected call and expand it.  */
+  newfn = ix86_builtin_function_variants [(int)fncode];
+  call = build_function_call_expr (newfn, TREE_OPERAND (exp, 1));
+  return expand_call (call, target, ignore);
+}
+
 /* Store OPERAND to the memory after reload is completed.  This means
    that we can't easily use assign_stack_local.  */
 rtx
 /* Store OPERAND to the memory after reload is completed.  This means
    that we can't easily use assign_stack_local.  */
 rtx
index 628a5dd..307cc97 100644 (file)
@@ -497,6 +497,8 @@ extern int x86_prefetch_sse;
 #define EXTRA_SPECS                                                    \
   { "cc1_cpu",  CC1_CPU_SPEC },                                                \
   SUBTARGET_EXTRA_SPECS
 #define EXTRA_SPECS                                                    \
   { "cc1_cpu",  CC1_CPU_SPEC },                                                \
   SUBTARGET_EXTRA_SPECS
+
+#define LINK_GCC_MATH_SPEC "%{msselibm:-lgcc-math}"
 \f
 /* target machine storage layout */
 
 \f
 /* target machine storage layout */
 
index 2a51fcb..9cd29b4 100644 (file)
@@ -201,6 +201,10 @@ msseregparm
 Target RejectNegative Mask(SSEREGPARM)
 Use SSE register passing conventions for SF and DF mode
 
 Target RejectNegative Mask(SSEREGPARM)
 Use SSE register passing conventions for SF and DF mode
 
+msselibm
+Target Mask(SSELIBM)
+Use SSE2 ABI libgcc-math routines if using SSE math
+
 msvr3-shlib
 Target Report Mask(SVR3_SHLIB)
 Uninitialized locals in .bss
 msvr3-shlib
 Target Report Mask(SVR3_SHLIB)
 Uninitialized locals in .bss
index 9d5a8f6..a20349d 100644 (file)
@@ -6804,6 +6804,35 @@ v2sf __builtin_ia32_pswapdsf (v2sf)
 v2si __builtin_ia32_pswapdsi (v2si)
 @end smallexample
 
 v2si __builtin_ia32_pswapdsi (v2si)
 @end smallexample
 
+The following built-in functions are available when @option{-msse2}
+is used.  All of them generate calls to an SSE2 ABI IEEE754 math intrinsic
+that is part of the name.  Rather than using these directly you may
+want them automatically substituted for calls to the regular intrinsics
+using the @option{-msselibm}.
+
+@smallexample
+double __builtin_sse2_acos (double)
+float __builtin_sse2_acosf (float)
+double __builtin_sse2_asin (double)
+float __builtin_sse2_asinf (float)
+double __builtin_sse2_atan (double)
+float __builtin_sse2_atanf (float)
+double __builtin_sse2_atan2 (double, double)
+float __builtin_sse2_atan2f (float, float)
+double __builtin_sse2_cos (double)
+float __builtin_sse2_cosf (float)
+double __builtin_sse2_exp (double)
+float __builtin_sse2_expf (float)
+double __builtin_sse2_log10 (double)
+float __builtin_sse2_log10f (float)
+double __builtin_sse2_log (double)
+float __builtin_sse2_logf (float)
+double __builtin_sse2_sin (double)
+float __builtin_sse2_sinf (float)
+double __builtin_sse2_tan (double)
+float __builtin_sse2_tanf (float)
+@end smallexample
+
 @node MIPS DSP Built-in Functions
 @subsection MIPS DSP Built-in Functions
 
 @node MIPS DSP Built-in Functions
 @subsection MIPS DSP Built-in Functions
 
index d8f69e8..8edff2a 100644 (file)
@@ -528,7 +528,7 @@ Objective-C and Objective-C++ Dialects}.
 -mno-fp-ret-in-387  -msoft-float  -msvr3-shlib @gol
 -mno-wide-multiply  -mrtd  -malign-double @gol
 -mpreferred-stack-boundary=@var{num} @gol
 -mno-fp-ret-in-387  -msoft-float  -msvr3-shlib @gol
 -mno-wide-multiply  -mrtd  -malign-double @gol
 -mpreferred-stack-boundary=@var{num} @gol
--mmmx  -msse  -msse2 -msse3 -m3dnow @gol
+-mmmx  -msse  -msse2 -msse3 -m3dnow -msselibm @gol
 -mthreads  -mno-align-stringops  -minline-all-stringops @gol
 -mpush-args  -maccumulate-outgoing-args  -m128bit-long-double @gol
 -m96bit-long-double  -mregparm=@var{num}  -msseregparm @gol
 -mthreads  -mno-align-stringops  -minline-all-stringops @gol
 -mpush-args  -maccumulate-outgoing-args  -m128bit-long-double @gol
 -m96bit-long-double  -mregparm=@var{num}  -msseregparm @gol
@@ -9437,6 +9437,12 @@ supported architecture, using the appropriate flags.  In particular,
 the file containing the CPU detection code should be compiled without
 these options.
 
 the file containing the CPU detection code should be compiled without
 these options.
 
+@item -msselibm
+@opindex msselibm
+Use special versions of certain libm routines that come with an SSE
+ABI and an SSE implementation.  Useful together with @option{-mfpmath=sse}
+to avoid moving values between SSE registers and the x87 FP stack.
+
 @item -mpush-args
 @itemx -mno-push-args
 @opindex mpush-args
 @item -mpush-args
 @itemx -mno-push-args
 @opindex mpush-args
index b7387cf..2be4100 100644 (file)
@@ -338,6 +338,7 @@ extern rtx expand_builtin (tree, rtx, rtx, enum machine_mode, int);
 extern tree std_build_builtin_va_list (void);
 extern void std_expand_builtin_va_start (tree, rtx);
 extern rtx default_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
 extern tree std_build_builtin_va_list (void);
 extern void std_expand_builtin_va_start (tree, rtx);
 extern rtx default_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
+extern rtx default_expand_library_builtin (tree, rtx, rtx, enum machine_mode, int);
 extern void expand_builtin_setjmp_setup (rtx, rtx);
 extern void expand_builtin_setjmp_receiver (rtx);
 extern rtx expand_builtin_saveregs (void);
 extern void expand_builtin_setjmp_setup (rtx, rtx);
 extern void expand_builtin_setjmp_receiver (rtx);
 extern rtx expand_builtin_saveregs (void);
index 0bd34ee..a2cefe7 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -680,6 +680,10 @@ proper position among the other output files.  */
 #endif
 #endif
 
 #endif
 #endif
 
+#ifndef LINK_GCC_MATH_SPEC
+#define LINK_GCC_MATH_SPEC ""
+#endif
+
 #ifndef LINK_PIE_SPEC
 #ifdef HAVE_LD_PIE
 #define LINK_PIE_SPEC "%{pie:-pie} "
 #ifndef LINK_PIE_SPEC
 #ifdef HAVE_LD_PIE
 #define LINK_PIE_SPEC "%{pie:-pie} "
@@ -702,7 +706,7 @@ proper position among the other output files.  */
     %{static:} %{L*} %(mfwrap) %{fopenmp:%:include(libgomp.spec)%(link_gomp)}\
     %(link_libgcc) %o %(mflib)\
     %{fprofile-arcs|fprofile-generate|coverage:-lgcov}\
     %{static:} %{L*} %(mfwrap) %{fopenmp:%:include(libgomp.spec)%(link_gomp)}\
     %(link_libgcc) %o %(mflib)\
     %{fprofile-arcs|fprofile-generate|coverage:-lgcov}\
-    %{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}\
+    %{!nostdlib:%{!nodefaultlibs:%(link_gcc_math) %(link_ssp) %(link_gcc_c_sequence)}}\
     %{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}"
 #endif
 
     %{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}"
 #endif
 
@@ -733,6 +737,7 @@ static const char *cc1_spec = CC1_SPEC;
 static const char *cc1plus_spec = CC1PLUS_SPEC;
 static const char *link_gcc_c_sequence_spec = LINK_GCC_C_SEQUENCE_SPEC;
 static const char *link_ssp_spec = LINK_SSP_SPEC;
 static const char *cc1plus_spec = CC1PLUS_SPEC;
 static const char *link_gcc_c_sequence_spec = LINK_GCC_C_SEQUENCE_SPEC;
 static const char *link_ssp_spec = LINK_SSP_SPEC;
+static const char *link_gcc_math_spec = LINK_GCC_MATH_SPEC;
 static const char *asm_spec = ASM_SPEC;
 static const char *asm_final_spec = ASM_FINAL_SPEC;
 static const char *link_spec = LINK_SPEC;
 static const char *asm_spec = ASM_SPEC;
 static const char *asm_final_spec = ASM_FINAL_SPEC;
 static const char *link_spec = LINK_SPEC;
@@ -1540,6 +1545,7 @@ static struct spec_list static_specs[] =
   INIT_STATIC_SPEC ("cc1plus",                 &cc1plus_spec),
   INIT_STATIC_SPEC ("link_gcc_c_sequence",     &link_gcc_c_sequence_spec),
   INIT_STATIC_SPEC ("link_ssp",                        &link_ssp_spec),
   INIT_STATIC_SPEC ("cc1plus",                 &cc1plus_spec),
   INIT_STATIC_SPEC ("link_gcc_c_sequence",     &link_gcc_c_sequence_spec),
   INIT_STATIC_SPEC ("link_ssp",                        &link_ssp_spec),
+  INIT_STATIC_SPEC ("link_gcc_math",           &link_gcc_math_spec),
   INIT_STATIC_SPEC ("endfile",                 &endfile_spec),
   INIT_STATIC_SPEC ("link",                    &link_spec),
   INIT_STATIC_SPEC ("lib",                     &lib_spec),
   INIT_STATIC_SPEC ("endfile",                 &endfile_spec),
   INIT_STATIC_SPEC ("link",                    &link_spec),
   INIT_STATIC_SPEC ("lib",                     &lib_spec),
index 7599101..ffeec2e 100644 (file)
@@ -320,6 +320,7 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 /* In builtins.c.  */
 #define TARGET_INIT_BUILTINS hook_void_void
 #define TARGET_EXPAND_BUILTIN default_expand_builtin
 /* In builtins.c.  */
 #define TARGET_INIT_BUILTINS hook_void_void
 #define TARGET_EXPAND_BUILTIN default_expand_builtin
+#define TARGET_EXPAND_LIBRARY_BUILTIN default_expand_library_builtin
 #define TARGET_RESOLVE_OVERLOADED_BUILTIN NULL
 #define TARGET_FOLD_BUILTIN hook_tree_tree_tree_bool_null
 
 #define TARGET_RESOLVE_OVERLOADED_BUILTIN NULL
 #define TARGET_FOLD_BUILTIN hook_tree_tree_tree_bool_null
 
@@ -578,6 +579,7 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
   TARGET_ALIGN_ANON_BITFIELD,                  \
   TARGET_INIT_BUILTINS,                                \
   TARGET_EXPAND_BUILTIN,                       \
   TARGET_ALIGN_ANON_BITFIELD,                  \
   TARGET_INIT_BUILTINS,                                \
   TARGET_EXPAND_BUILTIN,                       \
+  TARGET_EXPAND_LIBRARY_BUILTIN,               \
   TARGET_RESOLVE_OVERLOADED_BUILTIN,           \
   TARGET_FOLD_BUILTIN,                         \
   TARGET_MANGLE_FUNDAMENTAL_TYPE,              \
   TARGET_RESOLVE_OVERLOADED_BUILTIN,           \
   TARGET_FOLD_BUILTIN,                         \
   TARGET_MANGLE_FUNDAMENTAL_TYPE,              \
index 36f2463..2ac0882 100644 (file)
@@ -369,6 +369,10 @@ struct gcc_target
   rtx (* expand_builtin) (tree exp, rtx target, rtx subtarget,
                          enum machine_mode mode, int ignore);
 
   rtx (* expand_builtin) (tree exp, rtx target, rtx subtarget,
                          enum machine_mode mode, int ignore);
 
+  /* Expand a target-specific library builtin.  */
+  rtx (* expand_library_builtin) (tree exp, rtx target, rtx subtarget,
+                         enum machine_mode mode, int ignore);
+
   /* Select a replacement for a target-specific builtin.  This is done
      *before* regular type checking, and so allows the target to implement
      a crude form of function overloading.  The result is a complete
   /* Select a replacement for a target-specific builtin.  This is done
      *before* regular type checking, and so allows the target to implement
      a crude form of function overloading.  The result is a complete
index 5c8e59b..47f6623 100644 (file)
@@ -1,3 +1,11 @@
+2006-01-31  Richard Guenther  <rguenther@suse.de>
+
+       * gcc.target/i386/sselibm-1.c: New testcase.
+       * gcc.target/i386/sselibm-2.c: Likewise.
+       * gcc.target/i386/sselibm-3.c: Likewise.
+       * gcc.target/i386/sselibm-4.c: Likewise.
+       * gcc.target/i386/sselibm-5.c: Likewise.
+
 2005-01-30  Erik Edelmann  <eedelman@gcc.gnu.org>
 
        PR fortran/24266
 2005-01-30  Erik Edelmann  <eedelman@gcc.gnu.org>
 
        PR fortran/24266
diff --git a/gcc/testsuite/gcc.target/i386/sselibm-1.c b/gcc/testsuite/gcc.target/i386/sselibm-1.c
new file mode 100644 (file)
index 0000000..1e9f0c6
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-msse2 -mfpmath=sse" } */
+/* { dg-require-effective-target ilp32 } */
+
+double sin(double);
+
+double foo(double x)
+{
+  return sin(x);
+}
+
+/* { dg-final { scan-assembler-not "__libm_sse2_sin" } } */
diff --git a/gcc/testsuite/gcc.target/i386/sselibm-2.c b/gcc/testsuite/gcc.target/i386/sselibm-2.c
new file mode 100644 (file)
index 0000000..8450262
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-msse2 -mfpmath=sse -msselibm" } */
+/* { dg-require-effective-target ilp32 } */
+
+double sin(double);
+
+double foo(double x)
+{
+  return sin(x);
+}
+
+/* { dg-final { scan-assembler "__libm_sse2_sin" } } */
diff --git a/gcc/testsuite/gcc.target/i386/sselibm-3.c b/gcc/testsuite/gcc.target/i386/sselibm-3.c
new file mode 100644 (file)
index 0000000..76c1134
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -msse2 -mfpmath=sse -msselibm" } */
+/* { dg-require-effective-target ilp32 } */
+
+double sin(double);
+double (*mysin)(double) = sin;
+
+double f1(double x)
+{
+  return sin(x);
+}
+
+double f2(double x)
+{
+  /* Verify we do not expand the following call to __libm_sse2_sin.  */
+  return (*mysin)(x);
+}
+
+/* { dg-final { scan-assembler-times "__libm_sse2_sin" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/sselibm-4.c b/gcc/testsuite/gcc.target/i386/sselibm-4.c
new file mode 100644 (file)
index 0000000..ad20bce
--- /dev/null
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -msse2 -mfpmath=sse -msselibm" } */
+/* { dg-require-effective-target ilp32 } */
+
+extern double acos(double);
+extern double asin(double);
+extern double atan(double);
+extern double atan2(double, double);
+extern double cos(double);
+extern double exp(double);
+extern double log10(double);
+extern double log(double);
+extern double sin(double);
+extern double tan(double);
+
+extern float acosf(float);
+extern float asinf(float);
+extern float atanf(float);
+extern float atan2f(float, float);
+extern float cosf(float);
+extern float expf(float);
+extern float log10f(float);
+extern float logf(float);
+extern float sinf(float);
+extern float tanf(float);
+
+float foof(float x)
+{
+  return acosf(x) + asinf(x) + atanf(x) + atan2f(x, x) + cosf(x) + expf(x)
+       + log10f(x) + logf(x) + sinf(x) + tanf(x);
+}
+
+double foo(double x)
+{
+  return acos(x) + asin(x) + atan(x) + atan2(x, x) + cos(x) + exp(x)
+       + log10(x) + log(x) + sin(x) + tan(x);
+}
+
+/* { dg-final { scan-assembler-times "__libm_sse2" 20 } } */
diff --git a/gcc/testsuite/gcc.target/i386/sselibm-5.c b/gcc/testsuite/gcc.target/i386/sselibm-5.c
new file mode 100644 (file)
index 0000000..c749319
--- /dev/null
@@ -0,0 +1,55 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -msse2 -mfpmath=sse -msselibm" } */
+/* { dg-require-effective-target ilp32 } */
+
+extern double acos(double);
+extern double asin(double);
+extern double atan(double);
+extern double atan2(double, double);
+extern double cos(double);
+extern double exp(double);
+extern double log10(double);
+extern double log(double);
+extern double sin(double);
+extern double tan(double);
+
+extern float acosf(float);
+extern float asinf(float);
+extern float atanf(float);
+extern float atan2f(float, float);
+extern float cosf(float);
+extern float expf(float);
+extern float log10f(float);
+extern float logf(float);
+extern float sinf(float);
+extern float tanf(float);
+
+float foof(float x)
+{
+  return __builtin_sse2_acosf(x)
+       + __builtin_sse2_asinf(x)
+       + __builtin_sse2_atanf(x)
+       + __builtin_sse2_atan2f(x, x)
+       + __builtin_sse2_cosf(x)
+       + __builtin_sse2_expf(x)
+       + __builtin_sse2_log10f(x)
+       + __builtin_sse2_logf(x)
+       + __builtin_sse2_sinf(x)
+       + __builtin_sse2_tanf(x);
+}
+
+double foo(double x)
+{
+  return __builtin_sse2_acos(x)
+       + __builtin_sse2_asin(x)
+       + __builtin_sse2_atan(x)
+       + __builtin_sse2_atan2(x, x)
+       + __builtin_sse2_cos(x)
+       + __builtin_sse2_exp(x)
+       + __builtin_sse2_log10(x)
+       + __builtin_sse2_log(x)
+       + __builtin_sse2_sin(x)
+       + __builtin_sse2_tan(x);
+}
+
+/* { dg-final { scan-assembler-times "__libm_sse2" 20 } } */