xref: /openbmc/qemu/tests/tcg/loongarch64/test_fclass.c (revision 68e26e1e812c8b09313d7929271f6cbd47ef4c07)
1*65cb15f4SSong Gao #include <stdio.h>
2*65cb15f4SSong Gao 
3*65cb15f4SSong Gao /* float class */
4*65cb15f4SSong Gao #define FLOAT_CLASS_SIGNALING_NAN      0x001
5*65cb15f4SSong Gao #define FLOAT_CLASS_QUIET_NAN          0x002
6*65cb15f4SSong Gao #define FLOAT_CLASS_NEGATIVE_INFINITY  0x004
7*65cb15f4SSong Gao #define FLOAT_CLASS_NEGATIVE_NORMAL    0x008
8*65cb15f4SSong Gao #define FLOAT_CLASS_NEGATIVE_SUBNORMAL 0x010
9*65cb15f4SSong Gao #define FLOAT_CLASS_NEGATIVE_ZERO      0x020
10*65cb15f4SSong Gao #define FLOAT_CLASS_POSITIVE_INFINITY  0x040
11*65cb15f4SSong Gao #define FLOAT_CLASS_POSITIVE_NORMAL    0x080
12*65cb15f4SSong Gao #define FLOAT_CLASS_POSITIVE_SUBNORMAL 0x100
13*65cb15f4SSong Gao #define FLOAT_CLASS_POSITIVE_ZERO      0x200
14*65cb15f4SSong Gao 
15*65cb15f4SSong Gao #define TEST_FCLASS(N)                            \
16*65cb15f4SSong Gao void test_fclass_##N(long s)                      \
17*65cb15f4SSong Gao {                                                 \
18*65cb15f4SSong Gao     double fd;                                    \
19*65cb15f4SSong Gao     long rd;                                      \
20*65cb15f4SSong Gao                                                   \
21*65cb15f4SSong Gao     asm volatile("fclass."#N" %0, %2\n\t"         \
22*65cb15f4SSong Gao                  "movfr2gr."#N" %1, %2\n\t"       \
23*65cb15f4SSong Gao                     : "=f"(fd), "=r"(rd)          \
24*65cb15f4SSong Gao                     : "f"(s)                      \
25*65cb15f4SSong Gao                     : );                          \
26*65cb15f4SSong Gao     switch (rd) {                                 \
27*65cb15f4SSong Gao     case FLOAT_CLASS_SIGNALING_NAN:               \
28*65cb15f4SSong Gao     case FLOAT_CLASS_QUIET_NAN:                   \
29*65cb15f4SSong Gao     case FLOAT_CLASS_NEGATIVE_INFINITY:           \
30*65cb15f4SSong Gao     case FLOAT_CLASS_NEGATIVE_NORMAL:             \
31*65cb15f4SSong Gao     case FLOAT_CLASS_NEGATIVE_SUBNORMAL:          \
32*65cb15f4SSong Gao     case FLOAT_CLASS_NEGATIVE_ZERO:               \
33*65cb15f4SSong Gao     case FLOAT_CLASS_POSITIVE_INFINITY:           \
34*65cb15f4SSong Gao     case FLOAT_CLASS_POSITIVE_NORMAL:             \
35*65cb15f4SSong Gao     case FLOAT_CLASS_POSITIVE_SUBNORMAL:          \
36*65cb15f4SSong Gao     case FLOAT_CLASS_POSITIVE_ZERO:               \
37*65cb15f4SSong Gao         break;                                    \
38*65cb15f4SSong Gao     default:                                      \
39*65cb15f4SSong Gao         printf("fclass."#N" test failed.\n");     \
40*65cb15f4SSong Gao         break;                                    \
41*65cb15f4SSong Gao     }                                             \
42*65cb15f4SSong Gao }
43*65cb15f4SSong Gao 
44*65cb15f4SSong Gao /*
45*65cb15f4SSong Gao  *  float format
46*65cb15f4SSong Gao  *  type     |    S  | Exponent  |  Fraction    |  example value
47*65cb15f4SSong Gao  *                31 | 30 --23   | 22  | 21 --0 |
48*65cb15f4SSong Gao  *                               | bit |
49*65cb15f4SSong Gao  *  SNAN         0/1 |   0xFF    | 0   |  !=0   |  0x7FBFFFFF
50*65cb15f4SSong Gao  *  QNAN         0/1 |   0xFF    | 1   |        |  0x7FCFFFFF
51*65cb15f4SSong Gao  *  -infinity     1  |   0xFF    |     0        |  0xFF800000
52*65cb15f4SSong Gao  *  -normal       1  | [1, 0xFE] | [0, 0x7FFFFF]|  0xFF7FFFFF
53*65cb15f4SSong Gao  *  -subnormal    1  |    0      |    !=0       |  0x807FFFFF
54*65cb15f4SSong Gao  *  -0            1  |    0      |     0        |  0x80000000
55*65cb15f4SSong Gao  *  +infinity     0  |   0xFF    |     0        |  0x7F800000
56*65cb15f4SSong Gao  *  +normal       0  | [1, 0xFE] | [0, 0x7FFFFF]|  0x7F7FFFFF
57*65cb15f4SSong Gao  *  +subnormal    0  |    0      |    !=0       |  0x007FFFFF
58*65cb15f4SSong Gao  *  +0            0  |    0      |     0        |  0x00000000
59*65cb15f4SSong Gao  */
60*65cb15f4SSong Gao 
61*65cb15f4SSong Gao long float_snan = 0x7FBFFFFF;
62*65cb15f4SSong Gao long float_qnan = 0x7FCFFFFF;
63*65cb15f4SSong Gao long float_neg_infinity = 0xFF800000;
64*65cb15f4SSong Gao long float_neg_normal = 0xFF7FFFFF;
65*65cb15f4SSong Gao long float_neg_subnormal = 0x807FFFFF;
66*65cb15f4SSong Gao long float_neg_zero = 0x80000000;
67*65cb15f4SSong Gao long float_post_infinity = 0x7F800000;
68*65cb15f4SSong Gao long float_post_normal = 0x7F7FFFFF;
69*65cb15f4SSong Gao long float_post_subnormal = 0x007FFFFF;
70*65cb15f4SSong Gao long float_post_zero = 0x00000000;
71*65cb15f4SSong Gao 
72*65cb15f4SSong Gao /*
73*65cb15f4SSong Gao  * double format
74*65cb15f4SSong Gao  *  type     |    S  | Exponent  |  Fraction     |  example value
75*65cb15f4SSong Gao  *                63 | 62  -- 52 | 51  | 50 -- 0 |
76*65cb15f4SSong Gao  *                               | bit |
77*65cb15f4SSong Gao  *  SNAN         0/1 |  0x7FF    | 0   |  !=0    | 0x7FF7FFFFFFFFFFFF
78*65cb15f4SSong Gao  *  QNAN         0/1 |  0x7FF    | 1   |         | 0x7FFFFFFFFFFFFFFF
79*65cb15f4SSong Gao  * -infinity      1  |  0x7FF    |    0          | 0xFFF0000000000000
80*65cb15f4SSong Gao  * -normal        1  |[1, 0x7FE] |               | 0xFFEFFFFFFFFFFFFF
81*65cb15f4SSong Gao  * -subnormal     1  |   0       |   !=0         | 0x8007FFFFFFFFFFFF
82*65cb15f4SSong Gao  * -0             1  |   0       |    0          | 0x8000000000000000
83*65cb15f4SSong Gao  * +infinity      0  |  0x7FF    |    0          | 0x7FF0000000000000
84*65cb15f4SSong Gao  * +normal        0  |[1, 0x7FE] |               | 0x7FEFFFFFFFFFFFFF
85*65cb15f4SSong Gao  * +subnormal     0  |  0        |   !=0         | 0x000FFFFFFFFFFFFF
86*65cb15f4SSong Gao  * +0             0  |  0        |   0           | 0x0000000000000000
87*65cb15f4SSong Gao  */
88*65cb15f4SSong Gao 
89*65cb15f4SSong Gao long double_snan = 0x7FF7FFFFFFFFFFFF;
90*65cb15f4SSong Gao long double_qnan = 0x7FFFFFFFFFFFFFFF;
91*65cb15f4SSong Gao long double_neg_infinity = 0xFFF0000000000000;
92*65cb15f4SSong Gao long double_neg_normal = 0xFFEFFFFFFFFFFFFF;
93*65cb15f4SSong Gao long double_neg_subnormal = 0x8007FFFFFFFFFFFF;
94*65cb15f4SSong Gao long double_neg_zero = 0x8000000000000000;
95*65cb15f4SSong Gao long double_post_infinity = 0x7FF0000000000000;
96*65cb15f4SSong Gao long double_post_normal = 0x7FEFFFFFFFFFFFFF;
97*65cb15f4SSong Gao long double_post_subnormal = 0x000FFFFFFFFFFFFF;
98*65cb15f4SSong Gao long double_post_zero = 0x0000000000000000;
99*65cb15f4SSong Gao 
100*65cb15f4SSong Gao TEST_FCLASS(s)
TEST_FCLASS(d)101*65cb15f4SSong Gao TEST_FCLASS(d)
102*65cb15f4SSong Gao 
103*65cb15f4SSong Gao int main()
104*65cb15f4SSong Gao {
105*65cb15f4SSong Gao     /* fclass.s */
106*65cb15f4SSong Gao     test_fclass_s(float_snan);
107*65cb15f4SSong Gao     test_fclass_s(float_qnan);
108*65cb15f4SSong Gao     test_fclass_s(float_neg_infinity);
109*65cb15f4SSong Gao     test_fclass_s(float_neg_normal);
110*65cb15f4SSong Gao     test_fclass_s(float_neg_subnormal);
111*65cb15f4SSong Gao     test_fclass_s(float_neg_zero);
112*65cb15f4SSong Gao     test_fclass_s(float_post_infinity);
113*65cb15f4SSong Gao     test_fclass_s(float_post_normal);
114*65cb15f4SSong Gao     test_fclass_s(float_post_subnormal);
115*65cb15f4SSong Gao     test_fclass_s(float_post_zero);
116*65cb15f4SSong Gao 
117*65cb15f4SSong Gao     /* fclass.d */
118*65cb15f4SSong Gao     test_fclass_d(double_snan);
119*65cb15f4SSong Gao     test_fclass_d(double_qnan);
120*65cb15f4SSong Gao     test_fclass_d(double_neg_infinity);
121*65cb15f4SSong Gao     test_fclass_d(double_neg_normal);
122*65cb15f4SSong Gao     test_fclass_d(double_neg_subnormal);
123*65cb15f4SSong Gao     test_fclass_d(double_neg_zero);
124*65cb15f4SSong Gao     test_fclass_d(double_post_infinity);
125*65cb15f4SSong Gao     test_fclass_d(double_post_normal);
126*65cb15f4SSong Gao     test_fclass_d(double_post_subnormal);
127*65cb15f4SSong Gao     test_fclass_d(double_post_zero);
128*65cb15f4SSong Gao 
129*65cb15f4SSong Gao     return 0;
130*65cb15f4SSong Gao }
131