3ccb523bdd
Darwin does not support strong symbol aliases and a work- around is provided in sfp-machine.h where a second function is created that simply calls the original. However this needs the arguments to the synthesized function to track the mode of the original function. So the fix here is to match known floating point modes from the incoming function and apply the one found to the new function args. The matching is highly specific to the current set of modes and will need adjusting should more cases be added. Signed-off-by: Iain Sandoe <iain@sandoe.co.uk> libgcc/ChangeLog: * config/i386/sfp-machine.h (alias_HFtype, alias_SFtype alias_DFtype, alias_TFtype): New. (ALIAS_SELECTOR): New. (strong_alias): Use __typeof and a _Generic selector to provide the type to the synthesized function.
101 lines
3.2 KiB
C
101 lines
3.2 KiB
C
#ifdef __MINGW32__
|
|
/* Make sure we are using gnu-style bitfield handling. */
|
|
#define _FP_STRUCT_LAYOUT __attribute__ ((gcc_struct))
|
|
#endif
|
|
|
|
/* 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
|
|
|
|
#ifdef __x86_64__
|
|
#include "config/i386/64/sfp-machine.h"
|
|
#else
|
|
#include "config/i386/32/sfp-machine.h"
|
|
#endif
|
|
|
|
#define _FP_KEEPNANFRACP 1
|
|
#define _FP_QNANNEGATEDP 0
|
|
|
|
#define _FP_NANSIGN_H 1
|
|
#define _FP_NANSIGN_S 1
|
|
#define _FP_NANSIGN_D 1
|
|
#define _FP_NANSIGN_E 1
|
|
#define _FP_NANSIGN_Q 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)
|
|
|
|
#ifndef _SOFT_FLOAT
|
|
#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_EX_ALL \
|
|
(FP_EX_INVALID | FP_EX_DENORM | FP_EX_DIVZERO | FP_EX_OVERFLOW \
|
|
| FP_EX_UNDERFLOW | FP_EX_INEXACT)
|
|
|
|
void __sfp_handle_exceptions (int);
|
|
|
|
#define FP_HANDLE_EXCEPTIONS \
|
|
do { \
|
|
if (__builtin_expect (_fex, 0)) \
|
|
__sfp_handle_exceptions (_fex); \
|
|
} while (0)
|
|
|
|
#define FP_TRAPPING_EXCEPTIONS ((~_fcw >> FP_EX_SHIFT) & FP_EX_ALL)
|
|
|
|
#define FP_ROUNDMODE (_fcw & FP_RND_MASK)
|
|
#endif
|
|
|
|
#define _FP_TININESS_AFTER_ROUNDING 1
|
|
|
|
#define __LITTLE_ENDIAN 1234
|
|
#define __BIG_ENDIAN 4321
|
|
|
|
#define __BYTE_ORDER __LITTLE_ENDIAN
|
|
|
|
/* Define ALIASNAME as a strong alias for NAME. */
|
|
#if defined __MACH__
|
|
/* Mach-O doesn't support aliasing, so we build a secondary function for
|
|
the alias - we need to do a bit of a dance to find out what the type of
|
|
the arguments is and then apply that to the secondary function.
|
|
If these functions ever return anything but CMPtype we need to revisit
|
|
this... */
|
|
typedef float alias_HFtype __attribute__ ((mode (HF)));
|
|
typedef float alias_SFtype __attribute__ ((mode (SF)));
|
|
typedef float alias_DFtype __attribute__ ((mode (DF)));
|
|
typedef float alias_TFtype __attribute__ ((mode (TF)));
|
|
#define ALIAS_SELECTOR \
|
|
CMPtype (*) (alias_HFtype, alias_HFtype): (alias_HFtype) 0, \
|
|
CMPtype (*) (alias_SFtype, alias_SFtype): (alias_SFtype) 0, \
|
|
CMPtype (*) (alias_DFtype, alias_DFtype): (alias_DFtype) 0, \
|
|
CMPtype (*) (alias_TFtype, alias_TFtype): (alias_TFtype) 0
|
|
#define strong_alias(name, aliasname) \
|
|
CMPtype aliasname (__typeof (_Generic (name, ALIAS_SELECTOR)) a, \
|
|
__typeof (_Generic (name, ALIAS_SELECTOR)) b) \
|
|
{ return name (a, b); }
|
|
#else
|
|
# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
|
|
# define _strong_alias(name, aliasname) \
|
|
extern __typeof (name) aliasname __attribute__ ((alias (#name)));
|
|
#endif
|