summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog41
-rw-r--r--gcc/config.gcc3
-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
-rw-r--r--gcc/longlong.h49
-rw-r--r--libgcc/ChangeLog15
-rw-r--r--libgcc/Makefile.in4
-rw-r--r--libgcc/config.host2
-rw-r--r--libgcc/config/ia64/__divxf3.asm11
-rw-r--r--libgcc/config/ia64/_fixtfdi.asm11
-rw-r--r--libgcc/config/ia64/_fixunstfdi.asm11
-rw-r--r--libgcc/config/ia64/_floatditf.asm11
-rw-r--r--libgcc/config/ia64/t-fprules-softfp2
-rw-r--r--libgcc/config/ia64/t-softfp-compat7
-rw-r--r--libgcc/config/ia64/tf-signs.c62
20 files changed, 508 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 87a7d4afdf6..077681c99bf 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,44 @@
+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.
+
2009-02-12 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/i386.c (construct_container): Rewrite processing
diff --git a/gcc/config.gcc b/gcc/config.gcc
index c0a52822131..99741c30d9a 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -3058,6 +3058,9 @@ case ${target} in
i[34567]86-*-linux* | x86_64-*-linux*)
tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp i386/t-linux"
;;
+ ia64*-*-linux*)
+ tmake_file="${tmake_file} ia64/t-fprules-softfp soft-fp/t-softfp"
+ ;;
mips*-*-*)
if test x$gnu_ld = xyes
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
diff --git a/gcc/longlong.h b/gcc/longlong.h
index 9bfd322d59f..57308bd9b79 100644
--- a/gcc/longlong.h
+++ b/gcc/longlong.h
@@ -432,6 +432,55 @@ UDItype __umulsidi3 (USItype, USItype);
__w; })
#endif /* __i960__ */
+#if defined (__ia64) && W_TYPE_SIZE == 64
+/* This form encourages gcc (pre-release 3.4 at least) to emit predicated
+ "sub r=r,r" and "sub r=r,r,1", giving a 2 cycle latency. The generic
+ code using "al<bl" arithmetically comes out making an actual 0 or 1 in a
+ register, which takes an extra cycle. */
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ UWtype __x; \
+ __x = (al) - (bl); \
+ if ((al) < (bl)) \
+ (sh) = (ah) - (bh) - 1; \
+ else \
+ (sh) = (ah) - (bh); \
+ (sl) = __x; \
+ } while (0)
+
+/* Do both product parts in assembly, since that gives better code with
+ all gcc versions. Some callers will just use the upper part, and in
+ that situation we waste an instruction, but not any cycles. */
+#define umul_ppmm(ph, pl, m0, m1) \
+ __asm__ ("xma.hu %0 = %2, %3, f0\n\txma.l %1 = %2, %3, f0" \
+ : "=&f" (ph), "=f" (pl) \
+ : "f" (m0), "f" (m1))
+#define count_leading_zeros(count, x) \
+ do { \
+ UWtype _x = (x), _y, _a, _c; \
+ __asm__ ("mux1 %0 = %1, @rev" : "=r" (_y) : "r" (_x)); \
+ __asm__ ("czx1.l %0 = %1" : "=r" (_a) : "r" (-_y | _y)); \
+ _c = (_a - 1) << 3; \
+ _x >>= _c; \
+ if (_x >= 1 << 4) \
+ _x >>= 4, _c += 4; \
+ if (_x >= 1 << 2) \
+ _x >>= 2, _c += 2; \
+ _c += _x >> 1; \
+ (count) = W_TYPE_SIZE - 1 - _c; \
+ } while (0)
+/* similar to what gcc does for __builtin_ffs, but 0 based rather than 1
+ based, and we don't need a special case for x==0 here */
+#define count_trailing_zeros(count, x) \
+ do { \
+ UWtype __ctz_x = (x); \
+ __asm__ ("popcnt %0 = %1" \
+ : "=r" (count) \
+ : "r" ((__ctz_x-1) & ~__ctz_x)); \
+ } while (0)
+#define UMUL_TIME 14
+#endif
+
#if defined (__M32R__) && W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
/* The cmp clears the condition bit. */ \
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index ea7a9156196..402dbe185f3 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,18 @@
+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.
+
2009-01-18 Ben Elliston <bje@au.ibm.com>
* config/i386/32/tf-signs.c (__copysigntf3, __fabstf2): Prototype.
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index 5718a501830..c9c36d5fa16 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -265,7 +265,9 @@ ASM_HIDDEN_OP = @asm_hidden_op@
define gen-hide-list
$(NM) -pg $< | \
- $(AWK) 'NF == 3 && $$2 !~ /^[UN]$$/ { print "\t$(ASM_HIDDEN_OP)", $$3 }' > $@T
+ $(AWK) 'NF == 3 && $$2 !~ /^[UN]$$/ && $$3 !~ /.*_compat/ \
+ && $$3 !~ /.*@.*/ \
+ { print "\t$(ASM_HIDDEN_OP)", $$3 }' > $@T
mv -f $@T $@
endef
else
diff --git a/libgcc/config.host b/libgcc/config.host
index 655ef953ce8..2225e679063 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -350,7 +350,7 @@ ia64*-*-freebsd*)
;;
ia64*-*-linux*)
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtfastmath.o"
- tmake_file="ia64/t-ia64"
+ tmake_file="ia64/t-ia64 ia64/t-fprules-softfp ia64/t-softfp-compat"
;;
ia64*-*-hpux*)
;;
diff --git a/libgcc/config/ia64/__divxf3.asm b/libgcc/config/ia64/__divxf3.asm
new file mode 100644
index 00000000000..f741bdaf9bc
--- /dev/null
+++ b/libgcc/config/ia64/__divxf3.asm
@@ -0,0 +1,11 @@
+#ifdef SHARED
+#define __divtf3 __divtf3_compat
+#endif
+
+#define L__divxf3
+#include "config/ia64/lib1funcs.asm"
+
+#ifdef SHARED
+#undef __divtf3
+.symver __divtf3_compat, __divtf3@GCC_3.0
+#endif
diff --git a/libgcc/config/ia64/_fixtfdi.asm b/libgcc/config/ia64/_fixtfdi.asm
new file mode 100644
index 00000000000..4d13c808c51
--- /dev/null
+++ b/libgcc/config/ia64/_fixtfdi.asm
@@ -0,0 +1,11 @@
+#ifdef SHARED
+#define __fixtfti __fixtfti_compat
+#endif
+
+#define L_fixtfdi
+#include "config/ia64/lib1funcs.asm"
+
+#ifdef SHARED
+#undef __fixtfti
+.symver __fixtfti_compat, __fixtfti@GCC_3.0
+#endif
diff --git a/libgcc/config/ia64/_fixunstfdi.asm b/libgcc/config/ia64/_fixunstfdi.asm
new file mode 100644
index 00000000000..b722d9e90dc
--- /dev/null
+++ b/libgcc/config/ia64/_fixunstfdi.asm
@@ -0,0 +1,11 @@
+#ifdef SHARED
+#define __fixunstfti __fixunstfti_compat
+#endif
+
+#define L_fixunstfdi
+#include "config/ia64/lib1funcs.asm"
+
+#ifdef SHARED
+#undef __fixunstfti
+.symver __fixunstfti_compat, __fixunstfti@GCC_3.0
+#endif
diff --git a/libgcc/config/ia64/_floatditf.asm b/libgcc/config/ia64/_floatditf.asm
new file mode 100644
index 00000000000..21d77028176
--- /dev/null
+++ b/libgcc/config/ia64/_floatditf.asm
@@ -0,0 +1,11 @@
+#ifdef SHARED
+#define __floattitf __floattitf_compat
+#endif
+
+#define L_floatditf
+#include "config/ia64/lib1funcs.asm"
+
+#ifdef SHARED
+#undef __floattitf
+.symver __floattitf_compat, __floattitf@GCC_3.0
+#endif
diff --git a/libgcc/config/ia64/t-fprules-softfp b/libgcc/config/ia64/t-fprules-softfp
new file mode 100644
index 00000000000..90acc376ec9
--- /dev/null
+++ b/libgcc/config/ia64/t-fprules-softfp
@@ -0,0 +1,2 @@
+# Provide fallbacks for __builtin_copysignq and __builtin_fabsq.
+LIB2ADD += $(srcdir)/config/ia64/tf-signs.c
diff --git a/libgcc/config/ia64/t-softfp-compat b/libgcc/config/ia64/t-softfp-compat
new file mode 100644
index 00000000000..d3dad68c48f
--- /dev/null
+++ b/libgcc/config/ia64/t-softfp-compat
@@ -0,0 +1,7 @@
+# Filter out the following TImode functions and provide backward binary
+# compatibility.
+# Replace __dvxf3 _fixtfdi _fixunstfdi _floatditf
+libgcc1-tf-functions = __divxf3 _fixtfdi _fixunstfdi _floatditf
+LIB1ASMFUNCS := $(filter-out $(libgcc1-tf-functions), $(LIB1ASMFUNCS))
+libgcc1-tf-compats = $(addsuffix .asm, $(libgcc1-tf-functions))
+LIB2ADD += $(addprefix $(srcdir)/config/ia64/, $(libgcc1-tf-compats))
diff --git a/libgcc/config/ia64/tf-signs.c b/libgcc/config/ia64/tf-signs.c
new file mode 100644
index 00000000000..9b42b9041f6
--- /dev/null
+++ b/libgcc/config/ia64/tf-signs.c
@@ -0,0 +1,62 @@
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA. */
+
+union _FP_UNION_Q
+{
+ __float128 flt;
+ struct
+ {
+ unsigned long frac1 : 64;
+ unsigned long frac0 : 48;
+ unsigned exp : 15;
+ unsigned sign : 1;
+ } bits __attribute__((packed));
+};
+
+__float128
+__copysigntf3 (__float128 a, __float128 b)
+{
+ union _FP_UNION_Q A, B;
+
+ A.flt = a;
+ B.flt = b;
+ A.bits.sign = B.bits.sign;
+
+ return A.flt;
+}
+
+__float128
+__fabstf2 (__float128 a)
+{
+ union _FP_UNION_Q A;
+
+ A.flt = a;
+ A.bits.sign = 0;
+
+ return A.flt;
+}