diff options
author | H.J. Lu <hjl@gcc.gnu.org> | 2009-02-12 08:30:53 -0800 |
---|---|---|
committer | H.J. Lu <hjl@gcc.gnu.org> | 2009-02-12 08:30:53 -0800 |
commit | c252db2030a54b9cd3095405704dc68c3029a461 (patch) | |
tree | a9970b42c2ad08d6a0e408e9b647d6568ed8bd41 /gcc/config/ia64 | |
parent | 0ce6dcfa37083451e9966bbc8db4bfe1e496e458 (diff) | |
download | gcc-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.c | 66 | ||||
-rw-r--r-- | gcc/config/ia64/lib1funcs.asm | 8 | ||||
-rw-r--r-- | gcc/config/ia64/libgcc-glibc.ver | 79 | ||||
-rw-r--r-- | gcc/config/ia64/linux.h | 10 | ||||
-rw-r--r-- | gcc/config/ia64/sfp-machine.h | 116 | ||||
-rw-r--r-- | gcc/config/ia64/t-fprules-softfp | 6 | ||||
-rw-r--r-- | gcc/config/ia64/t-glibc | 2 |
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 |