• 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  #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  
toRep16(uint16_t x)57  static inline uint16_t toRep16(uint16_t x)
58  {
59      return x;
60  }
61  
toRep32(float x)62  static inline uint32_t toRep32(float x)
63  {
64      uint32_t ret;
65      memcpy(&ret, &x, 4);
66      return ret;
67  }
68  
toRep64(double x)69  static inline uint64_t toRep64(double x)
70  {
71      uint64_t ret;
72      memcpy(&ret, &x, 8);
73      return ret;
74  }
75  
76  #if __LDBL_MANT_DIG__ == 113
toRep128(long double x)77  static inline __uint128_t toRep128(long double x)
78  {
79      __uint128_t ret;
80      memcpy(&ret, &x, 16);
81      return ret;
82  }
83  #endif
84  
compareResultH(uint16_t result,uint16_t expected)85  static inline int compareResultH(uint16_t result,
86                                   uint16_t expected)
87  {
88      uint16_t rep = toRep16(result);
89  
90      if (rep == expected){
91          return 0;
92      }
93      // test other posible NaN representation(signal NaN)
94      else if (expected == 0x7e00U){
95          if ((rep & 0x7c00U) == 0x7c00U &&
96              (rep & 0x3ffU) > 0){
97              return 0;
98          }
99      }
100      return 1;
101  }
102  
compareResultH(uint16_t result,uint16_t expected)103  static inline int compareResultH(uint16_t result,
104                                   uint16_t expected)
105  {
106      uint16_t rep = toRep16(result);
107  
108      if (rep == expected){
109          return 0;
110      }
111      // test other posible NaN representation(signal NaN)
112      else if (expected == 0x7e00U){
113          if ((rep & 0x7c00U) == 0x7c00U &&
114              (rep & 0x3ffU) > 0){
115              return 0;
116          }
117      }
118      return 1;
119  }
120  
compareResultF(float result,uint32_t expected)121  static inline int compareResultF(float result,
122                                   uint32_t expected)
123  {
124      uint32_t rep = toRep32(result);
125  
126      if (rep == expected){
127          return 0;
128      }
129      // test other posible NaN representation(signal NaN)
130      else if (expected == 0x7fc00000U){
131          if ((rep & 0x7f800000U) == 0x7f800000U &&
132              (rep & 0x7fffffU) > 0){
133              return 0;
134          }
135      }
136      return 1;
137  }
138  
compareResultD(double result,uint64_t expected)139  static inline int compareResultD(double result,
140                                   uint64_t expected)
141  {
142      uint64_t rep = toRep64(result);
143  
144      if (rep == expected){
145          return 0;
146      }
147      // test other posible NaN representation(signal NaN)
148      else if (expected == 0x7ff8000000000000UL){
149          if ((rep & 0x7ff0000000000000UL) == 0x7ff0000000000000UL &&
150              (rep & 0xfffffffffffffUL) > 0){
151              return 0;
152          }
153      }
154      return 1;
155  }
156  
157  #if __LDBL_MANT_DIG__ == 113
158  // return 0 if equal
159  // use two 64-bit integers intead of one 128-bit integer
160  // because 128-bit integer constant can't be assigned directly
compareResultLD(long double result,uint64_t expectedHi,uint64_t expectedLo)161  static inline int compareResultLD(long double result,
162                                    uint64_t expectedHi,
163                                    uint64_t expectedLo)
164  {
165      __uint128_t rep = toRep128(result);
166      uint64_t hi = rep >> 64;
167      uint64_t lo = rep;
168  
169      if (hi == expectedHi && lo == expectedLo){
170          return 0;
171      }
172      // test other posible NaN representation(signal NaN)
173      else if (expectedHi == 0x7fff800000000000UL && expectedLo == 0x0UL){
174          if ((hi & 0x7fff000000000000UL) == 0x7fff000000000000UL &&
175              ((hi & 0xffffffffffffUL) > 0 || lo > 0)){
176              return 0;
177          }
178      }
179      return 1;
180  }
181  #endif
182  
compareResultCMP(int result,enum EXPECTED_RESULT expected)183  static inline int compareResultCMP(int result,
184                                     enum EXPECTED_RESULT expected)
185  {
186      switch(expected){
187          case LESS_0:
188              if (result < 0)
189                  return 0;
190              break;
191          case LESS_EQUAL_0:
192              if (result <= 0)
193                  return 0;
194              break;
195          case EQUAL_0:
196              if (result == 0)
197                  return 0;
198              break;
199          case NEQUAL_0:
200              if (result != 0)
201                  return 0;
202              break;
203          case GREATER_EQUAL_0:
204              if (result >= 0)
205                  return 0;
206              break;
207          case GREATER_0:
208              if (result > 0)
209                  return 0;
210              break;
211          default:
212              return 1;
213      }
214      return 1;
215  }
216  
expectedStr(enum EXPECTED_RESULT expected)217  static inline char *expectedStr(enum EXPECTED_RESULT expected)
218  {
219      switch(expected){
220          case LESS_0:
221              return "<0";
222          case LESS_EQUAL_0:
223              return "<=0";
224          case EQUAL_0:
225              return "=0";
226          case NEQUAL_0:
227              return "!=0";
228          case GREATER_EQUAL_0:
229              return ">=0";
230          case GREATER_0:
231              return ">0";
232          default:
233              return "";
234      }
235      return "";
236  }
237  
makeQNaN16()238  static inline uint16_t makeQNaN16()
239  {
240      return fromRep16(0x7e00U);
241  }
242  
makeQNaN32()243  static inline float makeQNaN32()
244  {
245      return fromRep32(0x7fc00000U);
246  }
247  
makeQNaN64()248  static inline double makeQNaN64()
249  {
250      return fromRep64(0x7ff8000000000000UL);
251  }
252  
253  #if __LDBL_MANT_DIG__ == 113
makeQNaN128()254  static inline long double makeQNaN128()
255  {
256      return fromRep128(0x7fff800000000000UL, 0x0UL);
257  }
258  #endif
259  
makeNaN16(uint16_t rand)260  static inline uint16_t makeNaN16(uint16_t rand)
261  {
262      return fromRep16(0x7c00U | (rand & 0x7fffU));
263  }
264  
makeNaN16(uint16_t rand)265  static inline uint16_t makeNaN16(uint16_t rand)
266  {
267      return fromRep16(0x7c00U | (rand & 0x7fffU));
268  }
269  
makeNaN32(uint32_t rand)270  static inline float makeNaN32(uint32_t rand)
271  {
272      return fromRep32(0x7f800000U | (rand & 0x7fffffU));
273  }
274  
makeNaN64(uint64_t rand)275  static inline double makeNaN64(uint64_t rand)
276  {
277      return fromRep64(0x7ff0000000000000UL | (rand & 0xfffffffffffffUL));
278  }
279  
280  #if __LDBL_MANT_DIG__ == 113
makeNaN128(uint64_t rand)281  static inline long double makeNaN128(uint64_t rand)
282  {
283      return fromRep128(0x7fff000000000000UL | (rand & 0xffffffffffffUL), 0x0UL);
284  }
285  #endif
286  
makeInf16()287  static inline uint16_t makeInf16()
288  {
289      return fromRep16(0x7c00U);
290  }
291  
makeInf16()292  static inline uint16_t makeInf16()
293  {
294      return fromRep16(0x7c00U);
295  }
296  
makeInf32()297  static inline float makeInf32()
298  {
299      return fromRep32(0x7f800000U);
300  }
301  
makeInf64()302  static inline double makeInf64()
303  {
304      return fromRep64(0x7ff0000000000000UL);
305  }
306  
307  #if __LDBL_MANT_DIG__ == 113
makeInf128()308  static inline long double makeInf128()
309  {
310      return fromRep128(0x7fff000000000000UL, 0x0UL);
311  }
312  #endif
313