summaryrefslogtreecommitdiff
path: root/libgcc/config/libbid/bid_internal.h
diff options
context:
space:
mode:
Diffstat (limited to 'libgcc/config/libbid/bid_internal.h')
-rw-r--r--libgcc/config/libbid/bid_internal.h412
1 files changed, 226 insertions, 186 deletions
diff --git a/libgcc/config/libbid/bid_internal.h b/libgcc/config/libbid/bid_internal.h
index 7f117687b67..d389646870b 100644
--- a/libgcc/config/libbid/bid_internal.h
+++ b/libgcc/config/libbid/bid_internal.h
@@ -32,7 +32,6 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#include "bid_conf.h"
#include "bid_functions.h"
-
#define __BID_INLINE__ static __inline
/*********************************************************************
@@ -210,7 +209,7 @@ UINT64 X1, X0=X; \
C_128.w[0] = 0x378d8e63ffffffffull; \
} \
}
-
+
/*********************************************************************
*
* Multiply Macros
@@ -739,6 +738,8 @@ UINT128 _TMP2,_TMP8; \
///////////////////////////////////////
#define SPECIAL_ENCODING_MASK64 0x6000000000000000ull
#define INFINITY_MASK64 0x7800000000000000ull
+#define SINFINITY_MASK64 0xf800000000000000ull
+#define SSNAN_MASK64 0xfc00000000000000ull
#define NAN_MASK64 0x7c00000000000000ull
#define SNAN_MASK64 0x7e00000000000000ull
#define QUIET_MASK64 0xfdffffffffffffffull
@@ -762,21 +763,23 @@ UINT128 _TMP2,_TMP8; \
#define SMALL_COEFF_MASK32 0x001ffffful
#define EXPONENT_MASK32 0xff
#define LARGEST_BID32 0x77f8967f
+#define NAN_MASK32 0x7c000000
+#define SNAN_MASK32 0x7e000000
#define MASK_BINARY_EXPONENT 0x7ff0000000000000ull
#define BINARY_EXPONENT_BIAS 0x3ff
#define UPPER_EXPON_LIMIT 51
// data needed for BID pack/unpack macros
-extern UINT64 __bid_round_const_table[][19];
-extern UINT128 __bid_reciprocals10_128[];
-extern int __bid_recip_scale[];
-extern UINT128 __bid_power10_table_128[];
-extern int __bid_estimate_decimal_digits[];
-extern int __bid_estimate_bin_expon[];
-extern UINT64 __bid_power10_index_binexp[];
-extern int __bid_short_recip_scale[];
-extern UINT64 __bid_reciprocals10_64[];
-extern UINT128 __bid_power10_index_binexp_128[];
-extern UINT128 __bid_round_const_table_128[][36];
+extern UINT64 round_const_table[][19];
+extern UINT128 reciprocals10_128[];
+extern int recip_scale[];
+extern UINT128 power10_table_128[];
+extern int estimate_decimal_digits[];
+extern int estimate_bin_expon[];
+extern UINT64 power10_index_binexp[];
+extern int short_recip_scale[];
+extern UINT64 reciprocals10_64[];
+extern UINT128 power10_index_binexp_128[];
+extern UINT128 round_const_table_128[][36];
//////////////////////////////////////////////
@@ -798,10 +801,12 @@ unpack_BID64 (UINT64 * psign_x, int *pexponent_x,
coeff = (x & LARGE_COEFF_MASK64) | LARGE_COEFF_HIGH_BIT64;
if ((x & INFINITY_MASK64) == INFINITY_MASK64) {
- *pcoefficient_x = x;
- // check for non-canonical values
- if ((x & LARGE_COEFF_MASK64) >= 1000000000000000ull)
- *pcoefficient_x = x & (~LARGE_COEFF_MASK64);
+ *pexponent_x = 0;
+ *pcoefficient_x = x & 0xfe03ffffffffffffull;
+ if ((x & 0x0003ffffffffffffull) >= 1000000000000000ull)
+ *pcoefficient_x = x & 0xfe00000000000000ull;
+ if ((x & NAN_MASK64) == INFINITY_MASK64)
+ *pcoefficient_x = x & SINFINITY_MASK64;
return 0; // NaN or Infinity
}
// check for non-canonical values
@@ -811,7 +816,7 @@ unpack_BID64 (UINT64 * psign_x, int *pexponent_x,
// get exponent
tmp = x >> EXPONENT_SHIFT_LARGE64;
*pexponent_x = (int) (tmp & EXPONENT_MASK64);
- return 1;
+ return coeff;
}
// exponent
tmp = x >> EXPONENT_SHIFT_SMALL64;
@@ -865,20 +870,20 @@ get_BID64 (UINT64 sgn, int expon, UINT64 coeff, int rmode,
#endif
// get digits to be shifted out
extra_digits = -expon;
- coeff += __bid_round_const_table[rmode][extra_digits];
+ coeff += round_const_table[rmode][extra_digits];
// get coeff*(2^M[extra_digits])/10^extra_digits
__mul_64x128_full (QH, Q_low, coeff,
- __bid_reciprocals10_128[extra_digits]);
+ reciprocals10_128[extra_digits]);
// now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
- amount = __bid_recip_scale[extra_digits];
+ amount = recip_scale[extra_digits];
C64 = QH >> amount;
#ifndef IEEE_ROUND_NEAREST_TIES_AWAY
#ifndef IEEE_ROUND_NEAREST
- if (rmode == 0) //ROUNDING_TO_NEAREST
+ if (rmode == 0) //ROUNDING_TO_NEAREST
#endif
if (C64 & 1) {
// check whether fractional part of initial_P/10^extra_digits is exactly .5
@@ -891,10 +896,10 @@ get_BID64 (UINT64 sgn, int expon, UINT64 coeff, int rmode,
remainder_h = remainder_h & QH;
if (!remainder_h
- && (Q_low.w[1] < __bid_reciprocals10_128[extra_digits].w[1]
- || (Q_low.w[1] == __bid_reciprocals10_128[extra_digits].w[1]
+ && (Q_low.w[1] < reciprocals10_128[extra_digits].w[1]
+ || (Q_low.w[1] == reciprocals10_128[extra_digits].w[1]
&& Q_low.w[0] <
- __bid_reciprocals10_128[extra_digits].w[0]))) {
+ reciprocals10_128[extra_digits].w[0]))) {
C64--;
}
}
@@ -914,27 +919,27 @@ get_BID64 (UINT64 sgn, int expon, UINT64 coeff, int rmode,
case ROUNDING_TIES_AWAY:
// test whether fractional part is 0
if (remainder_h == 0x8000000000000000ull
- && (Q_low.w[1] < __bid_reciprocals10_128[extra_digits].w[1]
- || (Q_low.w[1] == __bid_reciprocals10_128[extra_digits].w[1]
+ && (Q_low.w[1] < reciprocals10_128[extra_digits].w[1]
+ || (Q_low.w[1] == reciprocals10_128[extra_digits].w[1]
&& Q_low.w[0] <
- __bid_reciprocals10_128[extra_digits].w[0])))
+ reciprocals10_128[extra_digits].w[0])))
status = EXACT_STATUS;
break;
case ROUNDING_DOWN:
case ROUNDING_TO_ZERO:
if (!remainder_h
- && (Q_low.w[1] < __bid_reciprocals10_128[extra_digits].w[1]
- || (Q_low.w[1] == __bid_reciprocals10_128[extra_digits].w[1]
+ && (Q_low.w[1] < reciprocals10_128[extra_digits].w[1]
+ || (Q_low.w[1] == reciprocals10_128[extra_digits].w[1]
&& Q_low.w[0] <
- __bid_reciprocals10_128[extra_digits].w[0])))
+ reciprocals10_128[extra_digits].w[0])))
status = EXACT_STATUS;
break;
default:
// round up
__add_carry_out (Stemp.w[0], CY, Q_low.w[0],
- __bid_reciprocals10_128[extra_digits].w[0]);
+ reciprocals10_128[extra_digits].w[0]);
__add_carry_in_out (Stemp.w[1], carry, Q_low.w[1],
- __bid_reciprocals10_128[extra_digits].w[1], CY);
+ reciprocals10_128[extra_digits].w[1], CY);
if ((remainder_h >> (64 - amount)) + carry >=
(((UINT64) 1) << amount))
status = EXACT_STATUS;
@@ -1208,21 +1213,21 @@ get_BID64_UF (UINT64 sgn, int expon, UINT64 coeff, UINT64 R, int rmode,
coeff |= 1;
// get digits to be shifted out
extra_digits = 1 - expon;
- C128.w[0] = coeff + __bid_round_const_table[rmode][extra_digits];
+ C128.w[0] = coeff + round_const_table[rmode][extra_digits];
// get coeff*(2^M[extra_digits])/10^extra_digits
__mul_64x128_full (QH, Q_low, C128.w[0],
- __bid_reciprocals10_128[extra_digits]);
+ reciprocals10_128[extra_digits]);
// now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
- amount = __bid_recip_scale[extra_digits];
+ amount = recip_scale[extra_digits];
C64 = QH >> amount;
//__shr_128(C128, Q_high, amount);
#ifndef IEEE_ROUND_NEAREST_TIES_AWAY
#ifndef IEEE_ROUND_NEAREST
- if (rmode == 0) //ROUNDING_TO_NEAREST
+ if (rmode == 0) //ROUNDING_TO_NEAREST
#endif
if (C64 & 1) {
// check whether fractional part of initial_P/10^extra_digits is exactly .5
@@ -1235,10 +1240,10 @@ get_BID64_UF (UINT64 sgn, int expon, UINT64 coeff, UINT64 R, int rmode,
remainder_h = remainder_h & QH;
if (!remainder_h
- && (Q_low.w[1] < __bid_reciprocals10_128[extra_digits].w[1]
- || (Q_low.w[1] == __bid_reciprocals10_128[extra_digits].w[1]
+ && (Q_low.w[1] < reciprocals10_128[extra_digits].w[1]
+ || (Q_low.w[1] == reciprocals10_128[extra_digits].w[1]
&& Q_low.w[0] <
- __bid_reciprocals10_128[extra_digits].w[0]))) {
+ reciprocals10_128[extra_digits].w[0]))) {
C64--;
}
}
@@ -1258,27 +1263,27 @@ get_BID64_UF (UINT64 sgn, int expon, UINT64 coeff, UINT64 R, int rmode,
case ROUNDING_TIES_AWAY:
// test whether fractional part is 0
if (remainder_h == 0x8000000000000000ull
- && (Q_low.w[1] < __bid_reciprocals10_128[extra_digits].w[1]
- || (Q_low.w[1] == __bid_reciprocals10_128[extra_digits].w[1]
+ && (Q_low.w[1] < reciprocals10_128[extra_digits].w[1]
+ || (Q_low.w[1] == reciprocals10_128[extra_digits].w[1]
&& Q_low.w[0] <
- __bid_reciprocals10_128[extra_digits].w[0])))
+ reciprocals10_128[extra_digits].w[0])))
status = EXACT_STATUS;
break;
case ROUNDING_DOWN:
case ROUNDING_TO_ZERO:
if (!remainder_h
- && (Q_low.w[1] < __bid_reciprocals10_128[extra_digits].w[1]
- || (Q_low.w[1] == __bid_reciprocals10_128[extra_digits].w[1]
+ && (Q_low.w[1] < reciprocals10_128[extra_digits].w[1]
+ || (Q_low.w[1] == reciprocals10_128[extra_digits].w[1]
&& Q_low.w[0] <
- __bid_reciprocals10_128[extra_digits].w[0])))
+ reciprocals10_128[extra_digits].w[0])))
status = EXACT_STATUS;
break;
default:
// round up
__add_carry_out (Stemp.w[0], CY, Q_low.w[0],
- __bid_reciprocals10_128[extra_digits].w[0]);
+ reciprocals10_128[extra_digits].w[0]);
__add_carry_in_out (Stemp.w[1], carry, Q_low.w[1],
- __bid_reciprocals10_128[extra_digits].w[1], CY);
+ reciprocals10_128[extra_digits].w[1], CY);
if ((remainder_h >> (64 - amount)) + carry >=
(((UINT64) 1) << amount))
status = EXACT_STATUS;
@@ -1335,20 +1340,20 @@ get_BID64_small_mantissa (UINT64 sgn, int expon, UINT64 coeff,
#endif
// get digits to be shifted out
extra_digits = -expon;
- C128.w[0] = coeff + __bid_round_const_table[rmode][extra_digits];
+ C128.w[0] = coeff + round_const_table[rmode][extra_digits];
// get coeff*(2^M[extra_digits])/10^extra_digits
__mul_64x128_full (QH, Q_low, C128.w[0],
- __bid_reciprocals10_128[extra_digits]);
+ reciprocals10_128[extra_digits]);
// now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
- amount = __bid_recip_scale[extra_digits];
+ amount = recip_scale[extra_digits];
C64 = QH >> amount;
#ifndef IEEE_ROUND_NEAREST_TIES_AWAY
#ifndef IEEE_ROUND_NEAREST
- if (rmode == 0) //ROUNDING_TO_NEAREST
+ if (rmode == 0) //ROUNDING_TO_NEAREST
#endif
if (C64 & 1) {
// check whether fractional part of initial_P/10^extra_digits is exactly .5
@@ -1361,10 +1366,10 @@ get_BID64_small_mantissa (UINT64 sgn, int expon, UINT64 coeff,
remainder_h = remainder_h & QH;
if (!remainder_h
- && (Q_low.w[1] < __bid_reciprocals10_128[extra_digits].w[1]
- || (Q_low.w[1] == __bid_reciprocals10_128[extra_digits].w[1]
+ && (Q_low.w[1] < reciprocals10_128[extra_digits].w[1]
+ || (Q_low.w[1] == reciprocals10_128[extra_digits].w[1]
&& Q_low.w[0] <
- __bid_reciprocals10_128[extra_digits].w[0]))) {
+ reciprocals10_128[extra_digits].w[0]))) {
C64--;
}
}
@@ -1384,27 +1389,27 @@ get_BID64_small_mantissa (UINT64 sgn, int expon, UINT64 coeff,
case ROUNDING_TIES_AWAY:
// test whether fractional part is 0
if (remainder_h == 0x8000000000000000ull
- && (Q_low.w[1] < __bid_reciprocals10_128[extra_digits].w[1]
- || (Q_low.w[1] == __bid_reciprocals10_128[extra_digits].w[1]
+ && (Q_low.w[1] < reciprocals10_128[extra_digits].w[1]
+ || (Q_low.w[1] == reciprocals10_128[extra_digits].w[1]
&& Q_low.w[0] <
- __bid_reciprocals10_128[extra_digits].w[0])))
+ reciprocals10_128[extra_digits].w[0])))
status = EXACT_STATUS;
break;
case ROUNDING_DOWN:
case ROUNDING_TO_ZERO:
if (!remainder_h
- && (Q_low.w[1] < __bid_reciprocals10_128[extra_digits].w[1]
- || (Q_low.w[1] == __bid_reciprocals10_128[extra_digits].w[1]
+ && (Q_low.w[1] < reciprocals10_128[extra_digits].w[1]
+ || (Q_low.w[1] == reciprocals10_128[extra_digits].w[1]
&& Q_low.w[0] <
- __bid_reciprocals10_128[extra_digits].w[0])))
+ reciprocals10_128[extra_digits].w[0])))
status = EXACT_STATUS;
break;
default:
// round up
__add_carry_out (Stemp.w[0], CY, Q_low.w[0],
- __bid_reciprocals10_128[extra_digits].w[0]);
+ reciprocals10_128[extra_digits].w[0]);
__add_carry_in_out (Stemp.w[1], carry, Q_low.w[1],
- __bid_reciprocals10_128[extra_digits].w[1], CY);
+ reciprocals10_128[extra_digits].w[1], CY);
if ((remainder_h >> (64 - amount)) + carry >=
(((UINT64) 1) << amount))
status = EXACT_STATUS;
@@ -1525,13 +1530,13 @@ handle_UF_128_rem (UINT128 * pres, UINT64 sgn, int expon, UINT128 CQ,
#else
rmode = 0;
#endif
- T128 = __bid_round_const_table_128[rmode][ed2];
+ T128 = round_const_table_128[rmode][ed2];
__add_carry_out (CQ.w[0], carry, T128.w[0], CQ.w[0]);
CQ.w[1] = CQ.w[1] + T128.w[1] + carry;
- TP128 = __bid_reciprocals10_128[ed2];
+ TP128 = reciprocals10_128[ed2];
__mul_128x128_full (Qh, Ql, CQ, TP128);
- amount = __bid_recip_scale[ed2];
+ amount = recip_scale[ed2];
if (amount >= 64) {
CQ.w[0] = Qh.w[1] >> (amount - 64);
@@ -1553,9 +1558,9 @@ handle_UF_128_rem (UINT128 * pres, UINT64 sgn, int expon, UINT128 CQ,
__shl_128_long (Qh1, Qh, (128 - amount));
if (!Qh1.w[1] && !Qh1.w[0]
- && (Ql.w[1] < __bid_reciprocals10_128[ed2].w[1]
- || (Ql.w[1] == __bid_reciprocals10_128[ed2].w[1]
- && Ql.w[0] < __bid_reciprocals10_128[ed2].w[0]))) {
+ && (Ql.w[1] < reciprocals10_128[ed2].w[1]
+ || (Ql.w[1] == reciprocals10_128[ed2].w[1]
+ && Ql.w[0] < reciprocals10_128[ed2].w[0]))) {
CQ.w[0]--;
}
}
@@ -1575,25 +1580,25 @@ handle_UF_128_rem (UINT128 * pres, UINT64 sgn, int expon, UINT128 CQ,
case ROUNDING_TIES_AWAY:
// test whether fractional part is 0
if (Qh1.w[1] == 0x8000000000000000ull && (!Qh1.w[0])
- && (Ql.w[1] < __bid_reciprocals10_128[ed2].w[1]
- || (Ql.w[1] == __bid_reciprocals10_128[ed2].w[1]
- && Ql.w[0] < __bid_reciprocals10_128[ed2].w[0])))
+ && (Ql.w[1] < reciprocals10_128[ed2].w[1]
+ || (Ql.w[1] == reciprocals10_128[ed2].w[1]
+ && Ql.w[0] < reciprocals10_128[ed2].w[0])))
status = EXACT_STATUS;
break;
case ROUNDING_DOWN:
case ROUNDING_TO_ZERO:
if ((!Qh1.w[1]) && (!Qh1.w[0])
- && (Ql.w[1] < __bid_reciprocals10_128[ed2].w[1]
- || (Ql.w[1] == __bid_reciprocals10_128[ed2].w[1]
- && Ql.w[0] < __bid_reciprocals10_128[ed2].w[0])))
+ && (Ql.w[1] < reciprocals10_128[ed2].w[1]
+ || (Ql.w[1] == reciprocals10_128[ed2].w[1]
+ && Ql.w[0] < reciprocals10_128[ed2].w[0])))
status = EXACT_STATUS;
break;
default:
// round up
__add_carry_out (Stemp.w[0], CY, Ql.w[0],
- __bid_reciprocals10_128[ed2].w[0]);
+ reciprocals10_128[ed2].w[0]);
__add_carry_in_out (Stemp.w[1], carry, Ql.w[1],
- __bid_reciprocals10_128[ed2].w[1], CY);
+ reciprocals10_128[ed2].w[1], CY);
__shr_128_long (Qh, Qh1, (128 - amount));
Tmp.w[0] = 1;
Tmp.w[1] = 0;
@@ -1661,13 +1666,13 @@ handle_UF_128 (UINT128 * pres, UINT64 sgn, int expon, UINT128 CQ,
rmode = 0;
#endif
- T128 = __bid_round_const_table_128[rmode][ed2];
+ T128 = round_const_table_128[rmode][ed2];
__add_carry_out (CQ.w[0], carry, T128.w[0], CQ.w[0]);
CQ.w[1] = CQ.w[1] + T128.w[1] + carry;
- TP128 = __bid_reciprocals10_128[ed2];
+ TP128 = reciprocals10_128[ed2];
__mul_128x128_full (Qh, Ql, CQ, TP128);
- amount = __bid_recip_scale[ed2];
+ amount = recip_scale[ed2];
if (amount >= 64) {
CQ.w[0] = Qh.w[1] >> (amount - 64);
@@ -1689,9 +1694,9 @@ handle_UF_128 (UINT128 * pres, UINT64 sgn, int expon, UINT128 CQ,
__shl_128_long (Qh1, Qh, (128 - amount));
if (!Qh1.w[1] && !Qh1.w[0]
- && (Ql.w[1] < __bid_reciprocals10_128[ed2].w[1]
- || (Ql.w[1] == __bid_reciprocals10_128[ed2].w[1]
- && Ql.w[0] < __bid_reciprocals10_128[ed2].w[0]))) {
+ && (Ql.w[1] < reciprocals10_128[ed2].w[1]
+ || (Ql.w[1] == reciprocals10_128[ed2].w[1]
+ && Ql.w[0] < reciprocals10_128[ed2].w[0]))) {
CQ.w[0]--;
}
}
@@ -1711,25 +1716,25 @@ handle_UF_128 (UINT128 * pres, UINT64 sgn, int expon, UINT128 CQ,
case ROUNDING_TIES_AWAY:
// test whether fractional part is 0
if (Qh1.w[1] == 0x8000000000000000ull && (!Qh1.w[0])
- && (Ql.w[1] < __bid_reciprocals10_128[ed2].w[1]
- || (Ql.w[1] == __bid_reciprocals10_128[ed2].w[1]
- && Ql.w[0] < __bid_reciprocals10_128[ed2].w[0])))
+ && (Ql.w[1] < reciprocals10_128[ed2].w[1]
+ || (Ql.w[1] == reciprocals10_128[ed2].w[1]
+ && Ql.w[0] < reciprocals10_128[ed2].w[0])))
status = EXACT_STATUS;
break;
case ROUNDING_DOWN:
case ROUNDING_TO_ZERO:
if ((!Qh1.w[1]) && (!Qh1.w[0])
- && (Ql.w[1] < __bid_reciprocals10_128[ed2].w[1]
- || (Ql.w[1] == __bid_reciprocals10_128[ed2].w[1]
- && Ql.w[0] < __bid_reciprocals10_128[ed2].w[0])))
+ && (Ql.w[1] < reciprocals10_128[ed2].w[1]
+ || (Ql.w[1] == reciprocals10_128[ed2].w[1]
+ && Ql.w[0] < reciprocals10_128[ed2].w[0])))
status = EXACT_STATUS;
break;
default:
// round up
__add_carry_out (Stemp.w[0], CY, Ql.w[0],
- __bid_reciprocals10_128[ed2].w[0]);
+ reciprocals10_128[ed2].w[0]);
__add_carry_in_out (Stemp.w[1], carry, Ql.w[1],
- __bid_reciprocals10_128[ed2].w[1], CY);
+ reciprocals10_128[ed2].w[1], CY);
__shr_128_long (Qh, Qh1, (128 - amount));
Tmp.w[0] = 1;
Tmp.w[1] = 0;
@@ -1761,7 +1766,7 @@ handle_UF_128 (UINT128 * pres, UINT64 sgn, int expon, UINT128 CQ,
//
__BID_INLINE__ UINT64
unpack_BID128_value (UINT64 * psign_x, int *pexponent_x,
- UINT128 * pcoefficient_x, UINT128 x) {
+ UINT128 * pcoefficient_x, UINT128 x) {
UINT128 coeff, T33, T34;
UINT64 ex;
@@ -1778,21 +1783,35 @@ unpack_BID128_value (UINT64 * psign_x, int *pexponent_x,
return 0;
}
// 10^33
- T33 = __bid_power10_table_128[33];
- coeff.w[0] = x.w[0];
- coeff.w[1] = (x.w[1]) & LARGE_COEFF_MASK128;
+ T33 = power10_table_128[33];
+ /*coeff.w[0] = x.w[0];
+ coeff.w[1] = (x.w[1]) & LARGE_COEFF_MASK128;
+ pcoefficient_x->w[0] = x.w[0];
+ pcoefficient_x->w[1] = x.w[1];
+ if (__unsigned_compare_ge_128 (coeff, T33)) // non-canonical
+ pcoefficient_x->w[1] &= (~LARGE_COEFF_MASK128); */
+
pcoefficient_x->w[0] = x.w[0];
- pcoefficient_x->w[1] = x.w[1];
- if (__unsigned_compare_ge_128 (coeff, T33)) // non-canonical
- pcoefficient_x->w[1] &= (~LARGE_COEFF_MASK128);
- return 0; // NaN or Infinity
+ pcoefficient_x->w[1] = (x.w[1]) & 0x00003fffffffffffull;
+ if (__unsigned_compare_ge_128 ((*pcoefficient_x), T33)) // non-canonical
+ {
+ pcoefficient_x->w[1] = (x.w[1]) & 0xfe00000000000000ull;
+ pcoefficient_x->w[0] = 0;
+ } else
+ pcoefficient_x->w[1] = (x.w[1]) & 0xfe003fffffffffffull;
+ if ((x.w[1] & NAN_MASK64) == INFINITY_MASK64) {
+ pcoefficient_x->w[0] = 0;
+ pcoefficient_x->w[1] = x.w[1] & SINFINITY_MASK64;
+ }
+ *pexponent_x = 0;
+ return 0; // NaN or Infinity
}
coeff.w[0] = x.w[0];
coeff.w[1] = (x.w[1]) & SMALL_COEFF_MASK128;
// 10^34
- T34 = __bid_power10_table_128[34];
+ T34 = power10_table_128[34];
// check for non-canonical values
if (__unsigned_compare_ge_128 (coeff, T34))
coeff.w[0] = coeff.w[1] = 0;
@@ -1829,21 +1848,24 @@ unpack_BID128 (UINT64 * psign_x, int *pexponent_x,
return 0;
}
// 10^33
- T33 = __bid_power10_table_128[33];
+ T33 = power10_table_128[33];
coeff.w[0] = px->w[0];
coeff.w[1] = (px->w[1]) & LARGE_COEFF_MASK128;
pcoefficient_x->w[0] = px->w[0];
pcoefficient_x->w[1] = px->w[1];
- if (__unsigned_compare_ge_128 (coeff, T33)) // non-canonical
+ if (__unsigned_compare_ge_128 (coeff, T33)) { // non-canonical
pcoefficient_x->w[1] &= (~LARGE_COEFF_MASK128);
- return 0; // NaN or Infinity
+ pcoefficient_x->w[0] = 0;
+ }
+ *pexponent_x = 0;
+ return 0; // NaN or Infinity
}
coeff.w[0] = px->w[0];
coeff.w[1] = (px->w[1]) & SMALL_COEFF_MASK128;
// 10^34
- T34 = __bid_power10_table_128[34];
+ T34 = power10_table_128[34];
// check for non-canonical values
if (__unsigned_compare_ge_128 (coeff, T34))
coeff.w[0] = coeff.w[1] = 0;
@@ -1870,7 +1892,7 @@ get_BID128_very_fast_OF (UINT128 * pres, UINT64 sgn, int expon,
if ((unsigned) expon > DECIMAL_MAX_EXPON_128) {
if (expon - MAX_FORMAT_DIGITS_128 <= DECIMAL_MAX_EXPON_128) {
- T = __bid_power10_table_128[MAX_FORMAT_DIGITS_128 - 1];
+ T = power10_table_128[MAX_FORMAT_DIGITS_128 - 1];
while (__unsigned_compare_gt_128 (T, coeff)
&& expon > DECIMAL_MAX_EXPON_128) {
coeff.w[1] =
@@ -1979,14 +2001,15 @@ get_BID128 (UINT128 * pres, UINT64 sgn, int expon, UINT128 coeff,
coeff.w[0] = 0x38c15b0a00000000ull;
}
// check OF, UF
- if ((unsigned) expon > DECIMAL_MAX_EXPON_128) {
+ if (expon < 0 || expon > DECIMAL_MAX_EXPON_128) {
// check UF
- if (expon < 0)
+ if (expon < 0) {
return handle_UF_128 (pres, sgn, expon, coeff, prounding_mode,
fpsc);
+ }
if (expon - MAX_FORMAT_DIGITS_128 <= DECIMAL_MAX_EXPON_128) {
- T = __bid_power10_table_128[MAX_FORMAT_DIGITS_128 - 1];
+ T = power10_table_128[MAX_FORMAT_DIGITS_128 - 1];
while (__unsigned_compare_gt_128 (T, coeff)
&& expon > DECIMAL_MAX_EXPON_128) {
coeff.w[1] =
@@ -2000,7 +2023,12 @@ get_BID128 (UINT128 * pres, UINT64 sgn, int expon, UINT128 coeff,
expon--;
}
}
- if ((unsigned) expon > DECIMAL_MAX_EXPON_128) {
+ if (expon > DECIMAL_MAX_EXPON_128) {
+ if (!(coeff.w[1] | coeff.w[0])) {
+ pres->w[1] = sgn | (((UINT64) DECIMAL_MAX_EXPON_128) << 49);
+ pres->w[0] = 0;
+ return pres;
+ }
// OF
#ifdef SET_STATUS_FLAGS
__set_status_flags (fpsc, OVERFLOW_EXCEPTION | INEXACT_EXCEPTION);
@@ -2064,9 +2092,9 @@ get_BID128_string (UINT128 * pres, UINT64 sgn, int expon, UINT128 coeff) {
if (expon < DECIMAL_MAX_EXPON_128 + 34) {
while (expon > DECIMAL_MAX_EXPON_128 &&
- (coeff.w[1] < __bid_power10_table_128[33].w[1] ||
- (coeff.w[1] == __bid_power10_table_128[33].w[1]
- && coeff.w[0] < __bid_power10_table_128[33].w[0]))) {
+ (coeff.w[1] < power10_table_128[33].w[1] ||
+ (coeff.w[1] == power10_table_128[33].w[1]
+ && coeff.w[0] < power10_table_128[33].w[0]))) {
D2.w[1] = (coeff.w[1] << 1) | (coeff.w[0] >> 63);
D2.w[0] = coeff.w[0] << 1;
D8.w[1] = (coeff.w[1] << 3) | (coeff.w[0] >> 61);
@@ -2131,9 +2159,15 @@ unpack_BID32 (UINT32 * psign_x, int *pexponent_x,
if ((x & SPECIAL_ENCODING_MASK32) == SPECIAL_ENCODING_MASK32) {
// special encodings
- if ((x & INFINITY_MASK32) == INFINITY_MASK32)
+ if ((x & INFINITY_MASK32) == INFINITY_MASK32) {
+ *pcoefficient_x = x & 0xfe0fffff;
+ if ((x & 0x000fffff) >= 1000000)
+ *pcoefficient_x = x & 0xfe000000;
+ if ((x & NAN_MASK32) == INFINITY_MASK32)
+ *pcoefficient_x = x & 0xf8000000;
+ *pexponent_x = 0;
return 0; // NaN or Infinity
-
+ }
// coefficient
*pcoefficient_x = (x & SMALL_COEFF_MASK32) | LARGE_COEFF_HIGH_BIT32;
// check for non-canonical value
@@ -2196,21 +2230,27 @@ get_BID32 (UINT32 sgn, int expon, UINT64 coeff, int rmode,
#ifdef IEEE_ROUND_NEAREST
rmode = 0;
#endif
+#ifndef IEEE_ROUND_NEAREST_TIES_AWAY
+#ifndef IEEE_ROUND_NEAREST
+ if (sgn && (unsigned) (rmode - 1) < 2)
+ rmode = 3 - rmode;
+#endif
+#endif
extra_digits = -expon;
- coeff += __bid_round_const_table[rmode][extra_digits];
+ coeff += round_const_table[rmode][extra_digits];
// get coeff*(2^M[extra_digits])/10^extra_digits
- __mul_64x64_to_128 (Q, coeff, __bid_reciprocals10_64[extra_digits]);
+ __mul_64x64_to_128 (Q, coeff, reciprocals10_64[extra_digits]);
// now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
- amount = __bid_short_recip_scale[extra_digits];
+ amount = short_recip_scale[extra_digits];
C64 = Q.w[1] >> amount;
#ifndef IEEE_ROUND_NEAREST_TIES_AWAY
#ifndef IEEE_ROUND_NEAREST
- if (rmode == 0) //ROUNDING_TO_NEAREST
+ if (rmode == 0) //ROUNDING_TO_NEAREST
#endif
if (C64 & 1) {
// check whether fractional part of initial_P/10^extra_digits is exactly .5
@@ -2222,7 +2262,7 @@ get_BID32 (UINT32 sgn, int expon, UINT64 coeff, int rmode,
remainder_h >>= amount2;
remainder_h = remainder_h & Q.w[1];
- if (!remainder_h && (Q.w[0] < __bid_reciprocals10_64[extra_digits])) {
+ if (!remainder_h && (Q.w[0] < reciprocals10_64[extra_digits])) {
C64--;
}
}
@@ -2242,18 +2282,18 @@ get_BID32 (UINT32 sgn, int expon, UINT64 coeff, int rmode,
case ROUNDING_TIES_AWAY:
// test whether fractional part is 0
if (remainder_h == 0x8000000000000000ull
- && (Q.w[0] < __bid_reciprocals10_64[extra_digits]))
+ && (Q.w[0] < reciprocals10_64[extra_digits]))
status = EXACT_STATUS;
break;
case ROUNDING_DOWN:
case ROUNDING_TO_ZERO:
- if (!remainder_h && (Q.w[0] < __bid_reciprocals10_64[extra_digits]))
+ if (!remainder_h && (Q.w[0] < reciprocals10_64[extra_digits]))
status = EXACT_STATUS;
break;
default:
// round up
__add_carry_out (Stemp, carry, Q.w[0],
- __bid_reciprocals10_64[extra_digits]);
+ reciprocals10_64[extra_digits]);
if ((remainder_h >> (64 - amount)) + carry >=
(((UINT64) 1) << amount))
status = EXACT_STATUS;
@@ -2444,42 +2484,42 @@ ALIGN (16)
unsigned int digits1;
} DEC_DIGITS;
- extern DEC_DIGITS __bid_nr_digits[];
- extern UINT64 __bid_midpoint64[];
- extern UINT128 __bid_midpoint128[];
- extern UINT192 __bid_midpoint192[];
- extern UINT256 __bid_midpoint256[];
- extern UINT64 __bid_ten2k64[];
- extern UINT128 __bid_ten2k128[];
- extern UINT256 __bid_ten2k256[];
- extern UINT128 __bid_ten2mk128[];
- extern UINT64 __bid_ten2mk64[];
- extern UINT128 __bid_ten2mk128trunc[];
- extern int __bid_shiftright128[];
- extern UINT64 __bid_maskhigh128[];
- extern UINT64 __bid_maskhigh128M[];
- extern UINT64 __bid_maskhigh192M[];
- extern UINT64 __bid_maskhigh256M[];
- extern UINT64 __bid_one_half128[];
- extern UINT64 __bid_one_half128M[];
- extern UINT64 __bid_one_half192M[];
- extern UINT64 __bid_one_half256M[];
- extern UINT128 __bid_ten2mk128M[];
- extern UINT128 __bid_ten2mk128truncM[];
- extern UINT192 __bid_ten2mk192truncM[];
- extern UINT256 __bid_ten2mk256truncM[];
- extern int __bid_shiftright128M[];
- extern int __bid_shiftright192M[];
- extern int __bid_shiftright256M[];
- extern UINT192 __bid_ten2mk192M[];
- extern UINT256 __bid_ten2mk256M[];
- extern unsigned char __bid_char_table2[];
- extern unsigned char __bid_char_table3[];
-
- extern UINT64 __bid_ten2m3k64[];
- extern unsigned int __bid_shift_ten2m3k64[];
- extern UINT128 __bid_ten2m3k128[];
- extern unsigned int __bid_shift_ten2m3k128[];
+ extern DEC_DIGITS nr_digits[];
+ extern UINT64 midpoint64[];
+ extern UINT128 midpoint128[];
+ extern UINT192 midpoint192[];
+ extern UINT256 midpoint256[];
+ extern UINT64 ten2k64[];
+ extern UINT128 ten2k128[];
+ extern UINT256 ten2k256[];
+ extern UINT128 ten2mk128[];
+ extern UINT64 ten2mk64[];
+ extern UINT128 ten2mk128trunc[];
+ extern int shiftright128[];
+ extern UINT64 maskhigh128[];
+ extern UINT64 maskhigh128M[];
+ extern UINT64 maskhigh192M[];
+ extern UINT64 maskhigh256M[];
+ extern UINT64 onehalf128[];
+ extern UINT64 onehalf128M[];
+ extern UINT64 onehalf192M[];
+ extern UINT64 onehalf256M[];
+ extern UINT128 ten2mk128M[];
+ extern UINT128 ten2mk128truncM[];
+ extern UINT192 ten2mk192truncM[];
+ extern UINT256 ten2mk256truncM[];
+ extern int shiftright128M[];
+ extern int shiftright192M[];
+ extern int shiftright256M[];
+ extern UINT192 ten2mk192M[];
+ extern UINT256 ten2mk256M[];
+ extern unsigned char char_table2[];
+ extern unsigned char char_table3[];
+
+ extern UINT64 ten2m3k64[];
+ extern unsigned int shift_ten2m3k64[];
+ extern UINT128 ten2m3k128[];
+ extern unsigned int shift_ten2m3k128[];
@@ -2487,29 +2527,29 @@ ALIGN (16)
*************** TABLES FOR GENERAL ROUNDING FUNCTIONS *********************
***************************************************************************/
- extern UINT64 __bid_Kx64[];
- extern unsigned int __bid_Ex64m64[];
- extern UINT64 __bid_half64[];
- extern UINT64 __bid_mask64[];
- extern UINT64 __bid_ten2mxtrunc64[];
-
- extern UINT128 __bid_Kx128[];
- extern unsigned int __bid_Ex128m128[];
- extern UINT64 __bid_half128[];
- extern UINT64 __bid_mask128[];
- extern UINT128 __bid_ten2mxtrunc128[];
-
- extern UINT192 __bid_Kx192[];
- extern unsigned int __bid_Ex192m192[];
- extern UINT64 __bid_half192[];
- extern UINT64 __bid_mask192[];
- extern UINT192 __bid_ten2mxtrunc192[];
-
- extern UINT256 __bid_Kx256[];
- extern unsigned int __bid_Ex256m256[];
- extern UINT64 __bid_half256[];
- extern UINT64 __bid_mask256[];
- extern UINT256 __bid_ten2mxtrunc256[];
+ extern UINT64 Kx64[];
+ extern unsigned int Ex64m64[];
+ extern UINT64 half64[];
+ extern UINT64 mask64[];
+ extern UINT64 ten2mxtrunc64[];
+
+ extern UINT128 Kx128[];
+ extern unsigned int Ex128m128[];
+ extern UINT64 half128[];
+ extern UINT64 mask128[];
+ extern UINT128 ten2mxtrunc128[];
+
+ extern UINT192 Kx192[];
+ extern unsigned int Ex192m192[];
+ extern UINT64 half192[];
+ extern UINT64 mask192[];
+ extern UINT192 ten2mxtrunc192[];
+
+ extern UINT256 Kx256[];
+ extern unsigned int Ex256m256[];
+ extern UINT64 half256[];
+ extern UINT64 mask256[];
+ extern UINT256 ten2mxtrunc256[];
typedef union __bid64_128 {
UINT64 b64;
@@ -2564,9 +2604,9 @@ ALIGN (16)
positiveInfinity
};
-#endif
-
-typedef union { UINT32 ui32; float f; } BID_UI32FLOAT;
-typedef union { UINT64 ui64; double d; } BID_UI64DOUBLE;
-typedef union { UINT128 ui128; long double ld; } BID_UI128LONGDOUBLE;
+ typedef union {
+ UINT64 ui64;
+ double d;
+ } BID_UI64DOUBLE;
+#endif