Skip to content

[builtins] Convert more int to fp functions to use common implementation #67540

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 5 additions & 46 deletions compiler-rt/lib/builtins/floatdisf.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,52 +19,11 @@

#include "int_lib.h"

COMPILER_RT_ABI float __floatdisf(di_int a) {
if (a == 0)
return 0.0F;
const unsigned N = sizeof(di_int) * CHAR_BIT;
const di_int s = a >> (N - 1);
a = (du_int)(a ^ s) - s;
int sd = N - __builtin_clzll(a); // number of significant digits
si_int e = sd - 1; // exponent
if (sd > FLT_MANT_DIG) {
// start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
// finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
// 12345678901234567890123456
// 1 = msb 1 bit
// P = bit FLT_MANT_DIG-1 bits to the right of 1
// Q = bit FLT_MANT_DIG bits to the right of 1
// R = "or" of all bits to the right of Q
switch (sd) {
case FLT_MANT_DIG + 1:
a <<= 1;
break;
case FLT_MANT_DIG + 2:
break;
default:
a = ((du_int)a >> (sd - (FLT_MANT_DIG + 2))) |
((a & ((du_int)(-1) >> ((N + FLT_MANT_DIG + 2) - sd))) != 0);
};
// finish:
a |= (a & 4) != 0; // Or P into R
++a; // round - this step may add a significant bit
a >>= 2; // dump Q and R
// a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits
if (a & ((du_int)1 << FLT_MANT_DIG)) {
a >>= 1;
++e;
}
// a is now rounded to FLT_MANT_DIG bits
} else {
a <<= (FLT_MANT_DIG - sd);
// a is now rounded to FLT_MANT_DIG bits
}
float_bits fb;
fb.u = ((su_int)s & 0x80000000) | // sign
((e + 127) << 23) | // exponent
((su_int)a & 0x007FFFFF); // mantissa
return fb.f;
}
#define SRC_I64
#define DST_SINGLE
#include "int_to_fp_impl.inc"

COMPILER_RT_ABI float __floatdisf(di_int a) { return __floatXiYf__(a); }

#if defined(__ARM_EABI__)
#if defined(COMPILER_RT_ARMHF_TARGET)
Expand Down
52 changes: 5 additions & 47 deletions compiler-rt/lib/builtins/floattidf.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

#ifdef CRT_HAS_128BIT

#define SRC_I128
#define DST_DOUBLE
#include "int_to_fp_impl.inc"

// Returns: convert a to a double, rounding toward even.

// Assumption: double is a IEEE 64 bit floating point type
Expand All @@ -22,52 +26,6 @@
// seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm
// mmmm

COMPILER_RT_ABI double __floattidf(ti_int a) {
if (a == 0)
return 0.0;
const unsigned N = sizeof(ti_int) * CHAR_BIT;
const ti_int s = a >> (N - 1);
a = (a ^ s) - s;
int sd = N - __clzti2(a); // number of significant digits
si_int e = sd - 1; // exponent
if (sd > DBL_MANT_DIG) {
// start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
// finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
// 12345678901234567890123456
// 1 = msb 1 bit
// P = bit DBL_MANT_DIG-1 bits to the right of 1
// Q = bit DBL_MANT_DIG bits to the right of 1
// R = "or" of all bits to the right of Q
switch (sd) {
case DBL_MANT_DIG + 1:
a <<= 1;
break;
case DBL_MANT_DIG + 2:
break;
default:
a = ((tu_int)a >> (sd - (DBL_MANT_DIG + 2))) |
((a & ((tu_int)(-1) >> ((N + DBL_MANT_DIG + 2) - sd))) != 0);
};
// finish:
a |= (a & 4) != 0; // Or P into R
++a; // round - this step may add a significant bit
a >>= 2; // dump Q and R
// a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits
if (a & ((tu_int)1 << DBL_MANT_DIG)) {
a >>= 1;
++e;
}
// a is now rounded to DBL_MANT_DIG bits
} else {
a <<= (DBL_MANT_DIG - sd);
// a is now rounded to DBL_MANT_DIG bits
}
double_bits fb;
fb.u.s.high = ((su_int)s & 0x80000000) | // sign
((e + 1023) << 20) | // exponent
((su_int)(a >> 32) & 0x000FFFFF); // mantissa-high
fb.u.s.low = (su_int)a; // mantissa-low
return fb.f;
}
COMPILER_RT_ABI double __floattidf(ti_int a) { return __floatXiYf__(a); }

#endif // CRT_HAS_128BIT
51 changes: 5 additions & 46 deletions compiler-rt/lib/builtins/floattisf.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,58 +14,17 @@

#ifdef CRT_HAS_128BIT

#define SRC_I128
#define DST_SINGLE
#include "int_to_fp_impl.inc"

// Returns: convert a to a float, rounding toward even.

// Assumption: float is a IEEE 32 bit floating point type
// ti_int is a 128 bit integral type

// seee eeee emmm mmmm mmmm mmmm mmmm mmmm

COMPILER_RT_ABI float __floattisf(ti_int a) {
if (a == 0)
return 0.0F;
const unsigned N = sizeof(ti_int) * CHAR_BIT;
const ti_int s = a >> (N - 1);
a = (a ^ s) - s;
int sd = N - __clzti2(a); // number of significant digits
si_int e = sd - 1; // exponent
if (sd > FLT_MANT_DIG) {
// start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
// finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
// 12345678901234567890123456
// 1 = msb 1 bit
// P = bit FLT_MANT_DIG-1 bits to the right of 1
// Q = bit FLT_MANT_DIG bits to the right of 1
// R = "or" of all bits to the right of Q
switch (sd) {
case FLT_MANT_DIG + 1:
a <<= 1;
break;
case FLT_MANT_DIG + 2:
break;
default:
a = ((tu_int)a >> (sd - (FLT_MANT_DIG + 2))) |
((a & ((tu_int)(-1) >> ((N + FLT_MANT_DIG + 2) - sd))) != 0);
};
// finish:
a |= (a & 4) != 0; // Or P into R
++a; // round - this step may add a significant bit
a >>= 2; // dump Q and R
// a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits
if (a & ((tu_int)1 << FLT_MANT_DIG)) {
a >>= 1;
++e;
}
// a is now rounded to FLT_MANT_DIG bits
} else {
a <<= (FLT_MANT_DIG - sd);
// a is now rounded to FLT_MANT_DIG bits
}
float_bits fb;
fb.u = ((su_int)s & 0x80000000) | // sign
((e + 127) << 23) | // exponent
((su_int)a & 0x007FFFFF); // mantissa
return fb.f;
}
COMPILER_RT_ABI float __floattisf(ti_int a) { return __floatXiYf__(a); }

#endif // CRT_HAS_128BIT
53 changes: 5 additions & 48 deletions compiler-rt/lib/builtins/floattitf.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
#include "fp_lib.h"
#include "int_lib.h"

#define SRC_I128
#define DST_QUAD
#include "int_to_fp_impl.inc"

// Returns: convert a ti_int to a fp_t, rounding toward even.

// Assumption: fp_t is a IEEE 128 bit floating point type
Expand All @@ -26,53 +30,6 @@
// mmmm mmmm mmmm

#if defined(CRT_HAS_TF_MODE)
COMPILER_RT_ABI fp_t __floattitf(ti_int a) {
if (a == 0)
return 0.0;
const unsigned N = sizeof(ti_int) * CHAR_BIT;
const ti_int s = a >> (N - 1);
a = (a ^ s) - s;
int sd = N - __clzti2(a); // number of significant digits
int e = sd - 1; // exponent
if (sd > TF_MANT_DIG) {
// start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
// finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
// 12345678901234567890123456
// 1 = msb 1 bit
// P = bit LDBL_MANT_DIG-1 bits to the right of 1
// Q = bit LDBL_MANT_DIG bits to the right of 1
// R = "or" of all bits to the right of Q
switch (sd) {
case TF_MANT_DIG + 1:
a <<= 1;
break;
case TF_MANT_DIG + 2:
break;
default:
a = ((tu_int)a >> (sd - (TF_MANT_DIG + 2))) |
((a & ((tu_int)(-1) >> ((N + TF_MANT_DIG + 2) - sd))) != 0);
};
// finish:
a |= (a & 4) != 0; // Or P into R
++a; // round - this step may add a significant bit
a >>= 2; // dump Q and R
// a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits
if (a & ((tu_int)1 << TF_MANT_DIG)) {
a >>= 1;
++e;
}
// a is now rounded to LDBL_MANT_DIG bits
} else {
a <<= (TF_MANT_DIG - sd);
// a is now rounded to LDBL_MANT_DIG bits
}

long_double_bits fb;
fb.u.high.all = (s & 0x8000000000000000LL) // sign
| (du_int)(e + 16383) << 48 // exponent
| ((a >> 64) & 0x0000ffffffffffffLL); // significand
fb.u.low.all = (du_int)(a);
return fb.f;
}
COMPILER_RT_ABI fp_t __floattitf(ti_int a) { return __floatXiYf__(a); }

#endif
48 changes: 5 additions & 43 deletions compiler-rt/lib/builtins/floatundisf.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,49 +19,11 @@

#include "int_lib.h"

COMPILER_RT_ABI float __floatundisf(du_int a) {
if (a == 0)
return 0.0F;
const unsigned N = sizeof(du_int) * CHAR_BIT;
int sd = N - __builtin_clzll(a); // number of significant digits
si_int e = sd - 1; // 8 exponent
if (sd > FLT_MANT_DIG) {
// start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
// finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
// 12345678901234567890123456
// 1 = msb 1 bit
// P = bit FLT_MANT_DIG-1 bits to the right of 1
// Q = bit FLT_MANT_DIG bits to the right of 1
// R = "or" of all bits to the right of Q
switch (sd) {
case FLT_MANT_DIG + 1:
a <<= 1;
break;
case FLT_MANT_DIG + 2:
break;
default:
a = (a >> (sd - (FLT_MANT_DIG + 2))) |
((a & ((du_int)(-1) >> ((N + FLT_MANT_DIG + 2) - sd))) != 0);
};
// finish:
a |= (a & 4) != 0; // Or P into R
++a; // round - this step may add a significant bit
a >>= 2; // dump Q and R
// a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits
if (a & ((du_int)1 << FLT_MANT_DIG)) {
a >>= 1;
++e;
}
// a is now rounded to FLT_MANT_DIG bits
} else {
a <<= (FLT_MANT_DIG - sd);
// a is now rounded to FLT_MANT_DIG bits
}
float_bits fb;
fb.u = ((e + 127) << 23) | // exponent
((su_int)a & 0x007FFFFF); // mantissa
return fb.f;
}
#define SRC_U64
#define DST_SINGLE
#include "int_to_fp_impl.inc"

COMPILER_RT_ABI float __floatundisf(du_int a) { return __floatXiYf__(a); }

#if defined(__ARM_EABI__)
#if defined(COMPILER_RT_ARMHF_TARGET)
Expand Down
49 changes: 5 additions & 44 deletions compiler-rt/lib/builtins/floatuntidf.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

#ifdef CRT_HAS_128BIT

#define SRC_U128
#define DST_DOUBLE
#include "int_to_fp_impl.inc"

// Returns: convert a to a double, rounding toward even.

// Assumption: double is a IEEE 64 bit floating point type
Expand All @@ -22,49 +26,6 @@
// seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm
// mmmm

COMPILER_RT_ABI double __floatuntidf(tu_int a) {
if (a == 0)
return 0.0;
const unsigned N = sizeof(tu_int) * CHAR_BIT;
int sd = N - __clzti2(a); // number of significant digits
si_int e = sd - 1; // exponent
if (sd > DBL_MANT_DIG) {
// start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
// finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
// 12345678901234567890123456
// 1 = msb 1 bit
// P = bit DBL_MANT_DIG-1 bits to the right of 1
// Q = bit DBL_MANT_DIG bits to the right of 1
// R = "or" of all bits to the right of Q
switch (sd) {
case DBL_MANT_DIG + 1:
a <<= 1;
break;
case DBL_MANT_DIG + 2:
break;
default:
a = (a >> (sd - (DBL_MANT_DIG + 2))) |
((a & ((tu_int)(-1) >> ((N + DBL_MANT_DIG + 2) - sd))) != 0);
};
// finish:
a |= (a & 4) != 0; // Or P into R
++a; // round - this step may add a significant bit
a >>= 2; // dump Q and R
// a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits
if (a & ((tu_int)1 << DBL_MANT_DIG)) {
a >>= 1;
++e;
}
// a is now rounded to DBL_MANT_DIG bits
} else {
a <<= (DBL_MANT_DIG - sd);
// a is now rounded to DBL_MANT_DIG bits
}
double_bits fb;
fb.u.s.high = ((e + 1023) << 20) | // exponent
((su_int)(a >> 32) & 0x000FFFFF); // mantissa-high
fb.u.s.low = (su_int)a; // mantissa-low
return fb.f;
}
COMPILER_RT_ABI double __floatuntidf(tu_int a) { return __floatXiYf__(a); }

#endif // CRT_HAS_128BIT
Loading