summaryrefslogtreecommitdiff
path: root/lib/builtins/floatundidf.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/builtins/floatundidf.c')
-rw-r--r--lib/builtins/floatundidf.c138
1 files changed, 68 insertions, 70 deletions
diff --git a/lib/builtins/floatundidf.c b/lib/builtins/floatundidf.c
index 2c5c68ea4..6478caef0 100644
--- a/lib/builtins/floatundidf.c
+++ b/lib/builtins/floatundidf.c
@@ -17,96 +17,94 @@
* du_int is a 64 bit integral type
*/
-/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
+/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+ * mmmm */
#include "int_lib.h"
#ifndef __SOFT_FP__
-/* Support for systems that have hardware floating-point; we'll set the inexact flag
- * as a side-effect of this computation.
+/* Support for systems that have hardware floating-point; we'll set the inexact
+ * flag as a side-effect of this computation.
*/
-COMPILER_RT_ABI double
-__floatundidf(du_int a)
-{
- static const double twop52 = 4503599627370496.0; // 0x1.0p52
- static const double twop84 = 19342813113834066795298816.0; // 0x1.0p84
- static const double twop84_plus_twop52 = 19342813118337666422669312.0; // 0x1.00000001p84
+COMPILER_RT_ABI double __floatundidf(du_int a) {
+ static const double twop52 = 4503599627370496.0; // 0x1.0p52
+ static const double twop84 = 19342813113834066795298816.0; // 0x1.0p84
+ static const double twop84_plus_twop52 =
+ 19342813118337666422669312.0; // 0x1.00000001p84
- union { uint64_t x; double d; } high = { .d = twop84 };
- union { uint64_t x; double d; } low = { .d = twop52 };
+ union {
+ uint64_t x;
+ double d;
+ } high = {.d = twop84};
+ union {
+ uint64_t x;
+ double d;
+ } low = {.d = twop52};
- high.x |= a >> 32;
- low.x |= a & UINT64_C(0x00000000ffffffff);
+ high.x |= a >> 32;
+ low.x |= a & UINT64_C(0x00000000ffffffff);
- const double result = (high.d - twop84_plus_twop52) + low.d;
- return result;
+ const double result = (high.d - twop84_plus_twop52) + low.d;
+ return result;
}
#else
-/* Support for systems that don't have hardware floating-point; there are no flags to
- * set, and we don't want to code-gen to an unknown soft-float implementation.
+/* Support for systems that don't have hardware floating-point; there are no
+ * flags to set, and we don't want to code-gen to an unknown soft-float
+ * implementation.
*/
-COMPILER_RT_ABI double
-__floatundidf(du_int a)
-{
- if (a == 0)
- return 0.0;
- const unsigned N = sizeof(du_int) * CHAR_BIT;
- int sd = N - __builtin_clzll(a); /* number of significant digits */
- 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 & ((du_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 & ((du_int)1 << DBL_MANT_DIG))
- {
- a >>= 1;
- ++e;
- }
- /* a is now rounded to DBL_MANT_DIG bits */
+COMPILER_RT_ABI double __floatundidf(du_int a) {
+ if (a == 0)
+ return 0.0;
+ const unsigned N = sizeof(du_int) * CHAR_BIT;
+ int sd = N - __builtin_clzll(a); /* number of significant digits */
+ 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 & ((du_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 & ((du_int)1 << DBL_MANT_DIG)) {
+ a >>= 1;
+ ++e;
}
- 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;
+ /* 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;
}
#endif
#if defined(__ARM_EABI__)
#if defined(COMPILER_RT_ARMHF_TARGET)
-AEABI_RTABI double __aeabi_ul2d(du_int a) {
- return __floatundidf(a);
-}
+AEABI_RTABI double __aeabi_ul2d(du_int a) { return __floatundidf(a); }
#else
AEABI_RTABI double __aeabi_ul2d(du_int a) COMPILER_RT_ALIAS(__floatundidf);
#endif