blob: dcfe9619b2657a845de229c544b2cf94381c8cce [file] [log] [blame]
Nicolas Capens598f8d82016-09-26 15:09:10 -04001// 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"
Ben Clayton1c82c7b2019-04-30 12:49:27 +010016#include "Coroutine.hpp"
Nicolas Capens598f8d82016-09-26 15:09:10 -040017
Nicolas Capens228b05d2016-10-12 15:27:04 -040018#include "gtest/gtest.h"
Nicolas Capens598f8d82016-09-26 15:09:10 -040019
Ben Claytonb1243732019-02-27 23:56:18 +000020#include <tuple>
21
Nicolas Capens48461502018-08-06 14:20:45 -040022using namespace rr;
Nicolas Capens598f8d82016-09-26 15:09:10 -040023
Nicolas Capens7d9f76d2016-09-29 13:39:44 -040024int reference(int *p, int y)
25{
Nicolas Capens8820f642016-09-30 04:42:43 -040026 int x = p[-1];
Nicolas Capens7d9f76d2016-09-29 13:39:44 -040027 int z = 4;
28
29 for(int i = 0; i < 10; i++)
30 {
31 z += (2 << i) - (i / 3);
32 }
33
34 int sum = x + y + z;
Nicolas Capens228b05d2016-10-12 15:27:04 -040035
Nicolas Capens7d9f76d2016-09-29 13:39:44 -040036 return sum;
37}
38
Nicolas Capensc07dc4b2018-08-06 14:20:45 -040039TEST(ReactorUnitTests, Sample)
Nicolas Capens598f8d82016-09-26 15:09:10 -040040{
Nicolas Capens598f8d82016-09-26 15:09:10 -040041 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -040042 FunctionT<int(int*, int)> function;
Nicolas Capens598f8d82016-09-26 15:09:10 -040043 {
Nicolas Capense12780d2016-09-27 14:18:07 -040044 Pointer<Int> p = function.Arg<0>();
Nicolas Capens8820f642016-09-30 04:42:43 -040045 Int x = p[-1];
Nicolas Capens598f8d82016-09-26 15:09:10 -040046 Int y = function.Arg<1>();
Nicolas Capensb955d5b2016-09-28 22:36:28 -040047 Int z = 4;
48
Nicolas Capens611642a2016-09-28 16:45:04 -040049 For(Int i = 0, i < 10, i++)
50 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -040051 z += (2 << i) - (i / 3);
Nicolas Capens611642a2016-09-28 16:45:04 -040052 }
53
Nicolas Capens9709d4f2016-09-30 11:44:14 -040054 Float4 v;
55 v.z = As<Float>(z);
56 z = As<Int>(Float(Float4(v.xzxx).y));
57
Nicolas Capensb955d5b2016-09-28 22:36:28 -040058 Int sum = x + y + z;
Nicolas Capens5e6ca092017-01-13 15:09:21 -050059
Nicolas Capens598f8d82016-09-26 15:09:10 -040060 Return(sum);
61 }
62
Antonio Maiorano03935ae2019-10-29 16:20:27 -040063 auto routine = function("one");
Nicolas Capens598f8d82016-09-26 15:09:10 -040064
65 if(routine)
66 {
Nicolas Capens8820f642016-09-30 04:42:43 -040067 int one[2] = {1, 0};
Antonio Maiorano03935ae2019-10-29 16:20:27 -040068 int result = routine(&one[1], 2);
Nicolas Capens228b05d2016-10-12 15:27:04 -040069 EXPECT_EQ(result, reference(&one[1], 2));
Nicolas Capens598f8d82016-09-26 15:09:10 -040070 }
71 }
72
Nicolas Capens228b05d2016-10-12 15:27:04 -040073}
Nicolas Capens598f8d82016-09-26 15:09:10 -040074
Nicolas Capensc07dc4b2018-08-06 14:20:45 -040075TEST(ReactorUnitTests, Uninitialized)
Nicolas Capensf4452fc2016-12-12 13:08:06 -050076{
Nicolas Capensf4452fc2016-12-12 13:08:06 -050077 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -040078 FunctionT<int()> function;
Nicolas Capensf4452fc2016-12-12 13:08:06 -050079 {
80 Int a;
81 Int z = 4;
82 Int q;
83 Int c;
84 Int p;
85 Bool b;
86
87 q += q;
88
89 If(b)
90 {
91 c = p;
92 }
Nicolas Capens5e6ca092017-01-13 15:09:21 -050093
Nicolas Capensf4452fc2016-12-12 13:08:06 -050094 Return(a + z + q + c);
95 }
96
Antonio Maiorano03935ae2019-10-29 16:20:27 -040097 auto routine = function("one");
Nicolas Capensf4452fc2016-12-12 13:08:06 -050098
99 if(routine)
100 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400101 int result = routine();
Nicolas Capensf4452fc2016-12-12 13:08:06 -0500102 EXPECT_EQ(result, result); // Anything is fine, just don't crash
103 }
104 }
105
Nicolas Capensf4452fc2016-12-12 13:08:06 -0500106}
107
Nicolas Capens0192d152019-03-27 14:46:07 -0400108TEST(ReactorUnitTests, Unreachable)
109{
Nicolas Capens0192d152019-03-27 14:46:07 -0400110 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400111 FunctionT<int(int)> function;
Nicolas Capens0192d152019-03-27 14:46:07 -0400112 {
113 Int a = function.Arg<0>();
114 Int z = 4;
115
116 Return(a + z);
117
118 // Code beyond this point is unreachable but should not cause any
119 // compilation issues.
120
121 z += a;
122 }
123
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400124 auto routine = function("one");
Nicolas Capens0192d152019-03-27 14:46:07 -0400125
126 if(routine)
127 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400128 int result = routine(16);
Nicolas Capens0192d152019-03-27 14:46:07 -0400129 EXPECT_EQ(result, 20);
130 }
131 }
132
Nicolas Capens0192d152019-03-27 14:46:07 -0400133}
134
135TEST(ReactorUnitTests, VariableAddress)
136{
Nicolas Capens0192d152019-03-27 14:46:07 -0400137 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400138 FunctionT<int(int)> function;
Nicolas Capens0192d152019-03-27 14:46:07 -0400139 {
140 Int a = function.Arg<0>();
141 Int z = 0;
142 Pointer<Int> p = &z;
143 *p = 4;
144
145 Return(a + z);
146 }
147
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400148 auto routine = function("one");
Nicolas Capens0192d152019-03-27 14:46:07 -0400149
150 if(routine)
151 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400152 int result = routine(16);
Nicolas Capens0192d152019-03-27 14:46:07 -0400153 EXPECT_EQ(result, 20);
154 }
155 }
156
Nicolas Capens0192d152019-03-27 14:46:07 -0400157}
158
Nicolas Capensc07dc4b2018-08-06 14:20:45 -0400159TEST(ReactorUnitTests, SubVectorLoadStore)
Nicolas Capens23d99a42016-09-30 14:57:16 -0400160{
Nicolas Capens23d99a42016-09-30 14:57:16 -0400161 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400162 FunctionT<int(void*, void*)> function;
Nicolas Capens23d99a42016-09-30 14:57:16 -0400163 {
164 Pointer<Byte> in = function.Arg<0>();
165 Pointer<Byte> out = function.Arg<1>();
166
167 *Pointer<Int4>(out + 16 * 0) = *Pointer<Int4>(in + 16 * 0);
168 *Pointer<Short4>(out + 16 * 1) = *Pointer<Short4>(in + 16 * 1);
169 *Pointer<Byte8>(out + 16 * 2) = *Pointer<Byte8>(in + 16 * 2);
170 *Pointer<Byte4>(out + 16 * 3) = *Pointer<Byte4>(in + 16 * 3);
171 *Pointer<Short2>(out + 16 * 4) = *Pointer<Short2>(in + 16 * 4);
Nicolas Capens5e6ca092017-01-13 15:09:21 -0500172
Nicolas Capens23d99a42016-09-30 14:57:16 -0400173 Return(0);
174 }
175
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400176 auto routine = function("one");
Nicolas Capens23d99a42016-09-30 14:57:16 -0400177
178 if(routine)
179 {
180 int8_t in[16 * 5] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
181 17, 18, 19, 20, 21, 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0,
182 25, 26, 27, 28, 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 0,
183 33, 34, 35, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
184 37, 38, 39, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
185
186 int8_t out[16 * 5] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
187 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
188 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
189 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
190 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
Nicolas Capens5e6ca092017-01-13 15:09:21 -0500191
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400192 routine(in, out);
Nicolas Capens23d99a42016-09-30 14:57:16 -0400193
194 for(int row = 0; row < 5; row++)
195 {
196 for(int col = 0; col < 16; col++)
197 {
198 int i = row * 16 + col;
199
200 if(in[i] == 0)
201 {
202 EXPECT_EQ(out[i], -1) << "Row " << row << " column " << col << " not left untouched.";
203 }
204 else
205 {
206 EXPECT_EQ(out[i], in[i]) << "Row " << row << " column " << col << " not equal to input.";
207 }
208 }
209 }
210 }
211 }
212
Nicolas Capens23d99a42016-09-30 14:57:16 -0400213}
214
Nicolas Capensc07dc4b2018-08-06 14:20:45 -0400215TEST(ReactorUnitTests, VectorConstant)
Nicolas Capens8dfd9a72016-10-13 17:44:51 -0400216{
Nicolas Capens8dfd9a72016-10-13 17:44:51 -0400217 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400218 FunctionT<int(void*)> function;
Nicolas Capens8dfd9a72016-10-13 17:44:51 -0400219 {
220 Pointer<Byte> out = function.Arg<0>();
221
222 *Pointer<Int4>(out + 16 * 0) = Int4(0x04030201, 0x08070605, 0x0C0B0A09, 0x100F0E0D);
223 *Pointer<Short4>(out + 16 * 1) = Short4(0x1211, 0x1413, 0x1615, 0x1817);
224 *Pointer<Byte8>(out + 16 * 2) = Byte8(0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20);
225 *Pointer<Int2>(out + 16 * 3) = Int2(0x24232221, 0x28272625);
226
227 Return(0);
228 }
229
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400230 auto routine = function("one");
Nicolas Capens8dfd9a72016-10-13 17:44:51 -0400231
232 if(routine)
233 {
234 int8_t out[16 * 4] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
235 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
236 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
237 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
238
239 int8_t exp[16 * 4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
240 17, 18, 19, 20, 21, 22, 23, 24, -1, -1, -1, -1, -1, -1, -1, -1,
241 25, 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, -1, -1, -1, -1, -1,
242 33, 34, 35, 36, 37, 38, 39, 40, -1, -1, -1, -1, -1, -1, -1, -1};
243
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400244 routine(out);
Nicolas Capens8dfd9a72016-10-13 17:44:51 -0400245
246 for(int row = 0; row < 4; row++)
247 {
248 for(int col = 0; col < 16; col++)
249 {
250 int i = row * 16 + col;
251
252 EXPECT_EQ(out[i], exp[i]);
253 }
254 }
255 }
256 }
257
Nicolas Capens8dfd9a72016-10-13 17:44:51 -0400258}
259
Nicolas Capensc07dc4b2018-08-06 14:20:45 -0400260TEST(ReactorUnitTests, Concatenate)
Nicolas Capensc70a1162016-12-03 00:16:14 -0500261{
Nicolas Capensc70a1162016-12-03 00:16:14 -0500262 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400263 FunctionT<int(void*)> function;
Nicolas Capensc70a1162016-12-03 00:16:14 -0500264 {
265 Pointer<Byte> out = function.Arg<0>();
266
267 *Pointer<Int4>(out + 16 * 0) = Int4(Int2(0x04030201, 0x08070605), Int2(0x0C0B0A09, 0x100F0E0D));
268 *Pointer<Short8>(out + 16 * 1) = Short8(Short4(0x0201, 0x0403, 0x0605, 0x0807), Short4(0x0A09, 0x0C0B, 0x0E0D, 0x100F));
269
270 Return(0);
271 }
272
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400273 auto routine = function("one");
Nicolas Capensc70a1162016-12-03 00:16:14 -0500274
275 if(routine)
276 {
277 int8_t ref[16 * 5] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
278 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
279
280 int8_t out[16 * 5] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
281 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
Nicolas Capens5e6ca092017-01-13 15:09:21 -0500282
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400283 routine(out);
Nicolas Capensc70a1162016-12-03 00:16:14 -0500284
285 for(int row = 0; row < 2; row++)
286 {
287 for(int col = 0; col < 16; col++)
288 {
289 int i = row * 16 + col;
290
291 EXPECT_EQ(out[i], ref[i]) << "Row " << row << " column " << col << " not equal to reference.";
292 }
293 }
294 }
295 }
296
Nicolas Capensc70a1162016-12-03 00:16:14 -0500297}
298
Nicolas Capensc07dc4b2018-08-06 14:20:45 -0400299TEST(ReactorUnitTests, Swizzle)
Nicolas Capens363b61e2016-10-21 13:19:34 -0400300{
Nicolas Capens363b61e2016-10-21 13:19:34 -0400301 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400302 FunctionT<int(void*)> function;
Nicolas Capens363b61e2016-10-21 13:19:34 -0400303 {
304 Pointer<Byte> out = function.Arg<0>();
305
306 for(int i = 0; i < 256; i++)
307 {
308 *Pointer<Float4>(out + 16 * i) = Swizzle(Float4(1.0f, 2.0f, 3.0f, 4.0f), i);
309 }
310
311 for(int i = 0; i < 256; i++)
312 {
313 *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);
314 }
315
316 *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));
317 *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));
Nicolas Capens20e22c42016-10-25 17:32:37 -0400318 *Pointer<Int2>(out + 16 * (512 + 2)) = UnpackLow(Short4(1, 2, 3, 4), Short4(5, 6, 7, 8));
319 *Pointer<Int2>(out + 16 * (512 + 3)) = UnpackHigh(Short4(1, 2, 3, 4), Short4(5, 6, 7, 8));
320 *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));
321 *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));
Nicolas Capens363b61e2016-10-21 13:19:34 -0400322
Casey Dahlin9d56da22017-10-03 13:23:11 -0700323 for(int i = 0; i < 256; i++)
324 {
325 *Pointer<Short4>(out + 16 * (512 + 6) + (8 * i)) =
326 Swizzle(Short4(1, 2, 3, 4), i);
327 }
328
329 for(int i = 0; i < 256; i++)
330 {
331 *Pointer<Int4>(out + 16 * (512 + 6 + i) + (8 * 256)) =
332 Swizzle(Int4(1, 2, 3, 4), i);
333 }
334
Nicolas Capens363b61e2016-10-21 13:19:34 -0400335 Return(0);
336 }
337
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400338 auto routine = function("one");
Nicolas Capens363b61e2016-10-21 13:19:34 -0400339
340 if(routine)
341 {
Nicolas Capens20e22c42016-10-25 17:32:37 -0400342 struct
Nicolas Capens363b61e2016-10-21 13:19:34 -0400343 {
Nicolas Capens20e22c42016-10-25 17:32:37 -0400344 float f[256 + 256 + 2][4];
Casey Dahlin9d56da22017-10-03 13:23:11 -0700345 int i[388][4];
Nicolas Capens20e22c42016-10-25 17:32:37 -0400346 } out;
Nicolas Capens363b61e2016-10-21 13:19:34 -0400347
Nicolas Capens20e22c42016-10-25 17:32:37 -0400348 memset(&out, 0, sizeof(out));
Nicolas Capens363b61e2016-10-21 13:19:34 -0400349
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400350 routine(&out);
Nicolas Capens363b61e2016-10-21 13:19:34 -0400351
Nicolas Capens20e22c42016-10-25 17:32:37 -0400352 for(int i = 0; i < 256; i++)
Nicolas Capens363b61e2016-10-21 13:19:34 -0400353 {
Nicolas Capens20e22c42016-10-25 17:32:37 -0400354 EXPECT_EQ(out.f[i][0], float((i >> 0) & 0x03) + 1.0f);
355 EXPECT_EQ(out.f[i][1], float((i >> 2) & 0x03) + 1.0f);
356 EXPECT_EQ(out.f[i][2], float((i >> 4) & 0x03) + 1.0f);
357 EXPECT_EQ(out.f[i][3], float((i >> 6) & 0x03) + 1.0f);
Nicolas Capens363b61e2016-10-21 13:19:34 -0400358 }
Nicolas Capens20e22c42016-10-25 17:32:37 -0400359
360 for(int i = 0; i < 256; i++)
361 {
362 EXPECT_EQ(out.f[256 + i][0], float((i >> 0) & 0x03) + 1.0f);
363 EXPECT_EQ(out.f[256 + i][1], float((i >> 2) & 0x03) + 1.0f);
364 EXPECT_EQ(out.f[256 + i][2], float((i >> 4) & 0x03) + 5.0f);
365 EXPECT_EQ(out.f[256 + i][3], float((i >> 6) & 0x03) + 5.0f);
366 }
367
368 EXPECT_EQ(out.f[512 + 0][0], 1.0f);
369 EXPECT_EQ(out.f[512 + 0][1], 5.0f);
370 EXPECT_EQ(out.f[512 + 0][2], 2.0f);
371 EXPECT_EQ(out.f[512 + 0][3], 6.0f);
372
373 EXPECT_EQ(out.f[512 + 1][0], 3.0f);
374 EXPECT_EQ(out.f[512 + 1][1], 7.0f);
375 EXPECT_EQ(out.f[512 + 1][2], 4.0f);
376 EXPECT_EQ(out.f[512 + 1][3], 8.0f);
377
378 EXPECT_EQ(out.i[0][0], 0x00050001);
379 EXPECT_EQ(out.i[0][1], 0x00060002);
380 EXPECT_EQ(out.i[0][2], 0x00000000);
381 EXPECT_EQ(out.i[0][3], 0x00000000);
382
383 EXPECT_EQ(out.i[1][0], 0x00070003);
384 EXPECT_EQ(out.i[1][1], 0x00080004);
385 EXPECT_EQ(out.i[1][2], 0x00000000);
386 EXPECT_EQ(out.i[1][3], 0x00000000);
387
388 EXPECT_EQ(out.i[2][0], 0x0A020901);
389 EXPECT_EQ(out.i[2][1], 0x0C040B03);
390 EXPECT_EQ(out.i[2][2], 0x00000000);
391 EXPECT_EQ(out.i[2][3], 0x00000000);
392
393 EXPECT_EQ(out.i[3][0], 0x0E060D05);
394 EXPECT_EQ(out.i[3][1], 0x10080F07);
395 EXPECT_EQ(out.i[3][2], 0x00000000);
396 EXPECT_EQ(out.i[3][3], 0x00000000);
Casey Dahlin9d56da22017-10-03 13:23:11 -0700397
398 for(int i = 0; i < 256; i++)
399 {
400 EXPECT_EQ(out.i[4 + i/2][0 + (i%2) * 2] & 0xFFFF,
401 ((i >> 0) & 0x03) + 1);
402 EXPECT_EQ(out.i[4 + i/2][0 + (i%2) * 2] >> 16,
403 ((i >> 2) & 0x03) + 1);
404 EXPECT_EQ(out.i[4 + i/2][1 + (i%2) * 2] & 0xFFFF,
405 ((i >> 4) & 0x03) + 1);
406 EXPECT_EQ(out.i[4 + i/2][1 + (i%2) * 2] >> 16,
407 ((i >> 6) & 0x03) + 1);
408 }
409
410 for(int i = 0; i < 256; i++)
411 {
412 EXPECT_EQ(out.i[132 + i][0], ((i >> 0) & 0x03) + 1);
413 EXPECT_EQ(out.i[132 + i][1], ((i >> 2) & 0x03) + 1);
414 EXPECT_EQ(out.i[132 + i][2], ((i >> 4) & 0x03) + 1);
415 EXPECT_EQ(out.i[132 + i][3], ((i >> 6) & 0x03) + 1);
416 }
Nicolas Capens363b61e2016-10-21 13:19:34 -0400417 }
418 }
419
Nicolas Capens363b61e2016-10-21 13:19:34 -0400420}
421
Nicolas Capensc07dc4b2018-08-06 14:20:45 -0400422TEST(ReactorUnitTests, Branching)
Nicolas Capens9ed1a182016-10-24 09:52:23 -0400423{
Nicolas Capens9ed1a182016-10-24 09:52:23 -0400424 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400425 FunctionT<int()> function;
Nicolas Capens9ed1a182016-10-24 09:52:23 -0400426 {
427 Int x = 0;
428
429 For(Int i = 0, i < 8, i++)
430 {
431 If(i < 2)
432 {
433 x += 1;
434 }
435 Else If(i < 4)
436 {
437 x += 10;
438 }
439 Else If(i < 6)
440 {
441 x += 100;
442 }
443 Else
444 {
445 x += 1000;
446 }
447
448 For(Int i = 0, i < 5, i++)
449 x += 10000;
450 }
451
Nicolas Capensb0eb3772016-10-24 17:49:13 -0400452 For(Int i = 0, i < 10, i++)
453 for(int i = 0; i < 10; i++)
454 For(Int i = 0, i < 10, i++)
455 {
Nicolas Capens9ed1a182016-10-24 09:52:23 -0400456 x += 1000000;
Nicolas Capensb0eb3772016-10-24 17:49:13 -0400457 }
458
459 For(Int i = 0, i < 2, i++)
460 If(x == 1000402222)
461 {
462 If(x != 1000402222)
463 x += 1000000000;
Nicolas Capens9ed1a182016-10-24 09:52:23 -0400464 }
465 Else
466 x = -5;
467
468 Return(x);
469 }
470
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400471 auto routine = function("one");
Nicolas Capens9ed1a182016-10-24 09:52:23 -0400472
473 if(routine)
474 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400475 int result = routine();
Nicolas Capens9ed1a182016-10-24 09:52:23 -0400476
Nicolas Capensb0eb3772016-10-24 17:49:13 -0400477 EXPECT_EQ(result, 1000402222);
Nicolas Capens9ed1a182016-10-24 09:52:23 -0400478 }
479 }
480
Nicolas Capens9ed1a182016-10-24 09:52:23 -0400481}
482
Nicolas Capensc07dc4b2018-08-06 14:20:45 -0400483TEST(ReactorUnitTests, MinMax)
Nicolas Capens53a8a3f2016-10-26 00:23:12 -0400484{
Nicolas Capens53a8a3f2016-10-26 00:23:12 -0400485 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400486 FunctionT<int(void*)> function;
Nicolas Capens53a8a3f2016-10-26 00:23:12 -0400487 {
488 Pointer<Byte> out = function.Arg<0>();
489
490 *Pointer<Float4>(out + 16 * 0) = Min(Float4(1.0f, 0.0f, -0.0f, +0.0f), Float4(0.0f, 1.0f, +0.0f, -0.0f));
491 *Pointer<Float4>(out + 16 * 1) = Max(Float4(1.0f, 0.0f, -0.0f, +0.0f), Float4(0.0f, 1.0f, +0.0f, -0.0f));
492
493 *Pointer<Int4>(out + 16 * 2) = Min(Int4(1, 0, -1, -0), Int4(0, 1, 0, +0));
494 *Pointer<Int4>(out + 16 * 3) = Max(Int4(1, 0, -1, -0), Int4(0, 1, 0, +0));
495 *Pointer<UInt4>(out + 16 * 4) = Min(UInt4(1, 0, -1, -0), UInt4(0, 1, 0, +0));
496 *Pointer<UInt4>(out + 16 * 5) = Max(UInt4(1, 0, -1, -0), UInt4(0, 1, 0, +0));
497
498 *Pointer<Short4>(out + 16 * 6) = Min(Short4(1, 0, -1, -0), Short4(0, 1, 0, +0));
499 *Pointer<Short4>(out + 16 * 7) = Max(Short4(1, 0, -1, -0), Short4(0, 1, 0, +0));
500 *Pointer<UShort4>(out + 16 * 8) = Min(UShort4(1, 0, -1, -0), UShort4(0, 1, 0, +0));
501 *Pointer<UShort4>(out + 16 * 9) = Max(UShort4(1, 0, -1, -0), UShort4(0, 1, 0, +0));
502
503 Return(0);
504 }
505
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400506 auto routine = function("one");
Nicolas Capens53a8a3f2016-10-26 00:23:12 -0400507
508 if(routine)
509 {
Nicolas Capens92593eb2018-02-14 14:52:49 -0500510 unsigned int out[10][4];
Nicolas Capens53a8a3f2016-10-26 00:23:12 -0400511
512 memset(&out, 0, sizeof(out));
513
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400514 routine(&out);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -0400515
Nicolas Capens92593eb2018-02-14 14:52:49 -0500516 EXPECT_EQ(out[0][0], 0x00000000u);
517 EXPECT_EQ(out[0][1], 0x00000000u);
518 EXPECT_EQ(out[0][2], 0x00000000u);
519 EXPECT_EQ(out[0][3], 0x80000000u);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -0400520
Nicolas Capens92593eb2018-02-14 14:52:49 -0500521 EXPECT_EQ(out[1][0], 0x3F800000u);
522 EXPECT_EQ(out[1][1], 0x3F800000u);
523 EXPECT_EQ(out[1][2], 0x00000000u);
524 EXPECT_EQ(out[1][3], 0x80000000u);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -0400525
Nicolas Capens92593eb2018-02-14 14:52:49 -0500526 EXPECT_EQ(out[2][0], 0x00000000u);
527 EXPECT_EQ(out[2][1], 0x00000000u);
528 EXPECT_EQ(out[2][2], 0xFFFFFFFFu);
529 EXPECT_EQ(out[2][3], 0x00000000u);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -0400530
Nicolas Capens92593eb2018-02-14 14:52:49 -0500531 EXPECT_EQ(out[3][0], 0x00000001u);
532 EXPECT_EQ(out[3][1], 0x00000001u);
533 EXPECT_EQ(out[3][2], 0x00000000u);
534 EXPECT_EQ(out[3][3], 0x00000000u);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -0400535
Nicolas Capens92593eb2018-02-14 14:52:49 -0500536 EXPECT_EQ(out[4][0], 0x00000000u);
537 EXPECT_EQ(out[4][1], 0x00000000u);
538 EXPECT_EQ(out[4][2], 0x00000000u);
539 EXPECT_EQ(out[4][3], 0x00000000u);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -0400540
Nicolas Capens92593eb2018-02-14 14:52:49 -0500541 EXPECT_EQ(out[5][0], 0x00000001u);
542 EXPECT_EQ(out[5][1], 0x00000001u);
543 EXPECT_EQ(out[5][2], 0xFFFFFFFFu);
544 EXPECT_EQ(out[5][3], 0x00000000u);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -0400545
Nicolas Capens92593eb2018-02-14 14:52:49 -0500546 EXPECT_EQ(out[6][0], 0x00000000u);
547 EXPECT_EQ(out[6][1], 0x0000FFFFu);
548 EXPECT_EQ(out[6][2], 0x00000000u);
549 EXPECT_EQ(out[6][3], 0x00000000u);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -0400550
Nicolas Capens92593eb2018-02-14 14:52:49 -0500551 EXPECT_EQ(out[7][0], 0x00010001u);
552 EXPECT_EQ(out[7][1], 0x00000000u);
553 EXPECT_EQ(out[7][2], 0x00000000u);
554 EXPECT_EQ(out[7][3], 0x00000000u);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -0400555
Nicolas Capens92593eb2018-02-14 14:52:49 -0500556 EXPECT_EQ(out[8][0], 0x00000000u);
557 EXPECT_EQ(out[8][1], 0x00000000u);
558 EXPECT_EQ(out[8][2], 0x00000000u);
559 EXPECT_EQ(out[8][3], 0x00000000u);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -0400560
Nicolas Capens92593eb2018-02-14 14:52:49 -0500561 EXPECT_EQ(out[9][0], 0x00010001u);
562 EXPECT_EQ(out[9][1], 0x0000FFFFu);
563 EXPECT_EQ(out[9][2], 0x00000000u);
564 EXPECT_EQ(out[9][3], 0x00000000u);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -0400565 }
566 }
567
Nicolas Capens53a8a3f2016-10-26 00:23:12 -0400568}
569
Nicolas Capensc07dc4b2018-08-06 14:20:45 -0400570TEST(ReactorUnitTests, NotNeg)
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500571{
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500572 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400573 FunctionT<int(void*)> function;
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500574 {
575 Pointer<Byte> out = function.Arg<0>();
576
577 *Pointer<Int>(out + 16 * 0) = ~Int(0x55555555);
578 *Pointer<Short>(out + 16 * 1) = ~Short(0x5555);
579 *Pointer<Int4>(out + 16 * 2) = ~Int4(0x55555555, 0xAAAAAAAA, 0x00000000, 0xFFFFFFFF);
580 *Pointer<Short4>(out + 16 * 3) = ~Short4(0x5555, 0xAAAA, 0x0000, 0xFFFF);
581
582 *Pointer<Int>(out + 16 * 4) = -Int(0x55555555);
583 *Pointer<Short>(out + 16 * 5) = -Short(0x5555);
584 *Pointer<Int4>(out + 16 * 6) = -Int4(0x55555555, 0xAAAAAAAA, 0x00000000, 0xFFFFFFFF);
585 *Pointer<Short4>(out + 16 * 7) = -Short4(0x5555, 0xAAAA, 0x0000, 0xFFFF);
586
587 *Pointer<Float4>(out + 16 * 8) = -Float4(1.0f, -1.0f, 0.0f, -0.0f);
588
589 Return(0);
590 }
591
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400592 auto routine = function("one");
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500593
594 if(routine)
595 {
Nicolas Capensda5320a2018-02-08 10:26:10 -0500596 unsigned int out[10][4];
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500597
598 memset(&out, 0, sizeof(out));
599
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400600 routine(&out);
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500601
Nicolas Capensda5320a2018-02-08 10:26:10 -0500602 EXPECT_EQ(out[0][0], 0xAAAAAAAAu);
603 EXPECT_EQ(out[0][1], 0x00000000u);
604 EXPECT_EQ(out[0][2], 0x00000000u);
605 EXPECT_EQ(out[0][3], 0x00000000u);
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500606
Nicolas Capensda5320a2018-02-08 10:26:10 -0500607 EXPECT_EQ(out[1][0], 0x0000AAAAu);
608 EXPECT_EQ(out[1][1], 0x00000000u);
609 EXPECT_EQ(out[1][2], 0x00000000u);
610 EXPECT_EQ(out[1][3], 0x00000000u);
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500611
Nicolas Capensda5320a2018-02-08 10:26:10 -0500612 EXPECT_EQ(out[2][0], 0xAAAAAAAAu);
613 EXPECT_EQ(out[2][1], 0x55555555u);
614 EXPECT_EQ(out[2][2], 0xFFFFFFFFu);
615 EXPECT_EQ(out[2][3], 0x00000000u);
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500616
Nicolas Capensda5320a2018-02-08 10:26:10 -0500617 EXPECT_EQ(out[3][0], 0x5555AAAAu);
618 EXPECT_EQ(out[3][1], 0x0000FFFFu);
619 EXPECT_EQ(out[3][2], 0x00000000u);
620 EXPECT_EQ(out[3][3], 0x00000000u);
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500621
Nicolas Capensda5320a2018-02-08 10:26:10 -0500622 EXPECT_EQ(out[4][0], 0xAAAAAAABu);
623 EXPECT_EQ(out[4][1], 0x00000000u);
624 EXPECT_EQ(out[4][2], 0x00000000u);
625 EXPECT_EQ(out[4][3], 0x00000000u);
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500626
Nicolas Capensda5320a2018-02-08 10:26:10 -0500627 EXPECT_EQ(out[5][0], 0x0000AAABu);
628 EXPECT_EQ(out[5][1], 0x00000000u);
629 EXPECT_EQ(out[5][2], 0x00000000u);
630 EXPECT_EQ(out[5][3], 0x00000000u);
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500631
Nicolas Capensda5320a2018-02-08 10:26:10 -0500632 EXPECT_EQ(out[6][0], 0xAAAAAAABu);
633 EXPECT_EQ(out[6][1], 0x55555556u);
634 EXPECT_EQ(out[6][2], 0x00000000u);
635 EXPECT_EQ(out[6][3], 0x00000001u);
Nicolas Capens5e6ca092017-01-13 15:09:21 -0500636
Nicolas Capensda5320a2018-02-08 10:26:10 -0500637 EXPECT_EQ(out[7][0], 0x5556AAABu);
638 EXPECT_EQ(out[7][1], 0x00010000u);
639 EXPECT_EQ(out[7][2], 0x00000000u);
640 EXPECT_EQ(out[7][3], 0x00000000u);
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500641
Nicolas Capensda5320a2018-02-08 10:26:10 -0500642 EXPECT_EQ(out[8][0], 0xBF800000u);
643 EXPECT_EQ(out[8][1], 0x3F800000u);
644 EXPECT_EQ(out[8][2], 0x80000000u);
645 EXPECT_EQ(out[8][3], 0x00000000u);
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500646 }
647 }
648
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500649}
650
Nicolas Capensc07dc4b2018-08-06 14:20:45 -0400651TEST(ReactorUnitTests, VectorCompare)
Nicolas Capens5e6ca092017-01-13 15:09:21 -0500652{
Nicolas Capens5e6ca092017-01-13 15:09:21 -0500653 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400654 FunctionT<int(void*)> function;
Nicolas Capens5e6ca092017-01-13 15:09:21 -0500655 {
656 Pointer<Byte> out = function.Arg<0>();
657
658 *Pointer<Int4>(out + 16 * 0) = CmpEQ(Float4(1.0f, 1.0f, -0.0f, +0.0f), Float4(0.0f, 1.0f, +0.0f, -0.0f));
659 *Pointer<Int4>(out + 16 * 1) = CmpEQ(Int4(1, 0, -1, -0), Int4(0, 1, 0, +0));
660 *Pointer<Byte8>(out + 16 * 2) = CmpEQ(SByte8(1, 2, 3, 4, 5, 6, 7, 8), SByte8(7, 6, 5, 4, 3, 2, 1, 0));
661
662 *Pointer<Int4>(out + 16 * 3) = CmpNLT(Float4(1.0f, 1.0f, -0.0f, +0.0f), Float4(0.0f, 1.0f, +0.0f, -0.0f));
663 *Pointer<Int4>(out + 16 * 4) = CmpNLT(Int4(1, 0, -1, -0), Int4(0, 1, 0, +0));
664 *Pointer<Byte8>(out + 16 * 5) = CmpGT(SByte8(1, 2, 3, 4, 5, 6, 7, 8), SByte8(7, 6, 5, 4, 3, 2, 1, 0));
665
666 Return(0);
667 }
668
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400669 auto routine = function("one");
Nicolas Capens5e6ca092017-01-13 15:09:21 -0500670
671 if(routine)
672 {
Nicolas Capens92593eb2018-02-14 14:52:49 -0500673 unsigned int out[6][4];
Nicolas Capens5e6ca092017-01-13 15:09:21 -0500674
675 memset(&out, 0, sizeof(out));
676
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400677 routine(&out);
Nicolas Capens5e6ca092017-01-13 15:09:21 -0500678
Nicolas Capens92593eb2018-02-14 14:52:49 -0500679 EXPECT_EQ(out[0][0], 0x00000000u);
680 EXPECT_EQ(out[0][1], 0xFFFFFFFFu);
681 EXPECT_EQ(out[0][2], 0xFFFFFFFFu);
682 EXPECT_EQ(out[0][3], 0xFFFFFFFFu);
Nicolas Capens5e6ca092017-01-13 15:09:21 -0500683
Nicolas Capens92593eb2018-02-14 14:52:49 -0500684 EXPECT_EQ(out[1][0], 0x00000000u);
685 EXPECT_EQ(out[1][1], 0x00000000u);
686 EXPECT_EQ(out[1][2], 0x00000000u);
687 EXPECT_EQ(out[1][3], 0xFFFFFFFFu);
Nicolas Capens5e6ca092017-01-13 15:09:21 -0500688
Nicolas Capens92593eb2018-02-14 14:52:49 -0500689 EXPECT_EQ(out[2][0], 0xFF000000u);
690 EXPECT_EQ(out[2][1], 0x00000000u);
Nicolas Capens5e6ca092017-01-13 15:09:21 -0500691
Nicolas Capens92593eb2018-02-14 14:52:49 -0500692 EXPECT_EQ(out[3][0], 0xFFFFFFFFu);
693 EXPECT_EQ(out[3][1], 0xFFFFFFFFu);
694 EXPECT_EQ(out[3][2], 0xFFFFFFFFu);
695 EXPECT_EQ(out[3][3], 0xFFFFFFFFu);
Nicolas Capens5e6ca092017-01-13 15:09:21 -0500696
Nicolas Capens92593eb2018-02-14 14:52:49 -0500697 EXPECT_EQ(out[4][0], 0xFFFFFFFFu);
698 EXPECT_EQ(out[4][1], 0x00000000u);
699 EXPECT_EQ(out[4][2], 0x00000000u);
700 EXPECT_EQ(out[4][3], 0xFFFFFFFFu);
Nicolas Capens5e6ca092017-01-13 15:09:21 -0500701
Nicolas Capens92593eb2018-02-14 14:52:49 -0500702 EXPECT_EQ(out[5][0], 0x00000000u);
703 EXPECT_EQ(out[5][1], 0xFFFFFFFFu);
Nicolas Capens5e6ca092017-01-13 15:09:21 -0500704 }
705 }
706
Nicolas Capens5e6ca092017-01-13 15:09:21 -0500707}
708
Nicolas Capensc07dc4b2018-08-06 14:20:45 -0400709TEST(ReactorUnitTests, SaturatedAddAndSubtract)
Casey Dahlin642fc922017-09-28 17:18:41 -0700710{
Casey Dahlin642fc922017-09-28 17:18:41 -0700711 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400712 FunctionT<int(void*)> function;
Casey Dahlin642fc922017-09-28 17:18:41 -0700713 {
714 Pointer<Byte> out = function.Arg<0>();
715
716 *Pointer<Byte8>(out + 8 * 0) =
717 AddSat(Byte8(1, 2, 3, 4, 5, 6, 7, 8),
718 Byte8(7, 6, 5, 4, 3, 2, 1, 0));
719 *Pointer<Byte8>(out + 8 * 1) =
720 AddSat(Byte8(0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE),
721 Byte8(7, 6, 5, 4, 3, 2, 1, 0));
722 *Pointer<Byte8>(out + 8 * 2) =
723 SubSat(Byte8(1, 2, 3, 4, 5, 6, 7, 8),
724 Byte8(7, 6, 5, 4, 3, 2, 1, 0));
725
726 *Pointer<SByte8>(out + 8 * 3) =
727 AddSat(SByte8(1, 2, 3, 4, 5, 6, 7, 8),
728 SByte8(7, 6, 5, 4, 3, 2, 1, 0));
729 *Pointer<SByte8>(out + 8 * 4) =
730 AddSat(SByte8(0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E),
731 SByte8(7, 6, 5, 4, 3, 2, 1, 0));
732 *Pointer<SByte8>(out + 8 * 5) =
733 AddSat(SByte8(0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88),
734 SByte8(-7, -6, -5, -4, -3, -2, -1, -0));
735 *Pointer<SByte8>(out + 8 * 6) =
736 SubSat(SByte8(0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88),
737 SByte8(7, 6, 5, 4, 3, 2, 1, 0));
738
739 *Pointer<Short4>(out + 8 * 7) =
740 AddSat(Short4(1, 2, 3, 4), Short4(3, 2, 1, 0));
741 *Pointer<Short4>(out + 8 * 8) =
742 AddSat(Short4(0x7FFE, 0x7FFE, 0x7FFE, 0x7FFE),
743 Short4(3, 2, 1, 0));
744 *Pointer<Short4>(out + 8 * 9) =
745 AddSat(Short4(0x8001, 0x8002, 0x8003, 0x8004),
746 Short4(-3, -2, -1, -0));
747 *Pointer<Short4>(out + 8 * 10) =
748 SubSat(Short4(0x8001, 0x8002, 0x8003, 0x8004),
749 Short4(3, 2, 1, 0));
750
751 *Pointer<UShort4>(out + 8 * 11) =
752 AddSat(UShort4(1, 2, 3, 4), UShort4(3, 2, 1, 0));
753 *Pointer<UShort4>(out + 8 * 12) =
754 AddSat(UShort4(0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE),
755 UShort4(3, 2, 1, 0));
756 *Pointer<UShort4>(out + 8 * 13) =
757 SubSat(UShort4(1, 2, 3, 4), UShort4(3, 2, 1, 0));
758
759 Return(0);
760 }
761
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400762 auto routine = function("one");
Casey Dahlin642fc922017-09-28 17:18:41 -0700763
764 if(routine)
765 {
Nicolas Capens92593eb2018-02-14 14:52:49 -0500766 unsigned int out[14][2];
Casey Dahlin642fc922017-09-28 17:18:41 -0700767
768 memset(&out, 0, sizeof(out));
769
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400770 routine(&out);
Casey Dahlin642fc922017-09-28 17:18:41 -0700771
Nicolas Capens92593eb2018-02-14 14:52:49 -0500772 EXPECT_EQ(out[0][0], 0x08080808u);
773 EXPECT_EQ(out[0][1], 0x08080808u);
Casey Dahlin642fc922017-09-28 17:18:41 -0700774
Nicolas Capens92593eb2018-02-14 14:52:49 -0500775 EXPECT_EQ(out[1][0], 0xFFFFFFFFu);
776 EXPECT_EQ(out[1][1], 0xFEFFFFFFu);
Casey Dahlin642fc922017-09-28 17:18:41 -0700777
Nicolas Capens92593eb2018-02-14 14:52:49 -0500778 EXPECT_EQ(out[2][0], 0x00000000u);
779 EXPECT_EQ(out[2][1], 0x08060402u);
Casey Dahlin642fc922017-09-28 17:18:41 -0700780
Nicolas Capens92593eb2018-02-14 14:52:49 -0500781 EXPECT_EQ(out[3][0], 0x08080808u);
782 EXPECT_EQ(out[3][1], 0x08080808u);
Casey Dahlin642fc922017-09-28 17:18:41 -0700783
Nicolas Capens92593eb2018-02-14 14:52:49 -0500784 EXPECT_EQ(out[4][0], 0x7F7F7F7Fu);
785 EXPECT_EQ(out[4][1], 0x7E7F7F7Fu);
Casey Dahlin642fc922017-09-28 17:18:41 -0700786
Nicolas Capens92593eb2018-02-14 14:52:49 -0500787 EXPECT_EQ(out[5][0], 0x80808080u);
788 EXPECT_EQ(out[5][1], 0x88868482u);
Casey Dahlin642fc922017-09-28 17:18:41 -0700789
Nicolas Capens92593eb2018-02-14 14:52:49 -0500790 EXPECT_EQ(out[6][0], 0x80808080u);
791 EXPECT_EQ(out[6][1], 0x88868482u);
Casey Dahlin642fc922017-09-28 17:18:41 -0700792
Nicolas Capens92593eb2018-02-14 14:52:49 -0500793 EXPECT_EQ(out[7][0], 0x00040004u);
794 EXPECT_EQ(out[7][1], 0x00040004u);
Casey Dahlin642fc922017-09-28 17:18:41 -0700795
Nicolas Capens92593eb2018-02-14 14:52:49 -0500796 EXPECT_EQ(out[8][0], 0x7FFF7FFFu);
797 EXPECT_EQ(out[8][1], 0x7FFE7FFFu);
Casey Dahlin642fc922017-09-28 17:18:41 -0700798
Nicolas Capens92593eb2018-02-14 14:52:49 -0500799 EXPECT_EQ(out[9][0], 0x80008000u);
800 EXPECT_EQ(out[9][1], 0x80048002u);
Casey Dahlin642fc922017-09-28 17:18:41 -0700801
Nicolas Capens92593eb2018-02-14 14:52:49 -0500802 EXPECT_EQ(out[10][0], 0x80008000u);
803 EXPECT_EQ(out[10][1], 0x80048002u);
Casey Dahlin642fc922017-09-28 17:18:41 -0700804
Nicolas Capens92593eb2018-02-14 14:52:49 -0500805 EXPECT_EQ(out[11][0], 0x00040004u);
806 EXPECT_EQ(out[11][1], 0x00040004u);
Casey Dahlin642fc922017-09-28 17:18:41 -0700807
Nicolas Capens92593eb2018-02-14 14:52:49 -0500808 EXPECT_EQ(out[12][0], 0xFFFFFFFFu);
809 EXPECT_EQ(out[12][1], 0xFFFEFFFFu);
Casey Dahlin642fc922017-09-28 17:18:41 -0700810
Nicolas Capens92593eb2018-02-14 14:52:49 -0500811 EXPECT_EQ(out[13][0], 0x00000000u);
812 EXPECT_EQ(out[13][1], 0x00040002u);
Casey Dahlin642fc922017-09-28 17:18:41 -0700813 }
814 }
815
Casey Dahlin642fc922017-09-28 17:18:41 -0700816}
817
Nicolas Capensc07dc4b2018-08-06 14:20:45 -0400818TEST(ReactorUnitTests, Unpack)
Casey Dahlin4e759e42017-09-29 13:43:18 -0700819{
Casey Dahlin4e759e42017-09-29 13:43:18 -0700820 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400821 FunctionT<int(void*, void*)> function;
Casey Dahlin4e759e42017-09-29 13:43:18 -0700822 {
823 Pointer<Byte> in = function.Arg<0>();
824 Pointer<Byte> out = function.Arg<1>();
825
826 Byte4 test_byte_a = *Pointer<Byte4>(in + 4 * 0);
827 Byte4 test_byte_b = *Pointer<Byte4>(in + 4 * 1);
828
829 *Pointer<Short4>(out + 8 * 0) =
830 Unpack(test_byte_a, test_byte_b);
831
832 *Pointer<Short4>(out + 8 * 1) = Unpack(test_byte_a);
833
834 Return(0);
835 }
836
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400837 auto routine = function("one");
Casey Dahlin4e759e42017-09-29 13:43:18 -0700838
839 if(routine)
840 {
Nicolas Capens92593eb2018-02-14 14:52:49 -0500841 unsigned int in[1][2];
842 unsigned int out[2][2];
Casey Dahlin4e759e42017-09-29 13:43:18 -0700843
844 memset(&out, 0, sizeof(out));
845
Nicolas Capens92593eb2018-02-14 14:52:49 -0500846 in[0][0] = 0xABCDEF12u;
847 in[0][1] = 0x34567890u;
Casey Dahlin4e759e42017-09-29 13:43:18 -0700848
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400849 routine(&in, &out);
Casey Dahlin4e759e42017-09-29 13:43:18 -0700850
Nicolas Capens92593eb2018-02-14 14:52:49 -0500851 EXPECT_EQ(out[0][0], 0x78EF9012u);
852 EXPECT_EQ(out[0][1], 0x34AB56CDu);
Casey Dahlin4e759e42017-09-29 13:43:18 -0700853
Nicolas Capens92593eb2018-02-14 14:52:49 -0500854 EXPECT_EQ(out[1][0], 0xEFEF1212u);
855 EXPECT_EQ(out[1][1], 0xABABCDCDu);
Casey Dahlin4e759e42017-09-29 13:43:18 -0700856 }
857 }
858
Casey Dahlin4e759e42017-09-29 13:43:18 -0700859}
860
Nicolas Capensc07dc4b2018-08-06 14:20:45 -0400861TEST(ReactorUnitTests, Pack)
Casey Dahlin11658122017-09-29 16:32:32 -0700862{
Casey Dahlin11658122017-09-29 16:32:32 -0700863 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400864 FunctionT<int(void*)> function;
Casey Dahlin11658122017-09-29 16:32:32 -0700865 {
866 Pointer<Byte> out = function.Arg<0>();
867
868 *Pointer<SByte8>(out + 8 * 0) =
869 PackSigned(Short4(-1, -2, 1, 2),
870 Short4(3, 4, -3, -4));
871
872 *Pointer<Byte8>(out + 8 * 1) =
873 PackUnsigned(Short4(-1, -2, 1, 2),
874 Short4(3, 4, -3, -4));
875
876 *Pointer<Short8>(out + 8 * 2) =
877 PackSigned(Int4(-1, -2, 1, 2),
878 Int4(3, 4, -3, -4));
879
880 *Pointer<UShort8>(out + 8 * 4) =
881 PackUnsigned(Int4(-1, -2, 1, 2),
882 Int4(3, 4, -3, -4));
883
884 Return(0);
885 }
886
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400887 auto routine = function("one");
Casey Dahlin11658122017-09-29 16:32:32 -0700888
889 if(routine)
890 {
Nicolas Capens92593eb2018-02-14 14:52:49 -0500891 unsigned int out[6][2];
Casey Dahlin11658122017-09-29 16:32:32 -0700892
893 memset(&out, 0, sizeof(out));
894
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400895 routine(&out);
Casey Dahlin11658122017-09-29 16:32:32 -0700896
Nicolas Capens92593eb2018-02-14 14:52:49 -0500897 EXPECT_EQ(out[0][0], 0x0201FEFFu);
898 EXPECT_EQ(out[0][1], 0xFCFD0403u);
Casey Dahlin11658122017-09-29 16:32:32 -0700899
Nicolas Capens92593eb2018-02-14 14:52:49 -0500900 EXPECT_EQ(out[1][0], 0x02010000u);
901 EXPECT_EQ(out[1][1], 0x00000403u);
Casey Dahlin11658122017-09-29 16:32:32 -0700902
Nicolas Capens92593eb2018-02-14 14:52:49 -0500903 EXPECT_EQ(out[2][0], 0xFFFEFFFFu);
904 EXPECT_EQ(out[2][1], 0x00020001u);
Casey Dahlin11658122017-09-29 16:32:32 -0700905
Nicolas Capens92593eb2018-02-14 14:52:49 -0500906 EXPECT_EQ(out[3][0], 0x00040003u);
907 EXPECT_EQ(out[3][1], 0xFFFCFFFDu);
Casey Dahlin11658122017-09-29 16:32:32 -0700908
Nicolas Capens92593eb2018-02-14 14:52:49 -0500909 EXPECT_EQ(out[4][0], 0x00000000u);
910 EXPECT_EQ(out[4][1], 0x00020001u);
Casey Dahlin11658122017-09-29 16:32:32 -0700911
Nicolas Capens92593eb2018-02-14 14:52:49 -0500912 EXPECT_EQ(out[5][0], 0x00040003u);
913 EXPECT_EQ(out[5][1], 0x00000000u);
Casey Dahlin11658122017-09-29 16:32:32 -0700914 }
915 }
916
Casey Dahlin11658122017-09-29 16:32:32 -0700917}
918
Nicolas Capensc07dc4b2018-08-06 14:20:45 -0400919TEST(ReactorUnitTests, MulHigh)
Nicolas Capens92593eb2018-02-14 14:52:49 -0500920{
Casey Dahlin36fad3c2017-10-02 15:02:02 -0700921 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400922 FunctionT<int(void*)> function;
Casey Dahlin36fad3c2017-10-02 15:02:02 -0700923 {
924 Pointer<Byte> out = function.Arg<0>();
925
Chris Forbesaa8f6992019-03-01 14:18:30 -0800926 *Pointer<Short4>(out + 16 * 0) =
927 MulHigh(Short4(0x01AA, 0x02DD, 0x03EE, 0xF422),
928 Short4(0x01BB, 0x02CC, 0x03FF, 0xF411));
929 *Pointer<UShort4>(out + 16 * 1) =
930 MulHigh(UShort4(0x01AA, 0x02DD, 0x03EE, 0xF422),
931 UShort4(0x01BB, 0x02CC, 0x03FF, 0xF411));
Casey Dahlin36fad3c2017-10-02 15:02:02 -0700932
Chris Forbesaa8f6992019-03-01 14:18:30 -0800933 *Pointer<Int4>(out + 16 * 2) =
934 MulHigh(Int4(0x000001AA, 0x000002DD, 0xC8000000, 0xF8000000),
935 Int4(0x000001BB, 0x84000000, 0x000003EE, 0xD7000000));
936 *Pointer<UInt4>(out + 16 * 3) =
937 MulHigh(UInt4(0x000001AAu, 0x000002DDu, 0xC8000000u, 0xD8000000u),
938 UInt4(0x000001BBu, 0x84000000u, 0x000003EEu, 0xD7000000u));
939
940 *Pointer<Int4>(out + 16 * 4) =
941 MulHigh(Int4(0x7FFFFFFF, 0x7FFFFFFF, 0x80008000, 0xFFFFFFFF),
942 Int4(0x7FFFFFFF, 0x80000000, 0x80008000, 0xFFFFFFFF));
943 *Pointer<UInt4>(out + 16 * 5) =
944 MulHigh(UInt4(0x7FFFFFFFu, 0x7FFFFFFFu, 0x80008000u, 0xFFFFFFFFu),
945 UInt4(0x7FFFFFFFu, 0x80000000u, 0x80008000u, 0xFFFFFFFFu));
946
947 // (U)Short8 variants currently unimplemented.
948
Casey Dahlin36fad3c2017-10-02 15:02:02 -0700949 Return(0);
950 }
951
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400952 auto routine = function("one");
Casey Dahlin36fad3c2017-10-02 15:02:02 -0700953
954 if(routine)
955 {
Chris Forbesaa8f6992019-03-01 14:18:30 -0800956 unsigned int out[6][4];
Casey Dahlin36fad3c2017-10-02 15:02:02 -0700957
958 memset(&out, 0, sizeof(out));
959
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400960 routine(&out);
Casey Dahlin36fad3c2017-10-02 15:02:02 -0700961
Nicolas Capens92593eb2018-02-14 14:52:49 -0500962 EXPECT_EQ(out[0][0], 0x00080002u);
Chris Forbesaa8f6992019-03-01 14:18:30 -0800963 EXPECT_EQ(out[0][1], 0x008D000Fu);
Casey Dahlin36fad3c2017-10-02 15:02:02 -0700964
Nicolas Capens92593eb2018-02-14 14:52:49 -0500965 EXPECT_EQ(out[1][0], 0x00080002u);
Chris Forbesaa8f6992019-03-01 14:18:30 -0800966 EXPECT_EQ(out[1][1], 0xE8C0000Fu);
967
968 EXPECT_EQ(out[2][0], 0x00000000u);
969 EXPECT_EQ(out[2][1], 0xFFFFFE9Cu);
970 EXPECT_EQ(out[2][2], 0xFFFFFF23u);
971 EXPECT_EQ(out[2][3], 0x01480000u);
972
973 EXPECT_EQ(out[3][0], 0x00000000u);
974 EXPECT_EQ(out[3][1], 0x00000179u);
975 EXPECT_EQ(out[3][2], 0x00000311u);
976 EXPECT_EQ(out[3][3], 0xB5680000u);
977
978 EXPECT_EQ(out[4][0], 0x3FFFFFFFu);
979 EXPECT_EQ(out[4][1], 0xC0000000u);
980 EXPECT_EQ(out[4][2], 0x3FFF8000u);
981 EXPECT_EQ(out[4][3], 0x00000000u);
982
983 EXPECT_EQ(out[5][0], 0x3FFFFFFFu);
984 EXPECT_EQ(out[5][1], 0x3FFFFFFFu);
985 EXPECT_EQ(out[5][2], 0x40008000u);
986 EXPECT_EQ(out[5][3], 0xFFFFFFFEu);
Casey Dahlin36fad3c2017-10-02 15:02:02 -0700987 }
988 }
989
Casey Dahlin36fad3c2017-10-02 15:02:02 -0700990}
991
Nicolas Capensc07dc4b2018-08-06 14:20:45 -0400992TEST(ReactorUnitTests, MulAdd)
Nicolas Capens92593eb2018-02-14 14:52:49 -0500993{
Casey Dahlinb098c542017-10-03 11:24:01 -0700994 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -0400995 FunctionT<int(void*)> function;
Casey Dahlinb098c542017-10-03 11:24:01 -0700996 {
997 Pointer<Byte> out = function.Arg<0>();
998
999 *Pointer<Int2>(out + 8 * 0) =
1000 MulAdd(Short4(0x1aa, 0x2dd, 0x3ee, 0xF422),
1001 Short4(0x1bb, 0x2cc, 0x3ff, 0xF411));
1002
1003 // (U)Short8 variant is mentioned but unimplemented
1004 Return(0);
1005 }
1006
Antonio Maiorano03935ae2019-10-29 16:20:27 -04001007 auto routine = function("one");
Casey Dahlinb098c542017-10-03 11:24:01 -07001008
1009 if(routine)
1010 {
Nicolas Capens92593eb2018-02-14 14:52:49 -05001011 unsigned int out[1][2];
Casey Dahlinb098c542017-10-03 11:24:01 -07001012
1013 memset(&out, 0, sizeof(out));
1014
Antonio Maiorano03935ae2019-10-29 16:20:27 -04001015 routine(&out);
Casey Dahlinb098c542017-10-03 11:24:01 -07001016
Nicolas Capens92593eb2018-02-14 14:52:49 -05001017 EXPECT_EQ(out[0][0], 0x000AE34Au);
1018 EXPECT_EQ(out[0][1], 0x009D5254u);
Casey Dahlinb098c542017-10-03 11:24:01 -07001019 }
1020 }
1021
Casey Dahlinb098c542017-10-03 11:24:01 -07001022}
1023
Ben Clayton204a4102019-07-31 13:17:47 +01001024TEST(ReactorUnitTests, PointersEqual)
1025{
Antonio Maiorano03935ae2019-10-29 16:20:27 -04001026 FunctionT<int(void*, void*)> function;
Ben Clayton204a4102019-07-31 13:17:47 +01001027 {
1028 Pointer<Byte> ptrA = function.Arg<0>();
1029 Pointer<Byte> ptrB = function.Arg<1>();
1030 If (ptrA == ptrB)
1031 {
1032 Return(1);
1033 }
1034 Else
1035 {
1036 Return(0);
1037 }
1038 }
1039
1040 auto routine = function("one");
Ben Clayton204a4102019-07-31 13:17:47 +01001041 int* a = reinterpret_cast<int*>(uintptr_t(0x0000000000000000));
1042 int* b = reinterpret_cast<int*>(uintptr_t(0x00000000F0000000));
1043 int* c = reinterpret_cast<int*>(uintptr_t(0xF000000000000000));
Antonio Maiorano03935ae2019-10-29 16:20:27 -04001044 EXPECT_EQ(routine(&a, &a), 1);
1045 EXPECT_EQ(routine(&b, &b), 1);
1046 EXPECT_EQ(routine(&c, &c), 1);
Ben Clayton204a4102019-07-31 13:17:47 +01001047
Antonio Maiorano03935ae2019-10-29 16:20:27 -04001048 EXPECT_EQ(routine(&a, &b), 0);
1049 EXPECT_EQ(routine(&b, &a), 0);
1050 EXPECT_EQ(routine(&b, &c), 0);
1051 EXPECT_EQ(routine(&c, &b), 0);
1052 EXPECT_EQ(routine(&c, &a), 0);
1053 EXPECT_EQ(routine(&a, &c), 0);
Ben Clayton204a4102019-07-31 13:17:47 +01001054}
1055
Antonio Maiorano29ba7a02019-10-11 15:23:56 -04001056TEST(ReactorUnitTests, Args_2Mixed)
1057{
1058 // 2 mixed type args
Antonio Maiorano03935ae2019-10-29 16:20:27 -04001059 FunctionT<float(int, float)> function;
Antonio Maiorano29ba7a02019-10-11 15:23:56 -04001060 {
1061 Int a = function.Arg<0>();
1062 Float b = function.Arg<1>();
1063 Return(Float(a) + b);
1064 }
1065
1066 if (auto routine = function("one"))
1067 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -04001068 float result = routine(1, 2.f);
Antonio Maiorano29ba7a02019-10-11 15:23:56 -04001069 EXPECT_EQ(result, 3.f);
1070 }
1071}
1072
1073TEST(ReactorUnitTests, Args_4Mixed)
1074{
1075 // 4 mixed type args (max register allocation on Windows)
Antonio Maiorano03935ae2019-10-29 16:20:27 -04001076 FunctionT<float(int, float, int, float)> function;
Antonio Maiorano29ba7a02019-10-11 15:23:56 -04001077 {
1078 Int a = function.Arg<0>();
1079 Float b = function.Arg<1>();
1080 Int c = function.Arg<2>();
1081 Float d = function.Arg<3>();
1082 Return(Float(a) + b + Float(c) + d);
1083 }
1084
1085 if (auto routine = function("one"))
1086 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -04001087 float result = routine(1, 2.f, 3, 4.f);
Antonio Maiorano29ba7a02019-10-11 15:23:56 -04001088 EXPECT_EQ(result, 10.f);
1089 }
1090}
1091
1092TEST(ReactorUnitTests, Args_5Mixed)
1093{
1094 // 5 mixed type args (5th spills over to stack on Windows)
Antonio Maiorano03935ae2019-10-29 16:20:27 -04001095 FunctionT<float(int, float, int, float, int)> function;
Antonio Maiorano29ba7a02019-10-11 15:23:56 -04001096 {
1097 Int a = function.Arg<0>();
1098 Float b = function.Arg<1>();
1099 Int c = function.Arg<2>();
1100 Float d = function.Arg<3>();
1101 Int e = function.Arg<4>();
1102 Return(Float(a) + b + Float(c) + d + Float(e));
1103 }
1104
1105 if (auto routine = function("one"))
1106 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -04001107 float result = routine(1, 2.f, 3, 4.f, 5);
Antonio Maiorano29ba7a02019-10-11 15:23:56 -04001108 EXPECT_EQ(result, 15.f);
1109 }
1110}
1111
1112TEST(ReactorUnitTests, Args_GreaterThan5Mixed)
1113{
1114 // >5 mixed type args
Antonio Maiorano03935ae2019-10-29 16:20:27 -04001115 FunctionT<float(int, float, int, float, int, float, int, float, int, float)> function;
Antonio Maiorano29ba7a02019-10-11 15:23:56 -04001116 {
1117 Int a = function.Arg<0>();
1118 Float b = function.Arg<1>();
1119 Int c = function.Arg<2>();
1120 Float d = function.Arg<3>();
1121 Int e = function.Arg<4>();
1122 Float f = function.Arg<5>();
1123 Int g = function.Arg<6>();
1124 Float h = function.Arg<7>();
1125 Int i = function.Arg<8>();
1126 Float j = function.Arg<9>();
1127 Return(Float(a) + b + Float(c) + d + Float(e) + f + Float(g) + h + Float(i) + j);
1128 }
1129
1130 if (auto routine = function("one"))
1131 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -04001132 float result = routine(1, 2.f, 3, 4.f, 5, 6.f, 7, 8.f, 9, 10.f);
Antonio Maiorano29ba7a02019-10-11 15:23:56 -04001133 EXPECT_EQ(result, 55.f);
1134 }
1135}
1136
Ben Claytond853c122019-04-16 17:51:49 -04001137TEST(ReactorUnitTests, Call)
1138{
Ben Claytond853c122019-04-16 17:51:49 -04001139 struct Class
1140 {
Ben Clayton51f08312019-11-08 14:39:26 +00001141 static int Callback(Class *p, int i, float f)
Ben Claytond853c122019-04-16 17:51:49 -04001142 {
Ben Clayton51f08312019-11-08 14:39:26 +00001143 p->i = i;
1144 p->f = f;
Ben Claytond853c122019-04-16 17:51:49 -04001145 return i + int(f);
1146 }
1147
1148 int i = 0;
1149 float f = 0.0f;
1150 };
1151
Ben Clayton51f08312019-11-08 14:39:26 +00001152 FunctionT<int(void*)> function;
Ben Claytond853c122019-04-16 17:51:49 -04001153 {
Ben Clayton51f08312019-11-08 14:39:26 +00001154 Pointer<Byte> c = function.Arg<0>();
1155 auto res = Call(Class::Callback, c, 10, 20.0f);
1156 Return(res);
Ben Claytond853c122019-04-16 17:51:49 -04001157 }
Ben Clayton51f08312019-11-08 14:39:26 +00001158
1159 auto routine = function("one");
1160
1161 Class c;
1162 int res = routine(&c);
1163 EXPECT_EQ(res, 30);
1164 EXPECT_EQ(c.i, 10);
1165 EXPECT_EQ(c.f, 20.0f);
1166}
1167
Ben Claytonb7eb3a82019-11-19 00:43:50 +00001168TEST(ReactorUnitTests, CallMemberFunction)
1169{
Ben Claytonb7eb3a82019-11-19 00:43:50 +00001170 struct Class
1171 {
1172 int Callback(int argI, float argF)
1173 {
1174 i = argI;
1175 f = argF;
1176 return i + int(f);
1177 }
1178
1179 int i = 0;
1180 float f = 0.0f;
1181 };
1182
1183 Class c;
1184
1185 FunctionT<int()> function;
1186 {
1187 auto res = Call(&Class::Callback, &c, 10, 20.0f);
1188 Return(res);
1189 }
1190
1191 auto routine = function("one");
1192
1193 int res = routine();
1194 EXPECT_EQ(res, 30);
1195 EXPECT_EQ(c.i, 10);
1196 EXPECT_EQ(c.f, 20.0f);
1197}
1198
1199TEST(ReactorUnitTests, CallMemberFunctionIndirect)
1200{
Ben Claytonb7eb3a82019-11-19 00:43:50 +00001201 struct Class
1202 {
1203 int Callback(int argI, float argF)
1204 {
1205 i = argI;
1206 f = argF;
1207 return i + int(f);
1208 }
1209
1210 int i = 0;
1211 float f = 0.0f;
1212 };
1213
1214 FunctionT<int(void*)> function;
1215 {
1216 Pointer<Byte> c = function.Arg<0>();
1217 auto res = Call(&Class::Callback, c, 10, 20.0f);
1218 Return(res);
1219 }
1220
1221 auto routine = function("one");
1222
1223 Class c;
1224 int res = routine(&c);
1225 EXPECT_EQ(res, 30);
1226 EXPECT_EQ(c.i, 10);
1227 EXPECT_EQ(c.f, 20.0f);
1228}
1229
Ben Clayton51f08312019-11-08 14:39:26 +00001230TEST(ReactorUnitTests, CallImplicitCast)
1231{
Ben Clayton51f08312019-11-08 14:39:26 +00001232 struct Class
1233 {
1234 static void Callback(Class *c, const char* s)
1235 {
1236 c->str = s;
1237 }
1238 std::string str;
1239 };
1240
1241 FunctionT<void(Class *c, const char *s)> function;
1242 {
1243 Pointer<Byte> c = function.Arg<0>();
1244 Pointer<Byte> s = function.Arg<1>();
1245 Call(Class::Callback, c, s);
1246 }
1247
1248 auto routine = function("one");
1249
1250 Class c;
1251 routine(&c, "hello world");
1252 EXPECT_EQ(c.str, "hello world");
Antonio Maioranob7dad7d2019-10-11 15:26:58 -04001253}
Ben Claytond853c122019-04-16 17:51:49 -04001254
Antonio Maiorano01386d12019-11-20 14:43:48 -05001255TEST(ReactorUnitTests, Call_Args4)
1256{
1257 struct Class
1258 {
1259 static int Func(int a, int b, int c, int d)
1260 {
1261 return a + b + c + d;
1262 }
1263 };
1264
1265 {
1266 FunctionT<int()> function;
1267 {
1268 auto res = Call(Class::Func, 1, 2, 3, 4);
1269 Return(res);
1270 }
1271
1272 auto routine = function("one");
1273
1274 if(routine)
1275 {
1276 int res = routine();
1277 EXPECT_EQ(res, 1 + 2 + 3 + 4);
1278 }
1279 }
1280}
1281
1282TEST(ReactorUnitTests, Call_Args5)
1283{
1284 struct Class
1285 {
1286 static int Func(int a, int b, int c, int d, int e)
1287 {
1288 return a + b + c + d + e;
1289 }
1290 };
1291
1292 {
1293 FunctionT<int()> function;
1294 {
1295 auto res = Call(Class::Func, 1, 2, 3, 4, 5);
1296 Return(res);
1297 }
1298
1299 auto routine = function("one");
1300
1301 if(routine)
1302 {
1303 int res = routine();
1304 EXPECT_EQ(res, 1 + 2 + 3 + 4 + 5);
1305 }
1306 }
1307}
1308
1309TEST(ReactorUnitTests, Call_ArgsMany)
1310{
1311 struct Class
1312 {
1313 static int Func(int a, int b, int c, int d, int e, int f, int g, int h)
1314 {
1315 return a + b + c + d + e + f + g + h;
1316 }
1317 };
1318
1319 {
1320 FunctionT<int()> function;
1321 {
1322 auto res = Call(Class::Func, 1, 2, 3, 4, 5, 6, 7, 8);
1323 Return(res);
1324 }
1325
1326 auto routine = function("one");
1327
1328 if(routine)
1329 {
1330 int res = routine();
1331 EXPECT_EQ(res, 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8);
1332 }
1333 }
1334}
1335
1336TEST(ReactorUnitTests, Call_ArgsMixed)
1337{
1338 struct Class
1339 {
1340 static int Func(int a, float b, int* c, float* d, int e, float f, int* g, float* h)
1341 {
1342 return a + b + *c + *d + e + f + *g + *h;
1343 }
1344 };
1345
1346 {
1347 FunctionT<int()> function;
1348 {
1349 Int c(3);
1350 Float d(4);
1351 Int g(7);
1352 Float h(8);
1353 auto res = Call(Class::Func, 1, 2.f, &c, &d, 5, 6.f, &g, &h);
1354 Return(res);
1355 }
1356
1357 auto routine = function("one");
1358
1359 if(routine)
1360 {
1361 int res = routine();
1362 EXPECT_EQ(res, 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8);
1363 }
1364 }
1365}
1366
1367TEST(ReactorUnitTests, Call_ArgsPointer)
1368{
1369 struct Class
1370 {
1371 static int Func(int *a)
1372 {
1373 return *a;
1374 }
1375 };
1376
1377 {
1378 FunctionT<int()> function;
1379 {
1380 Int a(12345);
1381 auto res = Call(Class::Func, &a);
1382 Return(res);
1383 }
1384
1385 auto routine = function("one");
1386
1387 if(routine)
1388 {
1389 int res = routine();
1390 EXPECT_EQ(res, 12345);
1391 }
1392 }
1393}
1394
1395
Antonio Maioranob7dad7d2019-10-11 15:26:58 -04001396TEST(ReactorUnitTests, CallExternalCallRoutine)
1397{
Antonio Maioranob7dad7d2019-10-11 15:26:58 -04001398 // routine1 calls Class::Func, passing it a pointer to routine2, and Class::Func calls routine2
1399
1400 auto routine2 = [] {
Antonio Maiorano03935ae2019-10-29 16:20:27 -04001401 FunctionT<float(float, int)> function;
Antonio Maioranob7dad7d2019-10-11 15:26:58 -04001402 {
1403 Float a = function.Arg<0>();
1404 Int b = function.Arg<1>();
1405 Return(a + Float(b));
1406 }
1407 return function("two");
1408 }();
1409
1410 struct Class
1411 {
1412 static float Func(void* p, float a, int b)
1413 {
1414 auto funcToCall = reinterpret_cast<float(*)(float, int)>(p);
1415 return funcToCall(a, b);
1416 }
1417 };
1418
1419 auto routine1 = [] {
Antonio Maiorano03935ae2019-10-29 16:20:27 -04001420 FunctionT<float(void*, float, int)> function;
Antonio Maioranob7dad7d2019-10-11 15:26:58 -04001421 {
1422 Pointer<Byte> funcToCall = function.Arg<0>();
1423 Float a = function.Arg<1>();
1424 Int b = function.Arg<2>();
1425 Float result = Call(Class::Func, funcToCall, a, b);
1426 Return(result);
1427 }
1428 return function("one");
1429 }();
1430
Antonio Maiorano03935ae2019-10-29 16:20:27 -04001431 float result = routine1((void*)routine2.getEntry(), 12.f, 13);
Antonio Maioranob7dad7d2019-10-11 15:26:58 -04001432 EXPECT_EQ(result, 25.f);
Ben Claytond853c122019-04-16 17:51:49 -04001433}
1434
Stephen White17078c72019-02-27 14:39:14 -05001435// Check that a complex generated function which utilizes all 8 or 16 XMM
1436// registers computes the correct result.
1437// (Note that due to MSC's lack of support for inline assembly in x64,
Ben Claytonb1243732019-02-27 23:56:18 +00001438// this test does not actually check that the register contents are
Stephen White17078c72019-02-27 14:39:14 -05001439// preserved, just that the generated function computes the correct value.
1440// It's necessary to inspect the registers in a debugger to actually verify.)
1441TEST(ReactorUnitTests, PreserveXMMRegisters)
1442{
Stephen White17078c72019-02-27 14:39:14 -05001443 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -04001444 FunctionT<void(void*, void*)> function;
Stephen White17078c72019-02-27 14:39:14 -05001445 {
1446 Pointer<Byte> in = function.Arg<0>();
1447 Pointer<Byte> out = function.Arg<1>();
1448
1449 Float4 a = *Pointer<Float4>(in + 16 * 0);
1450 Float4 b = *Pointer<Float4>(in + 16 * 1);
1451 Float4 c = *Pointer<Float4>(in + 16 * 2);
1452 Float4 d = *Pointer<Float4>(in + 16 * 3);
1453 Float4 e = *Pointer<Float4>(in + 16 * 4);
1454 Float4 f = *Pointer<Float4>(in + 16 * 5);
1455 Float4 g = *Pointer<Float4>(in + 16 * 6);
1456 Float4 h = *Pointer<Float4>(in + 16 * 7);
1457 Float4 i = *Pointer<Float4>(in + 16 * 8);
1458 Float4 j = *Pointer<Float4>(in + 16 * 9);
1459 Float4 k = *Pointer<Float4>(in + 16 * 10);
1460 Float4 l = *Pointer<Float4>(in + 16 * 11);
1461 Float4 m = *Pointer<Float4>(in + 16 * 12);
1462 Float4 n = *Pointer<Float4>(in + 16 * 13);
1463 Float4 o = *Pointer<Float4>(in + 16 * 14);
1464 Float4 p = *Pointer<Float4>(in + 16 * 15);
1465
1466 Float4 ab = a + b;
1467 Float4 cd = c + d;
1468 Float4 ef = e + f;
1469 Float4 gh = g + h;
1470 Float4 ij = i + j;
1471 Float4 kl = k + l;
1472 Float4 mn = m + n;
1473 Float4 op = o + p;
1474
1475 Float4 abcd = ab + cd;
1476 Float4 efgh = ef + gh;
1477 Float4 ijkl = ij + kl;
1478 Float4 mnop = mn + op;
1479
1480 Float4 abcdefgh = abcd + efgh;
1481 Float4 ijklmnop = ijkl + mnop;
1482 Float4 sum = abcdefgh + ijklmnop;
1483 *Pointer<Float4>(out) = sum;
1484 Return();
1485 }
1486
Antonio Maiorano03935ae2019-10-29 16:20:27 -04001487 auto routine = function("one");
Stephen White17078c72019-02-27 14:39:14 -05001488 assert(routine);
1489
1490 float input[64] = { 1.0f, 0.0f, 0.0f, 0.0f,
1491 -1.0f, 1.0f, -1.0f, 0.0f,
1492 1.0f, 2.0f, -2.0f, 0.0f,
1493 -1.0f, 3.0f, -3.0f, 0.0f,
1494 1.0f, 4.0f, -4.0f, 0.0f,
1495 -1.0f, 5.0f, -5.0f, 0.0f,
1496 1.0f, 6.0f, -6.0f, 0.0f,
1497 -1.0f, 7.0f, -7.0f, 0.0f,
1498 1.0f, 8.0f, -8.0f, 0.0f,
1499 -1.0f, 9.0f, -9.0f, 0.0f,
1500 1.0f, 10.0f, -10.0f, 0.0f,
1501 -1.0f, 11.0f, -11.0f, 0.0f,
1502 1.0f, 12.0f, -12.0f, 0.0f,
1503 -1.0f, 13.0f, -13.0f, 0.0f,
1504 1.0f, 14.0f, -14.0f, 0.0f,
1505 -1.0f, 15.0f, -15.0f, 0.0f };
1506
1507 float result[4];
Stephen White17078c72019-02-27 14:39:14 -05001508
Antonio Maiorano03935ae2019-10-29 16:20:27 -04001509 routine(input, result);
Stephen White17078c72019-02-27 14:39:14 -05001510
1511 EXPECT_EQ(result[0], 0.0f);
1512 EXPECT_EQ(result[1], 120.0f);
1513 EXPECT_EQ(result[2], -120.0f);
1514 EXPECT_EQ(result[3], 0.0f);
1515 }
1516
Stephen White17078c72019-02-27 14:39:14 -05001517}
1518
Ben Claytonb1243732019-02-27 23:56:18 +00001519template <typename T>
Ben Clayton51f08312019-11-08 14:39:26 +00001520class CToReactorTCastTest : public ::testing::Test
Nicolas Capensf0d22ad2019-03-15 17:22:42 -04001521{
Ben Claytonf3b57972019-03-15 09:56:47 +00001522public:
1523 using CType = typename std::tuple_element<0, T>::type;
1524 using ReactorType = typename std::tuple_element<1, T>::type;
1525};
1526
Ben Clayton51f08312019-11-08 14:39:26 +00001527using CToReactorTCastTestTypes = ::testing::Types
Ben Claytonf3b57972019-03-15 09:56:47 +00001528 < // Subset of types that can be used as arguments.
Nicolas Capensf0d22ad2019-03-15 17:22:42 -04001529 // std::pair<bool, Bool>, FIXME(capn): Not supported as argument type by Subzero.
1530 // std::pair<uint8_t, Byte>, FIXME(capn): Not supported as argument type by Subzero.
1531 // std::pair<int8_t, SByte>, FIXME(capn): Not supported as argument type by Subzero.
1532 // std::pair<int16_t, Short>, FIXME(capn): Not supported as argument type by Subzero.
1533 // std::pair<uint16_t, UShort>, FIXME(capn): Not supported as argument type by Subzero.
Ben Claytonf3b57972019-03-15 09:56:47 +00001534 std::pair<int, Int>,
1535 std::pair<unsigned int, UInt>,
1536 std::pair<float, Float>
1537 >;
1538
Ben Clayton51f08312019-11-08 14:39:26 +00001539TYPED_TEST_SUITE(CToReactorTCastTest, CToReactorTCastTestTypes);
Ben Claytonf3b57972019-03-15 09:56:47 +00001540
Ben Clayton51f08312019-11-08 14:39:26 +00001541TYPED_TEST(CToReactorTCastTest, Casts)
Nicolas Capensf0d22ad2019-03-15 17:22:42 -04001542{
Ben Claytonf3b57972019-03-15 09:56:47 +00001543 using CType = typename TestFixture::CType;
1544 using ReactorType = typename TestFixture::ReactorType;
1545
Ben Clayton6897e9b2019-07-16 17:27:27 +01001546 std::shared_ptr<Routine> routine;
Ben Claytonf3b57972019-03-15 09:56:47 +00001547
1548 {
1549 Function< Int(ReactorType) > function;
1550 {
1551 ReactorType a = function.template Arg<0>();
1552 ReactorType b = CType{};
1553 RValue<ReactorType> c = RValue<ReactorType>(CType{});
1554 Bool same = (a == b) && (a == c);
1555 Return(IfThenElse(same, Int(1), Int(0))); // TODO: Ability to use Bools as return values.
1556 }
1557
1558 routine = function("one");
1559
1560 if(routine)
1561 {
1562 auto callable = (int(*)(CType))routine->getEntry();
1563 CType in = {};
1564 EXPECT_EQ(callable(in), 1);
1565 }
1566 }
1567
Ben Claytonf3b57972019-03-15 09:56:47 +00001568}
1569
1570template <typename T>
Nicolas Capensf0d22ad2019-03-15 17:22:42 -04001571class GEPTest : public ::testing::Test
1572{
Ben Claytonb1243732019-02-27 23:56:18 +00001573public:
1574 using CType = typename std::tuple_element<0, T>::type;
1575 using ReactorType = typename std::tuple_element<1, T>::type;
1576};
1577
1578using GEPTestTypes = ::testing::Types
1579 <
Ben Claytonf3b57972019-03-15 09:56:47 +00001580 std::pair<bool, Bool>,
Ben Claytonb1243732019-02-27 23:56:18 +00001581 std::pair<int8_t, Byte>,
1582 std::pair<int8_t, SByte>,
1583 std::pair<int8_t[4], Byte4>,
1584 std::pair<int8_t[4], SByte4>,
1585 std::pair<int8_t[8], Byte8>,
1586 std::pair<int8_t[8], SByte8>,
1587 std::pair<int8_t[16], Byte16>,
1588 std::pair<int8_t[16], SByte16>,
1589 std::pair<int16_t, Short>,
1590 std::pair<int16_t, UShort>,
1591 std::pair<int16_t[2], Short2>,
1592 std::pair<int16_t[2], UShort2>,
1593 std::pair<int16_t[4], Short4>,
1594 std::pair<int16_t[4], UShort4>,
1595 std::pair<int16_t[8], Short8>,
1596 std::pair<int16_t[8], UShort8>,
1597 std::pair<int, Int>,
1598 std::pair<int, UInt>,
1599 std::pair<int[2], Int2>,
1600 std::pair<int[2], UInt2>,
1601 std::pair<int[4], Int4>,
1602 std::pair<int[4], UInt4>,
1603 std::pair<int64_t, Long>,
1604 std::pair<int16_t, Half>,
1605 std::pair<float, Float>,
1606 std::pair<float[2], Float2>,
1607 std::pair<float[4], Float4>
1608 >;
1609
Alexis Hetu79d4ac92019-06-03 11:31:46 -04001610TYPED_TEST_SUITE(GEPTest, GEPTestTypes);
Ben Claytonb1243732019-02-27 23:56:18 +00001611
Nicolas Capensf0d22ad2019-03-15 17:22:42 -04001612TYPED_TEST(GEPTest, PtrOffsets)
1613{
Ben Claytonb1243732019-02-27 23:56:18 +00001614 using CType = typename TestFixture::CType;
1615 using ReactorType = typename TestFixture::ReactorType;
1616
Ben Clayton6897e9b2019-07-16 17:27:27 +01001617 std::shared_ptr<Routine> routine;
Ben Claytonb1243732019-02-27 23:56:18 +00001618
1619 {
1620 Function< Pointer<ReactorType>(Pointer<ReactorType>, Int) > function;
1621 {
1622 Pointer<ReactorType> pointer = function.template Arg<0>();
1623 Int index = function.template Arg<1>();
1624 Return(&pointer[index]);
1625 }
1626
1627 routine = function("one");
1628
1629 if(routine)
1630 {
1631 auto callable = (CType*(*)(CType*, unsigned int))routine->getEntry();
1632
1633 union PtrInt {
1634 CType* p;
1635 size_t i;
1636 };
1637
1638 PtrInt base;
1639 base.i = 0x10000;
1640
1641 for (int i = 0; i < 5; i++)
1642 {
1643 PtrInt reference;
1644 reference.p = &base.p[i];
1645
1646 PtrInt result;
1647 result.p = callable(base.p, i);
1648
1649 auto expect = reference.i - base.i;
1650 auto got = result.i - base.i;
1651
1652 EXPECT_EQ(got, expect) << "i:" << i;
1653 }
1654 }
1655 }
1656
Ben Claytonb1243732019-02-27 23:56:18 +00001657}
1658
Ben Clayton1c82c7b2019-04-30 12:49:27 +01001659TEST(ReactorUnitTests, Coroutines_Fibonacci)
1660{
1661 if (!rr::Caps.CoroutinesSupported)
1662 {
1663 SUCCEED() << "Coroutines not supported";
1664 return;
1665 }
1666
1667 Coroutine<int()> function;
1668 {
1669 Yield(Int(0));
1670 Yield(Int(1));
1671 Int current = 1;
1672 Int next = 1;
1673 While (true) {
1674 Yield(next);
1675 auto tmp = current + next;
1676 current = next;
1677 next = tmp;
1678 }
1679 }
1680
1681 auto coroutine = function();
1682
1683 int32_t expected[] =
1684 {
1685 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597,
1686 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418,
1687 317811,
1688 };
1689
1690 auto count = sizeof(expected) / sizeof(expected[0]);
1691
1692 for (size_t i = 0; i < count; i++)
1693 {
1694 int out = 0;
1695 EXPECT_EQ(coroutine->await(out), true);
1696 EXPECT_EQ(out, expected[i]);
1697 }
1698}
1699
1700TEST(ReactorUnitTests, Coroutines_Parameters)
1701{
1702 if (!rr::Caps.CoroutinesSupported)
1703 {
1704 SUCCEED() << "Coroutines not supported";
1705 return;
1706 }
1707
1708 Coroutine<uint8_t(uint8_t* data, int count)> function;
1709 {
1710 Pointer<Byte> data = function.Arg<0>();
1711 Int count = function.Arg<1>();
1712
1713 For(Int i = 0, i < count, i++)
1714 {
1715 Yield(data[i]);
1716 }
1717 }
1718
1719 uint8_t data[] = {10, 20, 30};
1720 auto coroutine = function(&data[0], 3);
1721
1722 uint8_t out = 0;
1723 EXPECT_EQ(coroutine->await(out), true);
1724 EXPECT_EQ(out, 10); out = 0;
1725 EXPECT_EQ(coroutine->await(out), true);
1726 EXPECT_EQ(out, 20); out = 0;
1727 EXPECT_EQ(coroutine->await(out), true);
1728 EXPECT_EQ(out, 30); out = 99;
1729 EXPECT_EQ(coroutine->await(out), false);
1730 EXPECT_EQ(out, 99);
1731 EXPECT_EQ(coroutine->await(out), false);
1732 EXPECT_EQ(out, 99);
1733}
1734
Antonio Maiorano7ffda5b2019-11-20 15:31:51 -05001735TEST(ReactorUnitTests, ExtractFromRValue)
1736{
1737 Function<Void(Pointer<Int4> values, Pointer<Int4> result)> function;
1738 {
1739 Pointer<Int4> vIn = function.Arg<0>();
1740 Pointer<Int4> resultIn = function.Arg<1>();
1741
1742 RValue<Int4> v = *vIn;
1743
1744 Int4 result(678);
1745
1746 If(Extract(v, 0) == 42)
1747 {
1748 result = Insert(result, 1, 0);
1749 }
1750
1751 If(Extract(v, 1) == 42)
1752 {
1753 result = Insert(result, 1, 1);
1754 }
1755
1756 *resultIn = result;
1757
1758 Return();
1759 }
1760
1761 auto routine = function("one");
1762 auto entry = (void(*)(int*, int*))routine->getEntry();
1763
1764 int v[4] = { 42, 42, 42, 42 };
1765 int result[4] = { 99, 99, 99, 99 };
1766 entry(v, result);
1767 EXPECT_EQ(result[0], 1);
1768 EXPECT_EQ(result[1], 1);
1769 EXPECT_EQ(result[2], 678);
1770 EXPECT_EQ(result[3], 678);
1771}
1772
Nicolas Capens228b05d2016-10-12 15:27:04 -04001773int main(int argc, char **argv)
1774{
1775 ::testing::InitGoogleTest(&argc, argv);
1776 return RUN_ALL_TESTS();
Nicolas Capens598f8d82016-09-26 15:09:10 -04001777}
Ben Clayton351be422019-04-30 12:26:57 +01001778
1779////////////////////////////////
1780// Trait compile time checks. //
1781////////////////////////////////
1782
Ben Clayton51f08312019-11-08 14:39:26 +00001783// Assert CToReactorT resolves to expected types.
1784static_assert(std::is_same<CToReactorT<void>, Void>::value, "");
1785static_assert(std::is_same<CToReactorT<bool>, Bool>::value, "");
1786static_assert(std::is_same<CToReactorT<uint8_t>, Byte>::value, "");
1787static_assert(std::is_same<CToReactorT<int8_t>, SByte>::value, "");
1788static_assert(std::is_same<CToReactorT<int16_t>, Short>::value, "");
1789static_assert(std::is_same<CToReactorT<uint16_t>, UShort>::value, "");
1790static_assert(std::is_same<CToReactorT<int32_t>, Int>::value, "");
1791static_assert(std::is_same<CToReactorT<uint64_t>, Long>::value, "");
1792static_assert(std::is_same<CToReactorT<uint32_t>, UInt>::value, "");
1793static_assert(std::is_same<CToReactorT<float>, Float>::value, "");
Ben Clayton351be422019-04-30 12:26:57 +01001794
Ben Clayton51f08312019-11-08 14:39:26 +00001795// Assert CToReactorT for known pointer types resolves to expected types.
1796static_assert(std::is_same<CToReactorT<void*>, Pointer<Byte>>::value, "");
1797static_assert(std::is_same<CToReactorT<bool*>, Pointer<Bool>>::value, "");
1798static_assert(std::is_same<CToReactorT<uint8_t*>, Pointer<Byte>>::value, "");
1799static_assert(std::is_same<CToReactorT<int8_t*>, Pointer<SByte>>::value, "");
1800static_assert(std::is_same<CToReactorT<int16_t*>, Pointer<Short>>::value, "");
1801static_assert(std::is_same<CToReactorT<uint16_t*>, Pointer<UShort>>::value, "");
1802static_assert(std::is_same<CToReactorT<int32_t*>, Pointer<Int>>::value, "");
1803static_assert(std::is_same<CToReactorT<uint64_t*>, Pointer<Long>>::value, "");
1804static_assert(std::is_same<CToReactorT<uint32_t*>, Pointer<UInt>>::value, "");
1805static_assert(std::is_same<CToReactorT<float*>, Pointer<Float>>::value, "");
1806static_assert(std::is_same<CToReactorT<uint16_t**>, Pointer<Pointer<UShort>>>::value, "");
1807static_assert(std::is_same<CToReactorT<uint16_t***>, Pointer<Pointer<Pointer<UShort>>>>::value, "");
Ben Clayton351be422019-04-30 12:26:57 +01001808
Ben Clayton51f08312019-11-08 14:39:26 +00001809// Assert CToReactorT for unknown pointer types resolves to Pointer<Byte>.
Ben Clayton351be422019-04-30 12:26:57 +01001810struct S{};
Ben Clayton51f08312019-11-08 14:39:26 +00001811static_assert(std::is_same<CToReactorT<S*>, Pointer<Byte>>::value, "");
1812static_assert(std::is_same<CToReactorT<S**>, Pointer<Pointer<Byte>>>::value, "");
1813static_assert(std::is_same<CToReactorT<S***>, Pointer<Pointer<Pointer<Byte>>>>::value, "");
Ben Clayton351be422019-04-30 12:26:57 +01001814
1815// Assert IsRValue<> resolves true for RValue<> types.
1816static_assert(IsRValue<RValue<Void>>::value, "");
1817static_assert(IsRValue<RValue<Bool>>::value, "");
1818static_assert(IsRValue<RValue<Byte>>::value, "");
1819static_assert(IsRValue<RValue<SByte>>::value, "");
1820static_assert(IsRValue<RValue<Short>>::value, "");
1821static_assert(IsRValue<RValue<UShort>>::value, "");
1822static_assert(IsRValue<RValue<Int>>::value, "");
1823static_assert(IsRValue<RValue<Long>>::value, "");
1824static_assert(IsRValue<RValue<UInt>>::value, "");
1825static_assert(IsRValue<RValue<Float>>::value, "");
1826
1827// Assert IsLValue<> resolves true for LValue types.
1828static_assert(IsLValue<Bool>::value, "");
1829static_assert(IsLValue<Byte>::value, "");
1830static_assert(IsLValue<SByte>::value, "");
1831static_assert(IsLValue<Short>::value, "");
1832static_assert(IsLValue<UShort>::value, "");
1833static_assert(IsLValue<Int>::value, "");
1834static_assert(IsLValue<Long>::value, "");
1835static_assert(IsLValue<UInt>::value, "");
1836static_assert(IsLValue<Float>::value, "");
1837
Ben Clayton208ed402019-05-03 22:30:03 +01001838// Assert IsReference<> resolves true for Reference types.
1839static_assert(IsReference<Reference<Bool>>::value, "");
1840static_assert(IsReference<Reference<Byte>>::value, "");
1841static_assert(IsReference<Reference<SByte>>::value, "");
1842static_assert(IsReference<Reference<Short>>::value, "");
1843static_assert(IsReference<Reference<UShort>>::value, "");
1844static_assert(IsReference<Reference<Int>>::value, "");
1845static_assert(IsReference<Reference<Long>>::value, "");
1846static_assert(IsReference<Reference<UInt>>::value, "");
1847static_assert(IsReference<Reference<Float>>::value, "");
1848
Ben Clayton351be422019-04-30 12:26:57 +01001849// Assert IsRValue<> resolves false for LValue types.
1850static_assert(!IsRValue<Void>::value, "");
1851static_assert(!IsRValue<Bool>::value, "");
1852static_assert(!IsRValue<Byte>::value, "");
1853static_assert(!IsRValue<SByte>::value, "");
1854static_assert(!IsRValue<Short>::value, "");
1855static_assert(!IsRValue<UShort>::value, "");
1856static_assert(!IsRValue<Int>::value, "");
1857static_assert(!IsRValue<Long>::value, "");
1858static_assert(!IsRValue<UInt>::value, "");
1859static_assert(!IsRValue<Float>::value, "");
1860
Ben Clayton208ed402019-05-03 22:30:03 +01001861// Assert IsRValue<> resolves false for Reference types.
1862static_assert(!IsRValue<Reference<Void>>::value, "");
1863static_assert(!IsRValue<Reference<Bool>>::value, "");
1864static_assert(!IsRValue<Reference<Byte>>::value, "");
1865static_assert(!IsRValue<Reference<SByte>>::value, "");
1866static_assert(!IsRValue<Reference<Short>>::value, "");
1867static_assert(!IsRValue<Reference<UShort>>::value, "");
1868static_assert(!IsRValue<Reference<Int>>::value, "");
1869static_assert(!IsRValue<Reference<Long>>::value, "");
1870static_assert(!IsRValue<Reference<UInt>>::value, "");
1871static_assert(!IsRValue<Reference<Float>>::value, "");
1872
Ben Clayton351be422019-04-30 12:26:57 +01001873// Assert IsRValue<> resolves false for C types.
1874static_assert(!IsRValue<void>::value, "");
1875static_assert(!IsRValue<bool>::value, "");
1876static_assert(!IsRValue<uint8_t>::value, "");
1877static_assert(!IsRValue<int8_t>::value, "");
1878static_assert(!IsRValue<int16_t>::value, "");
1879static_assert(!IsRValue<uint16_t>::value, "");
1880static_assert(!IsRValue<int32_t>::value, "");
1881static_assert(!IsRValue<uint64_t>::value, "");
1882static_assert(!IsRValue<uint32_t>::value, "");
1883static_assert(!IsRValue<float>::value, "");
1884
1885// Assert IsLValue<> resolves false for RValue<> types.
1886static_assert(!IsLValue<RValue<Void>>::value, "");
1887static_assert(!IsLValue<RValue<Bool>>::value, "");
1888static_assert(!IsLValue<RValue<Byte>>::value, "");
1889static_assert(!IsLValue<RValue<SByte>>::value, "");
1890static_assert(!IsLValue<RValue<Short>>::value, "");
1891static_assert(!IsLValue<RValue<UShort>>::value, "");
1892static_assert(!IsLValue<RValue<Int>>::value, "");
1893static_assert(!IsLValue<RValue<Long>>::value, "");
1894static_assert(!IsLValue<RValue<UInt>>::value, "");
1895static_assert(!IsLValue<RValue<Float>>::value, "");
1896
1897// Assert IsLValue<> resolves false for Void type.
1898static_assert(!IsLValue<Void>::value, "");
1899
Ben Clayton208ed402019-05-03 22:30:03 +01001900// Assert IsLValue<> resolves false for Reference<> types.
1901static_assert(!IsLValue<Reference<Void>>::value, "");
1902static_assert(!IsLValue<Reference<Bool>>::value, "");
1903static_assert(!IsLValue<Reference<Byte>>::value, "");
1904static_assert(!IsLValue<Reference<SByte>>::value, "");
1905static_assert(!IsLValue<Reference<Short>>::value, "");
1906static_assert(!IsLValue<Reference<UShort>>::value, "");
1907static_assert(!IsLValue<Reference<Int>>::value, "");
1908static_assert(!IsLValue<Reference<Long>>::value, "");
1909static_assert(!IsLValue<Reference<UInt>>::value, "");
1910static_assert(!IsLValue<Reference<Float>>::value, "");
1911
Ben Clayton351be422019-04-30 12:26:57 +01001912// Assert IsLValue<> resolves false for C types.
1913static_assert(!IsLValue<void>::value, "");
1914static_assert(!IsLValue<bool>::value, "");
1915static_assert(!IsLValue<uint8_t>::value, "");
1916static_assert(!IsLValue<int8_t>::value, "");
1917static_assert(!IsLValue<int16_t>::value, "");
1918static_assert(!IsLValue<uint16_t>::value, "");
1919static_assert(!IsLValue<int32_t>::value, "");
1920static_assert(!IsLValue<uint64_t>::value, "");
1921static_assert(!IsLValue<uint32_t>::value, "");
1922static_assert(!IsLValue<float>::value, "");
1923
1924// Assert IsDefined<> resolves true for RValue<> types.
1925static_assert(IsDefined<RValue<Void>>::value, "");
1926static_assert(IsDefined<RValue<Bool>>::value, "");
1927static_assert(IsDefined<RValue<Byte>>::value, "");
1928static_assert(IsDefined<RValue<SByte>>::value, "");
1929static_assert(IsDefined<RValue<Short>>::value, "");
1930static_assert(IsDefined<RValue<UShort>>::value, "");
1931static_assert(IsDefined<RValue<Int>>::value, "");
1932static_assert(IsDefined<RValue<Long>>::value, "");
1933static_assert(IsDefined<RValue<UInt>>::value, "");
1934static_assert(IsDefined<RValue<Float>>::value, "");
1935
1936// Assert IsDefined<> resolves true for LValue types.
1937static_assert(IsDefined<Void>::value, "");
1938static_assert(IsDefined<Bool>::value, "");
1939static_assert(IsDefined<Byte>::value, "");
1940static_assert(IsDefined<SByte>::value, "");
1941static_assert(IsDefined<Short>::value, "");
1942static_assert(IsDefined<UShort>::value, "");
1943static_assert(IsDefined<Int>::value, "");
1944static_assert(IsDefined<Long>::value, "");
1945static_assert(IsDefined<UInt>::value, "");
1946static_assert(IsDefined<Float>::value, "");
1947
Ben Clayton208ed402019-05-03 22:30:03 +01001948// Assert IsDefined<> resolves true for Reference<> types.
1949static_assert(IsDefined<Reference<Bool>>::value, "");
1950static_assert(IsDefined<Reference<Byte>>::value, "");
1951static_assert(IsDefined<Reference<SByte>>::value, "");
1952static_assert(IsDefined<Reference<Short>>::value, "");
1953static_assert(IsDefined<Reference<UShort>>::value, "");
1954static_assert(IsDefined<Reference<Int>>::value, "");
1955static_assert(IsDefined<Reference<Long>>::value, "");
1956static_assert(IsDefined<Reference<UInt>>::value, "");
1957static_assert(IsDefined<Reference<Float>>::value, "");
1958
Ben Clayton351be422019-04-30 12:26:57 +01001959// Assert IsDefined<> resolves true for C types.
1960static_assert(IsDefined<void>::value, "");
1961static_assert(IsDefined<bool>::value, "");
1962static_assert(IsDefined<uint8_t>::value, "");
1963static_assert(IsDefined<int8_t>::value, "");
1964static_assert(IsDefined<int16_t>::value, "");
1965static_assert(IsDefined<uint16_t>::value, "");
1966static_assert(IsDefined<int32_t>::value, "");
1967static_assert(IsDefined<uint64_t>::value, "");
1968static_assert(IsDefined<uint32_t>::value, "");
1969static_assert(IsDefined<float>::value, "");