blob: 7677c23d3b49639dbf8623f56f8503c274012d65 [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{
1139 if (!rr::Caps.CallSupported)
1140 {
1141 SUCCEED() << "rr::Call() not supported";
1142 return;
1143 }
1144
Ben Claytond853c122019-04-16 17:51:49 -04001145 struct Class
1146 {
Ben Clayton51f08312019-11-08 14:39:26 +00001147 static int Callback(Class *p, int i, float f)
Ben Claytond853c122019-04-16 17:51:49 -04001148 {
Ben Clayton51f08312019-11-08 14:39:26 +00001149 p->i = i;
1150 p->f = f;
Ben Claytond853c122019-04-16 17:51:49 -04001151 return i + int(f);
1152 }
1153
1154 int i = 0;
1155 float f = 0.0f;
1156 };
1157
Ben Clayton51f08312019-11-08 14:39:26 +00001158 FunctionT<int(void*)> function;
Ben Claytond853c122019-04-16 17:51:49 -04001159 {
Ben Clayton51f08312019-11-08 14:39:26 +00001160 Pointer<Byte> c = function.Arg<0>();
1161 auto res = Call(Class::Callback, c, 10, 20.0f);
1162 Return(res);
Ben Claytond853c122019-04-16 17:51:49 -04001163 }
Ben Clayton51f08312019-11-08 14:39:26 +00001164
1165 auto routine = function("one");
1166
1167 Class c;
1168 int res = routine(&c);
1169 EXPECT_EQ(res, 30);
1170 EXPECT_EQ(c.i, 10);
1171 EXPECT_EQ(c.f, 20.0f);
1172}
1173
1174TEST(ReactorUnitTests, CallImplicitCast)
1175{
1176 if (!rr::Caps.CallSupported)
1177 {
1178 SUCCEED() << "rr::Call() not supported";
1179 return;
1180 }
1181
1182 struct Class
1183 {
1184 static void Callback(Class *c, const char* s)
1185 {
1186 c->str = s;
1187 }
1188 std::string str;
1189 };
1190
1191 FunctionT<void(Class *c, const char *s)> function;
1192 {
1193 Pointer<Byte> c = function.Arg<0>();
1194 Pointer<Byte> s = function.Arg<1>();
1195 Call(Class::Callback, c, s);
1196 }
1197
1198 auto routine = function("one");
1199
1200 Class c;
1201 routine(&c, "hello world");
1202 EXPECT_EQ(c.str, "hello world");
Antonio Maioranob7dad7d2019-10-11 15:26:58 -04001203}
Ben Claytond853c122019-04-16 17:51:49 -04001204
Antonio Maioranob7dad7d2019-10-11 15:26:58 -04001205TEST(ReactorUnitTests, CallExternalCallRoutine)
1206{
1207 if (!rr::Caps.CallSupported)
1208 {
1209 SUCCEED() << "rr::Call() not supported";
1210 return;
1211 }
1212
1213 // routine1 calls Class::Func, passing it a pointer to routine2, and Class::Func calls routine2
1214
1215 auto routine2 = [] {
Antonio Maiorano03935ae2019-10-29 16:20:27 -04001216 FunctionT<float(float, int)> function;
Antonio Maioranob7dad7d2019-10-11 15:26:58 -04001217 {
1218 Float a = function.Arg<0>();
1219 Int b = function.Arg<1>();
1220 Return(a + Float(b));
1221 }
1222 return function("two");
1223 }();
1224
1225 struct Class
1226 {
1227 static float Func(void* p, float a, int b)
1228 {
1229 auto funcToCall = reinterpret_cast<float(*)(float, int)>(p);
1230 return funcToCall(a, b);
1231 }
1232 };
1233
1234 auto routine1 = [] {
Antonio Maiorano03935ae2019-10-29 16:20:27 -04001235 FunctionT<float(void*, float, int)> function;
Antonio Maioranob7dad7d2019-10-11 15:26:58 -04001236 {
1237 Pointer<Byte> funcToCall = function.Arg<0>();
1238 Float a = function.Arg<1>();
1239 Int b = function.Arg<2>();
1240 Float result = Call(Class::Func, funcToCall, a, b);
1241 Return(result);
1242 }
1243 return function("one");
1244 }();
1245
Antonio Maiorano03935ae2019-10-29 16:20:27 -04001246 float result = routine1((void*)routine2.getEntry(), 12.f, 13);
Antonio Maioranob7dad7d2019-10-11 15:26:58 -04001247 EXPECT_EQ(result, 25.f);
Ben Claytond853c122019-04-16 17:51:49 -04001248}
1249
Stephen White17078c72019-02-27 14:39:14 -05001250// Check that a complex generated function which utilizes all 8 or 16 XMM
1251// registers computes the correct result.
1252// (Note that due to MSC's lack of support for inline assembly in x64,
Ben Claytonb1243732019-02-27 23:56:18 +00001253// this test does not actually check that the register contents are
Stephen White17078c72019-02-27 14:39:14 -05001254// preserved, just that the generated function computes the correct value.
1255// It's necessary to inspect the registers in a debugger to actually verify.)
1256TEST(ReactorUnitTests, PreserveXMMRegisters)
1257{
Stephen White17078c72019-02-27 14:39:14 -05001258 {
Antonio Maiorano03935ae2019-10-29 16:20:27 -04001259 FunctionT<void(void*, void*)> function;
Stephen White17078c72019-02-27 14:39:14 -05001260 {
1261 Pointer<Byte> in = function.Arg<0>();
1262 Pointer<Byte> out = function.Arg<1>();
1263
1264 Float4 a = *Pointer<Float4>(in + 16 * 0);
1265 Float4 b = *Pointer<Float4>(in + 16 * 1);
1266 Float4 c = *Pointer<Float4>(in + 16 * 2);
1267 Float4 d = *Pointer<Float4>(in + 16 * 3);
1268 Float4 e = *Pointer<Float4>(in + 16 * 4);
1269 Float4 f = *Pointer<Float4>(in + 16 * 5);
1270 Float4 g = *Pointer<Float4>(in + 16 * 6);
1271 Float4 h = *Pointer<Float4>(in + 16 * 7);
1272 Float4 i = *Pointer<Float4>(in + 16 * 8);
1273 Float4 j = *Pointer<Float4>(in + 16 * 9);
1274 Float4 k = *Pointer<Float4>(in + 16 * 10);
1275 Float4 l = *Pointer<Float4>(in + 16 * 11);
1276 Float4 m = *Pointer<Float4>(in + 16 * 12);
1277 Float4 n = *Pointer<Float4>(in + 16 * 13);
1278 Float4 o = *Pointer<Float4>(in + 16 * 14);
1279 Float4 p = *Pointer<Float4>(in + 16 * 15);
1280
1281 Float4 ab = a + b;
1282 Float4 cd = c + d;
1283 Float4 ef = e + f;
1284 Float4 gh = g + h;
1285 Float4 ij = i + j;
1286 Float4 kl = k + l;
1287 Float4 mn = m + n;
1288 Float4 op = o + p;
1289
1290 Float4 abcd = ab + cd;
1291 Float4 efgh = ef + gh;
1292 Float4 ijkl = ij + kl;
1293 Float4 mnop = mn + op;
1294
1295 Float4 abcdefgh = abcd + efgh;
1296 Float4 ijklmnop = ijkl + mnop;
1297 Float4 sum = abcdefgh + ijklmnop;
1298 *Pointer<Float4>(out) = sum;
1299 Return();
1300 }
1301
Antonio Maiorano03935ae2019-10-29 16:20:27 -04001302 auto routine = function("one");
Stephen White17078c72019-02-27 14:39:14 -05001303 assert(routine);
1304
1305 float input[64] = { 1.0f, 0.0f, 0.0f, 0.0f,
1306 -1.0f, 1.0f, -1.0f, 0.0f,
1307 1.0f, 2.0f, -2.0f, 0.0f,
1308 -1.0f, 3.0f, -3.0f, 0.0f,
1309 1.0f, 4.0f, -4.0f, 0.0f,
1310 -1.0f, 5.0f, -5.0f, 0.0f,
1311 1.0f, 6.0f, -6.0f, 0.0f,
1312 -1.0f, 7.0f, -7.0f, 0.0f,
1313 1.0f, 8.0f, -8.0f, 0.0f,
1314 -1.0f, 9.0f, -9.0f, 0.0f,
1315 1.0f, 10.0f, -10.0f, 0.0f,
1316 -1.0f, 11.0f, -11.0f, 0.0f,
1317 1.0f, 12.0f, -12.0f, 0.0f,
1318 -1.0f, 13.0f, -13.0f, 0.0f,
1319 1.0f, 14.0f, -14.0f, 0.0f,
1320 -1.0f, 15.0f, -15.0f, 0.0f };
1321
1322 float result[4];
Stephen White17078c72019-02-27 14:39:14 -05001323
Antonio Maiorano03935ae2019-10-29 16:20:27 -04001324 routine(input, result);
Stephen White17078c72019-02-27 14:39:14 -05001325
1326 EXPECT_EQ(result[0], 0.0f);
1327 EXPECT_EQ(result[1], 120.0f);
1328 EXPECT_EQ(result[2], -120.0f);
1329 EXPECT_EQ(result[3], 0.0f);
1330 }
1331
Stephen White17078c72019-02-27 14:39:14 -05001332}
1333
Ben Claytonb1243732019-02-27 23:56:18 +00001334template <typename T>
Ben Clayton51f08312019-11-08 14:39:26 +00001335class CToReactorTCastTest : public ::testing::Test
Nicolas Capensf0d22ad2019-03-15 17:22:42 -04001336{
Ben Claytonf3b57972019-03-15 09:56:47 +00001337public:
1338 using CType = typename std::tuple_element<0, T>::type;
1339 using ReactorType = typename std::tuple_element<1, T>::type;
1340};
1341
Ben Clayton51f08312019-11-08 14:39:26 +00001342using CToReactorTCastTestTypes = ::testing::Types
Ben Claytonf3b57972019-03-15 09:56:47 +00001343 < // Subset of types that can be used as arguments.
Nicolas Capensf0d22ad2019-03-15 17:22:42 -04001344 // std::pair<bool, Bool>, FIXME(capn): Not supported as argument type by Subzero.
1345 // std::pair<uint8_t, Byte>, FIXME(capn): Not supported as argument type by Subzero.
1346 // std::pair<int8_t, SByte>, FIXME(capn): Not supported as argument type by Subzero.
1347 // std::pair<int16_t, Short>, FIXME(capn): Not supported as argument type by Subzero.
1348 // std::pair<uint16_t, UShort>, FIXME(capn): Not supported as argument type by Subzero.
Ben Claytonf3b57972019-03-15 09:56:47 +00001349 std::pair<int, Int>,
1350 std::pair<unsigned int, UInt>,
1351 std::pair<float, Float>
1352 >;
1353
Ben Clayton51f08312019-11-08 14:39:26 +00001354TYPED_TEST_SUITE(CToReactorTCastTest, CToReactorTCastTestTypes);
Ben Claytonf3b57972019-03-15 09:56:47 +00001355
Ben Clayton51f08312019-11-08 14:39:26 +00001356TYPED_TEST(CToReactorTCastTest, Casts)
Nicolas Capensf0d22ad2019-03-15 17:22:42 -04001357{
Ben Claytonf3b57972019-03-15 09:56:47 +00001358 using CType = typename TestFixture::CType;
1359 using ReactorType = typename TestFixture::ReactorType;
1360
Ben Clayton6897e9b2019-07-16 17:27:27 +01001361 std::shared_ptr<Routine> routine;
Ben Claytonf3b57972019-03-15 09:56:47 +00001362
1363 {
1364 Function< Int(ReactorType) > function;
1365 {
1366 ReactorType a = function.template Arg<0>();
1367 ReactorType b = CType{};
1368 RValue<ReactorType> c = RValue<ReactorType>(CType{});
1369 Bool same = (a == b) && (a == c);
1370 Return(IfThenElse(same, Int(1), Int(0))); // TODO: Ability to use Bools as return values.
1371 }
1372
1373 routine = function("one");
1374
1375 if(routine)
1376 {
1377 auto callable = (int(*)(CType))routine->getEntry();
1378 CType in = {};
1379 EXPECT_EQ(callable(in), 1);
1380 }
1381 }
1382
Ben Claytonf3b57972019-03-15 09:56:47 +00001383}
1384
1385template <typename T>
Nicolas Capensf0d22ad2019-03-15 17:22:42 -04001386class GEPTest : public ::testing::Test
1387{
Ben Claytonb1243732019-02-27 23:56:18 +00001388public:
1389 using CType = typename std::tuple_element<0, T>::type;
1390 using ReactorType = typename std::tuple_element<1, T>::type;
1391};
1392
1393using GEPTestTypes = ::testing::Types
1394 <
Ben Claytonf3b57972019-03-15 09:56:47 +00001395 std::pair<bool, Bool>,
Ben Claytonb1243732019-02-27 23:56:18 +00001396 std::pair<int8_t, Byte>,
1397 std::pair<int8_t, SByte>,
1398 std::pair<int8_t[4], Byte4>,
1399 std::pair<int8_t[4], SByte4>,
1400 std::pair<int8_t[8], Byte8>,
1401 std::pair<int8_t[8], SByte8>,
1402 std::pair<int8_t[16], Byte16>,
1403 std::pair<int8_t[16], SByte16>,
1404 std::pair<int16_t, Short>,
1405 std::pair<int16_t, UShort>,
1406 std::pair<int16_t[2], Short2>,
1407 std::pair<int16_t[2], UShort2>,
1408 std::pair<int16_t[4], Short4>,
1409 std::pair<int16_t[4], UShort4>,
1410 std::pair<int16_t[8], Short8>,
1411 std::pair<int16_t[8], UShort8>,
1412 std::pair<int, Int>,
1413 std::pair<int, UInt>,
1414 std::pair<int[2], Int2>,
1415 std::pair<int[2], UInt2>,
1416 std::pair<int[4], Int4>,
1417 std::pair<int[4], UInt4>,
1418 std::pair<int64_t, Long>,
1419 std::pair<int16_t, Half>,
1420 std::pair<float, Float>,
1421 std::pair<float[2], Float2>,
1422 std::pair<float[4], Float4>
1423 >;
1424
Alexis Hetu79d4ac92019-06-03 11:31:46 -04001425TYPED_TEST_SUITE(GEPTest, GEPTestTypes);
Ben Claytonb1243732019-02-27 23:56:18 +00001426
Nicolas Capensf0d22ad2019-03-15 17:22:42 -04001427TYPED_TEST(GEPTest, PtrOffsets)
1428{
Ben Claytonb1243732019-02-27 23:56:18 +00001429 using CType = typename TestFixture::CType;
1430 using ReactorType = typename TestFixture::ReactorType;
1431
Ben Clayton6897e9b2019-07-16 17:27:27 +01001432 std::shared_ptr<Routine> routine;
Ben Claytonb1243732019-02-27 23:56:18 +00001433
1434 {
1435 Function< Pointer<ReactorType>(Pointer<ReactorType>, Int) > function;
1436 {
1437 Pointer<ReactorType> pointer = function.template Arg<0>();
1438 Int index = function.template Arg<1>();
1439 Return(&pointer[index]);
1440 }
1441
1442 routine = function("one");
1443
1444 if(routine)
1445 {
1446 auto callable = (CType*(*)(CType*, unsigned int))routine->getEntry();
1447
1448 union PtrInt {
1449 CType* p;
1450 size_t i;
1451 };
1452
1453 PtrInt base;
1454 base.i = 0x10000;
1455
1456 for (int i = 0; i < 5; i++)
1457 {
1458 PtrInt reference;
1459 reference.p = &base.p[i];
1460
1461 PtrInt result;
1462 result.p = callable(base.p, i);
1463
1464 auto expect = reference.i - base.i;
1465 auto got = result.i - base.i;
1466
1467 EXPECT_EQ(got, expect) << "i:" << i;
1468 }
1469 }
1470 }
1471
Ben Claytonb1243732019-02-27 23:56:18 +00001472}
1473
Ben Clayton1c82c7b2019-04-30 12:49:27 +01001474TEST(ReactorUnitTests, Coroutines_Fibonacci)
1475{
1476 if (!rr::Caps.CoroutinesSupported)
1477 {
1478 SUCCEED() << "Coroutines not supported";
1479 return;
1480 }
1481
1482 Coroutine<int()> function;
1483 {
1484 Yield(Int(0));
1485 Yield(Int(1));
1486 Int current = 1;
1487 Int next = 1;
1488 While (true) {
1489 Yield(next);
1490 auto tmp = current + next;
1491 current = next;
1492 next = tmp;
1493 }
1494 }
1495
1496 auto coroutine = function();
1497
1498 int32_t expected[] =
1499 {
1500 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597,
1501 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418,
1502 317811,
1503 };
1504
1505 auto count = sizeof(expected) / sizeof(expected[0]);
1506
1507 for (size_t i = 0; i < count; i++)
1508 {
1509 int out = 0;
1510 EXPECT_EQ(coroutine->await(out), true);
1511 EXPECT_EQ(out, expected[i]);
1512 }
1513}
1514
1515TEST(ReactorUnitTests, Coroutines_Parameters)
1516{
1517 if (!rr::Caps.CoroutinesSupported)
1518 {
1519 SUCCEED() << "Coroutines not supported";
1520 return;
1521 }
1522
1523 Coroutine<uint8_t(uint8_t* data, int count)> function;
1524 {
1525 Pointer<Byte> data = function.Arg<0>();
1526 Int count = function.Arg<1>();
1527
1528 For(Int i = 0, i < count, i++)
1529 {
1530 Yield(data[i]);
1531 }
1532 }
1533
1534 uint8_t data[] = {10, 20, 30};
1535 auto coroutine = function(&data[0], 3);
1536
1537 uint8_t out = 0;
1538 EXPECT_EQ(coroutine->await(out), true);
1539 EXPECT_EQ(out, 10); out = 0;
1540 EXPECT_EQ(coroutine->await(out), true);
1541 EXPECT_EQ(out, 20); out = 0;
1542 EXPECT_EQ(coroutine->await(out), true);
1543 EXPECT_EQ(out, 30); out = 99;
1544 EXPECT_EQ(coroutine->await(out), false);
1545 EXPECT_EQ(out, 99);
1546 EXPECT_EQ(coroutine->await(out), false);
1547 EXPECT_EQ(out, 99);
1548}
1549
Nicolas Capens228b05d2016-10-12 15:27:04 -04001550int main(int argc, char **argv)
1551{
1552 ::testing::InitGoogleTest(&argc, argv);
1553 return RUN_ALL_TESTS();
Nicolas Capens598f8d82016-09-26 15:09:10 -04001554}
Ben Clayton351be422019-04-30 12:26:57 +01001555
1556////////////////////////////////
1557// Trait compile time checks. //
1558////////////////////////////////
1559
Ben Clayton51f08312019-11-08 14:39:26 +00001560// Assert CToReactorT resolves to expected types.
1561static_assert(std::is_same<CToReactorT<void>, Void>::value, "");
1562static_assert(std::is_same<CToReactorT<bool>, Bool>::value, "");
1563static_assert(std::is_same<CToReactorT<uint8_t>, Byte>::value, "");
1564static_assert(std::is_same<CToReactorT<int8_t>, SByte>::value, "");
1565static_assert(std::is_same<CToReactorT<int16_t>, Short>::value, "");
1566static_assert(std::is_same<CToReactorT<uint16_t>, UShort>::value, "");
1567static_assert(std::is_same<CToReactorT<int32_t>, Int>::value, "");
1568static_assert(std::is_same<CToReactorT<uint64_t>, Long>::value, "");
1569static_assert(std::is_same<CToReactorT<uint32_t>, UInt>::value, "");
1570static_assert(std::is_same<CToReactorT<float>, Float>::value, "");
Ben Clayton351be422019-04-30 12:26:57 +01001571
Ben Clayton51f08312019-11-08 14:39:26 +00001572// Assert CToReactorT for known pointer types resolves to expected types.
1573static_assert(std::is_same<CToReactorT<void*>, Pointer<Byte>>::value, "");
1574static_assert(std::is_same<CToReactorT<bool*>, Pointer<Bool>>::value, "");
1575static_assert(std::is_same<CToReactorT<uint8_t*>, Pointer<Byte>>::value, "");
1576static_assert(std::is_same<CToReactorT<int8_t*>, Pointer<SByte>>::value, "");
1577static_assert(std::is_same<CToReactorT<int16_t*>, Pointer<Short>>::value, "");
1578static_assert(std::is_same<CToReactorT<uint16_t*>, Pointer<UShort>>::value, "");
1579static_assert(std::is_same<CToReactorT<int32_t*>, Pointer<Int>>::value, "");
1580static_assert(std::is_same<CToReactorT<uint64_t*>, Pointer<Long>>::value, "");
1581static_assert(std::is_same<CToReactorT<uint32_t*>, Pointer<UInt>>::value, "");
1582static_assert(std::is_same<CToReactorT<float*>, Pointer<Float>>::value, "");
1583static_assert(std::is_same<CToReactorT<uint16_t**>, Pointer<Pointer<UShort>>>::value, "");
1584static_assert(std::is_same<CToReactorT<uint16_t***>, Pointer<Pointer<Pointer<UShort>>>>::value, "");
Ben Clayton351be422019-04-30 12:26:57 +01001585
Ben Clayton51f08312019-11-08 14:39:26 +00001586// Assert CToReactorT for unknown pointer types resolves to Pointer<Byte>.
Ben Clayton351be422019-04-30 12:26:57 +01001587struct S{};
Ben Clayton51f08312019-11-08 14:39:26 +00001588static_assert(std::is_same<CToReactorT<S*>, Pointer<Byte>>::value, "");
1589static_assert(std::is_same<CToReactorT<S**>, Pointer<Pointer<Byte>>>::value, "");
1590static_assert(std::is_same<CToReactorT<S***>, Pointer<Pointer<Pointer<Byte>>>>::value, "");
Ben Clayton351be422019-04-30 12:26:57 +01001591
1592// Assert IsRValue<> resolves true for RValue<> types.
1593static_assert(IsRValue<RValue<Void>>::value, "");
1594static_assert(IsRValue<RValue<Bool>>::value, "");
1595static_assert(IsRValue<RValue<Byte>>::value, "");
1596static_assert(IsRValue<RValue<SByte>>::value, "");
1597static_assert(IsRValue<RValue<Short>>::value, "");
1598static_assert(IsRValue<RValue<UShort>>::value, "");
1599static_assert(IsRValue<RValue<Int>>::value, "");
1600static_assert(IsRValue<RValue<Long>>::value, "");
1601static_assert(IsRValue<RValue<UInt>>::value, "");
1602static_assert(IsRValue<RValue<Float>>::value, "");
1603
1604// Assert IsLValue<> resolves true for LValue types.
1605static_assert(IsLValue<Bool>::value, "");
1606static_assert(IsLValue<Byte>::value, "");
1607static_assert(IsLValue<SByte>::value, "");
1608static_assert(IsLValue<Short>::value, "");
1609static_assert(IsLValue<UShort>::value, "");
1610static_assert(IsLValue<Int>::value, "");
1611static_assert(IsLValue<Long>::value, "");
1612static_assert(IsLValue<UInt>::value, "");
1613static_assert(IsLValue<Float>::value, "");
1614
Ben Clayton208ed402019-05-03 22:30:03 +01001615// Assert IsReference<> resolves true for Reference types.
1616static_assert(IsReference<Reference<Bool>>::value, "");
1617static_assert(IsReference<Reference<Byte>>::value, "");
1618static_assert(IsReference<Reference<SByte>>::value, "");
1619static_assert(IsReference<Reference<Short>>::value, "");
1620static_assert(IsReference<Reference<UShort>>::value, "");
1621static_assert(IsReference<Reference<Int>>::value, "");
1622static_assert(IsReference<Reference<Long>>::value, "");
1623static_assert(IsReference<Reference<UInt>>::value, "");
1624static_assert(IsReference<Reference<Float>>::value, "");
1625
Ben Clayton351be422019-04-30 12:26:57 +01001626// Assert IsRValue<> resolves false for LValue types.
1627static_assert(!IsRValue<Void>::value, "");
1628static_assert(!IsRValue<Bool>::value, "");
1629static_assert(!IsRValue<Byte>::value, "");
1630static_assert(!IsRValue<SByte>::value, "");
1631static_assert(!IsRValue<Short>::value, "");
1632static_assert(!IsRValue<UShort>::value, "");
1633static_assert(!IsRValue<Int>::value, "");
1634static_assert(!IsRValue<Long>::value, "");
1635static_assert(!IsRValue<UInt>::value, "");
1636static_assert(!IsRValue<Float>::value, "");
1637
Ben Clayton208ed402019-05-03 22:30:03 +01001638// Assert IsRValue<> resolves false for Reference types.
1639static_assert(!IsRValue<Reference<Void>>::value, "");
1640static_assert(!IsRValue<Reference<Bool>>::value, "");
1641static_assert(!IsRValue<Reference<Byte>>::value, "");
1642static_assert(!IsRValue<Reference<SByte>>::value, "");
1643static_assert(!IsRValue<Reference<Short>>::value, "");
1644static_assert(!IsRValue<Reference<UShort>>::value, "");
1645static_assert(!IsRValue<Reference<Int>>::value, "");
1646static_assert(!IsRValue<Reference<Long>>::value, "");
1647static_assert(!IsRValue<Reference<UInt>>::value, "");
1648static_assert(!IsRValue<Reference<Float>>::value, "");
1649
Ben Clayton351be422019-04-30 12:26:57 +01001650// Assert IsRValue<> resolves false for C types.
1651static_assert(!IsRValue<void>::value, "");
1652static_assert(!IsRValue<bool>::value, "");
1653static_assert(!IsRValue<uint8_t>::value, "");
1654static_assert(!IsRValue<int8_t>::value, "");
1655static_assert(!IsRValue<int16_t>::value, "");
1656static_assert(!IsRValue<uint16_t>::value, "");
1657static_assert(!IsRValue<int32_t>::value, "");
1658static_assert(!IsRValue<uint64_t>::value, "");
1659static_assert(!IsRValue<uint32_t>::value, "");
1660static_assert(!IsRValue<float>::value, "");
1661
1662// Assert IsLValue<> resolves false for RValue<> types.
1663static_assert(!IsLValue<RValue<Void>>::value, "");
1664static_assert(!IsLValue<RValue<Bool>>::value, "");
1665static_assert(!IsLValue<RValue<Byte>>::value, "");
1666static_assert(!IsLValue<RValue<SByte>>::value, "");
1667static_assert(!IsLValue<RValue<Short>>::value, "");
1668static_assert(!IsLValue<RValue<UShort>>::value, "");
1669static_assert(!IsLValue<RValue<Int>>::value, "");
1670static_assert(!IsLValue<RValue<Long>>::value, "");
1671static_assert(!IsLValue<RValue<UInt>>::value, "");
1672static_assert(!IsLValue<RValue<Float>>::value, "");
1673
1674// Assert IsLValue<> resolves false for Void type.
1675static_assert(!IsLValue<Void>::value, "");
1676
Ben Clayton208ed402019-05-03 22:30:03 +01001677// Assert IsLValue<> resolves false for Reference<> types.
1678static_assert(!IsLValue<Reference<Void>>::value, "");
1679static_assert(!IsLValue<Reference<Bool>>::value, "");
1680static_assert(!IsLValue<Reference<Byte>>::value, "");
1681static_assert(!IsLValue<Reference<SByte>>::value, "");
1682static_assert(!IsLValue<Reference<Short>>::value, "");
1683static_assert(!IsLValue<Reference<UShort>>::value, "");
1684static_assert(!IsLValue<Reference<Int>>::value, "");
1685static_assert(!IsLValue<Reference<Long>>::value, "");
1686static_assert(!IsLValue<Reference<UInt>>::value, "");
1687static_assert(!IsLValue<Reference<Float>>::value, "");
1688
Ben Clayton351be422019-04-30 12:26:57 +01001689// Assert IsLValue<> resolves false for C types.
1690static_assert(!IsLValue<void>::value, "");
1691static_assert(!IsLValue<bool>::value, "");
1692static_assert(!IsLValue<uint8_t>::value, "");
1693static_assert(!IsLValue<int8_t>::value, "");
1694static_assert(!IsLValue<int16_t>::value, "");
1695static_assert(!IsLValue<uint16_t>::value, "");
1696static_assert(!IsLValue<int32_t>::value, "");
1697static_assert(!IsLValue<uint64_t>::value, "");
1698static_assert(!IsLValue<uint32_t>::value, "");
1699static_assert(!IsLValue<float>::value, "");
1700
1701// Assert IsDefined<> resolves true for RValue<> types.
1702static_assert(IsDefined<RValue<Void>>::value, "");
1703static_assert(IsDefined<RValue<Bool>>::value, "");
1704static_assert(IsDefined<RValue<Byte>>::value, "");
1705static_assert(IsDefined<RValue<SByte>>::value, "");
1706static_assert(IsDefined<RValue<Short>>::value, "");
1707static_assert(IsDefined<RValue<UShort>>::value, "");
1708static_assert(IsDefined<RValue<Int>>::value, "");
1709static_assert(IsDefined<RValue<Long>>::value, "");
1710static_assert(IsDefined<RValue<UInt>>::value, "");
1711static_assert(IsDefined<RValue<Float>>::value, "");
1712
1713// Assert IsDefined<> resolves true for LValue types.
1714static_assert(IsDefined<Void>::value, "");
1715static_assert(IsDefined<Bool>::value, "");
1716static_assert(IsDefined<Byte>::value, "");
1717static_assert(IsDefined<SByte>::value, "");
1718static_assert(IsDefined<Short>::value, "");
1719static_assert(IsDefined<UShort>::value, "");
1720static_assert(IsDefined<Int>::value, "");
1721static_assert(IsDefined<Long>::value, "");
1722static_assert(IsDefined<UInt>::value, "");
1723static_assert(IsDefined<Float>::value, "");
1724
Ben Clayton208ed402019-05-03 22:30:03 +01001725// Assert IsDefined<> resolves true for Reference<> types.
1726static_assert(IsDefined<Reference<Bool>>::value, "");
1727static_assert(IsDefined<Reference<Byte>>::value, "");
1728static_assert(IsDefined<Reference<SByte>>::value, "");
1729static_assert(IsDefined<Reference<Short>>::value, "");
1730static_assert(IsDefined<Reference<UShort>>::value, "");
1731static_assert(IsDefined<Reference<Int>>::value, "");
1732static_assert(IsDefined<Reference<Long>>::value, "");
1733static_assert(IsDefined<Reference<UInt>>::value, "");
1734static_assert(IsDefined<Reference<Float>>::value, "");
1735
Ben Clayton351be422019-04-30 12:26:57 +01001736// Assert IsDefined<> resolves true for C types.
1737static_assert(IsDefined<void>::value, "");
1738static_assert(IsDefined<bool>::value, "");
1739static_assert(IsDefined<uint8_t>::value, "");
1740static_assert(IsDefined<int8_t>::value, "");
1741static_assert(IsDefined<int16_t>::value, "");
1742static_assert(IsDefined<uint16_t>::value, "");
1743static_assert(IsDefined<int32_t>::value, "");
1744static_assert(IsDefined<uint64_t>::value, "");
1745static_assert(IsDefined<uint32_t>::value, "");
1746static_assert(IsDefined<float>::value, "");