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