qemu-e2k/tests/tcg/m68k/denormal.c
Richard Henderson 722460652b fpu: Handle m68k extended precision denormals properly
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>
2023-09-16 14:57:16 +00:00

54 lines
1.1 KiB
C

/*
* 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;
}