Skip to content

Commit 69660cc

Browse files
authored
[builtins] Convert more int to fp functions to use common implementation (#67540)
Builds on #66903, converting the rest of the low-hanging fruit to use the common implementation. See #67540 (comment) for links to Alive2 comparisons of before/after.
1 parent 730df5a commit 69660cc

File tree

9 files changed

+63
-363
lines changed

9 files changed

+63
-363
lines changed

compiler-rt/lib/builtins/floatdisf.c

Lines changed: 5 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -19,52 +19,11 @@
1919

2020
#include "int_lib.h"
2121

22-
COMPILER_RT_ABI float __floatdisf(di_int a) {
23-
if (a == 0)
24-
return 0.0F;
25-
const unsigned N = sizeof(di_int) * CHAR_BIT;
26-
const di_int s = a >> (N - 1);
27-
a = (du_int)(a ^ s) - s;
28-
int sd = N - __builtin_clzll(a); // number of significant digits
29-
si_int e = sd - 1; // exponent
30-
if (sd > FLT_MANT_DIG) {
31-
// start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
32-
// finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
33-
// 12345678901234567890123456
34-
// 1 = msb 1 bit
35-
// P = bit FLT_MANT_DIG-1 bits to the right of 1
36-
// Q = bit FLT_MANT_DIG bits to the right of 1
37-
// R = "or" of all bits to the right of Q
38-
switch (sd) {
39-
case FLT_MANT_DIG + 1:
40-
a <<= 1;
41-
break;
42-
case FLT_MANT_DIG + 2:
43-
break;
44-
default:
45-
a = ((du_int)a >> (sd - (FLT_MANT_DIG + 2))) |
46-
((a & ((du_int)(-1) >> ((N + FLT_MANT_DIG + 2) - sd))) != 0);
47-
};
48-
// finish:
49-
a |= (a & 4) != 0; // Or P into R
50-
++a; // round - this step may add a significant bit
51-
a >>= 2; // dump Q and R
52-
// a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits
53-
if (a & ((du_int)1 << FLT_MANT_DIG)) {
54-
a >>= 1;
55-
++e;
56-
}
57-
// a is now rounded to FLT_MANT_DIG bits
58-
} else {
59-
a <<= (FLT_MANT_DIG - sd);
60-
// a is now rounded to FLT_MANT_DIG bits
61-
}
62-
float_bits fb;
63-
fb.u = ((su_int)s & 0x80000000) | // sign
64-
((e + 127) << 23) | // exponent
65-
((su_int)a & 0x007FFFFF); // mantissa
66-
return fb.f;
67-
}
22+
#define SRC_I64
23+
#define DST_SINGLE
24+
#include "int_to_fp_impl.inc"
25+
26+
COMPILER_RT_ABI float __floatdisf(di_int a) { return __floatXiYf__(a); }
6827

6928
#if defined(__ARM_EABI__)
7029
#if defined(COMPILER_RT_ARMHF_TARGET)

compiler-rt/lib/builtins/floattidf.c

Lines changed: 5 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414

1515
#ifdef CRT_HAS_128BIT
1616

17+
#define SRC_I128
18+
#define DST_DOUBLE
19+
#include "int_to_fp_impl.inc"
20+
1721
// Returns: convert a to a double, rounding toward even.
1822

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

25-
COMPILER_RT_ABI double __floattidf(ti_int a) {
26-
if (a == 0)
27-
return 0.0;
28-
const unsigned N = sizeof(ti_int) * CHAR_BIT;
29-
const ti_int s = a >> (N - 1);
30-
a = (a ^ s) - s;
31-
int sd = N - __clzti2(a); // number of significant digits
32-
si_int e = sd - 1; // exponent
33-
if (sd > DBL_MANT_DIG) {
34-
// start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
35-
// finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
36-
// 12345678901234567890123456
37-
// 1 = msb 1 bit
38-
// P = bit DBL_MANT_DIG-1 bits to the right of 1
39-
// Q = bit DBL_MANT_DIG bits to the right of 1
40-
// R = "or" of all bits to the right of Q
41-
switch (sd) {
42-
case DBL_MANT_DIG + 1:
43-
a <<= 1;
44-
break;
45-
case DBL_MANT_DIG + 2:
46-
break;
47-
default:
48-
a = ((tu_int)a >> (sd - (DBL_MANT_DIG + 2))) |
49-
((a & ((tu_int)(-1) >> ((N + DBL_MANT_DIG + 2) - sd))) != 0);
50-
};
51-
// finish:
52-
a |= (a & 4) != 0; // Or P into R
53-
++a; // round - this step may add a significant bit
54-
a >>= 2; // dump Q and R
55-
// a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits
56-
if (a & ((tu_int)1 << DBL_MANT_DIG)) {
57-
a >>= 1;
58-
++e;
59-
}
60-
// a is now rounded to DBL_MANT_DIG bits
61-
} else {
62-
a <<= (DBL_MANT_DIG - sd);
63-
// a is now rounded to DBL_MANT_DIG bits
64-
}
65-
double_bits fb;
66-
fb.u.s.high = ((su_int)s & 0x80000000) | // sign
67-
((e + 1023) << 20) | // exponent
68-
((su_int)(a >> 32) & 0x000FFFFF); // mantissa-high
69-
fb.u.s.low = (su_int)a; // mantissa-low
70-
return fb.f;
71-
}
29+
COMPILER_RT_ABI double __floattidf(ti_int a) { return __floatXiYf__(a); }
7230

7331
#endif // CRT_HAS_128BIT

compiler-rt/lib/builtins/floattisf.c

Lines changed: 5 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -14,58 +14,17 @@
1414

1515
#ifdef CRT_HAS_128BIT
1616

17+
#define SRC_I128
18+
#define DST_SINGLE
19+
#include "int_to_fp_impl.inc"
20+
1721
// Returns: convert a to a float, rounding toward even.
1822

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

2226
// seee eeee emmm mmmm mmmm mmmm mmmm mmmm
2327

24-
COMPILER_RT_ABI float __floattisf(ti_int a) {
25-
if (a == 0)
26-
return 0.0F;
27-
const unsigned N = sizeof(ti_int) * CHAR_BIT;
28-
const ti_int s = a >> (N - 1);
29-
a = (a ^ s) - s;
30-
int sd = N - __clzti2(a); // number of significant digits
31-
si_int e = sd - 1; // exponent
32-
if (sd > FLT_MANT_DIG) {
33-
// start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
34-
// finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
35-
// 12345678901234567890123456
36-
// 1 = msb 1 bit
37-
// P = bit FLT_MANT_DIG-1 bits to the right of 1
38-
// Q = bit FLT_MANT_DIG bits to the right of 1
39-
// R = "or" of all bits to the right of Q
40-
switch (sd) {
41-
case FLT_MANT_DIG + 1:
42-
a <<= 1;
43-
break;
44-
case FLT_MANT_DIG + 2:
45-
break;
46-
default:
47-
a = ((tu_int)a >> (sd - (FLT_MANT_DIG + 2))) |
48-
((a & ((tu_int)(-1) >> ((N + FLT_MANT_DIG + 2) - sd))) != 0);
49-
};
50-
// finish:
51-
a |= (a & 4) != 0; // Or P into R
52-
++a; // round - this step may add a significant bit
53-
a >>= 2; // dump Q and R
54-
// a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits
55-
if (a & ((tu_int)1 << FLT_MANT_DIG)) {
56-
a >>= 1;
57-
++e;
58-
}
59-
// a is now rounded to FLT_MANT_DIG bits
60-
} else {
61-
a <<= (FLT_MANT_DIG - sd);
62-
// a is now rounded to FLT_MANT_DIG bits
63-
}
64-
float_bits fb;
65-
fb.u = ((su_int)s & 0x80000000) | // sign
66-
((e + 127) << 23) | // exponent
67-
((su_int)a & 0x007FFFFF); // mantissa
68-
return fb.f;
69-
}
28+
COMPILER_RT_ABI float __floattisf(ti_int a) { return __floatXiYf__(a); }
7029

7130
#endif // CRT_HAS_128BIT

compiler-rt/lib/builtins/floattitf.c

Lines changed: 5 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
#include "fp_lib.h"
1717
#include "int_lib.h"
1818

19+
#define SRC_I128
20+
#define DST_QUAD
21+
#include "int_to_fp_impl.inc"
22+
1923
// Returns: convert a ti_int to a fp_t, rounding toward even.
2024

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

2832
#if defined(CRT_HAS_TF_MODE)
29-
COMPILER_RT_ABI fp_t __floattitf(ti_int a) {
30-
if (a == 0)
31-
return 0.0;
32-
const unsigned N = sizeof(ti_int) * CHAR_BIT;
33-
const ti_int s = a >> (N - 1);
34-
a = (a ^ s) - s;
35-
int sd = N - __clzti2(a); // number of significant digits
36-
int e = sd - 1; // exponent
37-
if (sd > TF_MANT_DIG) {
38-
// start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
39-
// finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
40-
// 12345678901234567890123456
41-
// 1 = msb 1 bit
42-
// P = bit LDBL_MANT_DIG-1 bits to the right of 1
43-
// Q = bit LDBL_MANT_DIG bits to the right of 1
44-
// R = "or" of all bits to the right of Q
45-
switch (sd) {
46-
case TF_MANT_DIG + 1:
47-
a <<= 1;
48-
break;
49-
case TF_MANT_DIG + 2:
50-
break;
51-
default:
52-
a = ((tu_int)a >> (sd - (TF_MANT_DIG + 2))) |
53-
((a & ((tu_int)(-1) >> ((N + TF_MANT_DIG + 2) - sd))) != 0);
54-
};
55-
// finish:
56-
a |= (a & 4) != 0; // Or P into R
57-
++a; // round - this step may add a significant bit
58-
a >>= 2; // dump Q and R
59-
// a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits
60-
if (a & ((tu_int)1 << TF_MANT_DIG)) {
61-
a >>= 1;
62-
++e;
63-
}
64-
// a is now rounded to LDBL_MANT_DIG bits
65-
} else {
66-
a <<= (TF_MANT_DIG - sd);
67-
// a is now rounded to LDBL_MANT_DIG bits
68-
}
69-
70-
long_double_bits fb;
71-
fb.u.high.all = (s & 0x8000000000000000LL) // sign
72-
| (du_int)(e + 16383) << 48 // exponent
73-
| ((a >> 64) & 0x0000ffffffffffffLL); // significand
74-
fb.u.low.all = (du_int)(a);
75-
return fb.f;
76-
}
33+
COMPILER_RT_ABI fp_t __floattitf(ti_int a) { return __floatXiYf__(a); }
7734

7835
#endif

compiler-rt/lib/builtins/floatundisf.c

Lines changed: 5 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -19,49 +19,11 @@
1919

2020
#include "int_lib.h"
2121

22-
COMPILER_RT_ABI float __floatundisf(du_int a) {
23-
if (a == 0)
24-
return 0.0F;
25-
const unsigned N = sizeof(du_int) * CHAR_BIT;
26-
int sd = N - __builtin_clzll(a); // number of significant digits
27-
si_int e = sd - 1; // 8 exponent
28-
if (sd > FLT_MANT_DIG) {
29-
// start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
30-
// finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
31-
// 12345678901234567890123456
32-
// 1 = msb 1 bit
33-
// P = bit FLT_MANT_DIG-1 bits to the right of 1
34-
// Q = bit FLT_MANT_DIG bits to the right of 1
35-
// R = "or" of all bits to the right of Q
36-
switch (sd) {
37-
case FLT_MANT_DIG + 1:
38-
a <<= 1;
39-
break;
40-
case FLT_MANT_DIG + 2:
41-
break;
42-
default:
43-
a = (a >> (sd - (FLT_MANT_DIG + 2))) |
44-
((a & ((du_int)(-1) >> ((N + FLT_MANT_DIG + 2) - sd))) != 0);
45-
};
46-
// finish:
47-
a |= (a & 4) != 0; // Or P into R
48-
++a; // round - this step may add a significant bit
49-
a >>= 2; // dump Q and R
50-
// a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits
51-
if (a & ((du_int)1 << FLT_MANT_DIG)) {
52-
a >>= 1;
53-
++e;
54-
}
55-
// a is now rounded to FLT_MANT_DIG bits
56-
} else {
57-
a <<= (FLT_MANT_DIG - sd);
58-
// a is now rounded to FLT_MANT_DIG bits
59-
}
60-
float_bits fb;
61-
fb.u = ((e + 127) << 23) | // exponent
62-
((su_int)a & 0x007FFFFF); // mantissa
63-
return fb.f;
64-
}
22+
#define SRC_U64
23+
#define DST_SINGLE
24+
#include "int_to_fp_impl.inc"
25+
26+
COMPILER_RT_ABI float __floatundisf(du_int a) { return __floatXiYf__(a); }
6527

6628
#if defined(__ARM_EABI__)
6729
#if defined(COMPILER_RT_ARMHF_TARGET)

compiler-rt/lib/builtins/floatuntidf.c

Lines changed: 5 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414

1515
#ifdef CRT_HAS_128BIT
1616

17+
#define SRC_U128
18+
#define DST_DOUBLE
19+
#include "int_to_fp_impl.inc"
20+
1721
// Returns: convert a to a double, rounding toward even.
1822

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

25-
COMPILER_RT_ABI double __floatuntidf(tu_int a) {
26-
if (a == 0)
27-
return 0.0;
28-
const unsigned N = sizeof(tu_int) * CHAR_BIT;
29-
int sd = N - __clzti2(a); // number of significant digits
30-
si_int e = sd - 1; // exponent
31-
if (sd > DBL_MANT_DIG) {
32-
// start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
33-
// finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
34-
// 12345678901234567890123456
35-
// 1 = msb 1 bit
36-
// P = bit DBL_MANT_DIG-1 bits to the right of 1
37-
// Q = bit DBL_MANT_DIG bits to the right of 1
38-
// R = "or" of all bits to the right of Q
39-
switch (sd) {
40-
case DBL_MANT_DIG + 1:
41-
a <<= 1;
42-
break;
43-
case DBL_MANT_DIG + 2:
44-
break;
45-
default:
46-
a = (a >> (sd - (DBL_MANT_DIG + 2))) |
47-
((a & ((tu_int)(-1) >> ((N + DBL_MANT_DIG + 2) - sd))) != 0);
48-
};
49-
// finish:
50-
a |= (a & 4) != 0; // Or P into R
51-
++a; // round - this step may add a significant bit
52-
a >>= 2; // dump Q and R
53-
// a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits
54-
if (a & ((tu_int)1 << DBL_MANT_DIG)) {
55-
a >>= 1;
56-
++e;
57-
}
58-
// a is now rounded to DBL_MANT_DIG bits
59-
} else {
60-
a <<= (DBL_MANT_DIG - sd);
61-
// a is now rounded to DBL_MANT_DIG bits
62-
}
63-
double_bits fb;
64-
fb.u.s.high = ((e + 1023) << 20) | // exponent
65-
((su_int)(a >> 32) & 0x000FFFFF); // mantissa-high
66-
fb.u.s.low = (su_int)a; // mantissa-low
67-
return fb.f;
68-
}
29+
COMPILER_RT_ABI double __floatuntidf(tu_int a) { return __floatXiYf__(a); }
6930

7031
#endif // CRT_HAS_128BIT

0 commit comments

Comments
 (0)