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