blob: db0370947d9999585f0514988ae8b0c862f9558d [file] [log] [blame]
Matt Wala89a7c2b2014-07-22 10:55:30 -07001//===- subzero/crosstest/test_arith_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 arithmetic operations
11//
12//===----------------------------------------------------------------------===//
13
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070014/* crosstest.py --test=test_arith.cpp --test=test_arith_frem.ll \
Jan Voungf37fbbe2014-07-09 16:13:13 -070015 --test=test_arith_sqrt.ll --driver=test_arith_main.cpp \
16 --prefix=Subzero_ --output=test_arith */
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070017
18#include <stdint.h>
19
Matt Wala7fa22d82014-07-17 12:41:31 -070020#include <climits> // CHAR_BIT
21#include <limits>
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070022#include <cfloat>
Matt Wala7fa22d82014-07-17 12:41:31 -070023#include <cmath> // fmodf
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070024#include <cstring> // memcmp
25#include <iostream>
26
27// Include test_arith.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_arith.h"
John Porto1d235422015-08-12 12:37:53 -070031#include "xdefs.h"
32
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070033namespace Subzero_ {
34#include "test_arith.h"
35}
36
Matt Wala7fa22d82014-07-17 12:41:31 -070037template <class T> bool inputsMayTriggerException(T Value1, T Value2) {
38 // Avoid HW divide-by-zero exception.
39 if (Value2 == 0)
40 return true;
41 // Avoid HW overflow exception (on x86-32). TODO: adjust
42 // for other architecture.
43 if (Value1 == std::numeric_limits<T>::min() && Value2 == -1)
44 return true;
45 return false;
46}
47
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070048template <typename TypeUnsigned, typename TypeSigned>
49void testsInt(size_t &TotalTests, size_t &Passes, size_t &Failures) {
50 typedef TypeUnsigned (*FuncTypeUnsigned)(TypeUnsigned, TypeUnsigned);
51 typedef TypeSigned (*FuncTypeSigned)(TypeSigned, TypeSigned);
Matt Wala35ec3732014-07-18 16:32:16 -070052 volatile unsigned Values[] = INT_VALUE_ARRAY;
53 const static size_t NumValues = sizeof(Values) / sizeof(*Values);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070054 static struct {
Jim Stichnoth7da431b2014-08-05 11:22:37 -070055 // For functions that operate on unsigned values, the
56 // FuncLlcSigned and FuncSzSigned fields are NULL. For functions
57 // that operate on signed values, the FuncLlcUnsigned and
58 // FuncSzUnsigned fields are NULL.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070059 const char *Name;
Jim Stichnoth7da431b2014-08-05 11:22:37 -070060 FuncTypeUnsigned FuncLlcUnsigned;
61 FuncTypeUnsigned FuncSzUnsigned;
62 FuncTypeSigned FuncLlcSigned;
63 FuncTypeSigned FuncSzSigned;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070064 bool ExcludeDivExceptions; // for divide related tests
65 } Funcs[] = {
Matt Walaafeaee42014-08-07 13:47:30 -070066#define X(inst, op, isdiv, isshift) \
Jim Stichnoth7da431b2014-08-05 11:22:37 -070067 { STR(inst), test##inst, Subzero_::test##inst, NULL, NULL, isdiv } \
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070068 ,
Jim Stichnothd9dc82e2015-03-03 17:06:33 -080069 UINTOP_TABLE
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070070#undef X
Matt Walaafeaee42014-08-07 13:47:30 -070071#define X(inst, op, isdiv, isshift) \
Jim Stichnoth7da431b2014-08-05 11:22:37 -070072 { STR(inst), NULL, NULL, test##inst, Subzero_::test##inst, isdiv } \
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070073 ,
Jim Stichnothd9dc82e2015-03-03 17:06:33 -080074 SINTOP_TABLE
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070075#undef X
John Porto98cc08c2015-11-24 12:30:01 -080076#define X(mult_by) \
77 { \
78 "Mult-By-" STR(mult_by), testMultiplyBy##mult_by, \
79 Subzero_::testMultiplyBy##mult_by, NULL, NULL, false \
80 } \
81 , {"Mult-By-Neg-" STR(mult_by), testMultiplyByNeg##mult_by, \
82 Subzero_::testMultiplyByNeg##mult_by, NULL, NULL, false},
83 MULIMM_TABLE};
84#undef X
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070085 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
86
87 if (sizeof(TypeUnsigned) <= sizeof(uint32_t)) {
88 // This is the "normal" version of the loop nest, for 32-bit or
89 // narrower types.
90 for (size_t f = 0; f < NumFuncs; ++f) {
91 for (size_t i = 0; i < NumValues; ++i) {
92 for (size_t j = 0; j < NumValues; ++j) {
93 TypeUnsigned Value1 = Values[i];
94 TypeUnsigned Value2 = Values[j];
95 // Avoid HW divide-by-zero exception.
Matt Wala7fa22d82014-07-17 12:41:31 -070096 if (Funcs[f].ExcludeDivExceptions &&
97 inputsMayTriggerException<TypeSigned>(Value1, Value2))
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070098 continue;
99 ++TotalTests;
Jim Stichnoth7da431b2014-08-05 11:22:37 -0700100 TypeUnsigned ResultSz, ResultLlc;
101 if (Funcs[f].FuncSzUnsigned) {
102 ResultSz = Funcs[f].FuncSzUnsigned(Value1, Value2);
103 ResultLlc = Funcs[f].FuncLlcUnsigned(Value1, Value2);
104 } else {
105 ResultSz = Funcs[f].FuncSzSigned(Value1, Value2);
106 ResultLlc = Funcs[f].FuncLlcSigned(Value1, Value2);
107 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700108 if (ResultSz == ResultLlc) {
109 ++Passes;
110 } else {
111 ++Failures;
Matt Wala7fa22d82014-07-17 12:41:31 -0700112 std::cout << "test" << Funcs[f].Name
113 << (CHAR_BIT * sizeof(TypeUnsigned)) << "(" << Value1
114 << ", " << Value2 << "): sz=" << (unsigned)ResultSz
Jim Stichnoth7da431b2014-08-05 11:22:37 -0700115 << " llc=" << (unsigned)ResultLlc << "\n";
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700116 }
117 }
118 }
119 }
120 } else {
121 // This is the 64-bit version. Test values are synthesized from
122 // the 32-bit values in Values[].
123 for (size_t f = 0; f < NumFuncs; ++f) {
124 for (size_t iLo = 0; iLo < NumValues; ++iLo) {
125 for (size_t iHi = 0; iHi < NumValues; ++iHi) {
126 for (size_t jLo = 0; jLo < NumValues; ++jLo) {
127 for (size_t jHi = 0; jHi < NumValues; ++jHi) {
128 TypeUnsigned Value1 =
129 (((TypeUnsigned)Values[iHi]) << 32) + Values[iLo];
130 TypeUnsigned Value2 =
131 (((TypeUnsigned)Values[jHi]) << 32) + Values[jLo];
Matt Wala7fa22d82014-07-17 12:41:31 -0700132 if (Funcs[f].ExcludeDivExceptions &&
133 inputsMayTriggerException<TypeSigned>(Value1, Value2))
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700134 continue;
135 ++TotalTests;
Jim Stichnoth7da431b2014-08-05 11:22:37 -0700136 TypeUnsigned ResultSz, ResultLlc;
137 if (Funcs[f].FuncSzUnsigned) {
138 ResultSz = Funcs[f].FuncSzUnsigned(Value1, Value2);
139 ResultLlc = Funcs[f].FuncLlcUnsigned(Value1, Value2);
140 } else {
141 ResultSz = Funcs[f].FuncSzSigned(Value1, Value2);
142 ResultLlc = Funcs[f].FuncLlcSigned(Value1, Value2);
143 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700144 if (ResultSz == ResultLlc) {
145 ++Passes;
146 } else {
147 ++Failures;
148 std::cout << "test" << Funcs[f].Name
Matt Wala7fa22d82014-07-17 12:41:31 -0700149 << (CHAR_BIT * sizeof(TypeUnsigned)) << "(" << Value1
John Portoba6a67c2015-09-25 15:19:45 -0700150 << ", " << Value2 << "): sz=" << (uint64)ResultSz
151 << " llc=" << (uint64)ResultLlc << "\n";
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700152 }
153 }
154 }
155 }
156 }
157 }
158 }
159}
160
Matt Wala7fa22d82014-07-17 12:41:31 -0700161const static size_t MaxTestsPerFunc = 100000;
162
Matt Wala89a7c2b2014-07-22 10:55:30 -0700163template <typename TypeUnsignedLabel, typename TypeSignedLabel>
Matt Wala7fa22d82014-07-17 12:41:31 -0700164void testsVecInt(size_t &TotalTests, size_t &Passes, size_t &Failures) {
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800165#if !defined(ARM32) && !defined(NONSFI)
John Portoba6a67c2015-09-25 15:19:45 -0700166 // TODO(jpp): remove this once vector support is implemented.
Matt Wala89a7c2b2014-07-22 10:55:30 -0700167 typedef typename Vectors<TypeUnsignedLabel>::Ty TypeUnsigned;
168 typedef typename Vectors<TypeSignedLabel>::Ty TypeSigned;
169 typedef typename Vectors<TypeUnsignedLabel>::ElementTy ElementTypeUnsigned;
170 typedef typename Vectors<TypeSignedLabel>::ElementTy ElementTypeSigned;
171
Matt Wala7fa22d82014-07-17 12:41:31 -0700172 typedef TypeUnsigned (*FuncTypeUnsigned)(TypeUnsigned, TypeUnsigned);
173 typedef TypeSigned (*FuncTypeSigned)(TypeSigned, TypeSigned);
Matt Wala35ec3732014-07-18 16:32:16 -0700174 volatile unsigned Values[] = INT_VALUE_ARRAY;
175 const static size_t NumValues = sizeof(Values) / sizeof(*Values);
Matt Wala7fa22d82014-07-17 12:41:31 -0700176 static struct {
Jim Stichnoth7da431b2014-08-05 11:22:37 -0700177 // For functions that operate on unsigned values, the
178 // FuncLlcSigned and FuncSzSigned fields are NULL. For functions
179 // that operate on signed values, the FuncLlcUnsigned and
180 // FuncSzUnsigned fields are NULL.
Matt Wala7fa22d82014-07-17 12:41:31 -0700181 const char *Name;
Jim Stichnoth7da431b2014-08-05 11:22:37 -0700182 FuncTypeUnsigned FuncLlcUnsigned;
183 FuncTypeUnsigned FuncSzUnsigned;
184 FuncTypeSigned FuncLlcSigned;
185 FuncTypeSigned FuncSzSigned;
Matt Wala7fa22d82014-07-17 12:41:31 -0700186 bool ExcludeDivExceptions; // for divide related tests
Matt Walaafeaee42014-08-07 13:47:30 -0700187 bool MaskShiftOperations; // for shift related tests
Matt Wala7fa22d82014-07-17 12:41:31 -0700188 } Funcs[] = {
Matt Walaafeaee42014-08-07 13:47:30 -0700189#define X(inst, op, isdiv, isshift) \
Jim Stichnothdd842db2015-01-27 12:53:53 -0800190 { STR(inst), test##inst, Subzero_::test##inst, NULL, NULL, isdiv, isshift } \
Matt Wala7fa22d82014-07-17 12:41:31 -0700191 ,
Jim Stichnothd9dc82e2015-03-03 17:06:33 -0800192 UINTOP_TABLE
Matt Wala7fa22d82014-07-17 12:41:31 -0700193#undef X
Matt Walaafeaee42014-08-07 13:47:30 -0700194#define X(inst, op, isdiv, isshift) \
Jim Stichnothdd842db2015-01-27 12:53:53 -0800195 { STR(inst), NULL, NULL, test##inst, Subzero_::test##inst, isdiv, isshift } \
Matt Wala7fa22d82014-07-17 12:41:31 -0700196 ,
Jim Stichnothd9dc82e2015-03-03 17:06:33 -0800197 SINTOP_TABLE
Matt Wala7fa22d82014-07-17 12:41:31 -0700198#undef X
Jim Stichnothd9dc82e2015-03-03 17:06:33 -0800199 };
Matt Wala7fa22d82014-07-17 12:41:31 -0700200 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
Matt Wala89a7c2b2014-07-22 10:55:30 -0700201 const static size_t NumElementsInType = Vectors<TypeUnsigned>::NumElements;
Matt Wala7fa22d82014-07-17 12:41:31 -0700202 for (size_t f = 0; f < NumFuncs; ++f) {
203 PRNG Index;
204 for (size_t i = 0; i < MaxTestsPerFunc; ++i) {
205 // Initialize the test vectors.
206 TypeUnsigned Value1, Value2;
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800207 for (size_t j = 0; j < NumElementsInType; ++j) {
Matt Wala35ec3732014-07-18 16:32:16 -0700208 ElementTypeUnsigned Element1 = Values[Index() % NumValues];
209 ElementTypeUnsigned Element2 = Values[Index() % NumValues];
Matt Wala7fa22d82014-07-17 12:41:31 -0700210 if (Funcs[f].ExcludeDivExceptions &&
211 inputsMayTriggerException<ElementTypeSigned>(Element1, Element2))
212 continue;
Matt Walaafeaee42014-08-07 13:47:30 -0700213 if (Funcs[f].MaskShiftOperations)
214 Element2 &= CHAR_BIT * sizeof(ElementTypeUnsigned) - 1;
Matt Wala7fa22d82014-07-17 12:41:31 -0700215 Value1[j] = Element1;
216 Value2[j] = Element2;
Matt Wala7fa22d82014-07-17 12:41:31 -0700217 }
218 // Perform the test.
Jim Stichnoth7da431b2014-08-05 11:22:37 -0700219 TypeUnsigned ResultSz, ResultLlc;
Matt Wala7fa22d82014-07-17 12:41:31 -0700220 ++TotalTests;
Jim Stichnoth7da431b2014-08-05 11:22:37 -0700221 if (Funcs[f].FuncSzUnsigned) {
222 ResultSz = Funcs[f].FuncSzUnsigned(Value1, Value2);
223 ResultLlc = Funcs[f].FuncLlcUnsigned(Value1, Value2);
224 } else {
225 ResultSz = Funcs[f].FuncSzSigned(Value1, Value2);
226 ResultLlc = Funcs[f].FuncLlcSigned(Value1, Value2);
227 }
Matt Wala7fa22d82014-07-17 12:41:31 -0700228 if (!memcmp(&ResultSz, &ResultLlc, sizeof(ResultSz))) {
229 ++Passes;
230 } else {
Matt Wala89a7c2b2014-07-22 10:55:30 -0700231 ++Failures;
Matt Wala7fa22d82014-07-17 12:41:31 -0700232 std::cout << "test" << Funcs[f].Name << "v" << NumElementsInType << "i"
Matt Wala89a7c2b2014-07-22 10:55:30 -0700233 << (CHAR_BIT * sizeof(ElementTypeUnsigned)) << "("
234 << vectAsString<TypeUnsignedLabel>(Value1) << ","
235 << vectAsString<TypeUnsignedLabel>(Value2)
236 << "): sz=" << vectAsString<TypeUnsignedLabel>(ResultSz)
237 << " llc=" << vectAsString<TypeUnsignedLabel>(ResultLlc)
Jim Stichnoth7da431b2014-08-05 11:22:37 -0700238 << "\n";
Matt Wala7fa22d82014-07-17 12:41:31 -0700239 }
240 }
241 }
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800242#endif // !ARM32 && !NONSFI
Matt Wala7fa22d82014-07-17 12:41:31 -0700243}
244
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700245template <typename Type>
246void testsFp(size_t &TotalTests, size_t &Passes, size_t &Failures) {
247 static const Type NegInf = -1.0 / 0.0;
248 static const Type PosInf = 1.0 / 0.0;
249 static const Type Nan = 0.0 / 0.0;
Jan Voungf37fbbe2014-07-09 16:13:13 -0700250 static const Type NegNan = -0.0 / 0.0;
Matt Wala7fa22d82014-07-17 12:41:31 -0700251 volatile Type Values[] = FP_VALUE_ARRAY(NegInf, PosInf, NegNan, Nan);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700252 const static size_t NumValues = sizeof(Values) / sizeof(*Values);
253 typedef Type (*FuncType)(Type, Type);
254 static struct {
255 const char *Name;
256 FuncType FuncLlc;
257 FuncType FuncSz;
258 } Funcs[] = {
259#define X(inst, op, func) \
260 { STR(inst), (FuncType)test##inst, (FuncType)Subzero_::test##inst } \
261 ,
Jim Stichnothd9dc82e2015-03-03 17:06:33 -0800262 FPOP_TABLE
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700263#undef X
Jim Stichnothd9dc82e2015-03-03 17:06:33 -0800264 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700265 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
266
267 for (size_t f = 0; f < NumFuncs; ++f) {
268 for (size_t i = 0; i < NumValues; ++i) {
269 for (size_t j = 0; j < NumValues; ++j) {
270 Type Value1 = Values[i];
271 Type Value2 = Values[j];
272 ++TotalTests;
273 Type ResultSz = Funcs[f].FuncSz(Value1, Value2);
274 Type ResultLlc = Funcs[f].FuncLlc(Value1, Value2);
275 // Compare results using memcmp() in case they are both NaN.
276 if (!memcmp(&ResultSz, &ResultLlc, sizeof(Type))) {
277 ++Passes;
278 } else {
279 ++Failures;
280 std::cout << std::fixed << "test" << Funcs[f].Name
Matt Wala7fa22d82014-07-17 12:41:31 -0700281 << (CHAR_BIT * sizeof(Type)) << "(" << Value1 << ", "
282 << Value2 << "): sz=" << ResultSz << " llc=" << ResultLlc
Jim Stichnoth7da431b2014-08-05 11:22:37 -0700283 << "\n";
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700284 }
285 }
286 }
287 }
Jan Voungf37fbbe2014-07-09 16:13:13 -0700288 for (size_t i = 0; i < NumValues; ++i) {
289 Type Value = Values[i];
290 ++TotalTests;
291 Type ResultSz = Subzero_::mySqrt(Value);
292 Type ResultLlc = mySqrt(Value);
293 // Compare results using memcmp() in case they are both NaN.
294 if (!memcmp(&ResultSz, &ResultLlc, sizeof(Type))) {
295 ++Passes;
296 } else {
297 ++Failures;
Matt Wala7fa22d82014-07-17 12:41:31 -0700298 std::cout << std::fixed << "test_sqrt" << (CHAR_BIT * sizeof(Type)) << "("
299 << Value << "): sz=" << ResultSz << " llc=" << ResultLlc
Jim Stichnoth7da431b2014-08-05 11:22:37 -0700300 << "\n";
Jan Voungf37fbbe2014-07-09 16:13:13 -0700301 }
Jim Stichnoth8c980d02015-03-19 13:01:50 -0700302 ++TotalTests;
303 ResultSz = Subzero_::myFabs(Value);
304 ResultLlc = myFabs(Value);
305 // Compare results using memcmp() in case they are both NaN.
306 if (!memcmp(&ResultSz, &ResultLlc, sizeof(Type))) {
307 ++Passes;
308 } else {
309 ++Failures;
310 std::cout << std::fixed << "test_fabs" << (CHAR_BIT * sizeof(Type)) << "("
311 << Value << "): sz=" << ResultSz << " llc=" << ResultLlc
312 << "\n";
313 }
Jan Voungf37fbbe2014-07-09 16:13:13 -0700314 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700315}
316
Matt Wala7fa22d82014-07-17 12:41:31 -0700317void testsVecFp(size_t &TotalTests, size_t &Passes, size_t &Failures) {
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800318#if !defined(ARM32) && !defined(NONSFI)
John Portoba6a67c2015-09-25 15:19:45 -0700319 // TODO(jpp): remove this once vector support is implemented.
Matt Wala7fa22d82014-07-17 12:41:31 -0700320 static const float NegInf = -1.0 / 0.0;
321 static const float PosInf = 1.0 / 0.0;
322 static const float Nan = 0.0 / 0.0;
323 static const float NegNan = -0.0 / 0.0;
324 volatile float Values[] = FP_VALUE_ARRAY(NegInf, PosInf, NegNan, Nan);
325 const static size_t NumValues = sizeof(Values) / sizeof(*Values);
326 typedef v4f32 (*FuncType)(v4f32, v4f32);
327 static struct {
328 const char *Name;
329 FuncType FuncLlc;
330 FuncType FuncSz;
331 } Funcs[] = {
332#define X(inst, op, func) \
333 { STR(inst), (FuncType)test##inst, (FuncType)Subzero_::test##inst } \
334 ,
Jim Stichnothd9dc82e2015-03-03 17:06:33 -0800335 FPOP_TABLE
Matt Wala7fa22d82014-07-17 12:41:31 -0700336#undef X
Jim Stichnothd9dc82e2015-03-03 17:06:33 -0800337 };
Matt Wala7fa22d82014-07-17 12:41:31 -0700338 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
339 const static size_t NumElementsInType = 4;
340 for (size_t f = 0; f < NumFuncs; ++f) {
341 PRNG Index;
342 for (size_t i = 0; i < MaxTestsPerFunc; ++i) {
343 // Initialize the test vectors.
344 v4f32 Value1, Value2;
345 for (size_t j = 0; j < NumElementsInType; ++j) {
Matt Wala35ec3732014-07-18 16:32:16 -0700346 Value1[j] = Values[Index() % NumValues];
347 Value2[j] = Values[Index() % NumValues];
Matt Wala7fa22d82014-07-17 12:41:31 -0700348 }
349 // Perform the test.
350 v4f32 ResultSz = Funcs[f].FuncSz(Value1, Value2);
351 v4f32 ResultLlc = Funcs[f].FuncLlc(Value1, Value2);
352 ++TotalTests;
353 if (!memcmp(&ResultSz, &ResultLlc, sizeof(ResultSz))) {
354 ++Passes;
355 } else {
356 ++Failures;
Matt Wala89a7c2b2014-07-22 10:55:30 -0700357 std::cout << "test" << Funcs[f].Name << "v4f32"
358 << "(" << vectAsString<v4f32>(Value1) << ","
359 << vectAsString<v4f32>(Value2)
360 << "): sz=" << vectAsString<v4f32>(ResultSz) << " llc"
Jim Stichnoth7da431b2014-08-05 11:22:37 -0700361 << vectAsString<v4f32>(ResultLlc) << "\n";
Matt Wala7fa22d82014-07-17 12:41:31 -0700362 }
Jim Stichnoth8c980d02015-03-19 13:01:50 -0700363 // Special case for unary fabs operation. Use Value1, ignore Value2.
364 ResultSz = Subzero_::myFabs(Value1);
365 ResultLlc = myFabs(Value1);
366 ++TotalTests;
367 if (!memcmp(&ResultSz, &ResultLlc, sizeof(ResultSz))) {
368 ++Passes;
369 } else {
370 ++Failures;
371 std::cout << "test_fabs_v4f32"
372 << "(" << vectAsString<v4f32>(Value1)
373 << "): sz=" << vectAsString<v4f32>(ResultSz) << " llc"
374 << vectAsString<v4f32>(ResultLlc) << "\n";
375 }
Matt Wala7fa22d82014-07-17 12:41:31 -0700376 }
377 }
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800378#endif // !ARM32 && !NONSFI
Matt Wala7fa22d82014-07-17 12:41:31 -0700379}
380
John Porto1d235422015-08-12 12:37:53 -0700381#ifdef X8664_STACK_HACK
382extern "C" int wrapped_main(int argc, char *argv[]) {
383#else // !defined(X8664_STACK_HACK)
384int main(int argc, char *argv[]) {
385#endif // X8664_STACK_HACK
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700386 size_t TotalTests = 0;
387 size_t Passes = 0;
388 size_t Failures = 0;
389
Jim Stichnoth3ef786f2014-09-08 11:19:21 -0700390 testsInt<bool, bool>(TotalTests, Passes, Failures);
Jim Stichnoth7da431b2014-08-05 11:22:37 -0700391 testsInt<uint8_t, myint8_t>(TotalTests, Passes, Failures);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700392 testsInt<uint16_t, int16_t>(TotalTests, Passes, Failures);
393 testsInt<uint32_t, int32_t>(TotalTests, Passes, Failures);
John Porto1d235422015-08-12 12:37:53 -0700394 testsInt<uint64, int64>(TotalTests, Passes, Failures);
Matt Wala89a7c2b2014-07-22 10:55:30 -0700395 testsVecInt<v4ui32, v4si32>(TotalTests, Passes, Failures);
396 testsVecInt<v8ui16, v8si16>(TotalTests, Passes, Failures);
397 testsVecInt<v16ui8, v16si8>(TotalTests, Passes, Failures);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700398 testsFp<float>(TotalTests, Passes, Failures);
399 testsFp<double>(TotalTests, Passes, Failures);
Matt Wala7fa22d82014-07-17 12:41:31 -0700400 testsVecFp(TotalTests, Passes, Failures);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700401
402 std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes
403 << " Failures=" << Failures << "\n";
404 return Failures;
405}