On 3/28/22 14:14, [email protected] wrote:
+static int64_t partsN(float_to_sint2)(FloatPartsN *p, FloatRoundMode rmode,
+ int scale, float_status *s, uint64_t *lo)
+{
+ int flags = 0;
+ uint64_t hi;
Similar comment about 'lo' vs '*lo'.
+ if (p->exp <= DECOMPOSED_BINARY_POINT) {
+ hi = 0;
+ *lo = p->frac_hi >> (DECOMPOSED_BINARY_POINT - p->exp);
+ } else if (p->exp <= 127) {
+ int shift = 127 - p->exp;
+ hi = shr_double(0, p->frac_hi, shift);
Same comment about double-shift w/ 0.
+ if (N > 64) {
+ *lo = shr_double(p->frac_hi, p->frac_lo, shift);
+ } else {
+ *lo = shr_double(p->frac_hi, 0, shift);
+ }
+ } else {
+ hi = UINT64_MAX;
+ *lo = UINT64_MAX;
+ }
+ if (p->sign) {
+ if (hi < INT64_MIN || (hi == INT64_MIN && *lo == 0)) {
+ *lo = -*lo;
+ hi = ~hi + !*lo;
+ } else {
+ flags = float_flag_invalid | float_flag_invalid_cvti;
+ hi = INT64_MIN;
+ *lo = 0;
+ }
+ } else if (hi > INT64_MAX) {
+ flags = float_flag_invalid | float_flag_invalid_cvti;
+ hi = INT64_MAX;
+ *lo = UINT64_MAX;
+ }
Hmm. It seemed easy to arrange the code this way with just a uint64_t, but here I think
it might be worth detecting overflow earlier, via exp.
if (p->exp < 127) {
/* No overflow possible */
int shift = 127 - p->exp;
if (shift >= 64) {
hi = 0;
lo = p->frac_hi >> (shift - 64);
} else {
hi = p->frac_hi >> shift;
lo = shr_double(p->frac_hi, N > 64 ? p->frac_lo : 0, shift);
}
if (p->sign) {
lo = -lo;
hi = ~hi + !lo;
}
break;
}
/* The only valid 127-bit number is UINT128_MIN. */
if (p->exp == 127 &&
p->sign &&
p->frac_hi == DECOMPOSED_IMPLICIT_BIT &&
(N <= 64 || p->frac_lo == 0)) {
hi = INT64_MIN;
lo = 0;
break;
}
/* Overflow. */
flags = ...;
if (p->sign)
...
r~