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