OSDN Git Service

Add SPIRV-Headers as git subtree
[android-x86/external-swiftshader.git] / src / Reactor / ReactorUnitTests.cpp
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 rr;
20
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
36 TEST(ReactorUnitTests, 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("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
76 TEST(ReactorUnitTests, 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("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
113 TEST(ReactorUnitTests, 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("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
173 TEST(ReactorUnitTests, 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("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
222 TEST(ReactorUnitTests, 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("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
265 TEST(ReactorUnitTests, 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                         for(int i = 0; i < 256; i++)
292                         {
293                                 *Pointer<Short4>(out + 16 * (512 + 6) + (8 * i)) =
294                                     Swizzle(Short4(1, 2, 3, 4), i);
295                         }
296
297                         for(int i = 0; i < 256; i++)
298                         {
299                                 *Pointer<Int4>(out + 16 * (512 + 6 + i) + (8 * 256)) =
300                                     Swizzle(Int4(1, 2, 3, 4), i);
301                         }
302
303                         Return(0);
304                 }
305
306                 routine = function("one");
307
308                 if(routine)
309                 {
310                         struct
311                         {
312                                 float f[256 + 256 + 2][4];
313                                 int i[388][4];
314                         } out;
315
316                         memset(&out, 0, sizeof(out));
317
318                         int(*callable)(void*) = (int(*)(void*))routine->getEntry();
319                         callable(&out);
320
321                         for(int i = 0; i < 256; i++)
322                         {
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);
327                         }
328
329                         for(int i = 0; i < 256; i++)
330                         {
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);
335                         }
336
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);
341
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);
346
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);
351
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);
356
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);
361
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);
366
367                         for(int i = 0; i < 256; i++)
368                         {
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);
377                         }
378
379                         for(int i = 0; i < 256; i++)
380                         {
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);
385                         }
386                 }
387         }
388
389         delete routine;
390 }
391
392 TEST(ReactorUnitTests, Branching)
393 {
394         Routine *routine = nullptr;
395
396         {
397                 Function<Int(Void)> function;
398                 {
399                         Int x = 0;
400
401                         For(Int i = 0, i < 8, i++)
402                         {
403                                 If(i < 2)
404                                 {
405                                         x += 1;
406                                 }
407                                 Else If(i < 4)
408                                 {
409                                         x += 10;
410                                 }
411                                 Else If(i < 6)
412                                 {
413                                         x += 100;
414                                 }
415                                 Else
416                                 {
417                                         x += 1000;
418                                 }
419
420                                 For(Int i = 0, i < 5, i++)
421                                         x += 10000;
422                         }
423
424                         For(Int i = 0, i < 10, i++)
425                                 for(int i = 0; i < 10; i++)
426                                         For(Int i = 0, i < 10, i++)
427                                         {
428                                                 x += 1000000;
429                                         }
430
431                         For(Int i = 0, i < 2, i++)
432                                 If(x == 1000402222)
433                                 {
434                                         If(x != 1000402222)
435                                                 x += 1000000000;
436                                 }
437                                 Else
438                                         x = -5;
439
440                         Return(x);
441                 }
442
443                 routine = function("one");
444
445                 if(routine)
446                 {
447                         int(*callable)() = (int(*)())routine->getEntry();
448                         int result = callable();
449
450                         EXPECT_EQ(result, 1000402222);
451                 }
452         }
453
454         delete routine;
455 }
456
457 TEST(ReactorUnitTests, MinMax)
458 {
459         Routine *routine = nullptr;
460
461         {
462                 Function<Int(Pointer<Byte>)> function;
463                 {
464                         Pointer<Byte> out = function.Arg<0>();
465
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));
468
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));
473
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));
478
479                         Return(0);
480                 }
481
482                 routine = function("one");
483
484                 if(routine)
485                 {
486                         unsigned int out[10][4];
487
488                         memset(&out, 0, sizeof(out));
489
490                         int(*callable)(void*) = (int(*)(void*))routine->getEntry();
491                         callable(&out);
492
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);
497
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);
502
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);
507
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);
512
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);
517
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);
522
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);
527
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);
532
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);
537
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);
542                 }
543         }
544
545         delete routine;
546 }
547
548 TEST(ReactorUnitTests, NotNeg)
549 {
550         Routine *routine = nullptr;
551
552         {
553                 Function<Int(Pointer<Byte>)> function;
554                 {
555                         Pointer<Byte> out = function.Arg<0>();
556
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);
561
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);
566
567                         *Pointer<Float4>(out + 16 * 8) = -Float4(1.0f, -1.0f, 0.0f, -0.0f);
568
569                         Return(0);
570                 }
571
572                 routine = function("one");
573
574                 if(routine)
575                 {
576                         unsigned int out[10][4];
577
578                         memset(&out, 0, sizeof(out));
579
580                         int(*callable)(void*) = (int(*)(void*))routine->getEntry();
581                         callable(&out);
582
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);
587
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);
592
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);
597
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);
602
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);
607
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);
612
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);
617
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);
622
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);
627                 }
628         }
629
630         delete routine;
631 }
632
633 TEST(ReactorUnitTests, VectorCompare)
634 {
635         Routine *routine = nullptr;
636
637         {
638                 Function<Int(Pointer<Byte>)> function;
639                 {
640                         Pointer<Byte> out = function.Arg<0>();
641
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));
645
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));
649
650                         Return(0);
651                 }
652
653                 routine = function("one");
654
655                 if(routine)
656                 {
657                         unsigned int out[6][4];
658
659                         memset(&out, 0, sizeof(out));
660
661                         int(*callable)(void*) = (int(*)(void*))routine->getEntry();
662                         callable(&out);
663
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);
668
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);
673
674                         EXPECT_EQ(out[2][0], 0xFF000000u);
675                         EXPECT_EQ(out[2][1], 0x00000000u);
676
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);
681
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);
686
687                         EXPECT_EQ(out[5][0], 0x00000000u);
688                         EXPECT_EQ(out[5][1], 0xFFFFFFFFu);
689                 }
690         }
691
692         delete routine;
693 }
694
695 TEST(ReactorUnitTests, SaturatedAddAndSubtract)
696 {
697         Routine *routine = nullptr;
698
699         {
700                 Function<Int(Pointer<Byte>)> function;
701                 {
702                         Pointer<Byte> out = function.Arg<0>();
703
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));
713
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));
726
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),
731                                        Short4(3, 2, 1, 0));
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),
737                                        Short4(3, 2, 1, 0));
738
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));
746
747                         Return(0);
748                 }
749
750                 routine = function("one");
751
752                 if(routine)
753                 {
754                         unsigned int out[14][2];
755
756                         memset(&out, 0, sizeof(out));
757
758                         int(*callable)(void*) = (int(*)(void*))routine->getEntry();
759                         callable(&out);
760
761                         EXPECT_EQ(out[0][0], 0x08080808u);
762                         EXPECT_EQ(out[0][1], 0x08080808u);
763
764                         EXPECT_EQ(out[1][0], 0xFFFFFFFFu);
765                         EXPECT_EQ(out[1][1], 0xFEFFFFFFu);
766
767                         EXPECT_EQ(out[2][0], 0x00000000u);
768                         EXPECT_EQ(out[2][1], 0x08060402u);
769
770                         EXPECT_EQ(out[3][0], 0x08080808u);
771                         EXPECT_EQ(out[3][1], 0x08080808u);
772
773                         EXPECT_EQ(out[4][0], 0x7F7F7F7Fu);
774                         EXPECT_EQ(out[4][1], 0x7E7F7F7Fu);
775
776                         EXPECT_EQ(out[5][0], 0x80808080u);
777                         EXPECT_EQ(out[5][1], 0x88868482u);
778
779                         EXPECT_EQ(out[6][0], 0x80808080u);
780                         EXPECT_EQ(out[6][1], 0x88868482u);
781
782                         EXPECT_EQ(out[7][0], 0x00040004u);
783                         EXPECT_EQ(out[7][1], 0x00040004u);
784
785                         EXPECT_EQ(out[8][0], 0x7FFF7FFFu);
786                         EXPECT_EQ(out[8][1], 0x7FFE7FFFu);
787
788                         EXPECT_EQ(out[9][0], 0x80008000u);
789                         EXPECT_EQ(out[9][1], 0x80048002u);
790
791                         EXPECT_EQ(out[10][0], 0x80008000u);
792                         EXPECT_EQ(out[10][1], 0x80048002u);
793
794                         EXPECT_EQ(out[11][0], 0x00040004u);
795                         EXPECT_EQ(out[11][1], 0x00040004u);
796
797                         EXPECT_EQ(out[12][0], 0xFFFFFFFFu);
798                         EXPECT_EQ(out[12][1], 0xFFFEFFFFu);
799
800                         EXPECT_EQ(out[13][0], 0x00000000u);
801                         EXPECT_EQ(out[13][1], 0x00040002u);
802                 }
803         }
804
805         delete routine;
806 }
807
808 TEST(ReactorUnitTests, Unpack)
809 {
810         Routine *routine = nullptr;
811
812         {
813                 Function<Int(Pointer<Byte>,Pointer<Byte>)> function;
814                 {
815                         Pointer<Byte> in = function.Arg<0>();
816                         Pointer<Byte> out = function.Arg<1>();
817
818                         Byte4 test_byte_a = *Pointer<Byte4>(in + 4 * 0);
819                         Byte4 test_byte_b = *Pointer<Byte4>(in + 4 * 1);
820
821                         *Pointer<Short4>(out + 8 * 0) =
822                                 Unpack(test_byte_a, test_byte_b);
823
824                         *Pointer<Short4>(out + 8 * 1) = Unpack(test_byte_a);
825
826                         Return(0);
827                 }
828
829                 routine = function("one");
830
831                 if(routine)
832                 {
833                         unsigned int in[1][2];
834                         unsigned int out[2][2];
835
836                         memset(&out, 0, sizeof(out));
837
838                         in[0][0] = 0xABCDEF12u;
839                         in[0][1] = 0x34567890u;
840
841                         int(*callable)(void*,void*) = (int(*)(void*,void*))routine->getEntry();
842                         callable(&in, &out);
843
844                         EXPECT_EQ(out[0][0], 0x78EF9012u);
845                         EXPECT_EQ(out[0][1], 0x34AB56CDu);
846
847                         EXPECT_EQ(out[1][0], 0xEFEF1212u);
848                         EXPECT_EQ(out[1][1], 0xABABCDCDu);
849                 }
850         }
851
852         delete routine;
853 }
854
855 TEST(ReactorUnitTests, Pack)
856 {
857         Routine *routine = nullptr;
858
859         {
860                 Function<Int(Pointer<Byte>)> function;
861                 {
862                         Pointer<Byte> out = function.Arg<0>();
863
864                         *Pointer<SByte8>(out + 8 * 0) =
865                                 PackSigned(Short4(-1, -2, 1, 2),
866                                            Short4(3, 4, -3, -4));
867
868                         *Pointer<Byte8>(out + 8 * 1) =
869                                 PackUnsigned(Short4(-1, -2, 1, 2),
870                                              Short4(3, 4, -3, -4));
871
872                         *Pointer<Short8>(out + 8 * 2) =
873                                 PackSigned(Int4(-1, -2, 1, 2),
874                                            Int4(3, 4, -3, -4));
875
876                         *Pointer<UShort8>(out + 8 * 4) =
877                                 PackUnsigned(Int4(-1, -2, 1, 2),
878                                              Int4(3, 4, -3, -4));
879
880                         Return(0);
881                 }
882
883                 routine = function("one");
884
885                 if(routine)
886                 {
887                         unsigned int out[6][2];
888
889                         memset(&out, 0, sizeof(out));
890
891                         int(*callable)(void*) = (int(*)(void*))routine->getEntry();
892                         callable(&out);
893
894                         EXPECT_EQ(out[0][0], 0x0201FEFFu);
895                         EXPECT_EQ(out[0][1], 0xFCFD0403u);
896
897                         EXPECT_EQ(out[1][0], 0x02010000u);
898                         EXPECT_EQ(out[1][1], 0x00000403u);
899
900                         EXPECT_EQ(out[2][0], 0xFFFEFFFFu);
901                         EXPECT_EQ(out[2][1], 0x00020001u);
902
903                         EXPECT_EQ(out[3][0], 0x00040003u);
904                         EXPECT_EQ(out[3][1], 0xFFFCFFFDu);
905
906                         EXPECT_EQ(out[4][0], 0x00000000u);
907                         EXPECT_EQ(out[4][1], 0x00020001u);
908
909                         EXPECT_EQ(out[5][0], 0x00040003u);
910                         EXPECT_EQ(out[5][1], 0x00000000u);
911                 }
912         }
913
914         delete routine;
915 }
916
917 TEST(ReactorUnitTests, MulHigh)
918 {
919         Routine *routine = nullptr;
920
921         {
922                 Function<Int(Pointer<Byte>)> function;
923                 {
924                         Pointer<Byte> out = function.Arg<0>();
925
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));
932
933                         // (U)Short8 variants are mentioned but unimplemented
934                         Return(0);
935                 }
936
937                 routine = function("one");
938
939                 if(routine)
940                 {
941                         unsigned int out[2][2];
942
943                         memset(&out, 0, sizeof(out));
944
945                         int(*callable)(void*) = (int(*)(void*))routine->getEntry();
946                         callable(&out);
947
948                         EXPECT_EQ(out[0][0], 0x00080002u);
949                         EXPECT_EQ(out[0][1], 0x008D000fu);
950
951                         EXPECT_EQ(out[1][0], 0x00080002u);
952                         EXPECT_EQ(out[1][1], 0xe8C0000Fu);
953                 }
954         }
955
956         delete routine;
957 }
958
959 TEST(ReactorUnitTests, MulAdd)
960 {
961         Routine *routine = nullptr;
962
963         {
964                 Function<Int(Pointer<Byte>)> function;
965                 {
966                         Pointer<Byte> out = function.Arg<0>();
967
968                         *Pointer<Int2>(out + 8 * 0) =
969                                 MulAdd(Short4(0x1aa, 0x2dd, 0x3ee, 0xF422),
970                                        Short4(0x1bb, 0x2cc, 0x3ff, 0xF411));
971
972                         // (U)Short8 variant is mentioned but unimplemented
973                         Return(0);
974                 }
975
976                 routine = function("one");
977
978                 if(routine)
979                 {
980                         unsigned int out[1][2];
981
982                         memset(&out, 0, sizeof(out));
983
984                         int(*callable)(void*) = (int(*)(void*))routine->getEntry();
985                         callable(&out);
986
987                         EXPECT_EQ(out[0][0], 0x000AE34Au);
988                         EXPECT_EQ(out[0][1], 0x009D5254u);
989                 }
990         }
991
992         delete routine;
993 }
994
995 int main(int argc, char **argv)
996 {
997         ::testing::InitGoogleTest(&argc, argv);
998         return RUN_ALL_TESTS();
999 }