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 
42 #if __LDBL_MANT_DIG__ == 113
fromRep128(uint64_t hi,uint64_t lo)43 static inline long double fromRep128(uint64_t hi, uint64_t lo)
44 {
45     __uint128_t x = ((__uint128_t)hi << 64) + lo;
46     long double ret;
47     memcpy(&ret, &x, 16);
48     return ret;
49 }
50 #endif
51 
toRep16(uint16_t x)52 static inline uint16_t toRep16(uint16_t x)
53 {
54     return x;
55 }
56 
toRep16(uint16_t x)57 static inline uint16_t toRep16(uint16_t x)
58 {
59     return x;
60 }
61 
toRep32(float x)62 static inline uint32_t toRep32(float x)
63 {
64     uint32_t ret;
65     memcpy(&ret, &x, 4);
66     return ret;
67 }
68 
toRep64(double x)69 static inline uint64_t toRep64(double x)
70 {
71     uint64_t ret;
72     memcpy(&ret, &x, 8);
73     return ret;
74 }
75 
76 #if __LDBL_MANT_DIG__ == 113
toRep128(long double x)77 static inline __uint128_t toRep128(long double x)
78 {
79     __uint128_t ret;
80     memcpy(&ret, &x, 16);
81     return ret;
82 }
83 #endif
84 
compareResultH(uint16_t result,uint16_t expected)85 static inline int compareResultH(uint16_t result,
86                                  uint16_t expected)
87 {
88     uint16_t rep = toRep16(result);
89 
90     if (rep == expected){
91         return 0;
92     }
93     // test other posible NaN representation(signal NaN)
94     else if (expected == 0x7e00U){
95         if ((rep & 0x7c00U) == 0x7c00U &&
96             (rep & 0x3ffU) > 0){
97             return 0;
98         }
99     }
100     return 1;
101 }
102 
compareResultH(uint16_t result,uint16_t expected)103 static inline int compareResultH(uint16_t result,
104                                  uint16_t expected)
105 {
106     uint16_t rep = toRep16(result);
107 
108     if (rep == expected){
109         return 0;
110     }
111     // test other posible NaN representation(signal NaN)
112     else if (expected == 0x7e00U){
113         if ((rep & 0x7c00U) == 0x7c00U &&
114             (rep & 0x3ffU) > 0){
115             return 0;
116         }
117     }
118     return 1;
119 }
120 
compareResultF(float result,uint32_t expected)121 static inline int compareResultF(float result,
122                                  uint32_t expected)
123 {
124     uint32_t rep = toRep32(result);
125 
126     if (rep == expected){
127         return 0;
128     }
129     // test other posible NaN representation(signal NaN)
130     else if (expected == 0x7fc00000U){
131         if ((rep & 0x7f800000U) == 0x7f800000U &&
132             (rep & 0x7fffffU) > 0){
133             return 0;
134         }
135     }
136     return 1;
137 }
138 
compareResultD(double result,uint64_t expected)139 static inline int compareResultD(double result,
140                                  uint64_t expected)
141 {
142     uint64_t rep = toRep64(result);
143 
144     if (rep == expected){
145         return 0;
146     }
147     // test other posible NaN representation(signal NaN)
148     else if (expected == 0x7ff8000000000000UL){
149         if ((rep & 0x7ff0000000000000UL) == 0x7ff0000000000000UL &&
150             (rep & 0xfffffffffffffUL) > 0){
151             return 0;
152         }
153     }
154     return 1;
155 }
156 
157 #if __LDBL_MANT_DIG__ == 113
158 // return 0 if equal
159 // use two 64-bit integers intead of one 128-bit integer
160 // because 128-bit integer constant can't be assigned directly
compareResultLD(long double result,uint64_t expectedHi,uint64_t expectedLo)161 static inline int compareResultLD(long double result,
162                                   uint64_t expectedHi,
163                                   uint64_t expectedLo)
164 {
165     __uint128_t rep = toRep128(result);
166     uint64_t hi = rep >> 64;
167     uint64_t lo = rep;
168 
169     if (hi == expectedHi && lo == expectedLo){
170         return 0;
171     }
172     // test other posible NaN representation(signal NaN)
173     else if (expectedHi == 0x7fff800000000000UL && expectedLo == 0x0UL){
174         if ((hi & 0x7fff000000000000UL) == 0x7fff000000000000UL &&
175             ((hi & 0xffffffffffffUL) > 0 || lo > 0)){
176             return 0;
177         }
178     }
179     return 1;
180 }
181 #endif
182 
compareResultCMP(int result,enum EXPECTED_RESULT expected)183 static inline int compareResultCMP(int result,
184                                    enum EXPECTED_RESULT expected)
185 {
186     switch(expected){
187         case LESS_0:
188             if (result < 0)
189                 return 0;
190             break;
191         case LESS_EQUAL_0:
192             if (result <= 0)
193                 return 0;
194             break;
195         case EQUAL_0:
196             if (result == 0)
197                 return 0;
198             break;
199         case NEQUAL_0:
200             if (result != 0)
201                 return 0;
202             break;
203         case GREATER_EQUAL_0:
204             if (result >= 0)
205                 return 0;
206             break;
207         case GREATER_0:
208             if (result > 0)
209                 return 0;
210             break;
211         default:
212             return 1;
213     }
214     return 1;
215 }
216 
expectedStr(enum EXPECTED_RESULT expected)217 static inline char *expectedStr(enum EXPECTED_RESULT expected)
218 {
219     switch(expected){
220         case LESS_0:
221             return "<0";
222         case LESS_EQUAL_0:
223             return "<=0";
224         case EQUAL_0:
225             return "=0";
226         case NEQUAL_0:
227             return "!=0";
228         case GREATER_EQUAL_0:
229             return ">=0";
230         case GREATER_0:
231             return ">0";
232         default:
233             return "";
234     }
235     return "";
236 }
237 
makeQNaN16()238 static inline uint16_t makeQNaN16()
239 {
240     return fromRep16(0x7e00U);
241 }
242 
makeQNaN32()243 static inline float makeQNaN32()
244 {
245     return fromRep32(0x7fc00000U);
246 }
247 
makeQNaN64()248 static inline double makeQNaN64()
249 {
250     return fromRep64(0x7ff8000000000000UL);
251 }
252 
253 #if __LDBL_MANT_DIG__ == 113
makeQNaN128()254 static inline long double makeQNaN128()
255 {
256     return fromRep128(0x7fff800000000000UL, 0x0UL);
257 }
258 #endif
259 
makeNaN16(uint16_t rand)260 static inline uint16_t makeNaN16(uint16_t rand)
261 {
262     return fromRep16(0x7c00U | (rand & 0x7fffU));
263 }
264 
makeNaN16(uint16_t rand)265 static inline uint16_t makeNaN16(uint16_t rand)
266 {
267     return fromRep16(0x7c00U | (rand & 0x7fffU));
268 }
269 
makeNaN32(uint32_t rand)270 static inline float makeNaN32(uint32_t rand)
271 {
272     return fromRep32(0x7f800000U | (rand & 0x7fffffU));
273 }
274 
makeNaN64(uint64_t rand)275 static inline double makeNaN64(uint64_t rand)
276 {
277     return fromRep64(0x7ff0000000000000UL | (rand & 0xfffffffffffffUL));
278 }
279 
280 #if __LDBL_MANT_DIG__ == 113
makeNaN128(uint64_t rand)281 static inline long double makeNaN128(uint64_t rand)
282 {
283     return fromRep128(0x7fff000000000000UL | (rand & 0xffffffffffffUL), 0x0UL);
284 }
285 #endif
286 
makeInf16()287 static inline uint16_t makeInf16()
288 {
289     return fromRep16(0x7c00U);
290 }
291 
makeInf16()292 static inline uint16_t makeInf16()
293 {
294     return fromRep16(0x7c00U);
295 }
296 
makeInf32()297 static inline float makeInf32()
298 {
299     return fromRep32(0x7f800000U);
300 }
301 
makeInf64()302 static inline double makeInf64()
303 {
304     return fromRep64(0x7ff0000000000000UL);
305 }
306 
307 #if __LDBL_MANT_DIG__ == 113
makeInf128()308 static inline long double makeInf128()
309 {
310     return fromRep128(0x7fff000000000000UL, 0x0UL);
311 }
312 #endif
313