Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tests/tcg/m68k/packeddecimal-1.c | 41 ++++++++++++++++++++++++++++
tests/tcg/m68k/packeddecimal-2.c | 46 ++++++++++++++++++++++++++++++++
tests/tcg/m68k/Makefile.target | 4 ++-
3 files changed, 90 insertions(+), 1 deletion(-)
create mode 100644 tests/tcg/m68k/packeddecimal-1.c
create mode 100644 tests/tcg/m68k/packeddecimal-2.c
diff --git a/tests/tcg/m68k/packeddecimal-1.c b/tests/tcg/m68k/packeddecimal-1.c
new file mode 100644
index 0000000000..5433acd17b
--- /dev/null
+++ b/tests/tcg/m68k/packeddecimal-1.c
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/* Test packed decimal real conversion to long double. */
+
+#include <stdio.h>
+
+struct T {
+ unsigned int d[3];
+ long double f;
+};
+
+static const struct T tests[] = {
+ { { 0x00000001, 0x00000000, 0x00000000 }, 1.0e0l },
+ { { 0x01000001, 0x00000000, 0x00000000 }, 1.0e1l },
+ { { 0x00100001, 0x00000000, 0x00000000 }, 1.0e10l },
+ { { 0x00000000, 0x10000000, 0x00000000 }, 0.1e0l },
+ { { 0x41000001, 0x00000000, 0x00000000 }, 1.0e-1l },
+ { { 0x85000005, 0x55550000, 0x00000000 }, -5.5555e5l },
+ { { 0x09990009, 0x99999999, 0x99999999 }, 9.9999999999999999e999l },
+ { { 0x03210001, 0x23456789, 0x12345678 }, 1.2345678912345678e123l },
+ { { 0x00000000, 0x00000000, 0x00000000 }, 0.0l },
+ { { 0x80000000, 0x00000000, 0x00000000 }, -0.0l },
+ { { 0x09990000, 0x00000000, 0x00000000 }, 0.0e999l },
+};
+
+int main()
+{
+ int ret = 0;
+
+ for (int i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
+ const struct T *t = &tests[i];
+ long double f;
+
+ asm("fmove.p (%1),%0" : "=f"(f) : "a"(t->d));
+
+ if (f != t->f) {
+ fprintf(stderr, "Mismatch at %d: %.17Le != %.17Le\n", i, f, t->f);
+ ret = 1;
+ }
+ }
+ return ret;
+}
diff --git a/tests/tcg/m68k/packeddecimal-2.c b/tests/tcg/m68k/packeddecimal-2.c
new file mode 100644
index 0000000000..448e97ce89
--- /dev/null
+++ b/tests/tcg/m68k/packeddecimal-2.c
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/* Test packed decimal real conversion from long double, dynamic k-factor */
+
+#include <stdio.h>
+#include <float.h>
+
+struct T {
+ unsigned int d[3];
+ long double lf;
+ int kfactor;
+};
+
+static const struct T tests[] = {
+ { { 0x00000001, 0x00000000, 0x00000000 }, 1.0e0l, 0 },
+ { { 0x00100001, 0x00000000, 0x00000000 }, 1.0e10l, 0 },
+ { { 0x41000001, 0x00000000, 0x00000000 }, 1.0e-1l, 0 },
+ { { 0x85000005, 0x55550000, 0x00000000 }, -5.5555e5l, 5 },
+ { { 0x45000005, 0x55550000, 0x00000000 }, 5.5555e-5l, 5 },
+ { { 0x05000002, 0x22220000, 0x00000000 }, 2.2222e5, 99 },
+ { { 0x05000002, 0x22220000, 0x00000000 }, 2.2222e5, 5 },
+ { { 0x05000002, 0x20000000, 0x00000000 }, 2.2222e5, 2 },
+ { { 0x02394001, 0x18973149, 0x53572318 }, LDBL_MAX, 17 },
+ { { 0x42394001, 0x68105157, 0x15560468 }, LDBL_MIN, 17 },
+ { { 0x41594001, 0x82259976, 0x59412373 }, LDBL_TRUE_MIN, 17 },
+};
+
+int main()
+{
+ int ret = 0;
+
+ for (int i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
+ const struct T *t = &tests[i];
+ unsigned int out[3];
+
+ asm("fmove.p %1,(%0),%2"
+ : : "a"(out), "f"(t->lf), "d"(t->kfactor) : "memory");
+
+ if (out[0] != t->d[0] || out[1] != t->d[1] || out[2] != t->d[2]) {
+ fprintf(stderr, "Mismatch at %d: %08x%08x%08x != %08x%08x%08x\n",
+ i, out[0], out[1], out[2],
+ t->d[0], t->d[1], t->d[2]);
+ ret = 1;
+ }
+ }
+ return ret;
+}
diff --git a/tests/tcg/m68k/Makefile.target b/tests/tcg/m68k/Makefile.target
index 33f7b1b127..b505260b79 100644
--- a/tests/tcg/m68k/Makefile.target
+++ b/tests/tcg/m68k/Makefile.target
@@ -4,4 +4,6 @@
#
VPATH += $(SRC_PATH)/tests/tcg/m68k
-TESTS += trap denormal
+TESTS += trap denormal packeddecimal-1 packeddecimal-2
+
+run-packeddecimal-%: QEMU_OPTS += -cpu m68020
--
2.43.0