• 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 
18 enum EXPECTED_RESULT {
19     LESS_0, LESS_EQUAL_0, EQUAL_0, GREATER_0, GREATER_EQUAL_0, NEQUAL_0
20 };
21 
fromRep32(uint32_t x)22 static inline float fromRep32(uint32_t x)
23 {
24     float ret;
25     memcpy(&ret, &x, 4);
26     return ret;
27 }
28 
fromRep64(uint64_t x)29 static inline double fromRep64(uint64_t x)
30 {
31     double ret;
32     memcpy(&ret, &x, 8);
33     return ret;
34 }
35 
fromRep128(uint64_t hi,uint64_t lo)36 static 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 
toRep32(float x)44 static inline uint32_t toRep32(float x)
45 {
46     uint32_t ret;
47     memcpy(&ret, &x, 4);
48     return ret;
49 }
50 
toRep64(double x)51 static inline uint64_t toRep64(double x)
52 {
53     uint64_t ret;
54     memcpy(&ret, &x, 8);
55     return ret;
56 }
57 
toRep128(long double x)58 static inline __uint128_t toRep128(long double x)
59 {
60     __uint128_t ret;
61     memcpy(&ret, &x, 16);
62     return ret;
63 }
64 
compareResultF(float result,uint32_t expected)65 static 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 
compareResultD(double result,uint64_t expected)83 static 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
compareResultLD(long double result,uint64_t expectedHi,uint64_t expectedLo)104 static 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 
compareResultCMP(int result,enum EXPECTED_RESULT expected)125 static 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 
expectedStr(enum EXPECTED_RESULT expected)159 static 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 
makeQNaN32()180 static inline float makeQNaN32()
181 {
182     return fromRep32(0x7fc00000U);
183 }
184 
makeQNaN64()185 static inline double makeQNaN64()
186 {
187     return fromRep64(0x7ff8000000000000UL);
188 }
189 
makeQNaN128()190 static inline long double makeQNaN128()
191 {
192     return fromRep128(0x7fff800000000000UL, 0x0UL);
193 }
194 
makeNaN32(uint32_t rand)195 static inline float makeNaN32(uint32_t rand)
196 {
197     return fromRep32(0x7f800000U | (rand & 0x7fffffU));
198 }
199 
makeNaN64(uint64_t rand)200 static inline double makeNaN64(uint64_t rand)
201 {
202     return fromRep64(0x7ff0000000000000UL | (rand & 0xfffffffffffffUL));
203 }
204 
makeNaN128(uint64_t rand)205 static inline long double makeNaN128(uint64_t rand)
206 {
207     return fromRep128(0x7fff000000000000UL | (rand & 0xffffffffffffUL), 0x0UL);
208 }
209 
makeInf32()210 static inline float makeInf32()
211 {
212     return fromRep32(0x7f800000U);
213 }
214 
makeInf64()215 static inline double makeInf64()
216 {
217     return fromRep64(0x7ff0000000000000UL);
218 }
219 
makeInf128()220 static inline long double makeInf128()
221 {
222     return fromRep128(0x7fff000000000000UL, 0x0UL);
223 }
224