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
This commit is contained in:
H.J. Lu 2009-02-12 08:30:53 -08:00
parent 0ce6dcfa37
commit c252db2030
20 changed files with 508 additions and 8 deletions

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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)));

View File

@ -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

View File

@ -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

View File

@ -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. */ \

View File

@ -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.

View File

@ -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

View File

@ -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*)
;;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,2 @@
# Provide fallbacks for __builtin_copysignq and __builtin_fabsq.
LIB2ADD += $(srcdir)/config/ia64/tf-signs.c

View File

@ -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))

View File

@ -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;
}