aboutsummaryrefslogtreecommitdiff
path: root/fpu/softfloat-parts.c.inc
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2020-11-14 14:21:16 -0800
committerRichard Henderson <richard.henderson@linaro.org>2021-06-03 13:59:34 -0700
commit4ab4aef01830ad733a2552307630a1699d8caf72 (patch)
tree5da16fae36e0110f9cc1d12348227fc5fbdf4e72 /fpu/softfloat-parts.c.inc
parent453d9c61dd5681159051c6e4d07e7b2633de2e70 (diff)
softfloat: Move round_to_uint_and_pack to softfloat-parts.c.inc
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>
Diffstat (limited to 'fpu/softfloat-parts.c.inc')
-rw-r--r--fpu/softfloat-parts.c.inc68
1 files changed, 67 insertions, 1 deletions
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index 7f69da1d8f..483bdc0e21 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -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)
@@ -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;
+}