Skip to content

Commit

Permalink
softfloat: Move round_to_uint_and_pack to softfloat-parts.c.inc
Browse files Browse the repository at this point in the history
Rename to parts$N_float_to_uint.  Reimplement
float128_to_uint{32,64}{_round_to_zero} with FloatParts128.

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
  • Loading branch information
rth7680 committed Jun 3, 2021
1 parent 453d9c6 commit 4ab4aef
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 278 deletions.
68 changes: 67 additions & 1 deletion fpu/softfloat-parts.c.inc
Expand Up @@ -763,7 +763,7 @@ static void partsN(round_to_int)(FloatPartsN *a, FloatRoundMode rmode,
* the largest positive integer is returned. Otherwise, if the
* conversion overflows, the largest integer with the same sign as `a'
* is returned.
*/
*/
static int64_t partsN(float_to_sint)(FloatPartsN *p, FloatRoundMode rmode,
int scale, int64_t min, int64_t max,
float_status *s)
Expand Down Expand Up @@ -817,3 +817,69 @@ static int64_t partsN(float_to_sint)(FloatPartsN *p, FloatRoundMode rmode,
float_raise(flags, s);
return r;
}

/*
* Returns the result of converting the floating-point value `a' to
* the unsigned integer format. The conversion is performed according
* to the IEC/IEEE Standard for Binary Floating-Point
* Arithmetic---which means in particular that the conversion is
* rounded according to the current rounding mode. If `a' is a NaN,
* the largest unsigned integer is returned. Otherwise, if the
* conversion overflows, the largest unsigned integer is returned. If
* the 'a' is negative, the result is rounded and zero is returned;
* values that do not round to zero will raise the inexact exception
* flag.
*/
static uint64_t partsN(float_to_uint)(FloatPartsN *p, FloatRoundMode rmode,
int scale, uint64_t max, float_status *s)
{
int flags = 0;
uint64_t r;

switch (p->cls) {
case float_class_snan:
case float_class_qnan:
flags = float_flag_invalid;
r = max;
break;

case float_class_inf:
flags = float_flag_invalid;
r = p->sign ? 0 : max;
break;

case float_class_zero:
return 0;

case float_class_normal:
/* TODO: N - 2 is frac_size for rounding; could use input fmt. */
if (parts_round_to_int_normal(p, rmode, scale, N - 2)) {
flags = float_flag_inexact;
if (p->cls == float_class_zero) {
r = 0;
break;
}
}

if (p->sign) {
flags = float_flag_invalid;
r = 0;
} else if (p->exp > DECOMPOSED_BINARY_POINT) {
flags = float_flag_invalid;
r = max;
} else {
r = p->frac_hi >> (DECOMPOSED_BINARY_POINT - p->exp);
if (r > max) {
flags = float_flag_invalid;
r = max;
}
}
break;

default:
g_assert_not_reached();
}

float_raise(flags, s);
return r;
}

0 comments on commit 4ab4aef

Please sign in to comment.