1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "Reactor.hpp"
16
17 #include "gtest/gtest.h"
18
19 using namespace sw;
20
reference(int * p,int y)21 int reference(int *p, int y)
22 {
23 int x = p[-1];
24 int z = 4;
25
26 for(int i = 0; i < 10; i++)
27 {
28 z += (2 << i) - (i / 3);
29 }
30
31 int sum = x + y + z;
32
33 return sum;
34 }
35
TEST(SubzeroReactorTest,Sample)36 TEST(SubzeroReactorTest, Sample)
37 {
38 Routine *routine = nullptr;
39
40 {
41 Function<Int(Pointer<Int>, Int)> function;
42 {
43 Pointer<Int> p = function.Arg<0>();
44 Int x = p[-1];
45 Int y = function.Arg<1>();
46 Int z = 4;
47
48 For(Int i = 0, i < 10, i++)
49 {
50 z += (2 << i) - (i / 3);
51 }
52
53 Float4 v;
54 v.z = As<Float>(z);
55 z = As<Int>(Float(Float4(v.xzxx).y));
56
57 Int sum = x + y + z;
58
59 Return(sum);
60 }
61
62 routine = function(L"one");
63
64 if(routine)
65 {
66 int (*callable)(int*, int) = (int(*)(int*,int))routine->getEntry();
67 int one[2] = {1, 0};
68 int result = callable(&one[1], 2);
69 EXPECT_EQ(result, reference(&one[1], 2));
70 }
71 }
72
73 delete routine;
74 }
75
TEST(SubzeroReactorTest,Uninitialized)76 TEST(SubzeroReactorTest, Uninitialized)
77 {
78 Routine *routine = nullptr;
79
80 {
81 Function<Int()> function;
82 {
83 Int a;
84 Int z = 4;
85 Int q;
86 Int c;
87 Int p;
88 Bool b;
89
90 q += q;
91
92 If(b)
93 {
94 c = p;
95 }
96
97 Return(a + z + q + c);
98 }
99
100 routine = function(L"one");
101
102 if(routine)
103 {
104 int (*callable)() = (int(*)())routine->getEntry();
105 int result = callable();
106 EXPECT_EQ(result, result); // Anything is fine, just don't crash
107 }
108 }
109
110 delete routine;
111 }
112
TEST(SubzeroReactorTest,SubVectorLoadStore)113 TEST(SubzeroReactorTest, SubVectorLoadStore)
114 {
115 Routine *routine = nullptr;
116
117 {
118 Function<Int(Pointer<Byte>, Pointer<Byte>)> function;
119 {
120 Pointer<Byte> in = function.Arg<0>();
121 Pointer<Byte> out = function.Arg<1>();
122
123 *Pointer<Int4>(out + 16 * 0) = *Pointer<Int4>(in + 16 * 0);
124 *Pointer<Short4>(out + 16 * 1) = *Pointer<Short4>(in + 16 * 1);
125 *Pointer<Byte8>(out + 16 * 2) = *Pointer<Byte8>(in + 16 * 2);
126 *Pointer<Byte4>(out + 16 * 3) = *Pointer<Byte4>(in + 16 * 3);
127 *Pointer<Short2>(out + 16 * 4) = *Pointer<Short2>(in + 16 * 4);
128
129 Return(0);
130 }
131
132 routine = function(L"one");
133
134 if(routine)
135 {
136 int8_t in[16 * 5] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
137 17, 18, 19, 20, 21, 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0,
138 25, 26, 27, 28, 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 0,
139 33, 34, 35, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
140 37, 38, 39, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
141
142 int8_t out[16 * 5] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
143 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
144 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
145 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
146 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
147
148 int (*callable)(void*, void*) = (int(*)(void*,void*))routine->getEntry();
149 callable(in, out);
150
151 for(int row = 0; row < 5; row++)
152 {
153 for(int col = 0; col < 16; col++)
154 {
155 int i = row * 16 + col;
156
157 if(in[i] == 0)
158 {
159 EXPECT_EQ(out[i], -1) << "Row " << row << " column " << col << " not left untouched.";
160 }
161 else
162 {
163 EXPECT_EQ(out[i], in[i]) << "Row " << row << " column " << col << " not equal to input.";
164 }
165 }
166 }
167 }
168 }
169
170 delete routine;
171 }
172
TEST(SubzeroReactorTest,VectorConstant)173 TEST(SubzeroReactorTest, VectorConstant)
174 {
175 Routine *routine = nullptr;
176
177 {
178 Function<Int(Pointer<Byte>)> function;
179 {
180 Pointer<Byte> out = function.Arg<0>();
181
182 *Pointer<Int4>(out + 16 * 0) = Int4(0x04030201, 0x08070605, 0x0C0B0A09, 0x100F0E0D);
183 *Pointer<Short4>(out + 16 * 1) = Short4(0x1211, 0x1413, 0x1615, 0x1817);
184 *Pointer<Byte8>(out + 16 * 2) = Byte8(0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20);
185 *Pointer<Int2>(out + 16 * 3) = Int2(0x24232221, 0x28272625);
186
187 Return(0);
188 }
189
190 routine = function(L"one");
191
192 if(routine)
193 {
194 int8_t out[16 * 4] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
195 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
196 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
197 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
198
199 int8_t exp[16 * 4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
200 17, 18, 19, 20, 21, 22, 23, 24, -1, -1, -1, -1, -1, -1, -1, -1,
201 25, 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, -1, -1, -1, -1, -1,
202 33, 34, 35, 36, 37, 38, 39, 40, -1, -1, -1, -1, -1, -1, -1, -1};
203
204 int(*callable)(void*) = (int(*)(void*))routine->getEntry();
205 callable(out);
206
207 for(int row = 0; row < 4; row++)
208 {
209 for(int col = 0; col < 16; col++)
210 {
211 int i = row * 16 + col;
212
213 EXPECT_EQ(out[i], exp[i]);
214 }
215 }
216 }
217 }
218
219 delete routine;
220 }
221
TEST(SubzeroReactorTest,Concatenate)222 TEST(SubzeroReactorTest, Concatenate)
223 {
224 Routine *routine = nullptr;
225
226 {
227 Function<Int(Pointer<Byte>)> function;
228 {
229 Pointer<Byte> out = function.Arg<0>();
230
231 *Pointer<Int4>(out + 16 * 0) = Int4(Int2(0x04030201, 0x08070605), Int2(0x0C0B0A09, 0x100F0E0D));
232 *Pointer<Short8>(out + 16 * 1) = Short8(Short4(0x0201, 0x0403, 0x0605, 0x0807), Short4(0x0A09, 0x0C0B, 0x0E0D, 0x100F));
233
234 Return(0);
235 }
236
237 routine = function(L"one");
238
239 if(routine)
240 {
241 int8_t ref[16 * 5] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
242 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
243
244 int8_t out[16 * 5] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
245 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
246
247 int (*callable)(void*) = (int(*)(void*))routine->getEntry();
248 callable(out);
249
250 for(int row = 0; row < 2; row++)
251 {
252 for(int col = 0; col < 16; col++)
253 {
254 int i = row * 16 + col;
255
256 EXPECT_EQ(out[i], ref[i]) << "Row " << row << " column " << col << " not equal to reference.";
257 }
258 }
259 }
260 }
261
262 delete routine;
263 }
264
TEST(SubzeroReactorTest,Swizzle)265 TEST(SubzeroReactorTest, Swizzle)
266 {
267 Routine *routine = nullptr;
268
269 {
270 Function<Int(Pointer<Byte>)> function;
271 {
272 Pointer<Byte> out = function.Arg<0>();
273
274 for(int i = 0; i < 256; i++)
275 {
276 *Pointer<Float4>(out + 16 * i) = Swizzle(Float4(1.0f, 2.0f, 3.0f, 4.0f), i);
277 }
278
279 for(int i = 0; i < 256; i++)
280 {
281 *Pointer<Float4>(out + 16 * (256 + i)) = ShuffleLowHigh(Float4(1.0f, 2.0f, 3.0f, 4.0f), Float4(5.0f, 6.0f, 7.0f, 8.0f), i);
282 }
283
284 *Pointer<Float4>(out + 16 * (512 + 0)) = UnpackLow(Float4(1.0f, 2.0f, 3.0f, 4.0f), Float4(5.0f, 6.0f, 7.0f, 8.0f));
285 *Pointer<Float4>(out + 16 * (512 + 1)) = UnpackHigh(Float4(1.0f, 2.0f, 3.0f, 4.0f), Float4(5.0f, 6.0f, 7.0f, 8.0f));
286 *Pointer<Int2>(out + 16 * (512 + 2)) = UnpackLow(Short4(1, 2, 3, 4), Short4(5, 6, 7, 8));
287 *Pointer<Int2>(out + 16 * (512 + 3)) = UnpackHigh(Short4(1, 2, 3, 4), Short4(5, 6, 7, 8));
288 *Pointer<Short4>(out + 16 * (512 + 4)) = UnpackLow(Byte8(1, 2, 3, 4, 5, 6, 7, 8), Byte8(9, 10, 11, 12, 13, 14, 15, 16));
289 *Pointer<Short4>(out + 16 * (512 + 5)) = UnpackHigh(Byte8(1, 2, 3, 4, 5, 6, 7, 8), Byte8(9, 10, 11, 12, 13, 14, 15, 16));
290
291 Return(0);
292 }
293
294 routine = function(L"one");
295
296 if(routine)
297 {
298 struct
299 {
300 float f[256 + 256 + 2][4];
301 int i[4][4];
302 } out;
303
304 memset(&out, 0, sizeof(out));
305
306 int(*callable)(void*) = (int(*)(void*))routine->getEntry();
307 callable(&out);
308
309 for(int i = 0; i < 256; i++)
310 {
311 EXPECT_EQ(out.f[i][0], float((i >> 0) & 0x03) + 1.0f);
312 EXPECT_EQ(out.f[i][1], float((i >> 2) & 0x03) + 1.0f);
313 EXPECT_EQ(out.f[i][2], float((i >> 4) & 0x03) + 1.0f);
314 EXPECT_EQ(out.f[i][3], float((i >> 6) & 0x03) + 1.0f);
315 }
316
317 for(int i = 0; i < 256; i++)
318 {
319 EXPECT_EQ(out.f[256 + i][0], float((i >> 0) & 0x03) + 1.0f);
320 EXPECT_EQ(out.f[256 + i][1], float((i >> 2) & 0x03) + 1.0f);
321 EXPECT_EQ(out.f[256 + i][2], float((i >> 4) & 0x03) + 5.0f);
322 EXPECT_EQ(out.f[256 + i][3], float((i >> 6) & 0x03) + 5.0f);
323 }
324
325 EXPECT_EQ(out.f[512 + 0][0], 1.0f);
326 EXPECT_EQ(out.f[512 + 0][1], 5.0f);
327 EXPECT_EQ(out.f[512 + 0][2], 2.0f);
328 EXPECT_EQ(out.f[512 + 0][3], 6.0f);
329
330 EXPECT_EQ(out.f[512 + 1][0], 3.0f);
331 EXPECT_EQ(out.f[512 + 1][1], 7.0f);
332 EXPECT_EQ(out.f[512 + 1][2], 4.0f);
333 EXPECT_EQ(out.f[512 + 1][3], 8.0f);
334
335 EXPECT_EQ(out.i[0][0], 0x00050001);
336 EXPECT_EQ(out.i[0][1], 0x00060002);
337 EXPECT_EQ(out.i[0][2], 0x00000000);
338 EXPECT_EQ(out.i[0][3], 0x00000000);
339
340 EXPECT_EQ(out.i[1][0], 0x00070003);
341 EXPECT_EQ(out.i[1][1], 0x00080004);
342 EXPECT_EQ(out.i[1][2], 0x00000000);
343 EXPECT_EQ(out.i[1][3], 0x00000000);
344
345 EXPECT_EQ(out.i[2][0], 0x0A020901);
346 EXPECT_EQ(out.i[2][1], 0x0C040B03);
347 EXPECT_EQ(out.i[2][2], 0x00000000);
348 EXPECT_EQ(out.i[2][3], 0x00000000);
349
350 EXPECT_EQ(out.i[3][0], 0x0E060D05);
351 EXPECT_EQ(out.i[3][1], 0x10080F07);
352 EXPECT_EQ(out.i[3][2], 0x00000000);
353 EXPECT_EQ(out.i[3][3], 0x00000000);
354 }
355 }
356
357 delete routine;
358 }
359
TEST(SubzeroReactorTest,Branching)360 TEST(SubzeroReactorTest, Branching)
361 {
362 Routine *routine = nullptr;
363
364 {
365 Function<Int(Void)> function;
366 {
367 Int x = 0;
368
369 For(Int i = 0, i < 8, i++)
370 {
371 If(i < 2)
372 {
373 x += 1;
374 }
375 Else If(i < 4)
376 {
377 x += 10;
378 }
379 Else If(i < 6)
380 {
381 x += 100;
382 }
383 Else
384 {
385 x += 1000;
386 }
387
388 For(Int i = 0, i < 5, i++)
389 x += 10000;
390 }
391
392 For(Int i = 0, i < 10, i++)
393 for(int i = 0; i < 10; i++)
394 For(Int i = 0, i < 10, i++)
395 {
396 x += 1000000;
397 }
398
399 For(Int i = 0, i < 2, i++)
400 If(x == 1000402222)
401 {
402 If(x != 1000402222)
403 x += 1000000000;
404 }
405 Else
406 x = -5;
407
408 Return(x);
409 }
410
411 routine = function(L"one");
412
413 if(routine)
414 {
415 int(*callable)() = (int(*)())routine->getEntry();
416 int result = callable();
417
418 EXPECT_EQ(result, 1000402222);
419 }
420 }
421
422 delete routine;
423 }
424
TEST(SubzeroReactorTest,MinMax)425 TEST(SubzeroReactorTest, MinMax)
426 {
427 Routine *routine = nullptr;
428
429 {
430 Function<Int(Pointer<Byte>)> function;
431 {
432 Pointer<Byte> out = function.Arg<0>();
433
434 *Pointer<Float4>(out + 16 * 0) = Min(Float4(1.0f, 0.0f, -0.0f, +0.0f), Float4(0.0f, 1.0f, +0.0f, -0.0f));
435 *Pointer<Float4>(out + 16 * 1) = Max(Float4(1.0f, 0.0f, -0.0f, +0.0f), Float4(0.0f, 1.0f, +0.0f, -0.0f));
436
437 *Pointer<Int4>(out + 16 * 2) = Min(Int4(1, 0, -1, -0), Int4(0, 1, 0, +0));
438 *Pointer<Int4>(out + 16 * 3) = Max(Int4(1, 0, -1, -0), Int4(0, 1, 0, +0));
439 *Pointer<UInt4>(out + 16 * 4) = Min(UInt4(1, 0, -1, -0), UInt4(0, 1, 0, +0));
440 *Pointer<UInt4>(out + 16 * 5) = Max(UInt4(1, 0, -1, -0), UInt4(0, 1, 0, +0));
441
442 *Pointer<Short4>(out + 16 * 6) = Min(Short4(1, 0, -1, -0), Short4(0, 1, 0, +0));
443 *Pointer<Short4>(out + 16 * 7) = Max(Short4(1, 0, -1, -0), Short4(0, 1, 0, +0));
444 *Pointer<UShort4>(out + 16 * 8) = Min(UShort4(1, 0, -1, -0), UShort4(0, 1, 0, +0));
445 *Pointer<UShort4>(out + 16 * 9) = Max(UShort4(1, 0, -1, -0), UShort4(0, 1, 0, +0));
446
447 Return(0);
448 }
449
450 routine = function(L"one");
451
452 if(routine)
453 {
454 int out[10][4];
455
456 memset(&out, 0, sizeof(out));
457
458 int(*callable)(void*) = (int(*)(void*))routine->getEntry();
459 callable(&out);
460
461 EXPECT_EQ(out[0][0], 0x00000000);
462 EXPECT_EQ(out[0][1], 0x00000000);
463 EXPECT_EQ(out[0][2], 0x00000000);
464 EXPECT_EQ(out[0][3], 0x80000000);
465
466 EXPECT_EQ(out[1][0], 0x3F800000);
467 EXPECT_EQ(out[1][1], 0x3F800000);
468 EXPECT_EQ(out[1][2], 0x00000000);
469 EXPECT_EQ(out[1][3], 0x80000000);
470
471 EXPECT_EQ(out[2][0], 0x00000000);
472 EXPECT_EQ(out[2][1], 0x00000000);
473 EXPECT_EQ(out[2][2], 0xFFFFFFFF);
474 EXPECT_EQ(out[2][3], 0x00000000);
475
476 EXPECT_EQ(out[3][0], 0x00000001);
477 EXPECT_EQ(out[3][1], 0x00000001);
478 EXPECT_EQ(out[3][2], 0x00000000);
479 EXPECT_EQ(out[3][3], 0x00000000);
480
481 EXPECT_EQ(out[4][0], 0x00000000);
482 EXPECT_EQ(out[4][1], 0x00000000);
483 EXPECT_EQ(out[4][2], 0x00000000);
484 EXPECT_EQ(out[4][3], 0x00000000);
485
486 EXPECT_EQ(out[5][0], 0x00000001);
487 EXPECT_EQ(out[5][1], 0x00000001);
488 EXPECT_EQ(out[5][2], 0xFFFFFFFF);
489 EXPECT_EQ(out[5][3], 0x00000000);
490
491 EXPECT_EQ(out[6][0], 0x00000000);
492 EXPECT_EQ(out[6][1], 0x0000FFFF);
493 EXPECT_EQ(out[6][2], 0x00000000);
494 EXPECT_EQ(out[6][3], 0x00000000);
495
496 EXPECT_EQ(out[7][0], 0x00010001);
497 EXPECT_EQ(out[7][1], 0x00000000);
498 EXPECT_EQ(out[7][2], 0x00000000);
499 EXPECT_EQ(out[7][3], 0x00000000);
500
501 EXPECT_EQ(out[8][0], 0x00000000);
502 EXPECT_EQ(out[8][1], 0x00000000);
503 EXPECT_EQ(out[8][2], 0x00000000);
504 EXPECT_EQ(out[8][3], 0x00000000);
505
506 EXPECT_EQ(out[9][0], 0x00010001);
507 EXPECT_EQ(out[9][1], 0x0000FFFF);
508 EXPECT_EQ(out[9][2], 0x00000000);
509 EXPECT_EQ(out[9][3], 0x00000000);
510 }
511 }
512
513 delete routine;
514 }
515
TEST(SubzeroReactorTest,NotNeg)516 TEST(SubzeroReactorTest, NotNeg)
517 {
518 Routine *routine = nullptr;
519
520 {
521 Function<Int(Pointer<Byte>)> function;
522 {
523 Pointer<Byte> out = function.Arg<0>();
524
525 *Pointer<Int>(out + 16 * 0) = ~Int(0x55555555);
526 *Pointer<Short>(out + 16 * 1) = ~Short(0x5555);
527 *Pointer<Int4>(out + 16 * 2) = ~Int4(0x55555555, 0xAAAAAAAA, 0x00000000, 0xFFFFFFFF);
528 *Pointer<Short4>(out + 16 * 3) = ~Short4(0x5555, 0xAAAA, 0x0000, 0xFFFF);
529
530 *Pointer<Int>(out + 16 * 4) = -Int(0x55555555);
531 *Pointer<Short>(out + 16 * 5) = -Short(0x5555);
532 *Pointer<Int4>(out + 16 * 6) = -Int4(0x55555555, 0xAAAAAAAA, 0x00000000, 0xFFFFFFFF);
533 *Pointer<Short4>(out + 16 * 7) = -Short4(0x5555, 0xAAAA, 0x0000, 0xFFFF);
534
535 *Pointer<Float4>(out + 16 * 8) = -Float4(1.0f, -1.0f, 0.0f, -0.0f);
536
537 Return(0);
538 }
539
540 routine = function(L"one");
541
542 if(routine)
543 {
544 int out[10][4];
545
546 memset(&out, 0, sizeof(out));
547
548 int(*callable)(void*) = (int(*)(void*))routine->getEntry();
549 callable(&out);
550
551 EXPECT_EQ(out[0][0], 0xAAAAAAAA);
552 EXPECT_EQ(out[0][1], 0x00000000);
553 EXPECT_EQ(out[0][2], 0x00000000);
554 EXPECT_EQ(out[0][3], 0x00000000);
555
556 EXPECT_EQ(out[1][0], 0x0000AAAA);
557 EXPECT_EQ(out[1][1], 0x00000000);
558 EXPECT_EQ(out[1][2], 0x00000000);
559 EXPECT_EQ(out[1][3], 0x00000000);
560
561 EXPECT_EQ(out[2][0], 0xAAAAAAAA);
562 EXPECT_EQ(out[2][1], 0x55555555);
563 EXPECT_EQ(out[2][2], 0xFFFFFFFF);
564 EXPECT_EQ(out[2][3], 0x00000000);
565
566 EXPECT_EQ(out[3][0], 0x5555AAAA);
567 EXPECT_EQ(out[3][1], 0x0000FFFF);
568 EXPECT_EQ(out[3][2], 0x00000000);
569 EXPECT_EQ(out[3][3], 0x00000000);
570
571 EXPECT_EQ(out[4][0], 0xAAAAAAAB);
572 EXPECT_EQ(out[4][1], 0x00000000);
573 EXPECT_EQ(out[4][2], 0x00000000);
574 EXPECT_EQ(out[4][3], 0x00000000);
575
576 EXPECT_EQ(out[5][0], 0x0000AAAB);
577 EXPECT_EQ(out[5][1], 0x00000000);
578 EXPECT_EQ(out[5][2], 0x00000000);
579 EXPECT_EQ(out[5][3], 0x00000000);
580
581 EXPECT_EQ(out[6][0], 0xAAAAAAAB);
582 EXPECT_EQ(out[6][1], 0x55555556);
583 EXPECT_EQ(out[6][2], 0x00000000);
584 EXPECT_EQ(out[6][3], 0x00000001);
585
586 EXPECT_EQ(out[7][0], 0x5556AAAB);
587 EXPECT_EQ(out[7][1], 0x00010000);
588 EXPECT_EQ(out[7][2], 0x00000000);
589 EXPECT_EQ(out[7][3], 0x00000000);
590
591 EXPECT_EQ(out[8][0], 0xBF800000);
592 EXPECT_EQ(out[8][1], 0x3F800000);
593 EXPECT_EQ(out[8][2], 0x80000000);
594 EXPECT_EQ(out[8][3], 0x00000000);
595 }
596 }
597
598 delete routine;
599 }
600
TEST(SubzeroReactorTest,VectorCompare)601 TEST(SubzeroReactorTest, VectorCompare)
602 {
603 Routine *routine = nullptr;
604
605 {
606 Function<Int(Pointer<Byte>)> function;
607 {
608 Pointer<Byte> out = function.Arg<0>();
609
610 *Pointer<Int4>(out + 16 * 0) = CmpEQ(Float4(1.0f, 1.0f, -0.0f, +0.0f), Float4(0.0f, 1.0f, +0.0f, -0.0f));
611 *Pointer<Int4>(out + 16 * 1) = CmpEQ(Int4(1, 0, -1, -0), Int4(0, 1, 0, +0));
612 *Pointer<Byte8>(out + 16 * 2) = CmpEQ(SByte8(1, 2, 3, 4, 5, 6, 7, 8), SByte8(7, 6, 5, 4, 3, 2, 1, 0));
613
614 *Pointer<Int4>(out + 16 * 3) = CmpNLT(Float4(1.0f, 1.0f, -0.0f, +0.0f), Float4(0.0f, 1.0f, +0.0f, -0.0f));
615 *Pointer<Int4>(out + 16 * 4) = CmpNLT(Int4(1, 0, -1, -0), Int4(0, 1, 0, +0));
616 *Pointer<Byte8>(out + 16 * 5) = CmpGT(SByte8(1, 2, 3, 4, 5, 6, 7, 8), SByte8(7, 6, 5, 4, 3, 2, 1, 0));
617
618 Return(0);
619 }
620
621 routine = function(L"one");
622
623 if(routine)
624 {
625 int out[6][4];
626
627 memset(&out, 0, sizeof(out));
628
629 int(*callable)(void*) = (int(*)(void*))routine->getEntry();
630 callable(&out);
631
632 EXPECT_EQ(out[0][0], 0x00000000);
633 EXPECT_EQ(out[0][1], 0xFFFFFFFF);
634 EXPECT_EQ(out[0][2], 0xFFFFFFFF);
635 EXPECT_EQ(out[0][3], 0xFFFFFFFF);
636
637 EXPECT_EQ(out[1][0], 0x00000000);
638 EXPECT_EQ(out[1][1], 0x00000000);
639 EXPECT_EQ(out[1][2], 0x00000000);
640 EXPECT_EQ(out[1][3], 0xFFFFFFFF);
641
642 EXPECT_EQ(out[2][0], 0xFF000000);
643 EXPECT_EQ(out[2][1], 0x00000000);
644
645 EXPECT_EQ(out[3][0], 0xFFFFFFFF);
646 EXPECT_EQ(out[3][1], 0xFFFFFFFF);
647 EXPECT_EQ(out[3][2], 0xFFFFFFFF);
648 EXPECT_EQ(out[3][3], 0xFFFFFFFF);
649
650 EXPECT_EQ(out[4][0], 0xFFFFFFFF);
651 EXPECT_EQ(out[4][1], 0x00000000);
652 EXPECT_EQ(out[4][2], 0x00000000);
653 EXPECT_EQ(out[4][3], 0xFFFFFFFF);
654
655 EXPECT_EQ(out[5][0], 0x00000000);
656 EXPECT_EQ(out[5][1], 0xFFFFFFFF);
657 }
658 }
659
660 delete routine;
661 }
662
main(int argc,char ** argv)663 int main(int argc, char **argv)
664 {
665 ::testing::InitGoogleTest(&argc, argv);
666 return RUN_ALL_TESTS();
667 }
668