1 //===--------------------------- fp_test.h - ------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines shared functions for the test.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include <stdlib.h>
15 #include <limits.h>
16 #include <string.h>
17 #include <stdint.h>
18 
19 enum EXPECTED_RESULT {
20     LESS_0, LESS_EQUAL_0, EQUAL_0, GREATER_0, GREATER_EQUAL_0, NEQUAL_0
21 };
22 
fromRep16(uint16_t x)23 static inline uint16_t fromRep16(uint16_t x)
24 {
25     return x;
26 }
27 
fromRep32(uint32_t x)28 static inline float fromRep32(uint32_t x)
29 {
30     float ret;
31     memcpy(&ret, &x, 4);
32     return ret;
33 }
34 
fromRep64(uint64_t x)35 static inline double fromRep64(uint64_t x)
36 {
37     double ret;
38     memcpy(&ret, &x, 8);
39     return ret;
40 }
41 
fromRep128(uint64_t hi,uint64_t lo)42 static inline long double fromRep128(uint64_t hi, uint64_t lo)
43 {
44     __uint128_t x = ((__uint128_t)hi << 64) + lo;
45     long double ret;
46     memcpy(&ret, &x, 16);
47     return ret;
48 }
49 
toRep16(uint16_t x)50 static inline uint16_t toRep16(uint16_t x)
51 {
52     return x;
53 }
54 
toRep32(float x)55 static inline uint32_t toRep32(float x)
56 {
57     uint32_t ret;
58     memcpy(&ret, &x, 4);
59     return ret;
60 }
61 
toRep64(double x)62 static inline uint64_t toRep64(double x)
63 {
64     uint64_t ret;
65     memcpy(&ret, &x, 8);
66     return ret;
67 }
68 
toRep128(long double x)69 static inline __uint128_t toRep128(long double x)
70 {
71     __uint128_t ret;
72     memcpy(&ret, &x, 16);
73     return ret;
74 }
75 
compareResultH(uint16_t result,uint16_t expected)76 static inline int compareResultH(uint16_t result,
77                                  uint16_t expected)
78 {
79     uint16_t rep = toRep16(result);
80 
81     if (rep == expected){
82         return 0;
83     }
84     // test other posible NaN representation(signal NaN)
85     else if (expected == 0x7e00U){
86         if ((rep & 0x7c00U) == 0x7c00U &&
87             (rep & 0x3ffU) > 0){
88             return 0;
89         }
90     }
91     return 1;
92 }
93 
compareResultF(float result,uint32_t expected)94 static inline int compareResultF(float result,
95                                  uint32_t expected)
96 {
97     uint32_t rep = toRep32(result);
98 
99     if (rep == expected){
100         return 0;
101     }
102     // test other posible NaN representation(signal NaN)
103     else if (expected == 0x7fc00000U){
104         if ((rep & 0x7f800000U) == 0x7f800000U &&
105             (rep & 0x7fffffU) > 0){
106             return 0;
107         }
108     }
109     return 1;
110 }
111 
compareResultD(double result,uint64_t expected)112 static inline int compareResultD(double result,
113                                  uint64_t expected)
114 {
115     uint64_t rep = toRep64(result);
116 
117     if (rep == expected){
118         return 0;
119     }
120     // test other posible NaN representation(signal NaN)
121     else if (expected == 0x7ff8000000000000UL){
122         if ((rep & 0x7ff0000000000000UL) == 0x7ff0000000000000UL &&
123             (rep & 0xfffffffffffffUL) > 0){
124             return 0;
125         }
126     }
127     return 1;
128 }
129 
130 // return 0 if equal
131 // use two 64-bit integers intead of one 128-bit integer
132 // because 128-bit integer constant can't be assigned directly
compareResultLD(long double result,uint64_t expectedHi,uint64_t expectedLo)133 static inline int compareResultLD(long double result,
134                                   uint64_t expectedHi,
135                                   uint64_t expectedLo)
136 {
137     __uint128_t rep = toRep128(result);
138     uint64_t hi = rep >> 64;
139     uint64_t lo = rep;
140 
141     if (hi == expectedHi && lo == expectedLo){
142         return 0;
143     }
144     // test other posible NaN representation(signal NaN)
145     else if (expectedHi == 0x7fff800000000000UL && expectedLo == 0x0UL){
146         if ((hi & 0x7fff000000000000UL) == 0x7fff000000000000UL &&
147             ((hi & 0xffffffffffffUL) > 0 || lo > 0)){
148             return 0;
149         }
150     }
151     return 1;
152 }
153 
compareResultCMP(int result,enum EXPECTED_RESULT expected)154 static inline int compareResultCMP(int result,
155                                    enum EXPECTED_RESULT expected)
156 {
157     switch(expected){
158         case LESS_0:
159             if (result < 0)
160                 return 0;
161             break;
162         case LESS_EQUAL_0:
163             if (result <= 0)
164                 return 0;
165             break;
166         case EQUAL_0:
167             if (result == 0)
168                 return 0;
169             break;
170         case NEQUAL_0:
171             if (result != 0)
172                 return 0;
173             break;
174         case GREATER_EQUAL_0:
175             if (result >= 0)
176                 return 0;
177             break;
178         case GREATER_0:
179             if (result > 0)
180                 return 0;
181             break;
182         default:
183             return 1;
184     }
185     return 1;
186 }
187 
expectedStr(enum EXPECTED_RESULT expected)188 static inline char *expectedStr(enum EXPECTED_RESULT expected)
189 {
190     switch(expected){
191         case LESS_0:
192             return "<0";
193         case LESS_EQUAL_0:
194             return "<=0";
195         case EQUAL_0:
196             return "=0";
197         case NEQUAL_0:
198             return "!=0";
199         case GREATER_EQUAL_0:
200             return ">=0";
201         case GREATER_0:
202             return ">0";
203         default:
204             return "";
205     }
206     return "";
207 }
208 
makeQNaN16()209 static inline uint16_t makeQNaN16()
210 {
211     return fromRep16(0x7e00U);
212 }
213 
makeQNaN32()214 static inline float makeQNaN32()
215 {
216     return fromRep32(0x7fc00000U);
217 }
218 
makeQNaN64()219 static inline double makeQNaN64()
220 {
221     return fromRep64(0x7ff8000000000000UL);
222 }
223 
makeQNaN128()224 static inline long double makeQNaN128()
225 {
226     return fromRep128(0x7fff800000000000UL, 0x0UL);
227 }
228 
makeNaN16(uint16_t rand)229 static inline uint16_t makeNaN16(uint16_t rand)
230 {
231     return fromRep16(0x7c00U | (rand & 0x7fffU));
232 }
233 
makeNaN32(uint32_t rand)234 static inline float makeNaN32(uint32_t rand)
235 {
236     return fromRep32(0x7f800000U | (rand & 0x7fffffU));
237 }
238 
makeNaN64(uint64_t rand)239 static inline double makeNaN64(uint64_t rand)
240 {
241     return fromRep64(0x7ff0000000000000UL | (rand & 0xfffffffffffffUL));
242 }
243 
makeNaN128(uint64_t rand)244 static inline long double makeNaN128(uint64_t rand)
245 {
246     return fromRep128(0x7fff000000000000UL | (rand & 0xffffffffffffUL), 0x0UL);
247 }
248 
makeInf16()249 static inline uint16_t makeInf16()
250 {
251     return fromRep16(0x7c00U);
252 }
253 
makeInf32()254 static inline float makeInf32()
255 {
256     return fromRep32(0x7f800000U);
257 }
258 
makeInf64()259 static inline double makeInf64()
260 {
261     return fromRep64(0x7ff0000000000000UL);
262 }
263 
makeInf128()264 static inline long double makeInf128()
265 {
266     return fromRep128(0x7fff000000000000UL, 0x0UL);
267 }
268