summaryrefslogtreecommitdiff
path: root/gcc/config/sparc/sparc.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/sparc/sparc.c')
-rw-r--r--gcc/config/sparc/sparc.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 8441783261a..28275b724d9 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -180,6 +180,7 @@ static void emit_soft_tfmode_cvt (enum rtx_code, rtx *);
static void emit_hard_tfmode_operation (enum rtx_code, rtx *);
static bool sparc_function_ok_for_sibcall (tree, tree);
+static void sparc_init_libfuncs (void);
static void sparc_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree);
static struct machine_function * sparc_init_machine_status (void);
@@ -252,6 +253,9 @@ enum processor_type sparc_cpu;
#undef TARGET_FUNCTION_OK_FOR_SIBCALL
#define TARGET_FUNCTION_OK_FOR_SIBCALL sparc_function_ok_for_sibcall
+#undef TARGET_INIT_LIBFUNCS
+#define TARGET_INIT_LIBFUNCS sparc_init_libfuncs
+
#ifdef HAVE_AS_TLS
#undef TARGET_HAVE_TLS
#define TARGET_HAVE_TLS true
@@ -8386,7 +8390,96 @@ sparc_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
&& ! TARGET_FLAT
&& (TARGET_ARCH64 || ! current_function_returns_struct));
}
+
+/* libfunc renaming. */
+#include "config/gofast.h"
+
+static void
+sparc_init_libfuncs (void)
+{
+ if (TARGET_ARCH32)
+ {
+ /* Use the subroutines that Sun's library provides for integer
+ multiply and divide. The `*' prevents an underscore from
+ being prepended by the compiler. .umul is a little faster
+ than .mul. */
+ set_optab_libfunc (smul_optab, SImode, "*.umul");
+ set_optab_libfunc (sdiv_optab, SImode, "*.div");
+ set_optab_libfunc (udiv_optab, SImode, "*.udiv");
+ set_optab_libfunc (smod_optab, SImode, "*.rem");
+ set_optab_libfunc (umod_optab, SImode, "*.urem");
+
+ /* TFmode arithmetic. These names are part of the SPARC 32bit ABI. */
+ set_optab_libfunc (add_optab, TFmode, "_Q_add");
+ set_optab_libfunc (sub_optab, TFmode, "_Q_sub");
+ set_optab_libfunc (neg_optab, TFmode, "_Q_neg");
+ set_optab_libfunc (smul_optab, TFmode, "_Q_mul");
+ set_optab_libfunc (sdiv_optab, TFmode, "_Q_div");
+
+ /* We can define the TFmode sqrt optab only if TARGET_FPU. This
+ is because with soft-float, the SFmode and DFmode sqrt
+ instructions will be absent, and the compiler will notice and
+ try to use the TFmode sqrt instruction for calls to the
+ builtin function sqrt, but this fails. */
+ if (TARGET_FPU)
+ set_optab_libfunc (sqrt_optab, TFmode, "_Q_sqrt");
+
+ eqtf2_libfunc = init_one_libfunc ("_Q_feq");
+ netf2_libfunc = init_one_libfunc ("_Q_fne");
+ gttf2_libfunc = init_one_libfunc ("_Q_fgt");
+ getf2_libfunc = init_one_libfunc ("_Q_fge");
+ lttf2_libfunc = init_one_libfunc ("_Q_flt");
+ letf2_libfunc = init_one_libfunc ("_Q_fle");
+
+ trunctfsf2_libfunc = init_one_libfunc ("_Q_qtos");
+ trunctfdf2_libfunc = init_one_libfunc ("_Q_qtod");
+ extendsftf2_libfunc = init_one_libfunc ("_Q_stoq");
+ extenddftf2_libfunc = init_one_libfunc ("_Q_dtoq");
+ floatsitf_libfunc = init_one_libfunc ("_Q_itoq");
+ fixtfsi_libfunc = init_one_libfunc ("_Q_qtoi");
+ fixunstfsi_libfunc = init_one_libfunc ("_Q_qtou");
+
+ if (SUN_CONVERSION_LIBFUNCS)
+ {
+ fixsfdi_libfunc = init_one_libfunc ("__ftoll");
+ fixunssfdi_libfunc = init_one_libfunc ("__ftoull");
+ fixdfdi_libfunc = init_one_libfunc ("__dtoll");
+ fixunsdfdi_libfunc = init_one_libfunc ("__dtoull");
+ }
+ }
+ if (TARGET_ARCH64)
+ {
+ /* In the SPARC 64bit ABI, SImode multiply and divide functions
+ do not exist in the library. Make sure the compiler does not
+ emit calls to them by accident. (It should always use the
+ hardware instructions.) */
+ set_optab_libfunc (smul_optab, SImode, 0);
+ set_optab_libfunc (sdiv_optab, SImode, 0);
+ set_optab_libfunc (udiv_optab, SImode, 0);
+ set_optab_libfunc (smod_optab, SImode, 0);
+ set_optab_libfunc (umod_optab, SImode, 0);
+
+ if (SUN_INTEGER_MULTIPLY_64)
+ {
+ set_optab_libfunc (smul_optab, DImode, "__mul64");
+ set_optab_libfunc (sdiv_optab, DImode, "__div64");
+ set_optab_libfunc (udiv_optab, DImode, "__udiv64");
+ set_optab_libfunc (smod_optab, DImode, "__rem64");
+ set_optab_libfunc (umod_optab, DImode, "__urem64");
+ }
+
+ if (SUN_CONVERSION_LIBFUNCS)
+ {
+ fixsfdi_libfunc = init_one_libfunc ("__ftol");
+ fixunssfdi_libfunc = init_one_libfunc ("__ftoul");
+ fixdfdi_libfunc = init_one_libfunc ("__dtol");
+ fixunsdfdi_libfunc = init_one_libfunc ("__dtoul");
+ }
+ }
+ gofast_maybe_init_libfuncs ();
+}
+
/* ??? Similar to the standard section selection, but force reloc-y-ness
if SUNOS4_SHARED_LIBRARIES. Unclear why this helps (as opposed to
pretending PIC always on), but that's what the old code did. */