mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-08 18:23:57 -06:00
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>
This commit is contained in:
parent
00f9ef8f3d
commit
722460652b
4 changed files with 66 additions and 5 deletions
|
@ -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
|
||||
|
|
53
tests/tcg/m68k/denormal.c
Normal file
53
tests/tcg/m68k/denormal.c
Normal file
|
@ -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;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue