Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(35)

Side by Side Diff: crosstest/test_arith_main.cpp

Issue 397833002: Lower the rest of the vector arithmetic operations. (Closed) Base URL: https://gerrit.chromium.org/gerrit/p/native_client/pnacl-subzero.git@master
Patch Set: Rebase Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « crosstest/test_arith_frem.ll ('k') | src/IceInstX8632.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* crosstest.py --test=test_arith.cpp --test=test_arith_frem.ll \ 1 /* crosstest.py --test=test_arith.cpp --test=test_arith_frem.ll \
2 --test=test_arith_sqrt.ll --driver=test_arith_main.cpp \ 2 --test=test_arith_sqrt.ll --driver=test_arith_main.cpp \
3 --prefix=Subzero_ --output=test_arith */ 3 --prefix=Subzero_ --output=test_arith */
4 4
5 #include <stdint.h> 5 #include <stdint.h>
6 6
7 #include <climits> // CHAR_BIT
8 #include <limits>
7 #include <cfloat> 9 #include <cfloat>
10 #include <cmath> // fmodf
8 #include <cstring> // memcmp 11 #include <cstring> // memcmp
9 #include <iostream> 12 #include <iostream>
10 13
11 // Include test_arith.h twice - once normally, and once within the 14 // Include test_arith.h twice - once normally, and once within the
12 // Subzero_ namespace, corresponding to the llc and Subzero translated 15 // Subzero_ namespace, corresponding to the llc and Subzero translated
13 // object files, respectively. 16 // object files, respectively.
14 #include "test_arith.h" 17 #include "test_arith.h"
15 namespace Subzero_ { 18 namespace Subzero_ {
16 #include "test_arith.h" 19 #include "test_arith.h"
17 } 20 }
18 21
19 volatile unsigned Values[] = { 0x0, 0x1, 0x7ffffffe, 0x7fffffff, 22 volatile unsigned Values[] = INT_VALUE_ARRAY;
20 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff,
21 0x7e, 0x7f, 0x80, 0x81,
22 0xfe, 0xff, 0x100, 0x101,
23 0x7ffe, 0x7fff, 0x8000, 0x8001,
24 0xfffe, 0xffff, 0x10000, 0x10001, };
25 const static size_t NumValues = sizeof(Values) / sizeof(*Values); 23 const static size_t NumValues = sizeof(Values) / sizeof(*Values);
26 24
25 template <class T> bool inputsMayTriggerException(T Value1, T Value2) {
26 // Avoid HW divide-by-zero exception.
27 if (Value2 == 0)
28 return true;
29 // Avoid HW overflow exception (on x86-32). TODO: adjust
30 // for other architecture.
31 if (Value1 == std::numeric_limits<T>::min() && Value2 == -1)
32 return true;
33 return false;
34 }
35
27 template <typename TypeUnsigned, typename TypeSigned> 36 template <typename TypeUnsigned, typename TypeSigned>
28 void testsInt(size_t &TotalTests, size_t &Passes, size_t &Failures) { 37 void testsInt(size_t &TotalTests, size_t &Passes, size_t &Failures) {
29 typedef TypeUnsigned (*FuncTypeUnsigned)(TypeUnsigned, TypeUnsigned); 38 typedef TypeUnsigned (*FuncTypeUnsigned)(TypeUnsigned, TypeUnsigned);
30 typedef TypeSigned (*FuncTypeSigned)(TypeSigned, TypeSigned); 39 typedef TypeSigned (*FuncTypeSigned)(TypeSigned, TypeSigned);
31 static struct { 40 static struct {
32 const char *Name; 41 const char *Name;
33 FuncTypeUnsigned FuncLlc; 42 FuncTypeUnsigned FuncLlc;
34 FuncTypeUnsigned FuncSz; 43 FuncTypeUnsigned FuncSz;
35 bool ExcludeDivExceptions; // for divide related tests 44 bool ExcludeDivExceptions; // for divide related tests
36 } Funcs[] = { 45 } Funcs[] = {
37 #define X(inst, op, isdiv) \ 46 #define X(inst, op, isdiv) \
38 { \ 47 { \
39 STR(inst), (FuncTypeUnsigned)test##inst, \ 48 STR(inst), (FuncTypeUnsigned)test##inst, \
40 (FuncTypeUnsigned)Subzero_::test##inst, isdiv \ 49 (FuncTypeUnsigned)Subzero_::test##inst, isdiv \
41 } \ 50 } \
42 , 51 ,
43 UINTOP_TABLE 52 UINTOP_TABLE
44 #undef X 53 #undef X
45 #define X(inst, op, isdiv) \ 54 #define X(inst, op, isdiv) \
46 { \ 55 { \
47 STR(inst), (FuncTypeUnsigned)(FuncTypeSigned)test##inst, \ 56 STR(inst), (FuncTypeUnsigned)(FuncTypeSigned)test##inst, \
48 (FuncTypeUnsigned)(FuncTypeSigned)Subzero_::test##inst, isdiv \ 57 (FuncTypeUnsigned)(FuncTypeSigned)Subzero_::test##inst, isdiv \
49 } \ 58 } \
50 , 59 ,
51 SINTOP_TABLE 60 SINTOP_TABLE
52 #undef X 61 #undef X
53 }; 62 };
54 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs); 63 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
55 64
56 if (sizeof(TypeUnsigned) <= sizeof(uint32_t)) { 65 if (sizeof(TypeUnsigned) <= sizeof(uint32_t)) {
57 // This is the "normal" version of the loop nest, for 32-bit or 66 // This is the "normal" version of the loop nest, for 32-bit or
58 // narrower types. 67 // narrower types.
59 for (size_t f = 0; f < NumFuncs; ++f) { 68 for (size_t f = 0; f < NumFuncs; ++f) {
60 for (size_t i = 0; i < NumValues; ++i) { 69 for (size_t i = 0; i < NumValues; ++i) {
61 for (size_t j = 0; j < NumValues; ++j) { 70 for (size_t j = 0; j < NumValues; ++j) {
62 TypeUnsigned Value1 = Values[i]; 71 TypeUnsigned Value1 = Values[i];
63 TypeUnsigned Value2 = Values[j]; 72 TypeUnsigned Value2 = Values[j];
64 // Avoid HW divide-by-zero exception. 73 // Avoid HW divide-by-zero exception.
65 if (Funcs[f].ExcludeDivExceptions && Value2 == 0) 74 if (Funcs[f].ExcludeDivExceptions &&
66 continue; 75 inputsMayTriggerException<TypeSigned>(Value1, Value2))
67 // Avoid HW overflow exception (on x86-32). TODO: adjust
68 // for other architectures.
69 if (Funcs[f].ExcludeDivExceptions && Value1 == 0x80000000 &&
70 Value2 == 0xffffffff)
71 continue; 76 continue;
72 ++TotalTests; 77 ++TotalTests;
73 TypeUnsigned ResultSz = Funcs[f].FuncSz(Value1, Value2); 78 TypeUnsigned ResultSz = Funcs[f].FuncSz(Value1, Value2);
74 TypeUnsigned ResultLlc = Funcs[f].FuncLlc(Value1, Value2); 79 TypeUnsigned ResultLlc = Funcs[f].FuncLlc(Value1, Value2);
75 if (ResultSz == ResultLlc) { 80 if (ResultSz == ResultLlc) {
76 ++Passes; 81 ++Passes;
77 } else { 82 } else {
78 ++Failures; 83 ++Failures;
79 std::cout << "test" << Funcs[f].Name << (8 * sizeof(TypeUnsigned)) 84 std::cout << "test" << Funcs[f].Name
80 << "(" << Value1 << ", " << Value2 85 << (CHAR_BIT * sizeof(TypeUnsigned)) << "(" << Value1
81 << "): sz=" << (unsigned)ResultSz 86 << ", " << Value2 << "): sz=" << (unsigned)ResultSz
82 << " llc=" << (unsigned)ResultLlc << std::endl; 87 << " llc=" << (unsigned)ResultLlc << std::endl;
83 } 88 }
84 } 89 }
85 } 90 }
86 } 91 }
87 } else { 92 } else {
88 // This is the 64-bit version. Test values are synthesized from 93 // This is the 64-bit version. Test values are synthesized from
89 // the 32-bit values in Values[]. 94 // the 32-bit values in Values[].
90 for (size_t f = 0; f < NumFuncs; ++f) { 95 for (size_t f = 0; f < NumFuncs; ++f) {
91 for (size_t iLo = 0; iLo < NumValues; ++iLo) { 96 for (size_t iLo = 0; iLo < NumValues; ++iLo) {
92 for (size_t iHi = 0; iHi < NumValues; ++iHi) { 97 for (size_t iHi = 0; iHi < NumValues; ++iHi) {
93 for (size_t jLo = 0; jLo < NumValues; ++jLo) { 98 for (size_t jLo = 0; jLo < NumValues; ++jLo) {
94 for (size_t jHi = 0; jHi < NumValues; ++jHi) { 99 for (size_t jHi = 0; jHi < NumValues; ++jHi) {
95 TypeUnsigned Value1 = 100 TypeUnsigned Value1 =
96 (((TypeUnsigned)Values[iHi]) << 32) + Values[iLo]; 101 (((TypeUnsigned)Values[iHi]) << 32) + Values[iLo];
97 TypeUnsigned Value2 = 102 TypeUnsigned Value2 =
98 (((TypeUnsigned)Values[jHi]) << 32) + Values[jLo]; 103 (((TypeUnsigned)Values[jHi]) << 32) + Values[jLo];
99 // Avoid HW divide-by-zero exception. 104 if (Funcs[f].ExcludeDivExceptions &&
100 if (Funcs[f].ExcludeDivExceptions && Value2 == 0) 105 inputsMayTriggerException<TypeSigned>(Value1, Value2))
101 continue; 106 continue;
102 ++TotalTests; 107 ++TotalTests;
103 TypeUnsigned ResultSz = Funcs[f].FuncSz(Value1, Value2); 108 TypeUnsigned ResultSz = Funcs[f].FuncSz(Value1, Value2);
104 TypeUnsigned ResultLlc = Funcs[f].FuncLlc(Value1, Value2); 109 TypeUnsigned ResultLlc = Funcs[f].FuncLlc(Value1, Value2);
105 if (ResultSz == ResultLlc) { 110 if (ResultSz == ResultLlc) {
106 ++Passes; 111 ++Passes;
107 } else { 112 } else {
108 ++Failures; 113 ++Failures;
109 std::cout << "test" << Funcs[f].Name 114 std::cout << "test" << Funcs[f].Name
110 << (8 * sizeof(TypeUnsigned)) << "(" << Value1 << ", " 115 << (CHAR_BIT * sizeof(TypeUnsigned)) << "(" << Value1
111 << Value2 << "): sz=" << (unsigned)ResultSz 116 << ", " << Value2 << "): sz=" << (unsigned)ResultSz
112 << " llc=" << (unsigned)ResultLlc << std::endl; 117 << " llc=" << (unsigned)ResultLlc << std::endl;
113 } 118 }
114 } 119 }
115 } 120 }
116 } 121 }
117 } 122 }
118 } 123 }
119 } 124 }
120 } 125 }
121 126
127 // Vectors are deterministically constructed by selecting elements from
128 // a pool of scalar values based on a pseudorandom sequence. Testing
129 // all possible combinations of scalar values from the value table is
130 // not tractable.
131 // TODO: Replace with a portable PRNG from C++11.
132 class PRNG {
133 public:
134 PRNG(uint32_t Seed = 1) : State(Seed) {}
135
136 uint32_t operator()() {
137 // Lewis, Goodman, and Miller (1969)
138 State = (16807 * State) % 2147483647;
139 return State;
140 }
141
142 private:
143 uint32_t State;
144 };
145
146 const static size_t MaxTestsPerFunc = 100000;
147
148 template <typename Type, typename ElementType, typename CastType>
149 void outputVector(const Type Vect) {
150 const static size_t NumElementsInType = sizeof(Type) / sizeof(ElementType);
151 for (size_t i = 0; i < NumElementsInType; ++i) {
152 if (i > 0)
153 std::cout << ", ";
154 std::cout << (CastType) Vect[i];
155 }
156 }
157
158 template <typename TypeUnsigned, typename TypeSigned,
159 typename ElementTypeUnsigned, typename ElementTypeSigned>
160 void testsVecInt(size_t &TotalTests, size_t &Passes, size_t &Failures) {
161 typedef TypeUnsigned (*FuncTypeUnsigned)(TypeUnsigned, TypeUnsigned);
162 typedef TypeSigned (*FuncTypeSigned)(TypeSigned, TypeSigned);
163 static struct {
164 const char *Name;
165 FuncTypeUnsigned FuncLlc;
166 FuncTypeUnsigned FuncSz;
167 bool ExcludeDivExceptions; // for divide related tests
168 } Funcs[] = {
169 #define X(inst, op, isdiv) \
170 { \
171 STR(inst), (FuncTypeUnsigned)test##inst, \
172 (FuncTypeUnsigned)Subzero_::test##inst, isdiv \
173 } \
174 ,
175 UINTOP_TABLE
176 #undef X
177 #define X(inst, op, isdiv) \
178 { \
179 STR(inst), (FuncTypeUnsigned)(FuncTypeSigned)test##inst, \
180 (FuncTypeUnsigned)(FuncTypeSigned)Subzero_::test##inst, isdiv \
181 } \
182 ,
183 SINTOP_TABLE
184 #undef X
185 };
186 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
187 const static size_t NumElementsInType =
188 sizeof(TypeUnsigned) / sizeof(ElementTypeUnsigned);
189 for (size_t f = 0; f < NumFuncs; ++f) {
190 PRNG Index;
191 for (size_t i = 0; i < MaxTestsPerFunc; ++i) {
192 // Initialize the test vectors.
193 TypeUnsigned Value1, Value2;
194 for (size_t j = 0; j < NumElementsInType;) {
195 ElementTypeUnsigned Element1 = Values[Index() % NumElementsInType];
196 ElementTypeUnsigned Element2 = Values[Index() % NumElementsInType];
197 if (Funcs[f].ExcludeDivExceptions &&
198 inputsMayTriggerException<ElementTypeSigned>(Element1, Element2))
199 continue;
200 Value1[j] = Element1;
201 Value2[j] = Element2;
202 ++j;
203 }
204 // Perform the test.
205 TypeUnsigned ResultSz = Funcs[f].FuncSz(Value1, Value2);
206 TypeUnsigned ResultLlc = Funcs[f].FuncLlc(Value1, Value2);
207 ++TotalTests;
208 if (!memcmp(&ResultSz, &ResultLlc, sizeof(ResultSz))) {
209 ++Passes;
210 } else {
211 std::cout << "test" << Funcs[f].Name << "v" << NumElementsInType << "i"
212 << (CHAR_BIT * sizeof(ElementTypeUnsigned)) << "(";
213 outputVector<TypeUnsigned, ElementTypeUnsigned, unsigned>(Value1);
214 std::cout << ", ";
215 outputVector<TypeUnsigned, ElementTypeUnsigned, unsigned>(Value2);
216 std::cout << "): sz=";
217 outputVector<TypeUnsigned, ElementTypeUnsigned, unsigned>(ResultSz);
218 std::cout << " llc=";
219 outputVector<TypeUnsigned, ElementTypeUnsigned, unsigned>(ResultLlc);
220 std::cout << std::endl;
221 }
222 }
223 }
224 }
225
122 template <typename Type> 226 template <typename Type>
123 void testsFp(size_t &TotalTests, size_t &Passes, size_t &Failures) { 227 void testsFp(size_t &TotalTests, size_t &Passes, size_t &Failures) {
124 static const Type NegInf = -1.0 / 0.0; 228 static const Type NegInf = -1.0 / 0.0;
125 static const Type PosInf = 1.0 / 0.0; 229 static const Type PosInf = 1.0 / 0.0;
126 static const Type Nan = 0.0 / 0.0; 230 static const Type Nan = 0.0 / 0.0;
127 static const Type NegNan = -0.0 / 0.0; 231 static const Type NegNan = -0.0 / 0.0;
128 volatile Type Values[] = { 232 volatile Type Values[] = FP_VALUE_ARRAY(NegInf, PosInf, NegNan, Nan);
129 0, 1, 0x7e,
130 0x7f, 0x80, 0x81,
131 0xfe, 0xff, 0x7ffe,
132 0x7fff, 0x8000, 0x8001,
133 0xfffe, 0xffff, 0x7ffffffe,
134 0x7fffffff, 0x80000000, 0x80000001,
135 0xfffffffe, 0xffffffff, 0x100000000ll,
136 0x100000001ll, 0x7ffffffffffffffell, 0x7fffffffffffffffll,
137 0x8000000000000000ll, 0x8000000000000001ll, 0xfffffffffffffffell,
138 0xffffffffffffffffll, NegInf, PosInf,
139 Nan, NegNan, -0.0,
140 FLT_MIN, FLT_MAX,
141 DBL_MIN, DBL_MAX
142 };
143 const static size_t NumValues = sizeof(Values) / sizeof(*Values); 233 const static size_t NumValues = sizeof(Values) / sizeof(*Values);
144 typedef Type (*FuncType)(Type, Type); 234 typedef Type (*FuncType)(Type, Type);
145 static struct { 235 static struct {
146 const char *Name; 236 const char *Name;
147 FuncType FuncLlc; 237 FuncType FuncLlc;
148 FuncType FuncSz; 238 FuncType FuncSz;
149 } Funcs[] = { 239 } Funcs[] = {
150 #define X(inst, op, func) \ 240 #define X(inst, op, func) \
151 { STR(inst), (FuncType)test##inst, (FuncType)Subzero_::test##inst } \ 241 { STR(inst), (FuncType)test##inst, (FuncType)Subzero_::test##inst } \
152 , 242 ,
153 FPOP_TABLE 243 FPOP_TABLE
154 #undef X 244 #undef X
155 }; 245 };
156 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs); 246 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
157 247
158 for (size_t f = 0; f < NumFuncs; ++f) { 248 for (size_t f = 0; f < NumFuncs; ++f) {
159 for (size_t i = 0; i < NumValues; ++i) { 249 for (size_t i = 0; i < NumValues; ++i) {
160 for (size_t j = 0; j < NumValues; ++j) { 250 for (size_t j = 0; j < NumValues; ++j) {
161 Type Value1 = Values[i]; 251 Type Value1 = Values[i];
162 Type Value2 = Values[j]; 252 Type Value2 = Values[j];
163 ++TotalTests; 253 ++TotalTests;
164 Type ResultSz = Funcs[f].FuncSz(Value1, Value2); 254 Type ResultSz = Funcs[f].FuncSz(Value1, Value2);
165 Type ResultLlc = Funcs[f].FuncLlc(Value1, Value2); 255 Type ResultLlc = Funcs[f].FuncLlc(Value1, Value2);
166 // Compare results using memcmp() in case they are both NaN. 256 // Compare results using memcmp() in case they are both NaN.
167 if (!memcmp(&ResultSz, &ResultLlc, sizeof(Type))) { 257 if (!memcmp(&ResultSz, &ResultLlc, sizeof(Type))) {
168 ++Passes; 258 ++Passes;
169 } else { 259 } else {
170 ++Failures; 260 ++Failures;
171 std::cout << std::fixed << "test" << Funcs[f].Name 261 std::cout << std::fixed << "test" << Funcs[f].Name
172 << (8 * sizeof(Type)) << "(" << Value1 << ", " << Value2 262 << (CHAR_BIT * sizeof(Type)) << "(" << Value1 << ", "
173 << "): sz=" << ResultSz << " llc=" << ResultLlc 263 << Value2 << "): sz=" << ResultSz << " llc=" << ResultLlc
174 << std::endl; 264 << std::endl;
175 } 265 }
176 } 266 }
177 } 267 }
178 } 268 }
179 for (size_t i = 0; i < NumValues; ++i) { 269 for (size_t i = 0; i < NumValues; ++i) {
180 Type Value = Values[i]; 270 Type Value = Values[i];
181 ++TotalTests; 271 ++TotalTests;
182 Type ResultSz = Subzero_::mySqrt(Value); 272 Type ResultSz = Subzero_::mySqrt(Value);
183 Type ResultLlc = mySqrt(Value); 273 Type ResultLlc = mySqrt(Value);
184 // Compare results using memcmp() in case they are both NaN. 274 // Compare results using memcmp() in case they are both NaN.
185 if (!memcmp(&ResultSz, &ResultLlc, sizeof(Type))) { 275 if (!memcmp(&ResultSz, &ResultLlc, sizeof(Type))) {
186 ++Passes; 276 ++Passes;
187 } else { 277 } else {
188 ++Failures; 278 ++Failures;
189 std::cout << std::fixed << "test_sqrt" 279 std::cout << std::fixed << "test_sqrt" << (CHAR_BIT * sizeof(Type)) << "("
190 << (8 * sizeof(Type)) << "(" << Value 280 << Value << "): sz=" << ResultSz << " llc=" << ResultLlc
191 << "): sz=" << ResultSz << " llc=" << ResultLlc
192 << std::endl; 281 << std::endl;
193 } 282 }
194 } 283 }
195 } 284 }
196 285
286 void testsVecFp(size_t &TotalTests, size_t &Passes, size_t &Failures) {
287 static const float NegInf = -1.0 / 0.0;
288 static const float PosInf = 1.0 / 0.0;
289 static const float Nan = 0.0 / 0.0;
290 static const float NegNan = -0.0 / 0.0;
291 volatile float Values[] = FP_VALUE_ARRAY(NegInf, PosInf, NegNan, Nan);
292 const static size_t NumValues = sizeof(Values) / sizeof(*Values);
293 typedef v4f32 (*FuncType)(v4f32, v4f32);
294 static struct {
295 const char *Name;
296 FuncType FuncLlc;
297 FuncType FuncSz;
298 } Funcs[] = {
299 #define X(inst, op, func) \
300 { STR(inst), (FuncType)test##inst, (FuncType)Subzero_::test##inst } \
301 ,
302 FPOP_TABLE
303 #undef X
304 };
305 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
306 const static size_t NumElementsInType = 4;
307 for (size_t f = 0; f < NumFuncs; ++f) {
308 PRNG Index;
309 for (size_t i = 0; i < MaxTestsPerFunc; ++i) {
310 // Initialize the test vectors.
311 v4f32 Value1, Value2;
312 for (size_t j = 0; j < NumElementsInType; ++j) {
313 Value1[j] = Values[Index() % NumElementsInType];
314 Value2[j] = Values[Index() % NumElementsInType];
315 }
316 // Perform the test.
317 v4f32 ResultSz = Funcs[f].FuncSz(Value1, Value2);
318 v4f32 ResultLlc = Funcs[f].FuncLlc(Value1, Value2);
319 ++TotalTests;
320 if (!memcmp(&ResultSz, &ResultLlc, sizeof(ResultSz))) {
321 ++Passes;
322 } else {
323 ++Failures;
324 std::cout << std::fixed << "test" << Funcs[f].Name << "v4f32"
325 << "(";
326 outputVector<v4f32, float, float>(Value1);
327 std::cout << ", ";
328 outputVector<v4f32, float, float>(Value2);
329 std::cout << "): sz=";
330 outputVector<v4f32, float, float>(ResultSz);
331 std::cout << " llc=";
332 outputVector<v4f32, float, float>(ResultLlc);
333 std::cout << std::endl;
334 }
335 }
336 }
337 }
338
197 int main(int argc, char **argv) { 339 int main(int argc, char **argv) {
198 size_t TotalTests = 0; 340 size_t TotalTests = 0;
199 size_t Passes = 0; 341 size_t Passes = 0;
200 size_t Failures = 0; 342 size_t Failures = 0;
201 343
202 testsInt<uint8_t, int8_t>(TotalTests, Passes, Failures); 344 testsInt<uint8_t, int8_t>(TotalTests, Passes, Failures);
203 testsInt<uint16_t, int16_t>(TotalTests, Passes, Failures); 345 testsInt<uint16_t, int16_t>(TotalTests, Passes, Failures);
204 testsInt<uint32_t, int32_t>(TotalTests, Passes, Failures); 346 testsInt<uint32_t, int32_t>(TotalTests, Passes, Failures);
205 testsInt<uint64_t, int64_t>(TotalTests, Passes, Failures); 347 testsInt<uint64_t, int64_t>(TotalTests, Passes, Failures);
348 testsVecInt<v4ui32, v4si32, uint32_t, int32_t>(TotalTests, Passes, Failures);
349 testsVecInt<v8ui16, v8si16, uint16_t, int16_t>(TotalTests, Passes, Failures);
350 testsVecInt<v16ui8, v16si8, uint8_t, int8_t>(TotalTests, Passes, Failures);
206 testsFp<float>(TotalTests, Passes, Failures); 351 testsFp<float>(TotalTests, Passes, Failures);
207 testsFp<double>(TotalTests, Passes, Failures); 352 testsFp<double>(TotalTests, Passes, Failures);
353 testsVecFp(TotalTests, Passes, Failures);
208 354
209 std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes 355 std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes
210 << " Failures=" << Failures << "\n"; 356 << " Failures=" << Failures << "\n";
211 return Failures; 357 return Failures;
212 } 358 }
359
360 extern "C" {
361 // Subzero helpers
362 v4si32 Sz_shl_v4i32(v4si32 a, v4si32 b) { return a << b; }
363 v4si32 Sz_ashr_v4i32(v4si32 a, v4si32 b) { return a >> b; }
364 v4ui32 Sz_lshr_v4i32(v4ui32 a, v4ui32 b) { return a >> b; }
365 v4si32 Sz_sdiv_v4i32(v4si32 a, v4si32 b) { return a / b; }
366 v4ui32 Sz_udiv_v4i32(v4ui32 a, v4ui32 b) { return a / b; }
367 v4si32 Sz_srem_v4i32(v4si32 a, v4si32 b) { return a % b; }
368 v4ui32 Sz_urem_v4i32(v4ui32 a, v4ui32 b) { return a % b; }
369
370 v8si16 Sz_shl_v8i16(v8si16 a, v8si16 b) { return a << b; }
371 v8si16 Sz_ashr_v8i16(v8si16 a, v8si16 b) { return a >> b; }
372 v8ui16 Sz_lshr_v8i16(v8ui16 a, v8ui16 b) { return a >> b; }
373 v8si16 Sz_sdiv_v8i16(v8si16 a, v8si16 b) { return a / b; }
374 v8ui16 Sz_udiv_v8i16(v8ui16 a, v8ui16 b) { return a / b; }
375 v8si16 Sz_srem_v8i16(v8si16 a, v8si16 b) { return a % b; }
376 v8ui16 Sz_urem_v8i16(v8ui16 a, v8ui16 b) { return a % b; }
377
378 v16ui8 Sz_mul_v16i8(v16ui8 a, v16ui8 b) { return a * b; }
379 v16si8 Sz_shl_v16i8(v16si8 a, v16si8 b) { return a << b; }
380 v16si8 Sz_ashr_v16i8(v16si8 a, v16si8 b) { return a >> b; }
381 v16ui8 Sz_lshr_v16i8(v16ui8 a, v16ui8 b) { return a >> b; }
382 v16si8 Sz_sdiv_v16i8(v16si8 a, v16si8 b) { return a / b; }
383 v16ui8 Sz_udiv_v16i8(v16ui8 a, v16ui8 b) { return a / b; }
384 v16si8 Sz_srem_v16i8(v16si8 a, v16si8 b) { return a % b; }
385 v16ui8 Sz_urem_v16i8(v16ui8 a, v16ui8 b) { return a % b; }
386
387 v4f32 Sz_frem_v4f32(v4f32 a, v4f32 b) {
388 v4f32 Result;
389 for (int i = 0; i < 4; ++i)
390 Result[i] = fmodf(a[i], b[i]);
391 return Result;
392 }
393 }
OLDNEW
« no previous file with comments | « crosstest/test_arith_frem.ll ('k') | src/IceInstX8632.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698