diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2021-06-04 10:04:11 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2021-06-04 10:04:11 +0100 |
commit | 5a95f5ce3cd5842cc8f61a91ecd4fb4e8d10104f (patch) | |
tree | 16fd0e145c30eda1500cb96918580d3d6fbb9b7b /tests | |
parent | 453d9c61dd5681159051c6e4d07e7b2633de2e70 (diff) | |
parent | 5d0204b82ade0ea0630d6add894954135ee54ab1 (diff) |
Merge remote-tracking branch 'remotes/rth-gitlab/tags/pull-fpu-20210603' into staging
Finish conversion of float128 and floatx80 to FloatParts.
Implement float128_muladd and float128_{min,max}*.
Optimize int-to-float conversion with hard-float.
# gpg: Signature made Thu 03 Jun 2021 22:13:10 BST
# gpg: using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F
# gpg: issuer "richard.henderson@linaro.org"
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full]
# Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A 05C0 64DF 38E8 AF7E 215F
* remotes/rth-gitlab/tags/pull-fpu-20210603: (29 commits)
softfloat: Use hard-float for {u}int64_to_float{32,64}
tests/fp: Enable more tests
softfloat: Convert modrem operations to FloatParts
softfloat: Move floatN_log2 to softfloat-parts.c.inc
softfloat: Convert float32_exp2 to FloatParts
softfloat: Convert floatx80 compare to FloatParts
softfloat: Convert floatx80_scalbn to FloatParts
softfloat: Convert floatx80 to integer to FloatParts
softfloat: Convert floatx80 float conversions to FloatParts
softfloat: Convert integer to floatx80 to FloatParts
softfloat: Convert floatx80_round_to_int to FloatParts
softfloat: Convert floatx80_round to FloatParts
softfloat: Convert floatx80_sqrt to FloatParts
softfloat: Convert floatx80_div to FloatParts
softfloat: Convert floatx80_mul to FloatParts
softfloat: Convert floatx80_add/sub to FloatParts
tests/fp/fp-test: Reverse order of floatx80 precision tests
softfloat: Adjust parts_uncanon_normal for floatx80
softfloat: Introduce Floatx80RoundPrec
softfloat: Reduce FloatFmt
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/fp/fp-test-log2.c | 118 | ||||
-rw-r--r-- | tests/fp/fp-test.c | 9 | ||||
-rw-r--r-- | tests/fp/meson.build | 27 | ||||
-rw-r--r-- | tests/fp/wrap.c.inc | 2 |
4 files changed, 143 insertions, 13 deletions
diff --git a/tests/fp/fp-test-log2.c b/tests/fp/fp-test-log2.c new file mode 100644 index 0000000000..4eae93eb7c --- /dev/null +++ b/tests/fp/fp-test-log2.c @@ -0,0 +1,118 @@ +/* + * fp-test-log2.c - test QEMU's softfloat log2 + * + * Copyright (C) 2020, Linaro, Ltd. + * + * License: GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ +#ifndef HW_POISON_H +#error Must define HW_POISON_H to work around TARGET_* poisoning +#endif + +#include "qemu/osdep.h" +#include "qemu/cutils.h" +#include <math.h> +#include "fpu/softfloat.h" + +typedef union { + double d; + float64 i; +} ufloat64; + +static int errors; + +static void compare(ufloat64 test, ufloat64 real, ufloat64 soft, bool exact) +{ + int msb; + uint64_t ulp = UINT64_MAX; + + if (real.i == soft.i) { + return; + } + msb = 63 - __builtin_clzll(real.i ^ soft.i); + + if (msb < 52) { + if (real.i > soft.i) { + ulp = real.i - soft.i; + } else { + ulp = soft.i - real.i; + } + } + + /* glibc allows 3 ulp error in its libm-test-ulps; allow 4 here */ + if (!exact && ulp <= 4) { + return; + } + + printf("test: %016" PRIx64 " %+.13a\n" + " sf: %016" PRIx64 " %+.13a\n" + "libm: %016" PRIx64 " %+.13a\n", + test.i, test.d, soft.i, soft.d, real.i, real.d); + + if (msb == 63) { + printf("Error in sign!\n\n"); + } else if (msb >= 52) { + printf("Error in exponent: %d\n\n", + (int)(soft.i >> 52) - (int)(real.i >> 52)); + } else { + printf("Error in fraction: %" PRIu64 " ulp\n\n", ulp); + } + + if (++errors == 20) { + exit(1); + } +} + +int main(int ac, char **av) +{ + ufloat64 test, real, soft; + float_status qsf = {0}; + int i; + + set_float_rounding_mode(float_round_nearest_even, &qsf); + + test.d = 0.0; + real.d = -__builtin_inf(); + soft.i = float64_log2(test.i, &qsf); + compare(test, real, soft, true); + + test.d = 1.0; + real.d = 0.0; + soft.i = float64_log2(test.i, &qsf); + compare(test, real, soft, true); + + test.d = 2.0; + real.d = 1.0; + soft.i = float64_log2(test.i, &qsf); + compare(test, real, soft, true); + + test.d = 4.0; + real.d = 2.0; + soft.i = float64_log2(test.i, &qsf); + compare(test, real, soft, true); + + test.d = 0x1p64; + real.d = 64.0; + soft.i = float64_log2(test.i, &qsf); + compare(test, real, soft, true); + + test.d = __builtin_inf(); + real.d = __builtin_inf(); + soft.i = float64_log2(test.i, &qsf); + compare(test, real, soft, true); + + for (i = 0; i < 10000; ++i) { + test.d = drand48() + 1.0; /* [1.0, 2.0) */ + real.d = log2(test.d); + soft.i = float64_log2(test.i, &qsf); + compare(test, real, soft, false); + + test.d = drand48() * 100; /* [0.0, 100) */ + real.d = log2(test.d); + soft.i = float64_log2(test.i, &qsf); + compare(test, real, soft, false); + } + + return 0; +} diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c index ff131afbde..352dd71c44 100644 --- a/tests/fp/fp-test.c +++ b/tests/fp/fp-test.c @@ -963,18 +963,21 @@ static void QEMU_NORETURN run_test(void) verCases_usesExact = !!(attrs & FUNC_ARG_EXACT); for (k = 0; k < 3; k++) { - int prec80 = 32; + FloatX80RoundPrec qsf_prec80 = floatx80_precision_x; + int prec80 = 80; int l; if (k == 1) { prec80 = 64; + qsf_prec80 = floatx80_precision_d; } else if (k == 2) { - prec80 = 80; + prec80 = 32; + qsf_prec80 = floatx80_precision_s; } verCases_roundingPrecision = 0; slow_extF80_roundingPrecision = prec80; - qsf.floatx80_rounding_precision = prec80; + qsf.floatx80_rounding_precision = qsf_prec80; if (attrs & FUNC_EFF_ROUNDINGPRECISION) { verCases_roundingPrecision = prec80; diff --git a/tests/fp/meson.build b/tests/fp/meson.build index 1c3eee9955..07e2cdc8d2 100644 --- a/tests/fp/meson.build +++ b/tests/fp/meson.build @@ -556,7 +556,9 @@ softfloat_conv_tests = { 'extF80_to_f64 extF80_to_f128 ' + 'f128_to_f16', 'int-to-float': 'i32_to_f16 i64_to_f16 i32_to_f32 i64_to_f32 ' + - 'i32_to_f64 i64_to_f64 i32_to_f128 i64_to_f128', + 'i32_to_f64 i64_to_f64 ' + + 'i32_to_extF80 i64_to_extF80 ' + + 'i32_to_f128 i64_to_f128', 'uint-to-float': 'ui32_to_f16 ui64_to_f16 ui32_to_f32 ui64_to_f32 ' + 'ui32_to_f64 ui64_to_f64 ui64_to_f128 ' + 'ui32_to_extF80 ui64_to_extF80', @@ -581,7 +583,7 @@ softfloat_conv_tests = { 'extF80_to_ui64 extF80_to_ui64_r_minMag ' + 'f128_to_ui64 f128_to_ui64_r_minMag', 'round-to-integer': 'f16_roundToInt f32_roundToInt ' + - 'f64_roundToInt f128_roundToInt' + 'f64_roundToInt extF80_roundToInt f128_roundToInt' } softfloat_tests = { 'eq_signaling' : 'compare', @@ -602,24 +604,20 @@ fptest_args = ['-s', '-l', '1'] fptest_rounding_args = ['-r', 'all'] # Conversion Routines: -# FIXME: i32_to_extF80 (broken), i64_to_extF80 (broken) -# extF80_roundToInt (broken) foreach k, v : softfloat_conv_tests test('fp-test-' + k, fptest, args: fptest_args + fptest_rounding_args + v.split(), suite: ['softfloat', 'softfloat-conv']) endforeach -# FIXME: extF80_{lt_quiet, rem} (broken), -# extF80_{mulAdd} (missing) foreach k, v : softfloat_tests - extF80_broken = ['lt_quiet', 'rem'].contains(k) test('fp-test-' + k, fptest, args: fptest_args + fptest_rounding_args + - ['f16_' + k, 'f32_' + k, 'f64_' + k, 'f128_' + k] + - (extF80_broken ? [] : ['extF80_' + k]), + ['f16_' + k, 'f32_' + k, 'f64_' + k, 'f128_' + k, 'extF80_' + k], suite: ['softfloat', 'softfloat-' + v]) endforeach + +# FIXME: extF80_{mulAdd} (missing) test('fp-test-mulAdd', fptest, # no fptest_rounding_args args: fptest_args + @@ -634,3 +632,14 @@ fpbench = executable( include_directories: [sfinc, include_directories(tfdir)], c_args: fpcflags, ) + +fptestlog2 = executable( + 'fp-test-log2', + ['fp-test-log2.c', '../../fpu/softfloat.c'], + link_with: [libsoftfloat], + dependencies: [qemuutil], + include_directories: [sfinc], + c_args: fpcflags, +) +test('fp-test-log2', fptestlog2, + suite: ['softfloat', 'softfloat-ops']) diff --git a/tests/fp/wrap.c.inc b/tests/fp/wrap.c.inc index cb1bb77e4c..9ff884c140 100644 --- a/tests/fp/wrap.c.inc +++ b/tests/fp/wrap.c.inc @@ -643,7 +643,7 @@ WRAP_CMP80(qemu_extF80M_eq, floatx80_eq_quiet) WRAP_CMP80(qemu_extF80M_le, floatx80_le) WRAP_CMP80(qemu_extF80M_lt, floatx80_lt) WRAP_CMP80(qemu_extF80M_le_quiet, floatx80_le_quiet) -WRAP_CMP80(qemu_extF80M_lt_quiet, floatx80_le_quiet) +WRAP_CMP80(qemu_extF80M_lt_quiet, floatx80_lt_quiet) #undef WRAP_CMP80 #define WRAP_CMP128(name, func) \ |