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