• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
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(ReactorUnitTests,Sample)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 
TEST(ReactorUnitTests,Uninitialized)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 
TEST(ReactorUnitTests,SubVectorLoadStore)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 
TEST(ReactorUnitTests,VectorConstant)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 
TEST(ReactorUnitTests,Concatenate)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 
TEST(ReactorUnitTests,Swizzle)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 
TEST(ReactorUnitTests,Branching)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 
TEST(ReactorUnitTests,MinMax)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 
TEST(ReactorUnitTests,NotNeg)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 
TEST(ReactorUnitTests,VectorCompare)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 
TEST(ReactorUnitTests,SaturatedAddAndSubtract)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 
TEST(ReactorUnitTests,Unpack)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 
TEST(ReactorUnitTests,Pack)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 
TEST(ReactorUnitTests,MulHigh)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 
TEST(ReactorUnitTests,MulAdd)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 
main(int argc,char ** argv)995 int main(int argc, char **argv)
996 {
997 	::testing::InitGoogleTest(&argc, argv);
998 	return RUN_ALL_TESTS();
999 }
1000