1 //===- subzero/crosstest/test_cast_main.cpp - Driver for tests ------------===//
2 //
3 // The Subzero Code Generator
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Driver for crosstesting cast operations.
11 //
12 //===----------------------------------------------------------------------===//
13
14 /* crosstest.py --test=test_cast.cpp --test=test_cast_to_u1.ll \
15 --test=test_cast_vectors.ll \
16 --driver=test_cast_main.cpp --prefix=Subzero_ --output=test_cast */
17
18 #include <cfloat>
19 #include <cstring>
20 #include <iostream>
21 #include <stdint.h>
22
23 #include "test_arith.def"
24 #include "vectors.h"
25 #include "xdefs.h"
26
27 // Include test_cast.h twice - once normally, and once within the
28 // Subzero_ namespace, corresponding to the llc and Subzero translated
29 // object files, respectively.
30 #include "test_cast.h"
31 namespace Subzero_ {
32 #include "test_cast.h"
33 }
34
35 #define XSTR(s) STR(s)
36 #define STR(s) #s
37 #define COMPARE(Func, FromCName, ToCName, Input, FromString) \
38 do { \
39 ToCName ResultSz, ResultLlc; \
40 ResultLlc = Func<FromCName, ToCName>(Input); \
41 ResultSz = Subzero_::Func<FromCName, ToCName>(Input); \
42 ++TotalTests; \
43 if (!memcmp(&ResultLlc, &ResultSz, sizeof(ToCName))) { \
44 ++Passes; \
45 } else { \
46 ++Failures; \
47 std::cout << std::fixed << XSTR(Func) << "<" << FromString \
48 << ", " XSTR(ToCName) ">(" << Input << "): "; \
49 if (sizeof(ToCName) == 1) \
50 std::cout << "sz=" << (int)ResultSz << " llc=" << (int)ResultLlc; \
51 else \
52 std::cout << "sz=" << ResultSz << " llc=" << ResultLlc; \
53 std::cout << "\n"; \
54 } \
55 } while (0)
56
57 #define COMPARE_ARG(Func, FromCName, ToCName, Input, FromString) \
58 do { \
59 ToCName ResultSz, ResultLlc; \
60 ResultLlc = Func<FromCName, ToCName>(1, Input, 2); \
61 ResultSz = Subzero_::Func<FromCName, ToCName>(1, Input, 2); \
62 ++TotalTests; \
63 if (!memcmp(&ResultLlc, &ResultSz, sizeof(ToCName))) { \
64 ++Passes; \
65 } else { \
66 ++Failures; \
67 std::cout << std::fixed << XSTR(Func) << "<" << FromString \
68 << ", " XSTR(ToCName) ">(" << Input << "): "; \
69 if (sizeof(ToCName) == 1) \
70 std::cout << "sz=" << (int)ResultSz << " llc=" << (int)ResultLlc; \
71 else \
72 std::cout << "sz=" << ResultSz << " llc=" << ResultLlc; \
73 std::cout << "\n"; \
74 } \
75 } while (0)
76
77 #define COMPARE_VEC(Func, FromCName, ToCName, Input, FromString, ToString) \
78 do { \
79 ToCName ResultSz, ResultLlc; \
80 ResultLlc = Func<FromCName, ToCName>(Input); \
81 ResultSz = Subzero_::Func<FromCName, ToCName>(Input); \
82 ++TotalTests; \
83 if (!memcmp(&ResultLlc, &ResultSz, sizeof(ToCName))) { \
84 ++Passes; \
85 } else { \
86 ++Failures; \
87 std::cout << std::fixed << XSTR(Func) << "<" << FromString << ", " \
88 << ToString << ">(" << vectAsString<FromCName>(Input) \
89 << "): "; \
90 std::cout << "sz=" << vectAsString<ToCName>(ResultSz) \
91 << " llc=" << vectAsString<ToCName>(ResultLlc); \
92 std::cout << "\n"; \
93 } \
94 } while (0)
95
96 template <typename FromType>
testValue(FromType Val,size_t & TotalTests,size_t & Passes,size_t & Failures,const char * FromTypeString)97 void testValue(FromType Val, size_t &TotalTests, size_t &Passes,
98 size_t &Failures, const char *FromTypeString) {
99 COMPARE(cast, FromType, bool, Val, FromTypeString);
100 COMPARE(cast, FromType, uint8_t, Val, FromTypeString);
101 COMPARE(cast, FromType, myint8_t, Val, FromTypeString);
102 COMPARE(cast, FromType, uint16_t, Val, FromTypeString);
103 COMPARE(cast, FromType, int16_t, Val, FromTypeString);
104 COMPARE(cast, FromType, uint32_t, Val, FromTypeString);
105 COMPARE(cast, FromType, int32_t, Val, FromTypeString);
106 COMPARE(cast, FromType, uint64, Val, FromTypeString);
107 COMPARE(cast, FromType, int64, Val, FromTypeString);
108 COMPARE(cast, FromType, float, Val, FromTypeString);
109 COMPARE(cast, FromType, double, Val, FromTypeString);
110 COMPARE_ARG(cast, FromType, bool, Val, FromTypeString);
111 COMPARE_ARG(cast, FromType, uint8_t, Val, FromTypeString);
112 COMPARE_ARG(cast, FromType, myint8_t, Val, FromTypeString);
113 COMPARE_ARG(cast, FromType, uint16_t, Val, FromTypeString);
114 COMPARE_ARG(cast, FromType, int16_t, Val, FromTypeString);
115 COMPARE_ARG(cast, FromType, uint32_t, Val, FromTypeString);
116 COMPARE_ARG(cast, FromType, int32_t, Val, FromTypeString);
117 COMPARE_ARG(cast, FromType, uint64, Val, FromTypeString);
118 COMPARE_ARG(cast, FromType, int64, Val, FromTypeString);
119 COMPARE_ARG(cast, FromType, float, Val, FromTypeString);
120 COMPARE_ARG(cast, FromType, double, Val, FromTypeString);
121 }
122
123 template <typename FromType, typename ToType>
testVector(size_t & TotalTests,size_t & Passes,size_t & Failures,const char * FromTypeString,const char * ToTypeString)124 void testVector(size_t &TotalTests, size_t &Passes, size_t &Failures,
125 const char *FromTypeString, const char *ToTypeString) {
126 const static size_t NumElementsInType = Vectors<FromType>::NumElements;
127 PRNG Index;
128 static const float NegInf = -1.0 / 0.0;
129 static const float PosInf = 1.0 / 0.0;
130 static const float Nan = 0.0 / 0.0;
131 static const float NegNan = -0.0 / 0.0;
132 volatile float Values[] = FP_VALUE_ARRAY(NegInf, PosInf, NegNan, Nan);
133 static const size_t NumValues = sizeof(Values) / sizeof(*Values);
134 const size_t MaxTestsPerFunc = 20000;
135 for (size_t i = 0; i < MaxTestsPerFunc; ++i) {
136 // Initialize the test vectors.
137 FromType Value;
138 for (size_t j = 0; j < NumElementsInType; ++j) {
139 Value[j] = Values[Index() % NumValues];
140 }
141 COMPARE_VEC(cast, FromType, ToType, Value, FromTypeString, ToTypeString);
142 }
143 }
144
main(int argc,char * argv[])145 int main(int argc, char *argv[]) {
146 size_t TotalTests = 0;
147 size_t Passes = 0;
148 size_t Failures = 0;
149
150 volatile bool ValsUi1[] = {false, true};
151 static const size_t NumValsUi1 = sizeof(ValsUi1) / sizeof(*ValsUi1);
152 volatile uint8_t ValsUi8[] = {0, 1, 0x7e, 0x7f, 0x80, 0x81, 0xfe, 0xff};
153 static const size_t NumValsUi8 = sizeof(ValsUi8) / sizeof(*ValsUi8);
154
155 volatile myint8_t ValsSi8[] = {0, 1, 0x7e, 0x7f, 0x80, 0x81, 0xfe, 0xff};
156 static const size_t NumValsSi8 = sizeof(ValsSi8) / sizeof(*ValsSi8);
157
158 volatile uint16_t ValsUi16[] = {0, 1, 0x7e, 0x7f, 0x80,
159 0x81, 0xfe, 0xff, 0x7ffe, 0x7fff,
160 0x8000, 0x8001, 0xfffe, 0xffff};
161 static const size_t NumValsUi16 = sizeof(ValsUi16) / sizeof(*ValsUi16);
162
163 volatile int16_t ValsSi16[] = {0, 1, 0x7e, 0x7f, 0x80,
164 0x81, 0xfe, 0xff, 0x7ffe, 0x7fff,
165 0x8000, 0x8001, 0xfffe, 0xffff};
166 static const size_t NumValsSi16 = sizeof(ValsSi16) / sizeof(*ValsSi16);
167
168 volatile size_t ValsUi32[] = {0, 1, 0x7e, 0x7f,
169 0x80, 0x81, 0xfe, 0xff,
170 0x7ffe, 0x7fff, 0x8000, 0x8001,
171 0xfffe, 0xffff, 0x7ffffffe, 0x7fffffff,
172 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff};
173 static const size_t NumValsUi32 = sizeof(ValsUi32) / sizeof(*ValsUi32);
174
175 volatile size_t ValsSi32[] = {0, 1, 0x7e, 0x7f,
176 0x80, 0x81, 0xfe, 0xff,
177 0x7ffe, 0x7fff, 0x8000, 0x8001,
178 0xfffe, 0xffff, 0x7ffffffe, 0x7fffffff,
179 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff};
180 static const size_t NumValsSi32 = sizeof(ValsSi32) / sizeof(*ValsSi32);
181
182 volatile uint64 ValsUi64[] = {0,
183 1,
184 0x7e,
185 0x7f,
186 0x80,
187 0x81,
188 0xfe,
189 0xff,
190 0x7ffe,
191 0x7fff,
192 0x8000,
193 0x8001,
194 0xfffe,
195 0xffff,
196 0x7ffffffe,
197 0x7fffffff,
198 0x80000000,
199 0x80000001,
200 0xfffffffe,
201 0xffffffff,
202 0x100000000ull,
203 0x100000001ull,
204 0x7ffffffffffffffeull,
205 0x7fffffffffffffffull,
206 0x8000000000000000ull,
207 0x8000000000000001ull,
208 0xfffffffffffffffeull,
209 0xffffffffffffffffull};
210 static const size_t NumValsUi64 = sizeof(ValsUi64) / sizeof(*ValsUi64);
211
212 volatile int64 ValsSi64[] = {0,
213 1,
214 0x7e,
215 0x7f,
216 0x80,
217 0x81,
218 0xfe,
219 0xff,
220 0x7ffe,
221 0x7fff,
222 0x8000,
223 0x8001,
224 0xfffe,
225 0xffff,
226 0x7ffffffe,
227 0x7fffffff,
228 0x80000000,
229 0x80000001,
230 0xfffffffe,
231 0xffffffff,
232 0x100000000ll,
233 0x100000001ll,
234 0x7ffffffffffffffell,
235 0x7fffffffffffffffll,
236 0x8000000000000000ll,
237 0x8000000000000001ll,
238 0xfffffffffffffffell,
239 0xffffffffffffffffll};
240 static const size_t NumValsSi64 = sizeof(ValsSi64) / sizeof(*ValsSi64);
241
242 static const double NegInf = -1.0 / 0.0;
243 static const double PosInf = 1.0 / 0.0;
244 static const double Nan = 0.0 / 0.0;
245 static const double NegNan = -0.0 / 0.0;
246 volatile float ValsF32[] = FP_VALUE_ARRAY(NegInf, PosInf, NegNan, Nan);
247 static const size_t NumValsF32 = sizeof(ValsF32) / sizeof(*ValsF32);
248
249 volatile double ValsF64[] = FP_VALUE_ARRAY(NegInf, PosInf, NegNan, Nan);
250 static const size_t NumValsF64 = sizeof(ValsF64) / sizeof(*ValsF64);
251
252 for (size_t i = 0; i < NumValsUi1; ++i) {
253 bool Val = ValsUi1[i];
254 testValue<bool>(Val, TotalTests, Passes, Failures, "bool");
255 }
256 for (size_t i = 0; i < NumValsUi8; ++i) {
257 uint8_t Val = ValsUi8[i];
258 testValue<uint8_t>(Val, TotalTests, Passes, Failures, "uint8_t");
259 }
260 for (size_t i = 0; i < NumValsSi8; ++i) {
261 myint8_t Val = ValsSi8[i];
262 testValue<myint8_t>(Val, TotalTests, Passes, Failures, "int8_t");
263 }
264 for (size_t i = 0; i < NumValsUi16; ++i) {
265 uint16_t Val = ValsUi16[i];
266 testValue<uint16_t>(Val, TotalTests, Passes, Failures, "uint16_t");
267 }
268 for (size_t i = 0; i < NumValsSi16; ++i) {
269 int16_t Val = ValsSi16[i];
270 testValue<int16_t>(Val, TotalTests, Passes, Failures, "int16_t");
271 }
272 for (size_t i = 0; i < NumValsUi32; ++i) {
273 uint32_t Val = ValsUi32[i];
274 testValue<uint32_t>(Val, TotalTests, Passes, Failures, "uint32_t");
275 COMPARE(castBits, uint32_t, float, Val, "uint32_t");
276 COMPARE_ARG(castBits, uint32_t, float, Val, "uint32_t");
277 }
278 for (size_t i = 0; i < NumValsSi32; ++i) {
279 int32_t Val = ValsSi32[i];
280 testValue<int32_t>(Val, TotalTests, Passes, Failures, "int32_t");
281 }
282 for (size_t i = 0; i < NumValsUi64; ++i) {
283 uint64 Val = ValsUi64[i];
284 testValue<uint64>(Val, TotalTests, Passes, Failures, "uint64");
285 COMPARE(castBits, uint64, double, Val, "uint64");
286 COMPARE_ARG(castBits, uint64, double, Val, "uint64");
287 }
288 for (size_t i = 0; i < NumValsSi64; ++i) {
289 int64 Val = ValsSi64[i];
290 testValue<int64>(Val, TotalTests, Passes, Failures, "int64");
291 }
292 for (size_t i = 0; i < NumValsF32; ++i) {
293 for (unsigned j = 0; j < 2; ++j) {
294 float Val = ValsF32[i];
295 if (j > 0)
296 Val = -Val;
297 testValue<float>(Val, TotalTests, Passes, Failures, "float");
298 COMPARE(castBits, float, uint32_t, Val, "float");
299 COMPARE_ARG(castBits, float, uint32_t, Val, "float");
300 }
301 }
302 for (size_t i = 0; i < NumValsF64; ++i) {
303 for (unsigned j = 0; j < 2; ++j) {
304 double Val = ValsF64[i];
305 if (j > 0)
306 Val = -Val;
307 testValue<double>(Val, TotalTests, Passes, Failures, "double");
308 COMPARE(castBits, double, uint64, Val, "double");
309 COMPARE_ARG(castBits, double, uint64, Val, "double");
310 }
311 }
312
313 testVector<v4ui32, v4f32>(TotalTests, Passes, Failures, "v4ui32", "v4f32");
314 testVector<v4si32, v4f32>(TotalTests, Passes, Failures, "v4si32", "v4f32");
315 testVector<v4f32, v4si32>(TotalTests, Passes, Failures, "v4f32", "v4si32");
316 testVector<v4f32, v4ui32>(TotalTests, Passes, Failures, "v4f32", "v4ui32");
317
318 std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes
319 << " Failures=" << Failures << "\n";
320 return Failures;
321 }
322