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

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: Format crosstest.py 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
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[] = {
(...skipping 18 matching lines...) Expand all
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 // TODO: Replace with a portable PRNG from C++11.
Jim Stichnoth 2014/07/16 19:17:10 It would be good to have a comment explaining that
wala 2014/07/17 01:34:53 Adding a comment: Done. The current size of the i
Jim Stichnoth 2014/07/17 13:03:13 Ah yes - I was forgetting that extra ^2 in my calc
128 class PRNG {
129 public:
130 PRNG(uint32_t Seed = 1) : State(Seed) {}
131
132 uint32_t operator()() {
133 // Lewis, Goodman, and Miller (1969)
134 State = (16807 * State) % 2147483647;
135 return State;
136 }
137
138 private:
139 uint32_t State;
140 };
141
142 const static size_t MaxTestsPerFunc = 100000;
143
144 template <typename Type, typename ElementType, typename CastType>
145 void outputVector(const Type Vect) {
146 const static size_t NumElementsInType = sizeof(Type) / sizeof(ElementType);
147 for (size_t i = 0; i < NumElementsInType; ++i) {
148 if (i > 0)
149 std::cout << ", ";
150 std::cout << (CastType) Vect[i];
151 }
152 }
153
154 template <typename TypeUnsigned, typename TypeSigned,
155 typename ElementTypeUnsigned, typename ElementTypeSigned>
156 void testsVecInt(size_t &TotalTests, size_t &Passes, size_t &Failures) {
157 typedef TypeUnsigned (*FuncTypeUnsigned)(TypeUnsigned, TypeUnsigned);
158 typedef TypeSigned (*FuncTypeSigned)(TypeSigned, TypeSigned);
159 static struct {
160 const char *Name;
161 FuncTypeUnsigned FuncLlc;
162 FuncTypeUnsigned FuncSz;
163 bool ExcludeDivExceptions; // for divide related tests
164 } Funcs[] = {
165 #define X(inst, op, isdiv) \
166 { \
167 STR(inst), (FuncTypeUnsigned)test##inst, \
168 (FuncTypeUnsigned)Subzero_::test##inst, isdiv \
169 } \
170 ,
171 UINTOP_TABLE
172 #undef X
173 #define X(inst, op, isdiv) \
174 { \
175 STR(inst), (FuncTypeUnsigned)(FuncTypeSigned)test##inst, \
176 (FuncTypeUnsigned)(FuncTypeSigned)Subzero_::test##inst, isdiv \
177 } \
178 ,
179 SINTOP_TABLE
jvoung (off chromium) 2014/07/16 19:23:26 indent seems a bit more than usual, for SINTOP_TAB
wala 2014/07/17 01:34:53 Done.
180 #undef X
181 };
182 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
183 const static size_t NumElementsInType =
184 sizeof(TypeUnsigned) / sizeof(ElementTypeUnsigned);
185 for (size_t f = 0; f < NumFuncs; ++f) {
186 PRNG Index;
187 for (size_t i = 0; i < MaxTestsPerFunc; ++i) {
188 // Initialize the test vectors.
189 TypeUnsigned Value1, Value2;
190 for (size_t j = 0; j < NumElementsInType;) {
191 ElementTypeUnsigned Element1 = Values[Index() % NumElementsInType];
192 ElementTypeUnsigned Element2 = Values[Index() % NumElementsInType];
193 if (Funcs[f].ExcludeDivExceptions &&
194 inputsMayTriggerException<ElementTypeSigned>(Element1, Element2))
195 continue;
196 Value1[j] = Element1;
197 Value2[j] = Element2;
198 ++j;
199 }
200 // Perform the test.
201 TypeUnsigned ResultSz = Funcs[f].FuncSz(Value1, Value2);
202 TypeUnsigned ResultLlc = Funcs[f].FuncLlc(Value1, Value2);
203 ++TotalTests;
204 if (!memcmp(&ResultSz, &ResultLlc, sizeof(ResultSz))) {
205 ++Passes;
206 } else {
207 std::cout << "test" << Funcs[f].Name << "v" << NumElementsInType << "i"
208 << (CHAR_BIT * sizeof(ElementTypeUnsigned)) << "(";
209 outputVector<TypeUnsigned, ElementTypeUnsigned, unsigned>(Value1);
210 std::cout << ", ";
211 outputVector<TypeUnsigned, ElementTypeUnsigned, unsigned>(Value2);
212 std::cout << "): sz=";
213 outputVector<TypeUnsigned, ElementTypeUnsigned, unsigned>(ResultSz);
214 std::cout << " llc=";
215 outputVector<TypeUnsigned, ElementTypeUnsigned, unsigned>(ResultLlc);
216 std::cout << std::endl;
217 }
218 }
219 }
220 }
221
122 template <typename Type> 222 template <typename Type>
123 void testsFp(size_t &TotalTests, size_t &Passes, size_t &Failures) { 223 void testsFp(size_t &TotalTests, size_t &Passes, size_t &Failures) {
124 static const Type NegInf = -1.0 / 0.0; 224 static const Type NegInf = -1.0 / 0.0;
125 static const Type PosInf = 1.0 / 0.0; 225 static const Type PosInf = 1.0 / 0.0;
126 static const Type Nan = 0.0 / 0.0; 226 static const Type Nan = 0.0 / 0.0;
127 static const Type NegNan = -0.0 / 0.0; 227 static const Type NegNan = -0.0 / 0.0;
128 volatile Type Values[] = { 228 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); 229 const static size_t NumValues = sizeof(Values) / sizeof(*Values);
144 typedef Type (*FuncType)(Type, Type); 230 typedef Type (*FuncType)(Type, Type);
145 static struct { 231 static struct {
146 const char *Name; 232 const char *Name;
147 FuncType FuncLlc; 233 FuncType FuncLlc;
148 FuncType FuncSz; 234 FuncType FuncSz;
149 } Funcs[] = { 235 } Funcs[] = {
150 #define X(inst, op, func) \ 236 #define X(inst, op, func) \
151 { STR(inst), (FuncType)test##inst, (FuncType)Subzero_::test##inst } \ 237 { STR(inst), (FuncType)test##inst, (FuncType)Subzero_::test##inst } \
152 , 238 ,
153 FPOP_TABLE 239 FPOP_TABLE
154 #undef X 240 #undef X
155 }; 241 };
156 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs); 242 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
157 243
158 for (size_t f = 0; f < NumFuncs; ++f) { 244 for (size_t f = 0; f < NumFuncs; ++f) {
159 for (size_t i = 0; i < NumValues; ++i) { 245 for (size_t i = 0; i < NumValues; ++i) {
160 for (size_t j = 0; j < NumValues; ++j) { 246 for (size_t j = 0; j < NumValues; ++j) {
161 Type Value1 = Values[i]; 247 Type Value1 = Values[i];
162 Type Value2 = Values[j]; 248 Type Value2 = Values[j];
163 ++TotalTests; 249 ++TotalTests;
164 Type ResultSz = Funcs[f].FuncSz(Value1, Value2); 250 Type ResultSz = Funcs[f].FuncSz(Value1, Value2);
165 Type ResultLlc = Funcs[f].FuncLlc(Value1, Value2); 251 Type ResultLlc = Funcs[f].FuncLlc(Value1, Value2);
166 // Compare results using memcmp() in case they are both NaN. 252 // Compare results using memcmp() in case they are both NaN.
167 if (!memcmp(&ResultSz, &ResultLlc, sizeof(Type))) { 253 if (!memcmp(&ResultSz, &ResultLlc, sizeof(Type))) {
168 ++Passes; 254 ++Passes;
169 } else { 255 } else {
170 ++Failures; 256 ++Failures;
171 std::cout << std::fixed << "test" << Funcs[f].Name 257 std::cout << std::fixed << "test" << Funcs[f].Name
172 << (8 * sizeof(Type)) << "(" << Value1 << ", " << Value2 258 << (CHAR_BIT * sizeof(Type)) << "(" << Value1 << ", "
173 << "): sz=" << ResultSz << " llc=" << ResultLlc 259 << Value2 << "): sz=" << ResultSz << " llc=" << ResultLlc
174 << std::endl; 260 << std::endl;
175 } 261 }
176 } 262 }
177 } 263 }
178 } 264 }
179 for (size_t i = 0; i < NumValues; ++i) { 265 for (size_t i = 0; i < NumValues; ++i) {
180 Type Value = Values[i]; 266 Type Value = Values[i];
181 ++TotalTests; 267 ++TotalTests;
182 Type ResultSz = Subzero_::mySqrt(Value); 268 Type ResultSz = Subzero_::mySqrt(Value);
183 Type ResultLlc = mySqrt(Value); 269 Type ResultLlc = mySqrt(Value);
184 // Compare results using memcmp() in case they are both NaN. 270 // Compare results using memcmp() in case they are both NaN.
185 if (!memcmp(&ResultSz, &ResultLlc, sizeof(Type))) { 271 if (!memcmp(&ResultSz, &ResultLlc, sizeof(Type))) {
186 ++Passes; 272 ++Passes;
187 } else { 273 } else {
188 ++Failures; 274 ++Failures;
189 std::cout << std::fixed << "test_sqrt" 275 std::cout << std::fixed << "test_sqrt" << (CHAR_BIT * sizeof(Type)) << "("
190 << (8 * sizeof(Type)) << "(" << Value 276 << Value << "): sz=" << ResultSz << " llc=" << ResultLlc
191 << "): sz=" << ResultSz << " llc=" << ResultLlc
192 << std::endl; 277 << std::endl;
193 } 278 }
194 } 279 }
195 } 280 }
196 281
282 void testsVecFp(size_t &TotalTests, size_t &Passes, size_t &Failures) {
283 static const float NegInf = -1.0 / 0.0;
284 static const float PosInf = 1.0 / 0.0;
285 static const float Nan = 0.0 / 0.0;
286 static const float NegNan = -0.0 / 0.0;
287 volatile float Values[] = FP_VALUE_ARRAY(NegInf, PosInf, NegNan, Nan);
288 const static size_t NumValues = sizeof(Values) / sizeof(*Values);
289 typedef v4f32 (*FuncType)(v4f32, v4f32);
290 static struct {
291 const char *Name;
292 FuncType FuncLlc;
293 FuncType FuncSz;
294 } Funcs[] = {
295 #define X(inst, op, func) \
296 { STR(inst), (FuncType)test##inst, (FuncType)Subzero_::test##inst } \
297 ,
298 FPOP_TABLE
299 #undef X
300 };
301 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
302 const static size_t NumElementsInType = 4;
303 for (size_t f = 0; f < NumFuncs; ++f) {
304 PRNG Index;
305 for (size_t i = 0; i < MaxTestsPerFunc; ++i) {
306 // Initialize the test vectors.
307 v4f32 Value1, Value2;
308 for (size_t j = 0; j < NumElementsInType; ++j) {
309 Value1[j] = Values[Index() % NumElementsInType];
310 Value2[j] = Values[Index() % NumElementsInType];
311 }
312 // Perform the test.
313 v4f32 ResultSz = Funcs[f].FuncSz(Value1, Value2);
314 v4f32 ResultLlc = Funcs[f].FuncLlc(Value1, Value2);
315 ++TotalTests;
316 if (!memcmp(&ResultSz, &ResultLlc, sizeof(ResultSz))) {
317 ++Passes;
318 } else {
319 ++Failures;
320 std::cout << std::fixed << "test" << Funcs[f].Name << "v4f32"
321 << "(";
322 outputVector<v4f32, float, float>(Value1);
323 std::cout << ", ";
324 outputVector<v4f32, float, float>(Value2);
325 std::cout << "): sz=";
326 outputVector<v4f32, float, float>(ResultSz);
327 std::cout << " llc=";
328 outputVector<v4f32, float, float>(ResultLlc);
329 std::cout << std::endl;
330 }
331 }
332 }
333 }
334
197 int main(int argc, char **argv) { 335 int main(int argc, char **argv) {
198 size_t TotalTests = 0; 336 size_t TotalTests = 0;
199 size_t Passes = 0; 337 size_t Passes = 0;
200 size_t Failures = 0; 338 size_t Failures = 0;
201 339
202 testsInt<uint8_t, int8_t>(TotalTests, Passes, Failures); 340 testsInt<uint8_t, int8_t>(TotalTests, Passes, Failures);
203 testsInt<uint16_t, int16_t>(TotalTests, Passes, Failures); 341 testsInt<uint16_t, int16_t>(TotalTests, Passes, Failures);
204 testsInt<uint32_t, int32_t>(TotalTests, Passes, Failures); 342 testsInt<uint32_t, int32_t>(TotalTests, Passes, Failures);
205 testsInt<uint64_t, int64_t>(TotalTests, Passes, Failures); 343 testsInt<uint64_t, int64_t>(TotalTests, Passes, Failures);
344 testsVecInt<v4ui32, v4si32, uint32_t, int32_t>(TotalTests, Passes, Failures);
345 testsVecInt<v8ui16, v8si16, uint16_t, int16_t>(TotalTests, Passes, Failures);
346 testsVecInt<v16ui8, v16si8, uint8_t, int8_t>(TotalTests, Passes, Failures);
206 testsFp<float>(TotalTests, Passes, Failures); 347 testsFp<float>(TotalTests, Passes, Failures);
207 testsFp<double>(TotalTests, Passes, Failures); 348 testsFp<double>(TotalTests, Passes, Failures);
349 testsVecFp(TotalTests, Passes, Failures);
208 350
209 std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes 351 std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes
210 << " Failures=" << Failures << "\n"; 352 << " Failures=" << Failures << "\n";
211 return Failures; 353 return Failures;
212 } 354 }
355
356 extern "C" {
357 // Subzero helpers
358 v4si32 Sz_shl_v4i32(v4si32 a, v4si32 b) { return a << b; }
359 v4si32 Sz_ashr_v4i32(v4si32 a, v4si32 b) { return a >> b; }
360 v4ui32 Sz_lshr_v4i32(v4ui32 a, v4ui32 b) { return a >> b; }
361 v4si32 Sz_sdiv_v4i32(v4si32 a, v4si32 b) { return a / b; }
362 v4ui32 Sz_udiv_v4i32(v4ui32 a, v4ui32 b) { return a / b; }
363 v4si32 Sz_srem_v4i32(v4si32 a, v4si32 b) { return a % b; }
364 v4ui32 Sz_urem_v4i32(v4ui32 a, v4ui32 b) { return a % b; }
365
366 v8si16 Sz_shl_v8i16(v8si16 a, v8si16 b) { return a << b; }
367 v8si16 Sz_ashr_v8i16(v8si16 a, v8si16 b) { return a >> b; }
368 v8ui16 Sz_lshr_v8i16(v8ui16 a, v8ui16 b) { return a >> b; }
369 v8si16 Sz_sdiv_v8i16(v8si16 a, v8si16 b) { return a / b; }
370 v8ui16 Sz_udiv_v8i16(v8ui16 a, v8ui16 b) { return a / b; }
371 v8si16 Sz_srem_v8i16(v8si16 a, v8si16 b) { return a % b; }
372 v8ui16 Sz_urem_v8i16(v8ui16 a, v8ui16 b) { return a % b; }
373
374 v16ui8 Sz_mul_v16i8(v16ui8 a, v16ui8 b) { return a * b; }
375 v16si8 Sz_shl_v16i8(v16si8 a, v16si8 b) { return a << b; }
376 v16si8 Sz_ashr_v16i8(v16si8 a, v16si8 b) { return a >> b; }
377 v16ui8 Sz_lshr_v16i8(v16ui8 a, v16ui8 b) { return a >> b; }
378 v16si8 Sz_sdiv_v16i8(v16si8 a, v16si8 b) { return a / b; }
379 v16ui8 Sz_udiv_v16i8(v16ui8 a, v16ui8 b) { return a / b; }
380 v16si8 Sz_srem_v16i8(v16si8 a, v16si8 b) { return a % b; }
381 v16ui8 Sz_urem_v16i8(v16ui8 a, v16ui8 b) { return a % b; }
382
383 v4f32 Sz_frem_v4f32(v4f32 a, v4f32 b) {
384 v4f32 Result;
385 for (int i = 0; i < 4; ++i)
386 Result[i] = fmodf(a[i], b[i]);
387 return Result;
388 }
389 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698