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