mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-01 01:31:26 +00:00
[builtins] Avoid using long double in generic sources (#69754)
Use of long double can be error-prone since it could be one of 80-bit extended precision float, IEEE 128-bit float, or IBM 128-bit float. Instead use an explicit xf_float typedef for the remaining cases where long double is being used in the implementation. This patch does not touch the PPC specializations which still use long double.
This commit is contained in:
parent
2282af26ea
commit
05a4212cc7
@ -17,16 +17,16 @@
|
||||
|
||||
// Returns: the quotient of (a + ib) / (c + id)
|
||||
|
||||
COMPILER_RT_ABI Lcomplex __divxc3(long double __a, long double __b,
|
||||
long double __c, long double __d) {
|
||||
COMPILER_RT_ABI Lcomplex __divxc3(xf_float __a, xf_float __b, xf_float __c,
|
||||
xf_float __d) {
|
||||
int __ilogbw = 0;
|
||||
long double __logbw = crt_logbl(crt_fmaxl(crt_fabsl(__c), crt_fabsl(__d)));
|
||||
xf_float __logbw = crt_logbl(crt_fmaxl(crt_fabsl(__c), crt_fabsl(__d)));
|
||||
if (crt_isfinite(__logbw)) {
|
||||
__ilogbw = (int)__logbw;
|
||||
__c = crt_scalbnl(__c, -__ilogbw);
|
||||
__d = crt_scalbnl(__d, -__ilogbw);
|
||||
}
|
||||
long double __denom = __c * __c + __d * __d;
|
||||
xf_float __denom = __c * __c + __d * __d;
|
||||
Lcomplex z;
|
||||
COMPLEX_REAL(z) = crt_scalbnl((__a * __c + __b * __d) / __denom, -__ilogbw);
|
||||
COMPLEX_IMAGINARY(z) =
|
||||
|
@ -17,7 +17,7 @@
|
||||
#define DST_QUAD
|
||||
#include "fp_extend_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI tf_float __extendxftf2(long double a) {
|
||||
COMPILER_RT_ABI tf_float __extendxftf2(xf_float a) {
|
||||
return __extendXfYf2__(a);
|
||||
}
|
||||
|
||||
|
@ -32,8 +32,8 @@
|
||||
#pragma warning(disable : 4700)
|
||||
#endif
|
||||
|
||||
COMPILER_RT_ABI du_int __fixunsxfdi(long double a) {
|
||||
long_double_bits fb;
|
||||
COMPILER_RT_ABI du_int __fixunsxfdi(xf_float a) {
|
||||
xf_bits fb;
|
||||
fb.f = a;
|
||||
int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
|
||||
if (e < 0 || (fb.u.high.s.low & 0x00008000))
|
||||
|
@ -32,8 +32,8 @@
|
||||
#pragma warning(disable : 4700)
|
||||
#endif
|
||||
|
||||
COMPILER_RT_ABI su_int __fixunsxfsi(long double a) {
|
||||
long_double_bits fb;
|
||||
COMPILER_RT_ABI su_int __fixunsxfsi(xf_float a) {
|
||||
xf_bits fb;
|
||||
fb.f = a;
|
||||
int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
|
||||
if (e < 0 || (fb.u.high.s.low & 0x00008000))
|
||||
|
@ -25,8 +25,8 @@
|
||||
// eeee | 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm
|
||||
// mmmm mmmm mmmm
|
||||
|
||||
COMPILER_RT_ABI tu_int __fixunsxfti(long double a) {
|
||||
long_double_bits fb;
|
||||
COMPILER_RT_ABI tu_int __fixunsxfti(xf_float a) {
|
||||
xf_bits fb;
|
||||
fb.f = a;
|
||||
int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
|
||||
if (e < 0 || (fb.u.high.s.low & 0x00008000))
|
||||
|
@ -31,10 +31,10 @@
|
||||
#pragma warning(disable : 4700)
|
||||
#endif
|
||||
|
||||
COMPILER_RT_ABI di_int __fixxfdi(long double a) {
|
||||
COMPILER_RT_ABI di_int __fixxfdi(xf_float a) {
|
||||
const di_int di_max = (di_int)((~(du_int)0) / 2);
|
||||
const di_int di_min = -di_max - 1;
|
||||
long_double_bits fb;
|
||||
xf_bits fb;
|
||||
fb.f = a;
|
||||
int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
|
||||
if (e < 0)
|
||||
|
@ -24,10 +24,10 @@
|
||||
// eeee | 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm
|
||||
// mmmm mmmm mmmm
|
||||
|
||||
COMPILER_RT_ABI ti_int __fixxfti(long double a) {
|
||||
COMPILER_RT_ABI ti_int __fixxfti(xf_float a) {
|
||||
const ti_int ti_max = (ti_int)((~(tu_int)0) / 2);
|
||||
const ti_int ti_min = -ti_max - 1;
|
||||
long_double_bits fb;
|
||||
xf_bits fb;
|
||||
fb.f = a;
|
||||
int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
|
||||
if (e < 0)
|
||||
|
@ -23,7 +23,7 @@
|
||||
// eeee | 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm
|
||||
// mmmm mmmm mmmm
|
||||
|
||||
COMPILER_RT_ABI long double __floatdixf(di_int a) {
|
||||
COMPILER_RT_ABI xf_float __floatdixf(di_int a) {
|
||||
if (a == 0)
|
||||
return 0.0;
|
||||
const unsigned N = sizeof(di_int) * CHAR_BIT;
|
||||
@ -31,7 +31,7 @@ COMPILER_RT_ABI long double __floatdixf(di_int a) {
|
||||
a = (a ^ s) - s;
|
||||
int clz = __builtin_clzll(a);
|
||||
int e = (N - 1) - clz; // exponent
|
||||
long_double_bits fb;
|
||||
xf_bits fb;
|
||||
fb.u.high.s.low = ((su_int)s & 0x00008000) | // sign
|
||||
(e + 16383); // exponent
|
||||
fb.u.low.all = a << clz; // mantissa
|
||||
|
@ -23,7 +23,7 @@
|
||||
// eeee | 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm
|
||||
// mmmm mmmm mmmm
|
||||
|
||||
COMPILER_RT_ABI long double __floattixf(ti_int a) {
|
||||
COMPILER_RT_ABI xf_float __floattixf(ti_int a) {
|
||||
if (a == 0)
|
||||
return 0.0;
|
||||
const unsigned N = sizeof(ti_int) * CHAR_BIT;
|
||||
@ -63,7 +63,7 @@ COMPILER_RT_ABI long double __floattixf(ti_int a) {
|
||||
a <<= (LDBL_MANT_DIG - sd);
|
||||
// a is now rounded to LDBL_MANT_DIG bits
|
||||
}
|
||||
long_double_bits fb;
|
||||
xf_bits fb;
|
||||
fb.u.high.s.low = ((su_int)s & 0x8000) | // sign
|
||||
(e + 16383); // exponent
|
||||
fb.u.low.all = (du_int)a; // mantissa
|
||||
|
@ -22,13 +22,13 @@
|
||||
// gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee
|
||||
// eeee | 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm
|
||||
// mmmm mmmm mmmm
|
||||
COMPILER_RT_ABI long double __floatundixf(du_int a) {
|
||||
COMPILER_RT_ABI xf_float __floatundixf(du_int a) {
|
||||
if (a == 0)
|
||||
return 0.0;
|
||||
const unsigned N = sizeof(du_int) * CHAR_BIT;
|
||||
int clz = __builtin_clzll(a);
|
||||
int e = (N - 1) - clz; // exponent
|
||||
long_double_bits fb;
|
||||
xf_bits fb;
|
||||
fb.u.high.s.low = (e + 16383); // exponent
|
||||
fb.u.low.all = a << clz; // mantissa
|
||||
return fb.f;
|
||||
|
@ -23,7 +23,7 @@
|
||||
// eeee | 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm
|
||||
// mmmm mmmm mmmm
|
||||
|
||||
COMPILER_RT_ABI long double __floatuntixf(tu_int a) {
|
||||
COMPILER_RT_ABI xf_float __floatuntixf(tu_int a) {
|
||||
if (a == 0)
|
||||
return 0.0;
|
||||
const unsigned N = sizeof(tu_int) * CHAR_BIT;
|
||||
@ -61,7 +61,7 @@ COMPILER_RT_ABI long double __floatuntixf(tu_int a) {
|
||||
a <<= (LDBL_MANT_DIG - sd);
|
||||
// a is now rounded to LDBL_MANT_DIG bits
|
||||
}
|
||||
long_double_bits fb;
|
||||
xf_bits fb;
|
||||
fb.u.high.s.low = (e + 16383); // exponent
|
||||
fb.u.low.all = (du_int)a; // mantissa
|
||||
return fb.f;
|
||||
|
@ -50,7 +50,7 @@ static inline int src_rep_t_clz_impl(src_rep_t a) {
|
||||
#define src_rep_t_clz src_rep_t_clz_impl
|
||||
|
||||
#elif defined SRC_80
|
||||
typedef long double src_t;
|
||||
typedef xf_float src_t;
|
||||
typedef __uint128_t src_rep_t;
|
||||
#define SRC_REP_C (__uint128_t)
|
||||
// sign bit, exponent and significand occupy the lower 80 bits.
|
||||
|
@ -60,7 +60,7 @@ static const int dstSigFracBits = 52;
|
||||
static const int dstExpBits = 11;
|
||||
|
||||
#elif defined DST_80
|
||||
typedef long double dst_t;
|
||||
typedef xf_float dst_t;
|
||||
typedef __uint128_t dst_rep_t;
|
||||
#define DST_REP_C (__uint128_t)
|
||||
static const int dstBits = 80;
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
// long double __floatdixf(di_int a);
|
||||
// xf_float __floatdixf(di_int a);
|
||||
|
||||
#ifdef __i386__
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
// long double __floatundixf(du_int a);16
|
||||
// xf_float __floatundixf(du_int a);16
|
||||
|
||||
#ifdef __i386__
|
||||
|
||||
|
@ -165,6 +165,14 @@ typedef struct {
|
||||
#define HAS_80_BIT_LONG_DOUBLE 0
|
||||
#endif
|
||||
|
||||
#if HAS_80_BIT_LONG_DOUBLE
|
||||
typedef long double xf_float;
|
||||
typedef union {
|
||||
uqwords u;
|
||||
xf_float f;
|
||||
} xf_bits;
|
||||
#endif
|
||||
|
||||
#ifdef __powerpc64__
|
||||
// From https://gcc.gnu.org/wiki/Ieee128PowerPC:
|
||||
// PowerPC64 uses the following suffixes:
|
||||
@ -213,11 +221,6 @@ typedef union {
|
||||
#endif
|
||||
|
||||
#if CRT_HAS_FLOATING_POINT
|
||||
typedef union {
|
||||
uqwords u;
|
||||
long double f;
|
||||
} long_double_bits;
|
||||
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
typedef float _Complex Fcomplex;
|
||||
typedef double _Complex Dcomplex;
|
||||
|
@ -17,12 +17,12 @@
|
||||
|
||||
// Returns: the product of a + ib and c + id
|
||||
|
||||
COMPILER_RT_ABI Lcomplex __mulxc3(long double __a, long double __b,
|
||||
long double __c, long double __d) {
|
||||
long double __ac = __a * __c;
|
||||
long double __bd = __b * __d;
|
||||
long double __ad = __a * __d;
|
||||
long double __bc = __b * __c;
|
||||
COMPILER_RT_ABI Lcomplex __mulxc3(xf_float __a, xf_float __b, xf_float __c,
|
||||
xf_float __d) {
|
||||
xf_float __ac = __a * __c;
|
||||
xf_float __bd = __b * __d;
|
||||
xf_float __ad = __a * __d;
|
||||
xf_float __bc = __b * __c;
|
||||
Lcomplex z;
|
||||
COMPLEX_REAL(z) = __ac - __bd;
|
||||
COMPLEX_IMAGINARY(z) = __ad + __bc;
|
||||
|
@ -16,9 +16,9 @@
|
||||
|
||||
// Returns: a ^ b
|
||||
|
||||
COMPILER_RT_ABI long double __powixf2(long double a, int b) {
|
||||
COMPILER_RT_ABI xf_float __powixf2(xf_float a, int b) {
|
||||
const int recip = b < 0;
|
||||
long double r = 1;
|
||||
xf_float r = 1;
|
||||
while (1) {
|
||||
if (b & 1)
|
||||
r *= a;
|
||||
|
@ -19,8 +19,7 @@
|
||||
} \
|
||||
}
|
||||
|
||||
long double _Complex __multc3(long double a, long double b, long double c,
|
||||
long double d) {
|
||||
xf_float _Complex __multc3(xf_float a, xf_float b, xf_float c, xf_float d) {
|
||||
long double ac = __gcc_qmul(a, c);
|
||||
long double bd = __gcc_qmul(b, d);
|
||||
long double ad = __gcc_qmul(a, d);
|
||||
|
@ -18,8 +18,6 @@
|
||||
#define DST_80
|
||||
#include "fp_trunc_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI long double __trunctfxf2(tf_float a) {
|
||||
return __truncXfYf2__(a);
|
||||
}
|
||||
COMPILER_RT_ABI xf_float __trunctfxf2(tf_float a) { return __truncXfYf2__(a); }
|
||||
|
||||
#endif
|
||||
|
@ -2,12 +2,12 @@
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
// long double __floatdixf(di_int a);
|
||||
// xf_float __floatdixf(di_int a);
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
#include "../int_lib.h"
|
||||
|
||||
long double __floatdixf(int64_t a) { return (long double)a; }
|
||||
xf_float __floatdixf(int64_t a) { return (xf_float)a; }
|
||||
|
||||
#endif // __i386__
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
// long double __floatundixf(du_int a);
|
||||
// xf_float __floatundixf(du_int a);
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user