mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-26 23:21:11 +00:00
Unbreak *tf builtins for hexfloat (#82208)
This re-lands cc0065a7d0
in a way that
keeps existing targets working.
---------
Original commit message:
#68132 ended up removing
__multc3 & __divtc3 from compiler-rt library builds that have
QUAD_PRECISION but not TF_MODE due to missing int128 support.
I added support for QUAD_PRECISION to use the native hex float long double representation.
---------
Co-authored-by: Sean Perry <perry@ca.ibm.com>
(cherry picked from commit 99c457dc2ef395872d7448c85609f6cb73a7f89b)
This commit is contained in:
parent
89d543227a
commit
c14879562f
@ -13,7 +13,7 @@
|
|||||||
#define QUAD_PRECISION
|
#define QUAD_PRECISION
|
||||||
#include "fp_lib.h"
|
#include "fp_lib.h"
|
||||||
|
|
||||||
#if defined(CRT_HAS_TF_MODE)
|
#if defined(CRT_HAS_F128)
|
||||||
|
|
||||||
// Returns: the quotient of (a + ib) / (c + id)
|
// Returns: the quotient of (a + ib) / (c + id)
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include "int_lib.h"
|
#include "int_lib.h"
|
||||||
#include "int_math.h"
|
#include "int_math.h"
|
||||||
|
#include "int_types.h"
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@ -93,13 +94,14 @@ static __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) {
|
|||||||
COMPILER_RT_ABI fp_t __adddf3(fp_t a, fp_t b);
|
COMPILER_RT_ABI fp_t __adddf3(fp_t a, fp_t b);
|
||||||
|
|
||||||
#elif defined QUAD_PRECISION
|
#elif defined QUAD_PRECISION
|
||||||
#if defined(CRT_HAS_TF_MODE)
|
#if defined(CRT_HAS_F128) && defined(CRT_HAS_128BIT)
|
||||||
typedef uint64_t half_rep_t;
|
typedef uint64_t half_rep_t;
|
||||||
typedef __uint128_t rep_t;
|
typedef __uint128_t rep_t;
|
||||||
typedef __int128_t srep_t;
|
typedef __int128_t srep_t;
|
||||||
typedef tf_float fp_t;
|
typedef tf_float fp_t;
|
||||||
#define HALF_REP_C UINT64_C
|
#define HALF_REP_C UINT64_C
|
||||||
#define REP_C (__uint128_t)
|
#define REP_C (__uint128_t)
|
||||||
|
#if defined(CRT_HAS_IEEE_TF)
|
||||||
// Note: Since there is no explicit way to tell compiler the constant is a
|
// Note: Since there is no explicit way to tell compiler the constant is a
|
||||||
// 128-bit integer, we let the constant be casted to 128-bit integer
|
// 128-bit integer, we let the constant be casted to 128-bit integer
|
||||||
#define significandBits 112
|
#define significandBits 112
|
||||||
@ -188,7 +190,10 @@ static __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) {
|
|||||||
#undef Word_HiMask
|
#undef Word_HiMask
|
||||||
#undef Word_LoMask
|
#undef Word_LoMask
|
||||||
#undef Word_FullMask
|
#undef Word_FullMask
|
||||||
#endif // defined(CRT_HAS_TF_MODE)
|
#endif // defined(CRT_HAS_IEEE_TF)
|
||||||
|
#else
|
||||||
|
typedef long double fp_t;
|
||||||
|
#endif // defined(CRT_HAS_F128) && defined(CRT_HAS_128BIT)
|
||||||
#else
|
#else
|
||||||
#error SINGLE_PRECISION, DOUBLE_PRECISION or QUAD_PRECISION must be defined.
|
#error SINGLE_PRECISION, DOUBLE_PRECISION or QUAD_PRECISION must be defined.
|
||||||
#endif
|
#endif
|
||||||
@ -196,19 +201,6 @@ static __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) {
|
|||||||
#if defined(SINGLE_PRECISION) || defined(DOUBLE_PRECISION) || \
|
#if defined(SINGLE_PRECISION) || defined(DOUBLE_PRECISION) || \
|
||||||
(defined(QUAD_PRECISION) && defined(CRT_HAS_TF_MODE))
|
(defined(QUAD_PRECISION) && defined(CRT_HAS_TF_MODE))
|
||||||
#define typeWidth (sizeof(rep_t) * CHAR_BIT)
|
#define typeWidth (sizeof(rep_t) * CHAR_BIT)
|
||||||
#define exponentBits (typeWidth - significandBits - 1)
|
|
||||||
#define maxExponent ((1 << exponentBits) - 1)
|
|
||||||
#define exponentBias (maxExponent >> 1)
|
|
||||||
|
|
||||||
#define implicitBit (REP_C(1) << significandBits)
|
|
||||||
#define significandMask (implicitBit - 1U)
|
|
||||||
#define signBit (REP_C(1) << (significandBits + exponentBits))
|
|
||||||
#define absMask (signBit - 1U)
|
|
||||||
#define exponentMask (absMask ^ significandMask)
|
|
||||||
#define oneRep ((rep_t)exponentBias << significandBits)
|
|
||||||
#define infRep exponentMask
|
|
||||||
#define quietBit (implicitBit >> 1)
|
|
||||||
#define qnanRep (exponentMask | quietBit)
|
|
||||||
|
|
||||||
static __inline rep_t toRep(fp_t x) {
|
static __inline rep_t toRep(fp_t x) {
|
||||||
const union {
|
const union {
|
||||||
@ -226,6 +218,21 @@ static __inline fp_t fromRep(rep_t x) {
|
|||||||
return rep.f;
|
return rep.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(QUAD_PRECISION) || defined(CRT_HAS_IEEE_TF)
|
||||||
|
#define exponentBits (typeWidth - significandBits - 1)
|
||||||
|
#define maxExponent ((1 << exponentBits) - 1)
|
||||||
|
#define exponentBias (maxExponent >> 1)
|
||||||
|
|
||||||
|
#define implicitBit (REP_C(1) << significandBits)
|
||||||
|
#define significandMask (implicitBit - 1U)
|
||||||
|
#define signBit (REP_C(1) << (significandBits + exponentBits))
|
||||||
|
#define absMask (signBit - 1U)
|
||||||
|
#define exponentMask (absMask ^ significandMask)
|
||||||
|
#define oneRep ((rep_t)exponentBias << significandBits)
|
||||||
|
#define infRep exponentMask
|
||||||
|
#define quietBit (implicitBit >> 1)
|
||||||
|
#define qnanRep (exponentMask | quietBit)
|
||||||
|
|
||||||
static __inline int normalize(rep_t *significand) {
|
static __inline int normalize(rep_t *significand) {
|
||||||
const int shift = rep_clz(*significand) - rep_clz(implicitBit);
|
const int shift = rep_clz(*significand) - rep_clz(implicitBit);
|
||||||
*significand <<= shift;
|
*significand <<= shift;
|
||||||
@ -328,6 +335,8 @@ static __inline fp_t __compiler_rt_scalbnX(fp_t x, int y) {
|
|||||||
return fromRep(sign | ((rep_t)exp << significandBits) | sig);
|
return fromRep(sign | ((rep_t)exp << significandBits) | sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // !defined(QUAD_PRECISION) || defined(CRT_HAS_IEEE_TF)
|
||||||
|
|
||||||
// Avoid using fmax from libm.
|
// Avoid using fmax from libm.
|
||||||
static __inline fp_t __compiler_rt_fmaxX(fp_t x, fp_t y) {
|
static __inline fp_t __compiler_rt_fmaxX(fp_t x, fp_t y) {
|
||||||
// If either argument is NaN, return the other argument. If both are NaN,
|
// If either argument is NaN, return the other argument. If both are NaN,
|
||||||
@ -405,6 +414,8 @@ static __inline tf_float __compiler_rt_fmaxtf(tf_float x, tf_float y) {
|
|||||||
#define __compiler_rt_logbl crt_logbl
|
#define __compiler_rt_logbl crt_logbl
|
||||||
#define __compiler_rt_scalbnl crt_scalbnl
|
#define __compiler_rt_scalbnl crt_scalbnl
|
||||||
#define __compiler_rt_fmaxl crt_fmaxl
|
#define __compiler_rt_fmaxl crt_fmaxl
|
||||||
|
#define crt_fabstf crt_fabsl
|
||||||
|
#define crt_copysigntf crt_copysignl
|
||||||
#else
|
#else
|
||||||
#error Unsupported TF mode type
|
#error Unsupported TF mode type
|
||||||
#endif
|
#endif
|
||||||
|
@ -189,12 +189,16 @@ typedef long double tf_float;
|
|||||||
#define CRT_LDBL_IEEE_F128
|
#define CRT_LDBL_IEEE_F128
|
||||||
#endif
|
#endif
|
||||||
#define TF_C(x) x##L
|
#define TF_C(x) x##L
|
||||||
#elif __LDBL_MANT_DIG__ == 113
|
#elif __LDBL_MANT_DIG__ == 113 || \
|
||||||
// Use long double instead of __float128 if it matches the IEEE 128-bit format.
|
(__FLT_RADIX__ == 16 && __LDBL_MANT_DIG__ == 28)
|
||||||
|
// Use long double instead of __float128 if it matches the IEEE 128-bit format
|
||||||
|
// or the IBM hexadecimal format.
|
||||||
#define CRT_LDBL_128BIT
|
#define CRT_LDBL_128BIT
|
||||||
#define CRT_HAS_F128
|
#define CRT_HAS_F128
|
||||||
|
#if __LDBL_MANT_DIG__ == 113
|
||||||
#define CRT_HAS_IEEE_TF
|
#define CRT_HAS_IEEE_TF
|
||||||
#define CRT_LDBL_IEEE_F128
|
#define CRT_LDBL_IEEE_F128
|
||||||
|
#endif
|
||||||
typedef long double tf_float;
|
typedef long double tf_float;
|
||||||
#define TF_C(x) x##L
|
#define TF_C(x) x##L
|
||||||
#elif defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)
|
#elif defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#include "int_lib.h"
|
#include "int_lib.h"
|
||||||
#include "int_math.h"
|
#include "int_math.h"
|
||||||
|
|
||||||
#if defined(CRT_HAS_TF_MODE)
|
#if defined(CRT_HAS_F128)
|
||||||
|
|
||||||
// Returns: the product of a + ib and c + id
|
// Returns: the product of a + ib and c + id
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user