summaryrefslogtreecommitdiff
path: root/gcc/config/ia64
diff options
context:
space:
mode:
authorH.J. Lu <hjl@gcc.gnu.org>2009-02-12 08:30:53 -0800
committerH.J. Lu <hjl@gcc.gnu.org>2009-02-12 08:30:53 -0800
commitc252db2030a54b9cd3095405704dc68c3029a461 (patch)
treea9970b42c2ad08d6a0e408e9b647d6568ed8bd41 /gcc/config/ia64
parent0ce6dcfa37083451e9966bbc8db4bfe1e496e458 (diff)
downloadgcc-c252db2030a54b9cd3095405704dc68c3029a461.tar.gz
longlong.h (sub_ddmmss): New for ia64.
gcc/ 2009-02-12 Uros Bizjak <ubizjak@gmail.com> * longlong.h (sub_ddmmss): New for ia64. Ported from GMP 4.2. (umul_ppmm): Likewise. (count_leading_zeros): Likewise. (count_trailing_zeros): Likewise. (UMUL_TIME): Likewise. 2009-02-12 H.J. Lu <hongjiu.lu@intel.com> * config.gcc: Add ia64/t-fprules-softfp soft-fp/t-softfp to tmake_file for ia64*-*-linux*. * config/ia64/ia64.c (ia64_soft_fp_init_libfuncs): New. (ia64_expand_compare): Use HPUX library for TFmode only for HPUX. (ia64_builtins): Add IA64_BUILTIN_COPYSIGNQ, IA64_BUILTIN_FABSQ and IA64_BUILTIN_INFQ. (ia64_init_builtins): Initialize __builtin_infq, __builtin_fabsq and __builtin_copysignq if not HPUX. (ia64_expand_builtin): Handle IA64_BUILTIN_COPYSIGNQ, IA64_BUILTIN_FABSQ and IA64_BUILTIN_INFQ. * config/ia64/lib1funcs.asm (__divtf3): Define only if SHARED is defined. (__fixtfti): Likewise. (__fixunstfti): Likewise. (__floattitf): Likewise. * config/ia64/libgcc-glibc.ver: New. * config/ia64/t-fprules-softfp: Likewise. * config/ia64/sfp-machine.h: Likewise. * config/ia64/linux.h (LIBGCC2_HAS_TF_MODE): New. (LIBGCC2_TF_CEXT): Likewise. (TF_SIZE): Likewise. (TARGET_INIT_LIBFUNCS): Likewise. * config/ia64/t-glibc: Add $(srcdir)/config/ia64/libgcc-glibc.ver to SHLIB_MAPFILES. libgcc/ 2009-02-12 H.J. Lu <hongjiu.lu@intel.com> * config.host: Add ia64/t-fprules-softfp ia64/t-softfp-compat to tmake_file for ia64*-*-linux*. * Makefile.in (gen-hide-list): Ignore .*_compat and .*@.*. * config/ia64/__divxf3.asm: New. * config/ia64/_fixtfdi.asm: Likewise. * config/ia64/_fixunstfdi.asm: Likewise. * config/ia64/_floatditf.asm: Likewise. * config/ia64/t-fprules-softfp: Likewise. * config/ia64/t-softfp-compat: Likewise. * config/ia64/tf-signs.c: Likewise. From-SVN: r144130
Diffstat (limited to 'gcc/config/ia64')
-rw-r--r--gcc/config/ia64/ia64.c66
-rw-r--r--gcc/config/ia64/lib1funcs.asm8
-rw-r--r--gcc/config/ia64/libgcc-glibc.ver79
-rw-r--r--gcc/config/ia64/linux.h10
-rw-r--r--gcc/config/ia64/sfp-machine.h116
-rw-r--r--gcc/config/ia64/t-fprules-softfp6
-rw-r--r--gcc/config/ia64/t-glibc2
7 files changed, 281 insertions, 6 deletions
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index ae77a98dec1..6c28801500a 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -279,6 +279,8 @@ static void ia64_sysv4_init_libfuncs (void)
ATTRIBUTE_UNUSED;
static void ia64_vms_init_libfuncs (void)
ATTRIBUTE_UNUSED;
+static void ia64_soft_fp_init_libfuncs (void)
+ ATTRIBUTE_UNUSED;
static tree ia64_handle_model_attribute (tree *, tree, tree, int, bool *);
static tree ia64_handle_version_id_attribute (tree *, tree, tree, int, bool *);
@@ -1513,7 +1515,7 @@ ia64_expand_compare (enum rtx_code code, enum machine_mode mode)
/* HPUX TFmode compare requires a library call to _U_Qfcmp, which takes a
magic number as its third argument, that indicates what to do.
The return value is an integer to be compared against zero. */
- else if (GET_MODE (op0) == TFmode)
+ else if (TARGET_HPUX && GET_MODE (op0) == TFmode)
{
enum qfcmp_magic {
QCMP_INV = 1, /* Raise FP_INVALID on SNaN as a side effect. */
@@ -9751,7 +9753,10 @@ process_for_unwind_directive (FILE *asm_out_file, rtx insn)
enum ia64_builtins
{
IA64_BUILTIN_BSP,
- IA64_BUILTIN_FLUSHRS
+ IA64_BUILTIN_COPYSIGNQ,
+ IA64_BUILTIN_FABSQ,
+ IA64_BUILTIN_FLUSHRS,
+ IA64_BUILTIN_INFQ
};
void
@@ -9775,10 +9780,35 @@ ia64_init_builtins (void)
/* The __float128 type. */
if (!TARGET_HPUX)
{
+ tree ftype, decl;
tree float128_type = make_node (REAL_TYPE);
+
TYPE_PRECISION (float128_type) = 128;
layout_type (float128_type);
(*lang_hooks.types.register_builtin_type) (float128_type, "__float128");
+
+ /* TFmode support builtins. */
+ ftype = build_function_type (float128_type, void_list_node);
+ add_builtin_function ("__builtin_infq", ftype,
+ IA64_BUILTIN_INFQ, BUILT_IN_MD,
+ NULL, NULL_TREE);
+
+ ftype = build_function_type_list (float128_type,
+ float128_type,
+ NULL_TREE);
+ decl = add_builtin_function ("__builtin_fabsq", ftype,
+ IA64_BUILTIN_FABSQ, BUILT_IN_MD,
+ "__fabstf2", NULL_TREE);
+ TREE_READONLY (decl) = 1;
+
+ ftype = build_function_type_list (float128_type,
+ float128_type,
+ float128_type,
+ NULL_TREE);
+ decl = add_builtin_function ("__builtin_copysignq", ftype,
+ IA64_BUILTIN_COPYSIGNQ, BUILT_IN_MD,
+ "__copysigntf3", NULL_TREE);
+ TREE_READONLY (decl) = 1;
}
else
/* Under HPUX, this is a synonym for "long double". */
@@ -9836,8 +9866,29 @@ ia64_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
emit_insn (gen_flushrs ());
return const0_rtx;
+ case IA64_BUILTIN_INFQ:
+ {
+ REAL_VALUE_TYPE inf;
+ rtx tmp;
+
+ real_inf (&inf);
+ tmp = CONST_DOUBLE_FROM_REAL_VALUE (inf, mode);
+
+ tmp = validize_mem (force_const_mem (mode, tmp));
+
+ if (target == 0)
+ target = gen_reg_rtx (mode);
+
+ emit_move_insn (target, tmp);
+ return target;
+ }
+
+ case IA64_BUILTIN_FABSQ:
+ case IA64_BUILTIN_COPYSIGNQ:
+ return expand_call (exp, target, ignore);
+
default:
- break;
+ gcc_unreachable ();
}
return NULL_RTX;
@@ -10000,6 +10051,13 @@ ia64_sysv4_init_libfuncs (void)
/* We leave out _U_Qfmin, _U_Qfmax and _U_Qfabs since soft-fp in
glibc doesn't have them. */
}
+
+/* Use soft-fp. */
+
+static void
+ia64_soft_fp_init_libfuncs (void)
+{
+}
/* For HPUX, it is illegal to have relocations in shared segments. */
@@ -10250,7 +10308,7 @@ ia64_scalar_mode_supported_p (enum machine_mode mode)
return true;
case TFmode:
- return TARGET_HPUX;
+ return true;
default:
return false;
diff --git a/gcc/config/ia64/lib1funcs.asm b/gcc/config/ia64/lib1funcs.asm
index 245a8bb1595..a92d67c7e9b 100644
--- a/gcc/config/ia64/lib1funcs.asm
+++ b/gcc/config/ia64/lib1funcs.asm
@@ -38,10 +38,12 @@
.text
.align 16
.global __divxf3
- .global __divtf3
.proc __divxf3
__divxf3:
+#ifdef SHARED
+ .global __divtf3
__divtf3:
+#endif
cmp.eq p7, p0 = r0, r0
frcpa.s0 f10, p6 = farg0, farg1
;;
@@ -757,6 +759,7 @@ __ia64_trampoline:
.endp __ia64_trampoline
#endif
+#ifdef SHARED
// Thunks for backward compatibility.
#ifdef L_fixtfdi
.text
@@ -781,7 +784,7 @@ __fixunstfti:
}
.endp __fixunstfti
#endif
-#if L_floatditf
+#ifdef L_floatditf
.align 16
.global __floattitf
.proc __floattitf
@@ -792,3 +795,4 @@ __floattitf:
}
.endp __floattitf
#endif
+#endif
diff --git a/gcc/config/ia64/libgcc-glibc.ver b/gcc/config/ia64/libgcc-glibc.ver
new file mode 100644
index 00000000000..3043ddf5caf
--- /dev/null
+++ b/gcc/config/ia64/libgcc-glibc.ver
@@ -0,0 +1,79 @@
+# 128 bit long double support was introduced with GCC 4.4.0. These lines
+# make the symbols to get @@GCC_4.4.0 attached.
+
+%exclude {
+ __addtf3
+ __divtc3
+ __divtf3
+ __eqtf2
+ __extenddftf2
+ __extendsftf2
+ __extendxftf2
+ __fixtfdi
+ __fixtfsi
+ __fixtfti
+ __fixunstfdi
+ __fixunstfsi
+ __fixunstfti
+ __floatditf
+ __floatsitf
+ __floattitf
+ __floatunditf
+ __floatunsitf
+ __floatuntitf
+ __getf2
+ __gttf2
+ __letf2
+ __lttf2
+ __multc3
+ __multf3
+ __negtf2
+ __netf2
+ __powitf2
+ __subtf3
+ __trunctfdf2
+ __trunctfsf2
+ __trunctfxf2
+ __unordtf2
+}
+
+# Those TF functions are the aliases of the XF functions before gcc 3.4.
+GCC_3.0 {
+ __divtf3
+ __fixtfti
+ __fixunstfti
+ __floattitf
+}
+
+GCC_4.4.0 {
+ __addtf3
+ __copysigntf3
+ __divtc3
+ __divtf3
+ __eqtf2
+ __extenddftf2
+ __extendsftf2
+ __fabstf2
+ __fixtfdi
+ __fixtfsi
+ __fixunstfdi
+ __fixunstfsi
+ __floatditf
+ __floatsitf
+ __floatunditf
+ __floatunsitf
+ __getf2
+ __gttf2
+ __letf2
+ __lttf2
+ __multc3
+ __multf3
+ __negtf2
+ __netf2
+ __powitf2
+ __subtf3
+ __trunctfdf2
+ __trunctfsf2
+ __trunctfxf2
+ __unordtf2
+}
diff --git a/gcc/config/ia64/linux.h b/gcc/config/ia64/linux.h
index cecae0dfe32..e883f893897 100644
--- a/gcc/config/ia64/linux.h
+++ b/gcc/config/ia64/linux.h
@@ -59,3 +59,13 @@ do { \
#define LINK_EH_SPEC ""
#define MD_UNWIND_SUPPORT "config/ia64/linux-unwind.h"
+
+/* Put all *tf routines in libgcc. */
+#undef LIBGCC2_HAS_TF_MODE
+#define LIBGCC2_HAS_TF_MODE 1
+#undef LIBGCC2_TF_CEXT
+#define LIBGCC2_TF_CEXT q
+#define TF_SIZE 113
+
+#undef TARGET_INIT_LIBFUNCS
+#define TARGET_INIT_LIBFUNCS ia64_soft_fp_init_libfuncs
diff --git a/gcc/config/ia64/sfp-machine.h b/gcc/config/ia64/sfp-machine.h
new file mode 100644
index 00000000000..bdcce772ca8
--- /dev/null
+++ b/gcc/config/ia64/sfp-machine.h
@@ -0,0 +1,116 @@
+#define _FP_W_TYPE_SIZE 64
+#define _FP_W_TYPE unsigned long
+#define _FP_WS_TYPE signed long
+#define _FP_I_TYPE long
+
+typedef int TItype __attribute__ ((mode (TI)));
+typedef unsigned int UTItype __attribute__ ((mode (TI)));
+
+#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
+
+/* The type of the result of a floating point comparison. This must
+ match `__libgcc_cmp_return__' in GCC for the target. */
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#define CMPtype __gcc_CMPtype
+
+#define _FP_MUL_MEAT_Q(R,X,Y) \
+ _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S _FP_QNANBIT_S
+#define _FP_NANFRAC_D _FP_QNANBIT_D
+#define _FP_NANFRAC_E _FP_QNANBIT_E, 0
+#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0
+#define _FP_NANSIGN_S 1
+#define _FP_NANSIGN_D 1
+#define _FP_NANSIGN_E 1
+#define _FP_NANSIGN_Q 1
+
+#define _FP_KEEPNANFRACP 1
+
+/* Here is something Intel misdesigned: the specs don't define
+ the case where we have two NaNs with same mantissas, but
+ different sign. Different operations pick up different NaNs. */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
+ do { \
+ if (_FP_FRAC_GT_##wc(X, Y) \
+ || (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*'))) \
+ { \
+ R##_s = X##_s; \
+ _FP_FRAC_COPY_##wc(R,X); \
+ } \
+ else \
+ { \
+ R##_s = Y##_s; \
+ _FP_FRAC_COPY_##wc(R,Y); \
+ } \
+ R##_c = FP_CLS_NAN; \
+ } while (0)
+
+#define FP_EX_INVALID 0x01
+#define FP_EX_DENORM 0x02
+#define FP_EX_DIVZERO 0x04
+#define FP_EX_OVERFLOW 0x08
+#define FP_EX_UNDERFLOW 0x10
+#define FP_EX_INEXACT 0x20
+
+#define FP_HANDLE_EXCEPTIONS \
+ do { \
+ double tmp, dummy; \
+ if (_fex & FP_EX_INVALID) \
+ { \
+ tmp = 0.0; \
+ __asm__ __volatile__ ("frcpa.s0 %0,p1=f0,f0" \
+ : "=f" (tmp) : : "p1" ); \
+ } \
+ if (_fex & FP_EX_DIVZERO) \
+ { \
+ __asm__ __volatile__ ("frcpa.s0 %0,p1=f1,f0" \
+ : "=f" (tmp) : : "p1" ); \
+ } \
+ if (_fex & FP_EX_OVERFLOW) \
+ { \
+ dummy = __DBL_MAX__; \
+ __asm__ __volatile__ ("fadd.d.s0 %0=%1,%1" \
+ : "=f" (dummy) : "0" (dummy)); \
+ } \
+ if (_fex & FP_EX_UNDERFLOW) \
+ { \
+ dummy = __DBL_MIN__; \
+ __asm__ __volatile__ ("fnma.d.s0 %0=%1,%1,f0" \
+ : "=f" (tmp) : "f" (dummy)); \
+ } \
+ if (_fex & FP_EX_INEXACT) \
+ { \
+ dummy = __DBL_MAX__; \
+ __asm__ __volatile__ ("fsub.d.s0 %0=%1,f1" \
+ : "=f" (dummy) : "0" (dummy)); \
+ } \
+ } while (0)
+
+#define FP_RND_NEAREST 0
+#define FP_RND_ZERO 0xc00L
+#define FP_RND_PINF 0x800L
+#define FP_RND_MINF 0x400L
+
+#define _FP_DECL_EX \
+ unsigned long int _fpsr __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE \
+ do { \
+ __asm__ __volatile__ ("mov.m %0=ar.fpsr" \
+ : "=r" (_fpsr)); \
+ } while (0)
+
+#define FP_ROUNDMODE (_fpsr & 0xc00L)
+
+#define __LITTLE_ENDIAN 1234
+#define __BIG_ENDIAN 4321
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME. */
+#define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+#define _strong_alias(name, aliasname) \
+ extern __typeof (name) aliasname __attribute__ ((alias (#name)));
diff --git a/gcc/config/ia64/t-fprules-softfp b/gcc/config/ia64/t-fprules-softfp
new file mode 100644
index 00000000000..4c876bfa996
--- /dev/null
+++ b/gcc/config/ia64/t-fprules-softfp
@@ -0,0 +1,6 @@
+softfp_float_modes := tf
+softfp_int_modes := si di ti
+softfp_extensions := sftf dftf xftf
+softfp_truncations := tfsf tfdf tfxf
+softfp_machine_header := ia64/sfp-machine.h
+softfp_exclude_libgcc2 := n
diff --git a/gcc/config/ia64/t-glibc b/gcc/config/ia64/t-glibc
index df4fe9c4404..e6d72b94a87 100644
--- a/gcc/config/ia64/t-glibc
+++ b/gcc/config/ia64/t-glibc
@@ -1,3 +1,5 @@
# Use system libunwind library on IA-64 GLIBC based system.
LIB2ADDEH = $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c \
$(srcdir)/unwind-compat.c
+
+SHLIB_MAPFILES += $(srcdir)/config/ia64/libgcc-glibc.ver