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