aboutsummaryrefslogtreecommitdiff
path: root/tests/tcg
diff options
context:
space:
mode:
authorSong Gao <gaosong@loongson.cn>2022-07-16 16:54:24 +0800
committerRichard Henderson <richard.henderson@linaro.org>2022-07-19 21:53:58 +0530
commit65cb15f4d64678900e48375ee360cc6cf577b99f (patch)
tree05e583fcba579258ba11517396abea157d91c4b8 /tests/tcg
parentfa50579a57abd271109117936c6886d2d1e3d9af (diff)
tests/tcg/loongarch64: Add fclass test
This includes: - FCLASS.{S/D} Signed-off-by: Song Gao <gaosong@loongson.cn> Message-Id: <20220716085426.3098060-7-gaosong@loongson.cn> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'tests/tcg')
-rw-r--r--tests/tcg/loongarch64/Makefile.target1
-rw-r--r--tests/tcg/loongarch64/test_fclass.c130
2 files changed, 131 insertions, 0 deletions
diff --git a/tests/tcg/loongarch64/Makefile.target b/tests/tcg/loongarch64/Makefile.target
index 24d6bb11e9..59d564725a 100644
--- a/tests/tcg/loongarch64/Makefile.target
+++ b/tests/tcg/loongarch64/Makefile.target
@@ -12,5 +12,6 @@ LDFLAGS+=-lm
LOONGARCH64_TESTS = test_bit
LOONGARCH64_TESTS += test_div
+LOONGARCH64_TESTS += test_fclass
TESTS += $(LOONGARCH64_TESTS)
diff --git a/tests/tcg/loongarch64/test_fclass.c b/tests/tcg/loongarch64/test_fclass.c
new file mode 100644
index 0000000000..7ba1d2c151
--- /dev/null
+++ b/tests/tcg/loongarch64/test_fclass.c
@@ -0,0 +1,130 @@
+#include <stdio.h>
+
+/* float class */
+#define FLOAT_CLASS_SIGNALING_NAN 0x001
+#define FLOAT_CLASS_QUIET_NAN 0x002
+#define FLOAT_CLASS_NEGATIVE_INFINITY 0x004
+#define FLOAT_CLASS_NEGATIVE_NORMAL 0x008
+#define FLOAT_CLASS_NEGATIVE_SUBNORMAL 0x010
+#define FLOAT_CLASS_NEGATIVE_ZERO 0x020
+#define FLOAT_CLASS_POSITIVE_INFINITY 0x040
+#define FLOAT_CLASS_POSITIVE_NORMAL 0x080
+#define FLOAT_CLASS_POSITIVE_SUBNORMAL 0x100
+#define FLOAT_CLASS_POSITIVE_ZERO 0x200
+
+#define TEST_FCLASS(N) \
+void test_fclass_##N(long s) \
+{ \
+ double fd; \
+ long rd; \
+ \
+ asm volatile("fclass."#N" %0, %2\n\t" \
+ "movfr2gr."#N" %1, %2\n\t" \
+ : "=f"(fd), "=r"(rd) \
+ : "f"(s) \
+ : ); \
+ switch (rd) { \
+ case FLOAT_CLASS_SIGNALING_NAN: \
+ case FLOAT_CLASS_QUIET_NAN: \
+ case FLOAT_CLASS_NEGATIVE_INFINITY: \
+ case FLOAT_CLASS_NEGATIVE_NORMAL: \
+ case FLOAT_CLASS_NEGATIVE_SUBNORMAL: \
+ case FLOAT_CLASS_NEGATIVE_ZERO: \
+ case FLOAT_CLASS_POSITIVE_INFINITY: \
+ case FLOAT_CLASS_POSITIVE_NORMAL: \
+ case FLOAT_CLASS_POSITIVE_SUBNORMAL: \
+ case FLOAT_CLASS_POSITIVE_ZERO: \
+ break; \
+ default: \
+ printf("fclass."#N" test failed.\n"); \
+ break; \
+ } \
+}
+
+/*
+ * float format
+ * type | S | Exponent | Fraction | example value
+ * 31 | 30 --23 | 22 | 21 --0 |
+ * | bit |
+ * SNAN 0/1 | 0xFF | 0 | !=0 | 0x7FBFFFFF
+ * QNAN 0/1 | 0xFF | 1 | | 0x7FCFFFFF
+ * -infinity 1 | 0xFF | 0 | 0xFF800000
+ * -normal 1 | [1, 0xFE] | [0, 0x7FFFFF]| 0xFF7FFFFF
+ * -subnormal 1 | 0 | !=0 | 0x807FFFFF
+ * -0 1 | 0 | 0 | 0x80000000
+ * +infinity 0 | 0xFF | 0 | 0x7F800000
+ * +normal 0 | [1, 0xFE] | [0, 0x7FFFFF]| 0x7F7FFFFF
+ * +subnormal 0 | 0 | !=0 | 0x007FFFFF
+ * +0 0 | 0 | 0 | 0x00000000
+ */
+
+long float_snan = 0x7FBFFFFF;
+long float_qnan = 0x7FCFFFFF;
+long float_neg_infinity = 0xFF800000;
+long float_neg_normal = 0xFF7FFFFF;
+long float_neg_subnormal = 0x807FFFFF;
+long float_neg_zero = 0x80000000;
+long float_post_infinity = 0x7F800000;
+long float_post_normal = 0x7F7FFFFF;
+long float_post_subnormal = 0x007FFFFF;
+long float_post_zero = 0x00000000;
+
+/*
+ * double format
+ * type | S | Exponent | Fraction | example value
+ * 63 | 62 -- 52 | 51 | 50 -- 0 |
+ * | bit |
+ * SNAN 0/1 | 0x7FF | 0 | !=0 | 0x7FF7FFFFFFFFFFFF
+ * QNAN 0/1 | 0x7FF | 1 | | 0x7FFFFFFFFFFFFFFF
+ * -infinity 1 | 0x7FF | 0 | 0xFFF0000000000000
+ * -normal 1 |[1, 0x7FE] | | 0xFFEFFFFFFFFFFFFF
+ * -subnormal 1 | 0 | !=0 | 0x8007FFFFFFFFFFFF
+ * -0 1 | 0 | 0 | 0x8000000000000000
+ * +infinity 0 | 0x7FF | 0 | 0x7FF0000000000000
+ * +normal 0 |[1, 0x7FE] | | 0x7FEFFFFFFFFFFFFF
+ * +subnormal 0 | 0 | !=0 | 0x000FFFFFFFFFFFFF
+ * +0 0 | 0 | 0 | 0x0000000000000000
+ */
+
+long double_snan = 0x7FF7FFFFFFFFFFFF;
+long double_qnan = 0x7FFFFFFFFFFFFFFF;
+long double_neg_infinity = 0xFFF0000000000000;
+long double_neg_normal = 0xFFEFFFFFFFFFFFFF;
+long double_neg_subnormal = 0x8007FFFFFFFFFFFF;
+long double_neg_zero = 0x8000000000000000;
+long double_post_infinity = 0x7FF0000000000000;
+long double_post_normal = 0x7FEFFFFFFFFFFFFF;
+long double_post_subnormal = 0x000FFFFFFFFFFFFF;
+long double_post_zero = 0x0000000000000000;
+
+TEST_FCLASS(s)
+TEST_FCLASS(d)
+
+int main()
+{
+ /* fclass.s */
+ test_fclass_s(float_snan);
+ test_fclass_s(float_qnan);
+ test_fclass_s(float_neg_infinity);
+ test_fclass_s(float_neg_normal);
+ test_fclass_s(float_neg_subnormal);
+ test_fclass_s(float_neg_zero);
+ test_fclass_s(float_post_infinity);
+ test_fclass_s(float_post_normal);
+ test_fclass_s(float_post_subnormal);
+ test_fclass_s(float_post_zero);
+
+ /* fclass.d */
+ test_fclass_d(double_snan);
+ test_fclass_d(double_qnan);
+ test_fclass_d(double_neg_infinity);
+ test_fclass_d(double_neg_normal);
+ test_fclass_d(double_neg_subnormal);
+ test_fclass_d(double_neg_zero);
+ test_fclass_d(double_post_infinity);
+ test_fclass_d(double_post_normal);
+ test_fclass_d(double_post_subnormal);
+ test_fclass_d(double_post_zero);
+
+ return 0;
+}