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