1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
15 #include "Reactor.hpp"
17 #include "gtest/gtest.h"
21 int reference(int *p, int y)
26 for(int i = 0; i < 10; i++)
28 z += (2 << i) - (i / 3);
36 TEST(ReactorUnitTests, Sample)
38 Routine *routine = nullptr;
41 Function<Int(Pointer<Int>, Int)> function;
43 Pointer<Int> p = function.Arg<0>();
45 Int y = function.Arg<1>();
48 For(Int i = 0, i < 10, i++)
50 z += (2 << i) - (i / 3);
55 z = As<Int>(Float(Float4(v.xzxx).y));
62 routine = function("one");
66 int (*callable)(int*, int) = (int(*)(int*,int))routine->getEntry();
68 int result = callable(&one[1], 2);
69 EXPECT_EQ(result, reference(&one[1], 2));
76 TEST(ReactorUnitTests, Uninitialized)
78 Routine *routine = nullptr;
81 Function<Int()> function;
97 Return(a + z + q + c);
100 routine = function("one");
104 int (*callable)() = (int(*)())routine->getEntry();
105 int result = callable();
106 EXPECT_EQ(result, result); // Anything is fine, just don't crash
113 TEST(ReactorUnitTests, SubVectorLoadStore)
115 Routine *routine = nullptr;
118 Function<Int(Pointer<Byte>, Pointer<Byte>)> function;
120 Pointer<Byte> in = function.Arg<0>();
121 Pointer<Byte> out = function.Arg<1>();
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);
132 routine = function("one");
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};
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};
148 int (*callable)(void*, void*) = (int(*)(void*,void*))routine->getEntry();
151 for(int row = 0; row < 5; row++)
153 for(int col = 0; col < 16; col++)
155 int i = row * 16 + col;
159 EXPECT_EQ(out[i], -1) << "Row " << row << " column " << col << " not left untouched.";
163 EXPECT_EQ(out[i], in[i]) << "Row " << row << " column " << col << " not equal to input.";
173 TEST(ReactorUnitTests, VectorConstant)
175 Routine *routine = nullptr;
178 Function<Int(Pointer<Byte>)> function;
180 Pointer<Byte> out = function.Arg<0>();
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);
190 routine = function("one");
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};
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};
204 int(*callable)(void*) = (int(*)(void*))routine->getEntry();
207 for(int row = 0; row < 4; row++)
209 for(int col = 0; col < 16; col++)
211 int i = row * 16 + col;
213 EXPECT_EQ(out[i], exp[i]);
222 TEST(ReactorUnitTests, Concatenate)
224 Routine *routine = nullptr;
227 Function<Int(Pointer<Byte>)> function;
229 Pointer<Byte> out = function.Arg<0>();
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));
237 routine = function("one");
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};
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};
247 int (*callable)(void*) = (int(*)(void*))routine->getEntry();
250 for(int row = 0; row < 2; row++)
252 for(int col = 0; col < 16; col++)
254 int i = row * 16 + col;
256 EXPECT_EQ(out[i], ref[i]) << "Row " << row << " column " << col << " not equal to reference.";
265 TEST(ReactorUnitTests, Swizzle)
267 Routine *routine = nullptr;
270 Function<Int(Pointer<Byte>)> function;
272 Pointer<Byte> out = function.Arg<0>();
274 for(int i = 0; i < 256; i++)
276 *Pointer<Float4>(out + 16 * i) = Swizzle(Float4(1.0f, 2.0f, 3.0f, 4.0f), i);
279 for(int i = 0; i < 256; i++)
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);
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));
291 for(int i = 0; i < 256; i++)
293 *Pointer<Short4>(out + 16 * (512 + 6) + (8 * i)) =
294 Swizzle(Short4(1, 2, 3, 4), i);
297 for(int i = 0; i < 256; i++)
299 *Pointer<Int4>(out + 16 * (512 + 6 + i) + (8 * 256)) =
300 Swizzle(Int4(1, 2, 3, 4), i);
306 routine = function("one");
312 float f[256 + 256 + 2][4];
316 memset(&out, 0, sizeof(out));
318 int(*callable)(void*) = (int(*)(void*))routine->getEntry();
321 for(int i = 0; i < 256; i++)
323 EXPECT_EQ(out.f[i][0], float((i >> 0) & 0x03) + 1.0f);
324 EXPECT_EQ(out.f[i][1], float((i >> 2) & 0x03) + 1.0f);
325 EXPECT_EQ(out.f[i][2], float((i >> 4) & 0x03) + 1.0f);
326 EXPECT_EQ(out.f[i][3], float((i >> 6) & 0x03) + 1.0f);
329 for(int i = 0; i < 256; i++)
331 EXPECT_EQ(out.f[256 + i][0], float((i >> 0) & 0x03) + 1.0f);
332 EXPECT_EQ(out.f[256 + i][1], float((i >> 2) & 0x03) + 1.0f);
333 EXPECT_EQ(out.f[256 + i][2], float((i >> 4) & 0x03) + 5.0f);
334 EXPECT_EQ(out.f[256 + i][3], float((i >> 6) & 0x03) + 5.0f);
337 EXPECT_EQ(out.f[512 + 0][0], 1.0f);
338 EXPECT_EQ(out.f[512 + 0][1], 5.0f);
339 EXPECT_EQ(out.f[512 + 0][2], 2.0f);
340 EXPECT_EQ(out.f[512 + 0][3], 6.0f);
342 EXPECT_EQ(out.f[512 + 1][0], 3.0f);
343 EXPECT_EQ(out.f[512 + 1][1], 7.0f);
344 EXPECT_EQ(out.f[512 + 1][2], 4.0f);
345 EXPECT_EQ(out.f[512 + 1][3], 8.0f);
347 EXPECT_EQ(out.i[0][0], 0x00050001);
348 EXPECT_EQ(out.i[0][1], 0x00060002);
349 EXPECT_EQ(out.i[0][2], 0x00000000);
350 EXPECT_EQ(out.i[0][3], 0x00000000);
352 EXPECT_EQ(out.i[1][0], 0x00070003);
353 EXPECT_EQ(out.i[1][1], 0x00080004);
354 EXPECT_EQ(out.i[1][2], 0x00000000);
355 EXPECT_EQ(out.i[1][3], 0x00000000);
357 EXPECT_EQ(out.i[2][0], 0x0A020901);
358 EXPECT_EQ(out.i[2][1], 0x0C040B03);
359 EXPECT_EQ(out.i[2][2], 0x00000000);
360 EXPECT_EQ(out.i[2][3], 0x00000000);
362 EXPECT_EQ(out.i[3][0], 0x0E060D05);
363 EXPECT_EQ(out.i[3][1], 0x10080F07);
364 EXPECT_EQ(out.i[3][2], 0x00000000);
365 EXPECT_EQ(out.i[3][3], 0x00000000);
367 for(int i = 0; i < 256; i++)
369 EXPECT_EQ(out.i[4 + i/2][0 + (i%2) * 2] & 0xFFFF,
370 ((i >> 0) & 0x03) + 1);
371 EXPECT_EQ(out.i[4 + i/2][0 + (i%2) * 2] >> 16,
372 ((i >> 2) & 0x03) + 1);
373 EXPECT_EQ(out.i[4 + i/2][1 + (i%2) * 2] & 0xFFFF,
374 ((i >> 4) & 0x03) + 1);
375 EXPECT_EQ(out.i[4 + i/2][1 + (i%2) * 2] >> 16,
376 ((i >> 6) & 0x03) + 1);
379 for(int i = 0; i < 256; i++)
381 EXPECT_EQ(out.i[132 + i][0], ((i >> 0) & 0x03) + 1);
382 EXPECT_EQ(out.i[132 + i][1], ((i >> 2) & 0x03) + 1);
383 EXPECT_EQ(out.i[132 + i][2], ((i >> 4) & 0x03) + 1);
384 EXPECT_EQ(out.i[132 + i][3], ((i >> 6) & 0x03) + 1);
392 TEST(ReactorUnitTests, Branching)
394 Routine *routine = nullptr;
397 Function<Int(Void)> function;
401 For(Int i = 0, i < 8, i++)
420 For(Int i = 0, i < 5, i++)
424 For(Int i = 0, i < 10, i++)
425 for(int i = 0; i < 10; i++)
426 For(Int i = 0, i < 10, i++)
431 For(Int i = 0, i < 2, i++)
443 routine = function("one");
447 int(*callable)() = (int(*)())routine->getEntry();
448 int result = callable();
450 EXPECT_EQ(result, 1000402222);
457 TEST(ReactorUnitTests, MinMax)
459 Routine *routine = nullptr;
462 Function<Int(Pointer<Byte>)> function;
464 Pointer<Byte> out = function.Arg<0>();
466 *Pointer<Float4>(out + 16 * 0) = Min(Float4(1.0f, 0.0f, -0.0f, +0.0f), Float4(0.0f, 1.0f, +0.0f, -0.0f));
467 *Pointer<Float4>(out + 16 * 1) = Max(Float4(1.0f, 0.0f, -0.0f, +0.0f), Float4(0.0f, 1.0f, +0.0f, -0.0f));
469 *Pointer<Int4>(out + 16 * 2) = Min(Int4(1, 0, -1, -0), Int4(0, 1, 0, +0));
470 *Pointer<Int4>(out + 16 * 3) = Max(Int4(1, 0, -1, -0), Int4(0, 1, 0, +0));
471 *Pointer<UInt4>(out + 16 * 4) = Min(UInt4(1, 0, -1, -0), UInt4(0, 1, 0, +0));
472 *Pointer<UInt4>(out + 16 * 5) = Max(UInt4(1, 0, -1, -0), UInt4(0, 1, 0, +0));
474 *Pointer<Short4>(out + 16 * 6) = Min(Short4(1, 0, -1, -0), Short4(0, 1, 0, +0));
475 *Pointer<Short4>(out + 16 * 7) = Max(Short4(1, 0, -1, -0), Short4(0, 1, 0, +0));
476 *Pointer<UShort4>(out + 16 * 8) = Min(UShort4(1, 0, -1, -0), UShort4(0, 1, 0, +0));
477 *Pointer<UShort4>(out + 16 * 9) = Max(UShort4(1, 0, -1, -0), UShort4(0, 1, 0, +0));
482 routine = function("one");
486 unsigned int out[10][4];
488 memset(&out, 0, sizeof(out));
490 int(*callable)(void*) = (int(*)(void*))routine->getEntry();
493 EXPECT_EQ(out[0][0], 0x00000000u);
494 EXPECT_EQ(out[0][1], 0x00000000u);
495 EXPECT_EQ(out[0][2], 0x00000000u);
496 EXPECT_EQ(out[0][3], 0x80000000u);
498 EXPECT_EQ(out[1][0], 0x3F800000u);
499 EXPECT_EQ(out[1][1], 0x3F800000u);
500 EXPECT_EQ(out[1][2], 0x00000000u);
501 EXPECT_EQ(out[1][3], 0x80000000u);
503 EXPECT_EQ(out[2][0], 0x00000000u);
504 EXPECT_EQ(out[2][1], 0x00000000u);
505 EXPECT_EQ(out[2][2], 0xFFFFFFFFu);
506 EXPECT_EQ(out[2][3], 0x00000000u);
508 EXPECT_EQ(out[3][0], 0x00000001u);
509 EXPECT_EQ(out[3][1], 0x00000001u);
510 EXPECT_EQ(out[3][2], 0x00000000u);
511 EXPECT_EQ(out[3][3], 0x00000000u);
513 EXPECT_EQ(out[4][0], 0x00000000u);
514 EXPECT_EQ(out[4][1], 0x00000000u);
515 EXPECT_EQ(out[4][2], 0x00000000u);
516 EXPECT_EQ(out[4][3], 0x00000000u);
518 EXPECT_EQ(out[5][0], 0x00000001u);
519 EXPECT_EQ(out[5][1], 0x00000001u);
520 EXPECT_EQ(out[5][2], 0xFFFFFFFFu);
521 EXPECT_EQ(out[5][3], 0x00000000u);
523 EXPECT_EQ(out[6][0], 0x00000000u);
524 EXPECT_EQ(out[6][1], 0x0000FFFFu);
525 EXPECT_EQ(out[6][2], 0x00000000u);
526 EXPECT_EQ(out[6][3], 0x00000000u);
528 EXPECT_EQ(out[7][0], 0x00010001u);
529 EXPECT_EQ(out[7][1], 0x00000000u);
530 EXPECT_EQ(out[7][2], 0x00000000u);
531 EXPECT_EQ(out[7][3], 0x00000000u);
533 EXPECT_EQ(out[8][0], 0x00000000u);
534 EXPECT_EQ(out[8][1], 0x00000000u);
535 EXPECT_EQ(out[8][2], 0x00000000u);
536 EXPECT_EQ(out[8][3], 0x00000000u);
538 EXPECT_EQ(out[9][0], 0x00010001u);
539 EXPECT_EQ(out[9][1], 0x0000FFFFu);
540 EXPECT_EQ(out[9][2], 0x00000000u);
541 EXPECT_EQ(out[9][3], 0x00000000u);
548 TEST(ReactorUnitTests, NotNeg)
550 Routine *routine = nullptr;
553 Function<Int(Pointer<Byte>)> function;
555 Pointer<Byte> out = function.Arg<0>();
557 *Pointer<Int>(out + 16 * 0) = ~Int(0x55555555);
558 *Pointer<Short>(out + 16 * 1) = ~Short(0x5555);
559 *Pointer<Int4>(out + 16 * 2) = ~Int4(0x55555555, 0xAAAAAAAA, 0x00000000, 0xFFFFFFFF);
560 *Pointer<Short4>(out + 16 * 3) = ~Short4(0x5555, 0xAAAA, 0x0000, 0xFFFF);
562 *Pointer<Int>(out + 16 * 4) = -Int(0x55555555);
563 *Pointer<Short>(out + 16 * 5) = -Short(0x5555);
564 *Pointer<Int4>(out + 16 * 6) = -Int4(0x55555555, 0xAAAAAAAA, 0x00000000, 0xFFFFFFFF);
565 *Pointer<Short4>(out + 16 * 7) = -Short4(0x5555, 0xAAAA, 0x0000, 0xFFFF);
567 *Pointer<Float4>(out + 16 * 8) = -Float4(1.0f, -1.0f, 0.0f, -0.0f);
572 routine = function("one");
576 unsigned int out[10][4];
578 memset(&out, 0, sizeof(out));
580 int(*callable)(void*) = (int(*)(void*))routine->getEntry();
583 EXPECT_EQ(out[0][0], 0xAAAAAAAAu);
584 EXPECT_EQ(out[0][1], 0x00000000u);
585 EXPECT_EQ(out[0][2], 0x00000000u);
586 EXPECT_EQ(out[0][3], 0x00000000u);
588 EXPECT_EQ(out[1][0], 0x0000AAAAu);
589 EXPECT_EQ(out[1][1], 0x00000000u);
590 EXPECT_EQ(out[1][2], 0x00000000u);
591 EXPECT_EQ(out[1][3], 0x00000000u);
593 EXPECT_EQ(out[2][0], 0xAAAAAAAAu);
594 EXPECT_EQ(out[2][1], 0x55555555u);
595 EXPECT_EQ(out[2][2], 0xFFFFFFFFu);
596 EXPECT_EQ(out[2][3], 0x00000000u);
598 EXPECT_EQ(out[3][0], 0x5555AAAAu);
599 EXPECT_EQ(out[3][1], 0x0000FFFFu);
600 EXPECT_EQ(out[3][2], 0x00000000u);
601 EXPECT_EQ(out[3][3], 0x00000000u);
603 EXPECT_EQ(out[4][0], 0xAAAAAAABu);
604 EXPECT_EQ(out[4][1], 0x00000000u);
605 EXPECT_EQ(out[4][2], 0x00000000u);
606 EXPECT_EQ(out[4][3], 0x00000000u);
608 EXPECT_EQ(out[5][0], 0x0000AAABu);
609 EXPECT_EQ(out[5][1], 0x00000000u);
610 EXPECT_EQ(out[5][2], 0x00000000u);
611 EXPECT_EQ(out[5][3], 0x00000000u);
613 EXPECT_EQ(out[6][0], 0xAAAAAAABu);
614 EXPECT_EQ(out[6][1], 0x55555556u);
615 EXPECT_EQ(out[6][2], 0x00000000u);
616 EXPECT_EQ(out[6][3], 0x00000001u);
618 EXPECT_EQ(out[7][0], 0x5556AAABu);
619 EXPECT_EQ(out[7][1], 0x00010000u);
620 EXPECT_EQ(out[7][2], 0x00000000u);
621 EXPECT_EQ(out[7][3], 0x00000000u);
623 EXPECT_EQ(out[8][0], 0xBF800000u);
624 EXPECT_EQ(out[8][1], 0x3F800000u);
625 EXPECT_EQ(out[8][2], 0x80000000u);
626 EXPECT_EQ(out[8][3], 0x00000000u);
633 TEST(ReactorUnitTests, VectorCompare)
635 Routine *routine = nullptr;
638 Function<Int(Pointer<Byte>)> function;
640 Pointer<Byte> out = function.Arg<0>();
642 *Pointer<Int4>(out + 16 * 0) = CmpEQ(Float4(1.0f, 1.0f, -0.0f, +0.0f), Float4(0.0f, 1.0f, +0.0f, -0.0f));
643 *Pointer<Int4>(out + 16 * 1) = CmpEQ(Int4(1, 0, -1, -0), Int4(0, 1, 0, +0));
644 *Pointer<Byte8>(out + 16 * 2) = CmpEQ(SByte8(1, 2, 3, 4, 5, 6, 7, 8), SByte8(7, 6, 5, 4, 3, 2, 1, 0));
646 *Pointer<Int4>(out + 16 * 3) = CmpNLT(Float4(1.0f, 1.0f, -0.0f, +0.0f), Float4(0.0f, 1.0f, +0.0f, -0.0f));
647 *Pointer<Int4>(out + 16 * 4) = CmpNLT(Int4(1, 0, -1, -0), Int4(0, 1, 0, +0));
648 *Pointer<Byte8>(out + 16 * 5) = CmpGT(SByte8(1, 2, 3, 4, 5, 6, 7, 8), SByte8(7, 6, 5, 4, 3, 2, 1, 0));
653 routine = function("one");
657 unsigned int out[6][4];
659 memset(&out, 0, sizeof(out));
661 int(*callable)(void*) = (int(*)(void*))routine->getEntry();
664 EXPECT_EQ(out[0][0], 0x00000000u);
665 EXPECT_EQ(out[0][1], 0xFFFFFFFFu);
666 EXPECT_EQ(out[0][2], 0xFFFFFFFFu);
667 EXPECT_EQ(out[0][3], 0xFFFFFFFFu);
669 EXPECT_EQ(out[1][0], 0x00000000u);
670 EXPECT_EQ(out[1][1], 0x00000000u);
671 EXPECT_EQ(out[1][2], 0x00000000u);
672 EXPECT_EQ(out[1][3], 0xFFFFFFFFu);
674 EXPECT_EQ(out[2][0], 0xFF000000u);
675 EXPECT_EQ(out[2][1], 0x00000000u);
677 EXPECT_EQ(out[3][0], 0xFFFFFFFFu);
678 EXPECT_EQ(out[3][1], 0xFFFFFFFFu);
679 EXPECT_EQ(out[3][2], 0xFFFFFFFFu);
680 EXPECT_EQ(out[3][3], 0xFFFFFFFFu);
682 EXPECT_EQ(out[4][0], 0xFFFFFFFFu);
683 EXPECT_EQ(out[4][1], 0x00000000u);
684 EXPECT_EQ(out[4][2], 0x00000000u);
685 EXPECT_EQ(out[4][3], 0xFFFFFFFFu);
687 EXPECT_EQ(out[5][0], 0x00000000u);
688 EXPECT_EQ(out[5][1], 0xFFFFFFFFu);
695 TEST(ReactorUnitTests, SaturatedAddAndSubtract)
697 Routine *routine = nullptr;
700 Function<Int(Pointer<Byte>)> function;
702 Pointer<Byte> out = function.Arg<0>();
704 *Pointer<Byte8>(out + 8 * 0) =
705 AddSat(Byte8(1, 2, 3, 4, 5, 6, 7, 8),
706 Byte8(7, 6, 5, 4, 3, 2, 1, 0));
707 *Pointer<Byte8>(out + 8 * 1) =
708 AddSat(Byte8(0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE),
709 Byte8(7, 6, 5, 4, 3, 2, 1, 0));
710 *Pointer<Byte8>(out + 8 * 2) =
711 SubSat(Byte8(1, 2, 3, 4, 5, 6, 7, 8),
712 Byte8(7, 6, 5, 4, 3, 2, 1, 0));
714 *Pointer<SByte8>(out + 8 * 3) =
715 AddSat(SByte8(1, 2, 3, 4, 5, 6, 7, 8),
716 SByte8(7, 6, 5, 4, 3, 2, 1, 0));
717 *Pointer<SByte8>(out + 8 * 4) =
718 AddSat(SByte8(0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E),
719 SByte8(7, 6, 5, 4, 3, 2, 1, 0));
720 *Pointer<SByte8>(out + 8 * 5) =
721 AddSat(SByte8(0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88),
722 SByte8(-7, -6, -5, -4, -3, -2, -1, -0));
723 *Pointer<SByte8>(out + 8 * 6) =
724 SubSat(SByte8(0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88),
725 SByte8(7, 6, 5, 4, 3, 2, 1, 0));
727 *Pointer<Short4>(out + 8 * 7) =
728 AddSat(Short4(1, 2, 3, 4), Short4(3, 2, 1, 0));
729 *Pointer<Short4>(out + 8 * 8) =
730 AddSat(Short4(0x7FFE, 0x7FFE, 0x7FFE, 0x7FFE),
732 *Pointer<Short4>(out + 8 * 9) =
733 AddSat(Short4(0x8001, 0x8002, 0x8003, 0x8004),
734 Short4(-3, -2, -1, -0));
735 *Pointer<Short4>(out + 8 * 10) =
736 SubSat(Short4(0x8001, 0x8002, 0x8003, 0x8004),
739 *Pointer<UShort4>(out + 8 * 11) =
740 AddSat(UShort4(1, 2, 3, 4), UShort4(3, 2, 1, 0));
741 *Pointer<UShort4>(out + 8 * 12) =
742 AddSat(UShort4(0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE),
743 UShort4(3, 2, 1, 0));
744 *Pointer<UShort4>(out + 8 * 13) =
745 SubSat(UShort4(1, 2, 3, 4), UShort4(3, 2, 1, 0));
750 routine = function("one");
754 unsigned int out[14][2];
756 memset(&out, 0, sizeof(out));
758 int(*callable)(void*) = (int(*)(void*))routine->getEntry();
761 EXPECT_EQ(out[0][0], 0x08080808u);
762 EXPECT_EQ(out[0][1], 0x08080808u);
764 EXPECT_EQ(out[1][0], 0xFFFFFFFFu);
765 EXPECT_EQ(out[1][1], 0xFEFFFFFFu);
767 EXPECT_EQ(out[2][0], 0x00000000u);
768 EXPECT_EQ(out[2][1], 0x08060402u);
770 EXPECT_EQ(out[3][0], 0x08080808u);
771 EXPECT_EQ(out[3][1], 0x08080808u);
773 EXPECT_EQ(out[4][0], 0x7F7F7F7Fu);
774 EXPECT_EQ(out[4][1], 0x7E7F7F7Fu);
776 EXPECT_EQ(out[5][0], 0x80808080u);
777 EXPECT_EQ(out[5][1], 0x88868482u);
779 EXPECT_EQ(out[6][0], 0x80808080u);
780 EXPECT_EQ(out[6][1], 0x88868482u);
782 EXPECT_EQ(out[7][0], 0x00040004u);
783 EXPECT_EQ(out[7][1], 0x00040004u);
785 EXPECT_EQ(out[8][0], 0x7FFF7FFFu);
786 EXPECT_EQ(out[8][1], 0x7FFE7FFFu);
788 EXPECT_EQ(out[9][0], 0x80008000u);
789 EXPECT_EQ(out[9][1], 0x80048002u);
791 EXPECT_EQ(out[10][0], 0x80008000u);
792 EXPECT_EQ(out[10][1], 0x80048002u);
794 EXPECT_EQ(out[11][0], 0x00040004u);
795 EXPECT_EQ(out[11][1], 0x00040004u);
797 EXPECT_EQ(out[12][0], 0xFFFFFFFFu);
798 EXPECT_EQ(out[12][1], 0xFFFEFFFFu);
800 EXPECT_EQ(out[13][0], 0x00000000u);
801 EXPECT_EQ(out[13][1], 0x00040002u);
808 TEST(ReactorUnitTests, Unpack)
810 Routine *routine = nullptr;
813 Function<Int(Pointer<Byte>,Pointer<Byte>)> function;
815 Pointer<Byte> in = function.Arg<0>();
816 Pointer<Byte> out = function.Arg<1>();
818 Byte4 test_byte_a = *Pointer<Byte4>(in + 4 * 0);
819 Byte4 test_byte_b = *Pointer<Byte4>(in + 4 * 1);
821 *Pointer<Short4>(out + 8 * 0) =
822 Unpack(test_byte_a, test_byte_b);
824 *Pointer<Short4>(out + 8 * 1) = Unpack(test_byte_a);
829 routine = function("one");
833 unsigned int in[1][2];
834 unsigned int out[2][2];
836 memset(&out, 0, sizeof(out));
838 in[0][0] = 0xABCDEF12u;
839 in[0][1] = 0x34567890u;
841 int(*callable)(void*,void*) = (int(*)(void*,void*))routine->getEntry();
844 EXPECT_EQ(out[0][0], 0x78EF9012u);
845 EXPECT_EQ(out[0][1], 0x34AB56CDu);
847 EXPECT_EQ(out[1][0], 0xEFEF1212u);
848 EXPECT_EQ(out[1][1], 0xABABCDCDu);
855 TEST(ReactorUnitTests, Pack)
857 Routine *routine = nullptr;
860 Function<Int(Pointer<Byte>)> function;
862 Pointer<Byte> out = function.Arg<0>();
864 *Pointer<SByte8>(out + 8 * 0) =
865 PackSigned(Short4(-1, -2, 1, 2),
866 Short4(3, 4, -3, -4));
868 *Pointer<Byte8>(out + 8 * 1) =
869 PackUnsigned(Short4(-1, -2, 1, 2),
870 Short4(3, 4, -3, -4));
872 *Pointer<Short8>(out + 8 * 2) =
873 PackSigned(Int4(-1, -2, 1, 2),
876 *Pointer<UShort8>(out + 8 * 4) =
877 PackUnsigned(Int4(-1, -2, 1, 2),
883 routine = function("one");
887 unsigned int out[6][2];
889 memset(&out, 0, sizeof(out));
891 int(*callable)(void*) = (int(*)(void*))routine->getEntry();
894 EXPECT_EQ(out[0][0], 0x0201FEFFu);
895 EXPECT_EQ(out[0][1], 0xFCFD0403u);
897 EXPECT_EQ(out[1][0], 0x02010000u);
898 EXPECT_EQ(out[1][1], 0x00000403u);
900 EXPECT_EQ(out[2][0], 0xFFFEFFFFu);
901 EXPECT_EQ(out[2][1], 0x00020001u);
903 EXPECT_EQ(out[3][0], 0x00040003u);
904 EXPECT_EQ(out[3][1], 0xFFFCFFFDu);
906 EXPECT_EQ(out[4][0], 0x00000000u);
907 EXPECT_EQ(out[4][1], 0x00020001u);
909 EXPECT_EQ(out[5][0], 0x00040003u);
910 EXPECT_EQ(out[5][1], 0x00000000u);
917 TEST(ReactorUnitTests, MulHigh)
919 Routine *routine = nullptr;
922 Function<Int(Pointer<Byte>)> function;
924 Pointer<Byte> out = function.Arg<0>();
926 *Pointer<Short4>(out + 8 * 0) =
927 MulHigh(Short4(0x1aa, 0x2dd, 0x3ee, 0xF422),
928 Short4(0x1bb, 0x2cc, 0x3ff, 0xF411));
929 *Pointer<UShort4>(out + 8 * 1) =
930 MulHigh(UShort4(0x1aa, 0x2dd, 0x3ee, 0xF422),
931 UShort4(0x1bb, 0x2cc, 0x3ff, 0xF411));
933 // (U)Short8 variants are mentioned but unimplemented
937 routine = function("one");
941 unsigned int out[2][2];
943 memset(&out, 0, sizeof(out));
945 int(*callable)(void*) = (int(*)(void*))routine->getEntry();
948 EXPECT_EQ(out[0][0], 0x00080002u);
949 EXPECT_EQ(out[0][1], 0x008D000fu);
951 EXPECT_EQ(out[1][0], 0x00080002u);
952 EXPECT_EQ(out[1][1], 0xe8C0000Fu);
959 TEST(ReactorUnitTests, MulAdd)
961 Routine *routine = nullptr;
964 Function<Int(Pointer<Byte>)> function;
966 Pointer<Byte> out = function.Arg<0>();
968 *Pointer<Int2>(out + 8 * 0) =
969 MulAdd(Short4(0x1aa, 0x2dd, 0x3ee, 0xF422),
970 Short4(0x1bb, 0x2cc, 0x3ff, 0xF411));
972 // (U)Short8 variant is mentioned but unimplemented
976 routine = function("one");
980 unsigned int out[1][2];
982 memset(&out, 0, sizeof(out));
984 int(*callable)(void*) = (int(*)(void*))routine->getEntry();
987 EXPECT_EQ(out[0][0], 0x000AE34Au);
988 EXPECT_EQ(out[0][1], 0x009D5254u);
995 int main(int argc, char **argv)
997 ::testing::InitGoogleTest(&argc, argv);
998 return RUN_ALL_TESTS();