[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 35/39] fpu: Handle m68k extended precision denormals properly
From: |
Richard Henderson |
Subject: |
[PULL 35/39] fpu: Handle m68k extended precision denormals properly |
Date: |
Fri, 15 Sep 2023 20:30:07 -0700 |
Motorola treats denormals with explicit integer bit set as
having unbiased exponent 0, unlike Intel which treats it as
having unbiased exponent 1 (more like all other IEEE formats
that have no explicit integer bit).
Add a flag on FloatFmt to differentiate the behaviour.
Reported-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
fpu/softfloat.c | 9 +++++-
tests/tcg/m68k/denormal.c | 53 ++++++++++++++++++++++++++++++++++
fpu/softfloat-parts.c.inc | 7 +++--
tests/tcg/m68k/Makefile.target | 2 +-
4 files changed, 66 insertions(+), 5 deletions(-)
create mode 100644 tests/tcg/m68k/denormal.c
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 2a33967094..027a8e576d 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -517,6 +517,7 @@ typedef struct {
* round_mask: bits below lsb which must be rounded
* The following optional modifiers are available:
* arm_althp: handle ARM Alternative Half Precision
+ * m68k_denormal: explicit integer bit for extended precision may be 1
*/
typedef struct {
int exp_size;
@@ -526,6 +527,7 @@ typedef struct {
int frac_size;
int frac_shift;
bool arm_althp;
+ bool m68k_denormal;
uint64_t round_mask;
} FloatFmt;
@@ -576,7 +578,12 @@ static const FloatFmt float128_params = {
static const FloatFmt floatx80_params[3] = {
[floatx80_precision_s] = { FLOATX80_PARAMS(23) },
[floatx80_precision_d] = { FLOATX80_PARAMS(52) },
- [floatx80_precision_x] = { FLOATX80_PARAMS(64) },
+ [floatx80_precision_x] = {
+ FLOATX80_PARAMS(64),
+#ifdef TARGET_M68K
+ .m68k_denormal = true,
+#endif
+ },
};
/* Unpack a float to parts, but do not canonicalize. */
diff --git a/tests/tcg/m68k/denormal.c b/tests/tcg/m68k/denormal.c
new file mode 100644
index 0000000000..20bd8c7332
--- /dev/null
+++ b/tests/tcg/m68k/denormal.c
@@ -0,0 +1,53 @@
+/*
+ * Test m68k extended double denormals.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+
+#define TEST(X, Y) { X, Y, X * Y }
+
+static volatile long double test[][3] = {
+ TEST(0x1p+16383l, 0x1p-16446l),
+ TEST(0x1.1p-8223l, 0x1.1p-8224l),
+ TEST(1.0l, 0x1p-16383l),
+};
+
+#undef TEST
+
+static void dump_ld(const char *label, long double ld)
+{
+ union {
+ long double d;
+ struct {
+ uint32_t exp:16;
+ uint32_t space:16;
+ uint32_t h;
+ uint32_t l;
+ };
+ } u;
+
+ u.d = ld;
+ printf("%12s: % -27La 0x%04x 0x%08x 0x%08x\n", label, u.d, u.exp, u.h,
u.l);
+}
+
+int main(void)
+{
+ int i, n = sizeof(test) / sizeof(test[0]), err = 0;
+
+ for (i = 0; i < n; ++i) {
+ long double x = test[i][0];
+ long double y = test[i][1];
+ long double build_mul = test[i][2];
+ long double runtime_mul = x * y;
+
+ if (runtime_mul != build_mul) {
+ dump_ld("x", x);
+ dump_ld("y", y);
+ dump_ld("build_mul", build_mul);
+ dump_ld("runtime_mul", runtime_mul);
+ err = 1;
+ }
+ }
+ return err;
+}
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index 527e15e6ab..a44649f4f4 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -118,7 +118,8 @@ static void partsN(canonicalize)(FloatPartsN *p,
float_status *status,
} else {
int shift = frac_normalize(p);
p->cls = float_class_normal;
- p->exp = fmt->frac_shift - fmt->exp_bias - shift + 1;
+ p->exp = fmt->frac_shift - fmt->exp_bias
+ - shift + !fmt->m68k_denormal;
}
} else if (likely(p->exp < fmt->exp_max) || fmt->arm_althp) {
p->cls = float_class_normal;
@@ -256,7 +257,7 @@ static void partsN(uncanon_normal)(FloatPartsN *p,
float_status *s,
is_tiny = !frac_addi(&discard, p, inc);
}
- frac_shrjam(p, 1 - exp);
+ frac_shrjam(p, !fmt->m68k_denormal - exp);
if (p->frac_lo & round_mask) {
/* Need to recompute round-to-even/round-to-odd. */
@@ -287,7 +288,7 @@ static void partsN(uncanon_normal)(FloatPartsN *p,
float_status *s,
p->frac_lo &= ~round_mask;
}
- exp = (p->frac_hi & DECOMPOSED_IMPLICIT_BIT) != 0;
+ exp = (p->frac_hi & DECOMPOSED_IMPLICIT_BIT) && !fmt->m68k_denormal;
frac_shr(p, frac_shift);
if (is_tiny && (flags & float_flag_inexact)) {
diff --git a/tests/tcg/m68k/Makefile.target b/tests/tcg/m68k/Makefile.target
index 1163c7ef03..6ff214e60a 100644
--- a/tests/tcg/m68k/Makefile.target
+++ b/tests/tcg/m68k/Makefile.target
@@ -4,7 +4,7 @@
#
VPATH += $(SRC_PATH)/tests/tcg/m68k
-TESTS += trap
+TESTS += trap denormal
# On m68k Linux supports 4k and 8k pages (but 8k is currently broken)
EXTRA_RUNS+=run-test-mmap-4096 # run-test-mmap-8192
--
2.34.1
- [PULL 25/39] accel/tcg: Split out io_prepare and io_failed, (continued)
- [PULL 25/39] accel/tcg: Split out io_prepare and io_failed, Richard Henderson, 2023/09/15
- [PULL 27/39] plugin: Simplify struct qemu_plugin_hwaddr, Richard Henderson, 2023/09/15
- [PULL 28/39] accel/tcg: Merge cpu_transaction_failed into io_failed, Richard Henderson, 2023/09/15
- [PULL 26/39] accel/tcg: Use CPUTLBEntryFull.phys_addr in io_failed, Richard Henderson, 2023/09/15
- [PULL 29/39] accel/tcg: Replace direct use of io_readx/io_writex in do_{ld, st}_1, Richard Henderson, 2023/09/15
- [PULL 31/39] accel/tcg: Merge io_writex into do_st_mmio_leN, Richard Henderson, 2023/09/15
- [PULL 30/39] accel/tcg: Merge io_readx into do_ld_mmio_beN, Richard Henderson, 2023/09/15
- [PULL 33/39] accel/tcg: Introduce do_st16_mmio_leN, Richard Henderson, 2023/09/15
- [PULL 32/39] accel/tcg: Introduce do_ld16_mmio_beN, Richard Henderson, 2023/09/15
- [PULL 34/39] fpu: Add conversions between bfloat16 and [u]int8, Richard Henderson, 2023/09/15
- [PULL 35/39] fpu: Handle m68k extended precision denormals properly,
Richard Henderson <=
- [PULL 37/39] util/cpuinfo-aarch64: Add CPUINFO_BTI, Richard Henderson, 2023/09/15
- [PULL 38/39] tcg/aarch64: Emit BTI insns at jump landing pads, Richard Henderson, 2023/09/15
- [PULL 39/39] tcg: Map code_gen_buffer with PROT_BTI, Richard Henderson, 2023/09/15
- [PULL 36/39] tcg: Add tcg_out_tb_start backend hook, Richard Henderson, 2023/09/15
- Re: [PULL 00/39] tcg patch queue, Richard Henderson, 2023/09/16