aboutsummaryrefslogtreecommitdiff
path: root/tests/tcg/multiarch
diff options
context:
space:
mode:
Diffstat (limited to 'tests/tcg/multiarch')
-rw-r--r--tests/tcg/multiarch/Makefile.target1
-rw-r--r--tests/tcg/multiarch/fnmsub.c37
2 files changed, 38 insertions, 0 deletions
diff --git a/tests/tcg/multiarch/Makefile.target b/tests/tcg/multiarch/Makefile.target
index 45c9cfe..bfdf719 100644
--- a/tests/tcg/multiarch/Makefile.target
+++ b/tests/tcg/multiarch/Makefile.target
@@ -29,6 +29,7 @@ run-float_%: float_%
$(call run-test,$<, $(QEMU) $(QEMU_OPTS) $<)
$(call conditional-diff-out,$<,$(SRC_PATH)/tests/tcg/$(TARGET_NAME)/$<.ref)
+fnmsub: LDFLAGS+=-lm
testthread: LDFLAGS+=-lpthread
diff --git a/tests/tcg/multiarch/fnmsub.c b/tests/tcg/multiarch/fnmsub.c
new file mode 100644
index 0000000..15dd41d
--- /dev/null
+++ b/tests/tcg/multiarch/fnmsub.c
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <stdio.h>
+#include <math.h>
+#include <fenv.h>
+
+union U {
+ double d;
+ unsigned long long l;
+};
+
+union U x = { .l = 0x4ff0000000000000ULL };
+union U y = { .l = 0x2ff0000000000000ULL };
+union U r;
+
+int main()
+{
+#ifdef FE_DOWNWARD
+ fesetround(FE_DOWNWARD);
+
+#if defined(__loongarch__)
+ asm("fnmsub.d %0, %1, %1, %2" : "=f"(r.d) : "f"(x.d), "f"(y.d));
+#elif defined(__powerpc64__)
+ asm("fnmsub %0,%1,%1,%2" : "=f"(r.d) : "f"(x.d), "f"(y.d));
+#elif defined(__s390x__) && 0 /* need -march=z14 */
+ asm("vfnms %0,%1,%1,%2,0,3" : "=f"(r.d) : "f"(x.d), "f"(y.d));
+#else
+ r.d = -fma(x.d, x.d, -y.d);
+#endif
+
+ if (r.l != 0xdfefffffffffffffULL) {
+ printf("r = %.18a (%016llx)\n", r.d, r.l);
+ return 1;
+ }
+#endif
+ return 0;
+}