blob: 1cdc32da02c1a5dbd6309aabb8fe1f31bd5b3dca [file] [log] [blame]
Nicolas Capens0bac2852016-05-07 06:09:58 -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
Nicolas Capens48461502018-08-06 14:20:45 -040015#ifndef rr_Reactor_hpp
16#define rr_Reactor_hpp
Nicolas Capensd022e412016-09-26 13:30:14 -040017
Nicolas Capens0bac2852016-05-07 06:09:58 -040018#include "Nucleus.hpp"
19#include "Routine.hpp"
20
Nicolas Capens4dd1eff2017-08-04 09:33:04 -040021#include <cassert>
Nicolas Capens3bbc5e12016-09-27 10:49:52 -040022#include <cstddef>
Chris Forbes878d4b02019-01-21 10:48:35 -080023#include <cstdio>
Ben Clayton1bc7ee92019-02-14 18:43:22 +000024
25#include <string>
26
Nicolas Capens3bbc5e12016-09-27 10:49:52 -040027#undef Bool
28
Ben Clayton1bc7ee92019-02-14 18:43:22 +000029#if !defined(NDEBUG) && (REACTOR_LLVM_VERSION >= 7)
30#define ENABLE_RR_PRINT 1 // Enables RR_PRINT(), RR_WATCH()
31#endif // !defined(NDEBUG) && (REACTOR_LLVM_VERSION >= 7)
32
Nicolas Capens48461502018-08-06 14:20:45 -040033namespace rr
Nicolas Capens0bac2852016-05-07 06:09:58 -040034{
Nicolas Capenseb253d02016-11-18 14:40:40 -050035 class Bool;
Nicolas Capensd022e412016-09-26 13:30:14 -040036 class Byte;
37 class SByte;
38 class Byte4;
39 class SByte4;
40 class Byte8;
41 class SByte8;
42 class Byte16;
43 class SByte16;
44 class Short;
45 class UShort;
Nicolas Capens16b5f152016-10-13 13:39:01 -040046 class Short2;
47 class UShort2;
Nicolas Capensd022e412016-09-26 13:30:14 -040048 class Short4;
49 class UShort4;
50 class Short8;
51 class UShort8;
52 class Int;
53 class UInt;
54 class Int2;
55 class UInt2;
56 class Int4;
57 class UInt4;
58 class Long;
Alexis Hetu734e2572018-12-20 14:00:49 -050059 class Half;
Nicolas Capensd022e412016-09-26 13:30:14 -040060 class Float;
61 class Float2;
62 class Float4;
63
64 class Void
65 {
66 public:
67 static Type *getType();
68
69 static bool isVoid()
70 {
71 return true;
72 }
Nicolas Capensd022e412016-09-26 13:30:14 -040073 };
74
75 template<class T>
76 class RValue;
77
78 template<class T>
79 class Pointer;
80
Nicolas Capens297d26e2016-11-18 12:52:17 -050081 class Variable
82 {
83 protected:
Ben Clayton1bc7ee92019-02-14 18:43:22 +000084 friend class PrintValue;
Nicolas Capens297d26e2016-11-18 12:52:17 -050085 Value *address;
86 };
87
Nicolas Capens22479eb2016-09-28 22:34:26 -040088 template<class T>
Nicolas Capens297d26e2016-11-18 12:52:17 -050089 class LValue : public Variable
Nicolas Capensd022e412016-09-26 13:30:14 -040090 {
91 public:
Nicolas Capens22479eb2016-09-28 22:34:26 -040092 LValue(int arraySize = 0);
Nicolas Capensd022e412016-09-26 13:30:14 -040093
Nicolas Capens297d26e2016-11-18 12:52:17 -050094 RValue<Pointer<T>> operator&();
95
Nicolas Capensd022e412016-09-26 13:30:14 -040096 static bool isVoid()
97 {
98 return false;
99 }
100
Nicolas Capens4126b8e2017-07-26 13:34:36 -0400101 Value *loadValue() const;
102 Value *storeValue(Value *value) const;
Nicolas Capensd294def2017-01-26 17:44:37 -0800103 Value *getAddress(Value *index, bool unsignedIndex) const;
Nicolas Capensd022e412016-09-26 13:30:14 -0400104 };
105
106 template<class T>
107 class Reference
108 {
109 public:
110 explicit Reference(Value *pointer, int alignment = 1);
111
112 RValue<T> operator=(RValue<T> rhs) const;
113 RValue<T> operator=(const Reference<T> &ref) const;
114
115 RValue<T> operator+=(RValue<T> rhs) const;
116
Ben Claytonec255732019-02-27 13:51:22 +0000117 RValue<Pointer<T>> operator&() const { return RValue<Pointer<T>>(address); }
118
Nicolas Capensd022e412016-09-26 13:30:14 -0400119 Value *loadValue() const;
120 int getAlignment() const;
121
122 private:
123 Value *address;
124
125 const int alignment;
126 };
127
128 template<class T>
Ben Clayton35e90e22019-03-15 10:06:06 +0000129 struct BoolLiteral
Nicolas Capensd022e412016-09-26 13:30:14 -0400130 {
131 struct type;
132 };
133
Nicolas Capenseb253d02016-11-18 14:40:40 -0500134 template<>
Ben Clayton35e90e22019-03-15 10:06:06 +0000135 struct BoolLiteral<Bool>
Nicolas Capenseb253d02016-11-18 14:40:40 -0500136 {
137 typedef bool type;
138 };
139
Ben Clayton35e90e22019-03-15 10:06:06 +0000140 template<class T>
141 struct IntLiteral
142 {
143 struct type;
144 };
145
Nicolas Capenseb253d02016-11-18 14:40:40 -0500146 template<>
147 struct IntLiteral<Int>
Nicolas Capensd022e412016-09-26 13:30:14 -0400148 {
149 typedef int type;
150 };
151
Nicolas Capenseb253d02016-11-18 14:40:40 -0500152 template<>
153 struct IntLiteral<UInt>
Nicolas Capensd022e412016-09-26 13:30:14 -0400154 {
155 typedef unsigned int type;
156 };
157
Nicolas Capenseb253d02016-11-18 14:40:40 -0500158 template<>
159 struct IntLiteral<Long>
Nicolas Capensd022e412016-09-26 13:30:14 -0400160 {
161 typedef int64_t type;
162 };
163
164 template<class T>
165 struct FloatLiteral
166 {
167 struct type;
168 };
169
Nicolas Capenseb253d02016-11-18 14:40:40 -0500170 template<>
171 struct FloatLiteral<Float>
Nicolas Capensd022e412016-09-26 13:30:14 -0400172 {
173 typedef float type;
174 };
175
176 template<class T>
177 class RValue
178 {
179 public:
180 explicit RValue(Value *rvalue);
181
182 RValue(const T &lvalue);
Ben Clayton35e90e22019-03-15 10:06:06 +0000183 RValue(typename BoolLiteral<T>::type i);
Nicolas Capensd022e412016-09-26 13:30:14 -0400184 RValue(typename IntLiteral<T>::type i);
185 RValue(typename FloatLiteral<T>::type f);
186 RValue(const Reference<T> &rhs);
187
188 RValue<T> &operator=(const RValue<T>&) = delete;
189
190 Value *value; // FIXME: Make private
191 };
192
193 template<typename T>
194 struct Argument
195 {
196 explicit Argument(Value *value) : value(value) {}
197
198 Value *value;
199 };
200
Nicolas Capens297d26e2016-11-18 12:52:17 -0500201 class Bool : public LValue<Bool>
Nicolas Capensd022e412016-09-26 13:30:14 -0400202 {
203 public:
204 Bool(Argument<Bool> argument);
205
Nicolas Capensa25311a2017-01-16 17:19:00 -0500206 Bool() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -0400207 Bool(bool x);
208 Bool(RValue<Bool> rhs);
209 Bool(const Bool &rhs);
210 Bool(const Reference<Bool> &rhs);
211
Nicolas Capens96d4e092016-11-18 14:22:38 -0500212 // RValue<Bool> operator=(bool rhs); // FIXME: Implement
213 RValue<Bool> operator=(RValue<Bool> rhs);
214 RValue<Bool> operator=(const Bool &rhs);
215 RValue<Bool> operator=(const Reference<Bool> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400216
217 static Type *getType();
218 };
219
220 RValue<Bool> operator!(RValue<Bool> val);
221 RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs);
222 RValue<Bool> operator||(RValue<Bool> lhs, RValue<Bool> rhs);
Ben Claytonf3b57972019-03-15 09:56:47 +0000223 RValue<Bool> operator!=(RValue<Bool> lhs, RValue<Bool> rhs);
224 RValue<Bool> operator==(RValue<Bool> lhs, RValue<Bool> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400225
Nicolas Capens297d26e2016-11-18 12:52:17 -0500226 class Byte : public LValue<Byte>
Nicolas Capensd022e412016-09-26 13:30:14 -0400227 {
228 public:
229 Byte(Argument<Byte> argument);
230
231 explicit Byte(RValue<Int> cast);
232 explicit Byte(RValue<UInt> cast);
233 explicit Byte(RValue<UShort> cast);
234
Nicolas Capensa25311a2017-01-16 17:19:00 -0500235 Byte() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -0400236 Byte(int x);
237 Byte(unsigned char x);
238 Byte(RValue<Byte> rhs);
239 Byte(const Byte &rhs);
240 Byte(const Reference<Byte> &rhs);
241
Nicolas Capens96d4e092016-11-18 14:22:38 -0500242 // RValue<Byte> operator=(unsigned char rhs); // FIXME: Implement
243 RValue<Byte> operator=(RValue<Byte> rhs);
244 RValue<Byte> operator=(const Byte &rhs);
245 RValue<Byte> operator=(const Reference<Byte> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400246
247 static Type *getType();
248 };
249
250 RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs);
251 RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs);
252 RValue<Byte> operator*(RValue<Byte> lhs, RValue<Byte> rhs);
253 RValue<Byte> operator/(RValue<Byte> lhs, RValue<Byte> rhs);
254 RValue<Byte> operator%(RValue<Byte> lhs, RValue<Byte> rhs);
255 RValue<Byte> operator&(RValue<Byte> lhs, RValue<Byte> rhs);
256 RValue<Byte> operator|(RValue<Byte> lhs, RValue<Byte> rhs);
257 RValue<Byte> operator^(RValue<Byte> lhs, RValue<Byte> rhs);
258 RValue<Byte> operator<<(RValue<Byte> lhs, RValue<Byte> rhs);
259 RValue<Byte> operator>>(RValue<Byte> lhs, RValue<Byte> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500260 RValue<Byte> operator+=(Byte &lhs, RValue<Byte> rhs);
261 RValue<Byte> operator-=(Byte &lhs, RValue<Byte> rhs);
262 RValue<Byte> operator*=(Byte &lhs, RValue<Byte> rhs);
263 RValue<Byte> operator/=(Byte &lhs, RValue<Byte> rhs);
264 RValue<Byte> operator%=(Byte &lhs, RValue<Byte> rhs);
265 RValue<Byte> operator&=(Byte &lhs, RValue<Byte> rhs);
266 RValue<Byte> operator|=(Byte &lhs, RValue<Byte> rhs);
267 RValue<Byte> operator^=(Byte &lhs, RValue<Byte> rhs);
268 RValue<Byte> operator<<=(Byte &lhs, RValue<Byte> rhs);
269 RValue<Byte> operator>>=(Byte &lhs, RValue<Byte> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400270 RValue<Byte> operator+(RValue<Byte> val);
271 RValue<Byte> operator-(RValue<Byte> val);
272 RValue<Byte> operator~(RValue<Byte> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500273 RValue<Byte> operator++(Byte &val, int); // Post-increment
274 const Byte &operator++(Byte &val); // Pre-increment
275 RValue<Byte> operator--(Byte &val, int); // Post-decrement
276 const Byte &operator--(Byte &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400277 RValue<Bool> operator<(RValue<Byte> lhs, RValue<Byte> rhs);
278 RValue<Bool> operator<=(RValue<Byte> lhs, RValue<Byte> rhs);
279 RValue<Bool> operator>(RValue<Byte> lhs, RValue<Byte> rhs);
280 RValue<Bool> operator>=(RValue<Byte> lhs, RValue<Byte> rhs);
281 RValue<Bool> operator!=(RValue<Byte> lhs, RValue<Byte> rhs);
282 RValue<Bool> operator==(RValue<Byte> lhs, RValue<Byte> rhs);
283
Nicolas Capens297d26e2016-11-18 12:52:17 -0500284 class SByte : public LValue<SByte>
Nicolas Capensd022e412016-09-26 13:30:14 -0400285 {
286 public:
287 SByte(Argument<SByte> argument);
288
289 explicit SByte(RValue<Int> cast);
290 explicit SByte(RValue<Short> cast);
291
Nicolas Capensa25311a2017-01-16 17:19:00 -0500292 SByte() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -0400293 SByte(signed char x);
294 SByte(RValue<SByte> rhs);
295 SByte(const SByte &rhs);
296 SByte(const Reference<SByte> &rhs);
297
Nicolas Capens96d4e092016-11-18 14:22:38 -0500298 // RValue<SByte> operator=(signed char rhs); // FIXME: Implement
299 RValue<SByte> operator=(RValue<SByte> rhs);
300 RValue<SByte> operator=(const SByte &rhs);
301 RValue<SByte> operator=(const Reference<SByte> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400302
303 static Type *getType();
304 };
305
306 RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs);
307 RValue<SByte> operator-(RValue<SByte> lhs, RValue<SByte> rhs);
308 RValue<SByte> operator*(RValue<SByte> lhs, RValue<SByte> rhs);
309 RValue<SByte> operator/(RValue<SByte> lhs, RValue<SByte> rhs);
310 RValue<SByte> operator%(RValue<SByte> lhs, RValue<SByte> rhs);
311 RValue<SByte> operator&(RValue<SByte> lhs, RValue<SByte> rhs);
312 RValue<SByte> operator|(RValue<SByte> lhs, RValue<SByte> rhs);
313 RValue<SByte> operator^(RValue<SByte> lhs, RValue<SByte> rhs);
314 RValue<SByte> operator<<(RValue<SByte> lhs, RValue<SByte> rhs);
315 RValue<SByte> operator>>(RValue<SByte> lhs, RValue<SByte> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500316 RValue<SByte> operator+=(SByte &lhs, RValue<SByte> rhs);
317 RValue<SByte> operator-=(SByte &lhs, RValue<SByte> rhs);
318 RValue<SByte> operator*=(SByte &lhs, RValue<SByte> rhs);
319 RValue<SByte> operator/=(SByte &lhs, RValue<SByte> rhs);
320 RValue<SByte> operator%=(SByte &lhs, RValue<SByte> rhs);
321 RValue<SByte> operator&=(SByte &lhs, RValue<SByte> rhs);
322 RValue<SByte> operator|=(SByte &lhs, RValue<SByte> rhs);
323 RValue<SByte> operator^=(SByte &lhs, RValue<SByte> rhs);
324 RValue<SByte> operator<<=(SByte &lhs, RValue<SByte> rhs);
325 RValue<SByte> operator>>=(SByte &lhs, RValue<SByte> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400326 RValue<SByte> operator+(RValue<SByte> val);
327 RValue<SByte> operator-(RValue<SByte> val);
328 RValue<SByte> operator~(RValue<SByte> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500329 RValue<SByte> operator++(SByte &val, int); // Post-increment
330 const SByte &operator++(SByte &val); // Pre-increment
331 RValue<SByte> operator--(SByte &val, int); // Post-decrement
332 const SByte &operator--(SByte &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400333 RValue<Bool> operator<(RValue<SByte> lhs, RValue<SByte> rhs);
334 RValue<Bool> operator<=(RValue<SByte> lhs, RValue<SByte> rhs);
335 RValue<Bool> operator>(RValue<SByte> lhs, RValue<SByte> rhs);
336 RValue<Bool> operator>=(RValue<SByte> lhs, RValue<SByte> rhs);
337 RValue<Bool> operator!=(RValue<SByte> lhs, RValue<SByte> rhs);
338 RValue<Bool> operator==(RValue<SByte> lhs, RValue<SByte> rhs);
339
Nicolas Capens297d26e2016-11-18 12:52:17 -0500340 class Short : public LValue<Short>
Nicolas Capensd022e412016-09-26 13:30:14 -0400341 {
342 public:
343 Short(Argument<Short> argument);
344
345 explicit Short(RValue<Int> cast);
346
Nicolas Capensa25311a2017-01-16 17:19:00 -0500347 Short() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -0400348 Short(short x);
349 Short(RValue<Short> rhs);
350 Short(const Short &rhs);
351 Short(const Reference<Short> &rhs);
352
Nicolas Capens96d4e092016-11-18 14:22:38 -0500353 // RValue<Short> operator=(short rhs); // FIXME: Implement
354 RValue<Short> operator=(RValue<Short> rhs);
355 RValue<Short> operator=(const Short &rhs);
356 RValue<Short> operator=(const Reference<Short> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400357
358 static Type *getType();
359 };
360
361 RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs);
362 RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs);
363 RValue<Short> operator*(RValue<Short> lhs, RValue<Short> rhs);
364 RValue<Short> operator/(RValue<Short> lhs, RValue<Short> rhs);
365 RValue<Short> operator%(RValue<Short> lhs, RValue<Short> rhs);
366 RValue<Short> operator&(RValue<Short> lhs, RValue<Short> rhs);
367 RValue<Short> operator|(RValue<Short> lhs, RValue<Short> rhs);
368 RValue<Short> operator^(RValue<Short> lhs, RValue<Short> rhs);
369 RValue<Short> operator<<(RValue<Short> lhs, RValue<Short> rhs);
370 RValue<Short> operator>>(RValue<Short> lhs, RValue<Short> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500371 RValue<Short> operator+=(Short &lhs, RValue<Short> rhs);
372 RValue<Short> operator-=(Short &lhs, RValue<Short> rhs);
373 RValue<Short> operator*=(Short &lhs, RValue<Short> rhs);
374 RValue<Short> operator/=(Short &lhs, RValue<Short> rhs);
375 RValue<Short> operator%=(Short &lhs, RValue<Short> rhs);
376 RValue<Short> operator&=(Short &lhs, RValue<Short> rhs);
377 RValue<Short> operator|=(Short &lhs, RValue<Short> rhs);
378 RValue<Short> operator^=(Short &lhs, RValue<Short> rhs);
379 RValue<Short> operator<<=(Short &lhs, RValue<Short> rhs);
380 RValue<Short> operator>>=(Short &lhs, RValue<Short> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400381 RValue<Short> operator+(RValue<Short> val);
382 RValue<Short> operator-(RValue<Short> val);
383 RValue<Short> operator~(RValue<Short> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500384 RValue<Short> operator++(Short &val, int); // Post-increment
385 const Short &operator++(Short &val); // Pre-increment
386 RValue<Short> operator--(Short &val, int); // Post-decrement
387 const Short &operator--(Short &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400388 RValue<Bool> operator<(RValue<Short> lhs, RValue<Short> rhs);
389 RValue<Bool> operator<=(RValue<Short> lhs, RValue<Short> rhs);
390 RValue<Bool> operator>(RValue<Short> lhs, RValue<Short> rhs);
391 RValue<Bool> operator>=(RValue<Short> lhs, RValue<Short> rhs);
392 RValue<Bool> operator!=(RValue<Short> lhs, RValue<Short> rhs);
393 RValue<Bool> operator==(RValue<Short> lhs, RValue<Short> rhs);
394
Nicolas Capens297d26e2016-11-18 12:52:17 -0500395 class UShort : public LValue<UShort>
Nicolas Capensd022e412016-09-26 13:30:14 -0400396 {
397 public:
398 UShort(Argument<UShort> argument);
399
400 explicit UShort(RValue<UInt> cast);
401 explicit UShort(RValue<Int> cast);
402
Nicolas Capensa25311a2017-01-16 17:19:00 -0500403 UShort() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -0400404 UShort(unsigned short x);
405 UShort(RValue<UShort> rhs);
406 UShort(const UShort &rhs);
407 UShort(const Reference<UShort> &rhs);
408
Nicolas Capens96d4e092016-11-18 14:22:38 -0500409 // RValue<UShort> operator=(unsigned short rhs); // FIXME: Implement
410 RValue<UShort> operator=(RValue<UShort> rhs);
411 RValue<UShort> operator=(const UShort &rhs);
412 RValue<UShort> operator=(const Reference<UShort> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400413
414 static Type *getType();
415 };
416
417 RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs);
418 RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs);
419 RValue<UShort> operator*(RValue<UShort> lhs, RValue<UShort> rhs);
420 RValue<UShort> operator/(RValue<UShort> lhs, RValue<UShort> rhs);
421 RValue<UShort> operator%(RValue<UShort> lhs, RValue<UShort> rhs);
422 RValue<UShort> operator&(RValue<UShort> lhs, RValue<UShort> rhs);
423 RValue<UShort> operator|(RValue<UShort> lhs, RValue<UShort> rhs);
424 RValue<UShort> operator^(RValue<UShort> lhs, RValue<UShort> rhs);
425 RValue<UShort> operator<<(RValue<UShort> lhs, RValue<UShort> rhs);
426 RValue<UShort> operator>>(RValue<UShort> lhs, RValue<UShort> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500427 RValue<UShort> operator+=(UShort &lhs, RValue<UShort> rhs);
428 RValue<UShort> operator-=(UShort &lhs, RValue<UShort> rhs);
429 RValue<UShort> operator*=(UShort &lhs, RValue<UShort> rhs);
430 RValue<UShort> operator/=(UShort &lhs, RValue<UShort> rhs);
431 RValue<UShort> operator%=(UShort &lhs, RValue<UShort> rhs);
432 RValue<UShort> operator&=(UShort &lhs, RValue<UShort> rhs);
433 RValue<UShort> operator|=(UShort &lhs, RValue<UShort> rhs);
434 RValue<UShort> operator^=(UShort &lhs, RValue<UShort> rhs);
435 RValue<UShort> operator<<=(UShort &lhs, RValue<UShort> rhs);
436 RValue<UShort> operator>>=(UShort &lhs, RValue<UShort> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400437 RValue<UShort> operator+(RValue<UShort> val);
438 RValue<UShort> operator-(RValue<UShort> val);
439 RValue<UShort> operator~(RValue<UShort> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500440 RValue<UShort> operator++(UShort &val, int); // Post-increment
441 const UShort &operator++(UShort &val); // Pre-increment
442 RValue<UShort> operator--(UShort &val, int); // Post-decrement
443 const UShort &operator--(UShort &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400444 RValue<Bool> operator<(RValue<UShort> lhs, RValue<UShort> rhs);
445 RValue<Bool> operator<=(RValue<UShort> lhs, RValue<UShort> rhs);
446 RValue<Bool> operator>(RValue<UShort> lhs, RValue<UShort> rhs);
447 RValue<Bool> operator>=(RValue<UShort> lhs, RValue<UShort> rhs);
448 RValue<Bool> operator!=(RValue<UShort> lhs, RValue<UShort> rhs);
449 RValue<Bool> operator==(RValue<UShort> lhs, RValue<UShort> rhs);
450
Nicolas Capens297d26e2016-11-18 12:52:17 -0500451 class Byte4 : public LValue<Byte4>
Nicolas Capensd022e412016-09-26 13:30:14 -0400452 {
453 public:
Nicolas Capens16b5f152016-10-13 13:39:01 -0400454 explicit Byte4(RValue<Byte8> cast);
455
Nicolas Capensa25311a2017-01-16 17:19:00 -0500456 Byte4() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -0400457 // Byte4(int x, int y, int z, int w);
458 // Byte4(RValue<Byte4> rhs);
459 // Byte4(const Byte4 &rhs);
Nicolas Capens16b5f152016-10-13 13:39:01 -0400460 Byte4(const Reference<Byte4> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400461
Nicolas Capens96d4e092016-11-18 14:22:38 -0500462 // RValue<Byte4> operator=(RValue<Byte4> rhs);
463 // RValue<Byte4> operator=(const Byte4 &rhs);
464 // RValue<Byte4> operator=(const Reference<Byte4> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400465
466 static Type *getType();
467 };
468
469// RValue<Byte4> operator+(RValue<Byte4> lhs, RValue<Byte4> rhs);
470// RValue<Byte4> operator-(RValue<Byte4> lhs, RValue<Byte4> rhs);
471// RValue<Byte4> operator*(RValue<Byte4> lhs, RValue<Byte4> rhs);
472// RValue<Byte4> operator/(RValue<Byte4> lhs, RValue<Byte4> rhs);
473// RValue<Byte4> operator%(RValue<Byte4> lhs, RValue<Byte4> rhs);
474// RValue<Byte4> operator&(RValue<Byte4> lhs, RValue<Byte4> rhs);
475// RValue<Byte4> operator|(RValue<Byte4> lhs, RValue<Byte4> rhs);
476// RValue<Byte4> operator^(RValue<Byte4> lhs, RValue<Byte4> rhs);
477// RValue<Byte4> operator<<(RValue<Byte4> lhs, RValue<Byte4> rhs);
478// RValue<Byte4> operator>>(RValue<Byte4> lhs, RValue<Byte4> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500479// RValue<Byte4> operator+=(Byte4 &lhs, RValue<Byte4> rhs);
480// RValue<Byte4> operator-=(Byte4 &lhs, RValue<Byte4> rhs);
481// RValue<Byte4> operator*=(Byte4 &lhs, RValue<Byte4> rhs);
482// RValue<Byte4> operator/=(Byte4 &lhs, RValue<Byte4> rhs);
483// RValue<Byte4> operator%=(Byte4 &lhs, RValue<Byte4> rhs);
484// RValue<Byte4> operator&=(Byte4 &lhs, RValue<Byte4> rhs);
485// RValue<Byte4> operator|=(Byte4 &lhs, RValue<Byte4> rhs);
486// RValue<Byte4> operator^=(Byte4 &lhs, RValue<Byte4> rhs);
487// RValue<Byte4> operator<<=(Byte4 &lhs, RValue<Byte4> rhs);
488// RValue<Byte4> operator>>=(Byte4 &lhs, RValue<Byte4> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400489// RValue<Byte4> operator+(RValue<Byte4> val);
490// RValue<Byte4> operator-(RValue<Byte4> val);
491// RValue<Byte4> operator~(RValue<Byte4> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500492// RValue<Byte4> operator++(Byte4 &val, int); // Post-increment
493// const Byte4 &operator++(Byte4 &val); // Pre-increment
494// RValue<Byte4> operator--(Byte4 &val, int); // Post-decrement
495// const Byte4 &operator--(Byte4 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400496
Nicolas Capens297d26e2016-11-18 12:52:17 -0500497 class SByte4 : public LValue<SByte4>
Nicolas Capensd022e412016-09-26 13:30:14 -0400498 {
499 public:
Nicolas Capensa25311a2017-01-16 17:19:00 -0500500 SByte4() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -0400501 // SByte4(int x, int y, int z, int w);
502 // SByte4(RValue<SByte4> rhs);
503 // SByte4(const SByte4 &rhs);
504 // SByte4(const Reference<SByte4> &rhs);
505
Nicolas Capens96d4e092016-11-18 14:22:38 -0500506 // RValue<SByte4> operator=(RValue<SByte4> rhs);
507 // RValue<SByte4> operator=(const SByte4 &rhs);
508 // RValue<SByte4> operator=(const Reference<SByte4> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400509
510 static Type *getType();
511 };
512
513// RValue<SByte4> operator+(RValue<SByte4> lhs, RValue<SByte4> rhs);
514// RValue<SByte4> operator-(RValue<SByte4> lhs, RValue<SByte4> rhs);
515// RValue<SByte4> operator*(RValue<SByte4> lhs, RValue<SByte4> rhs);
516// RValue<SByte4> operator/(RValue<SByte4> lhs, RValue<SByte4> rhs);
517// RValue<SByte4> operator%(RValue<SByte4> lhs, RValue<SByte4> rhs);
518// RValue<SByte4> operator&(RValue<SByte4> lhs, RValue<SByte4> rhs);
519// RValue<SByte4> operator|(RValue<SByte4> lhs, RValue<SByte4> rhs);
520// RValue<SByte4> operator^(RValue<SByte4> lhs, RValue<SByte4> rhs);
521// RValue<SByte4> operator<<(RValue<SByte4> lhs, RValue<SByte4> rhs);
522// RValue<SByte4> operator>>(RValue<SByte4> lhs, RValue<SByte4> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500523// RValue<SByte4> operator+=(SByte4 &lhs, RValue<SByte4> rhs);
524// RValue<SByte4> operator-=(SByte4 &lhs, RValue<SByte4> rhs);
525// RValue<SByte4> operator*=(SByte4 &lhs, RValue<SByte4> rhs);
526// RValue<SByte4> operator/=(SByte4 &lhs, RValue<SByte4> rhs);
527// RValue<SByte4> operator%=(SByte4 &lhs, RValue<SByte4> rhs);
528// RValue<SByte4> operator&=(SByte4 &lhs, RValue<SByte4> rhs);
529// RValue<SByte4> operator|=(SByte4 &lhs, RValue<SByte4> rhs);
530// RValue<SByte4> operator^=(SByte4 &lhs, RValue<SByte4> rhs);
531// RValue<SByte4> operator<<=(SByte4 &lhs, RValue<SByte4> rhs);
532// RValue<SByte4> operator>>=(SByte4 &lhs, RValue<SByte4> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400533// RValue<SByte4> operator+(RValue<SByte4> val);
534// RValue<SByte4> operator-(RValue<SByte4> val);
535// RValue<SByte4> operator~(RValue<SByte4> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500536// RValue<SByte4> operator++(SByte4 &val, int); // Post-increment
537// const SByte4 &operator++(SByte4 &val); // Pre-increment
538// RValue<SByte4> operator--(SByte4 &val, int); // Post-decrement
539// const SByte4 &operator--(SByte4 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400540
Nicolas Capens297d26e2016-11-18 12:52:17 -0500541 class Byte8 : public LValue<Byte8>
Nicolas Capensd022e412016-09-26 13:30:14 -0400542 {
543 public:
Nicolas Capensa25311a2017-01-16 17:19:00 -0500544 Byte8() = default;
Nicolas Capens3bbc5e12016-09-27 10:49:52 -0400545 Byte8(uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, uint8_t x6, uint8_t x7);
Nicolas Capensd022e412016-09-26 13:30:14 -0400546 Byte8(RValue<Byte8> rhs);
547 Byte8(const Byte8 &rhs);
548 Byte8(const Reference<Byte8> &rhs);
549
Nicolas Capens96d4e092016-11-18 14:22:38 -0500550 RValue<Byte8> operator=(RValue<Byte8> rhs);
551 RValue<Byte8> operator=(const Byte8 &rhs);
552 RValue<Byte8> operator=(const Reference<Byte8> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400553
554 static Type *getType();
555 };
556
557 RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs);
558 RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs);
559// RValue<Byte8> operator*(RValue<Byte8> lhs, RValue<Byte8> rhs);
560// RValue<Byte8> operator/(RValue<Byte8> lhs, RValue<Byte8> rhs);
561// RValue<Byte8> operator%(RValue<Byte8> lhs, RValue<Byte8> rhs);
562 RValue<Byte8> operator&(RValue<Byte8> lhs, RValue<Byte8> rhs);
563 RValue<Byte8> operator|(RValue<Byte8> lhs, RValue<Byte8> rhs);
564 RValue<Byte8> operator^(RValue<Byte8> lhs, RValue<Byte8> rhs);
565// RValue<Byte8> operator<<(RValue<Byte8> lhs, RValue<Byte8> rhs);
566// RValue<Byte8> operator>>(RValue<Byte8> lhs, RValue<Byte8> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500567 RValue<Byte8> operator+=(Byte8 &lhs, RValue<Byte8> rhs);
568 RValue<Byte8> operator-=(Byte8 &lhs, RValue<Byte8> rhs);
569// RValue<Byte8> operator*=(Byte8 &lhs, RValue<Byte8> rhs);
570// RValue<Byte8> operator/=(Byte8 &lhs, RValue<Byte8> rhs);
571// RValue<Byte8> operator%=(Byte8 &lhs, RValue<Byte8> rhs);
572 RValue<Byte8> operator&=(Byte8 &lhs, RValue<Byte8> rhs);
573 RValue<Byte8> operator|=(Byte8 &lhs, RValue<Byte8> rhs);
574 RValue<Byte8> operator^=(Byte8 &lhs, RValue<Byte8> rhs);
575// RValue<Byte8> operator<<=(Byte8 &lhs, RValue<Byte8> rhs);
576// RValue<Byte8> operator>>=(Byte8 &lhs, RValue<Byte8> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400577// RValue<Byte8> operator+(RValue<Byte8> val);
578// RValue<Byte8> operator-(RValue<Byte8> val);
579 RValue<Byte8> operator~(RValue<Byte8> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500580// RValue<Byte8> operator++(Byte8 &val, int); // Post-increment
581// const Byte8 &operator++(Byte8 &val); // Pre-increment
582// RValue<Byte8> operator--(Byte8 &val, int); // Post-decrement
583// const Byte8 &operator--(Byte8 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400584
585 RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y);
586 RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y);
587 RValue<Short4> Unpack(RValue<Byte4> x);
Nicolas Capens411273e2017-01-26 15:13:36 -0800588 RValue<Short4> Unpack(RValue<Byte4> x, RValue<Byte4> y);
Nicolas Capensd022e412016-09-26 13:30:14 -0400589 RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y);
590 RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y);
591 RValue<Int> SignMask(RValue<Byte8> x);
592// RValue<Byte8> CmpGT(RValue<Byte8> x, RValue<Byte8> y);
593 RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y);
594
Nicolas Capens297d26e2016-11-18 12:52:17 -0500595 class SByte8 : public LValue<SByte8>
Nicolas Capensd022e412016-09-26 13:30:14 -0400596 {
597 public:
Nicolas Capensa25311a2017-01-16 17:19:00 -0500598 SByte8() = default;
Nicolas Capens3bbc5e12016-09-27 10:49:52 -0400599 SByte8(uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, uint8_t x6, uint8_t x7);
Nicolas Capensd022e412016-09-26 13:30:14 -0400600 SByte8(RValue<SByte8> rhs);
601 SByte8(const SByte8 &rhs);
602 SByte8(const Reference<SByte8> &rhs);
603
Nicolas Capens96d4e092016-11-18 14:22:38 -0500604 RValue<SByte8> operator=(RValue<SByte8> rhs);
605 RValue<SByte8> operator=(const SByte8 &rhs);
606 RValue<SByte8> operator=(const Reference<SByte8> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400607
608 static Type *getType();
609 };
610
611 RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs);
612 RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs);
613// RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs);
614// RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs);
615// RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs);
616 RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs);
617 RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs);
618 RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs);
619// RValue<SByte8> operator<<(RValue<SByte8> lhs, RValue<SByte8> rhs);
620// RValue<SByte8> operator>>(RValue<SByte8> lhs, RValue<SByte8> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500621 RValue<SByte8> operator+=(SByte8 &lhs, RValue<SByte8> rhs);
622 RValue<SByte8> operator-=(SByte8 &lhs, RValue<SByte8> rhs);
623// RValue<SByte8> operator*=(SByte8 &lhs, RValue<SByte8> rhs);
624// RValue<SByte8> operator/=(SByte8 &lhs, RValue<SByte8> rhs);
625// RValue<SByte8> operator%=(SByte8 &lhs, RValue<SByte8> rhs);
626 RValue<SByte8> operator&=(SByte8 &lhs, RValue<SByte8> rhs);
627 RValue<SByte8> operator|=(SByte8 &lhs, RValue<SByte8> rhs);
628 RValue<SByte8> operator^=(SByte8 &lhs, RValue<SByte8> rhs);
629// RValue<SByte8> operator<<=(SByte8 &lhs, RValue<SByte8> rhs);
630// RValue<SByte8> operator>>=(SByte8 &lhs, RValue<SByte8> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400631// RValue<SByte8> operator+(RValue<SByte8> val);
632// RValue<SByte8> operator-(RValue<SByte8> val);
633 RValue<SByte8> operator~(RValue<SByte8> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500634// RValue<SByte8> operator++(SByte8 &val, int); // Post-increment
635// const SByte8 &operator++(SByte8 &val); // Pre-increment
636// RValue<SByte8> operator--(SByte8 &val, int); // Post-decrement
637// const SByte8 &operator--(SByte8 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400638
639 RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y);
640 RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y);
641 RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y);
642 RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y);
643 RValue<Int> SignMask(RValue<SByte8> x);
644 RValue<Byte8> CmpGT(RValue<SByte8> x, RValue<SByte8> y);
645 RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y);
646
Nicolas Capens297d26e2016-11-18 12:52:17 -0500647 class Byte16 : public LValue<Byte16>
Nicolas Capensd022e412016-09-26 13:30:14 -0400648 {
649 public:
Nicolas Capensa25311a2017-01-16 17:19:00 -0500650 Byte16() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -0400651 // Byte16(int x, int y, int z, int w);
652 Byte16(RValue<Byte16> rhs);
653 Byte16(const Byte16 &rhs);
654 Byte16(const Reference<Byte16> &rhs);
655
Nicolas Capens96d4e092016-11-18 14:22:38 -0500656 RValue<Byte16> operator=(RValue<Byte16> rhs);
657 RValue<Byte16> operator=(const Byte16 &rhs);
658 RValue<Byte16> operator=(const Reference<Byte16> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400659
660 static Type *getType();
661 };
662
663// RValue<Byte16> operator+(RValue<Byte16> lhs, RValue<Byte16> rhs);
664// RValue<Byte16> operator-(RValue<Byte16> lhs, RValue<Byte16> rhs);
665// RValue<Byte16> operator*(RValue<Byte16> lhs, RValue<Byte16> rhs);
666// RValue<Byte16> operator/(RValue<Byte16> lhs, RValue<Byte16> rhs);
667// RValue<Byte16> operator%(RValue<Byte16> lhs, RValue<Byte16> rhs);
668// RValue<Byte16> operator&(RValue<Byte16> lhs, RValue<Byte16> rhs);
669// RValue<Byte16> operator|(RValue<Byte16> lhs, RValue<Byte16> rhs);
670// RValue<Byte16> operator^(RValue<Byte16> lhs, RValue<Byte16> rhs);
671// RValue<Byte16> operator<<(RValue<Byte16> lhs, RValue<Byte16> rhs);
672// RValue<Byte16> operator>>(RValue<Byte16> lhs, RValue<Byte16> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500673// RValue<Byte16> operator+=(Byte16 &lhs, RValue<Byte16> rhs);
674// RValue<Byte16> operator-=(Byte16 &lhs, RValue<Byte16> rhs);
675// RValue<Byte16> operator*=(Byte16 &lhs, RValue<Byte16> rhs);
676// RValue<Byte16> operator/=(Byte16 &lhs, RValue<Byte16> rhs);
677// RValue<Byte16> operator%=(Byte16 &lhs, RValue<Byte16> rhs);
678// RValue<Byte16> operator&=(Byte16 &lhs, RValue<Byte16> rhs);
679// RValue<Byte16> operator|=(Byte16 &lhs, RValue<Byte16> rhs);
680// RValue<Byte16> operator^=(Byte16 &lhs, RValue<Byte16> rhs);
681// RValue<Byte16> operator<<=(Byte16 &lhs, RValue<Byte16> rhs);
682// RValue<Byte16> operator>>=(Byte16 &lhs, RValue<Byte16> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400683// RValue<Byte16> operator+(RValue<Byte16> val);
684// RValue<Byte16> operator-(RValue<Byte16> val);
685// RValue<Byte16> operator~(RValue<Byte16> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500686// RValue<Byte16> operator++(Byte16 &val, int); // Post-increment
687// const Byte16 &operator++(Byte16 &val); // Pre-increment
688// RValue<Byte16> operator--(Byte16 &val, int); // Post-decrement
689// const Byte16 &operator--(Byte16 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400690
Nicolas Capens297d26e2016-11-18 12:52:17 -0500691 class SByte16 : public LValue<SByte16>
Nicolas Capensd022e412016-09-26 13:30:14 -0400692 {
693 public:
Nicolas Capensa25311a2017-01-16 17:19:00 -0500694 SByte16() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -0400695 // SByte16(int x, int y, int z, int w);
696 // SByte16(RValue<SByte16> rhs);
697 // SByte16(const SByte16 &rhs);
698 // SByte16(const Reference<SByte16> &rhs);
699
Nicolas Capens96d4e092016-11-18 14:22:38 -0500700 // RValue<SByte16> operator=(RValue<SByte16> rhs);
701 // RValue<SByte16> operator=(const SByte16 &rhs);
702 // RValue<SByte16> operator=(const Reference<SByte16> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400703
704 static Type *getType();
705 };
706
707// RValue<SByte16> operator+(RValue<SByte16> lhs, RValue<SByte16> rhs);
708// RValue<SByte16> operator-(RValue<SByte16> lhs, RValue<SByte16> rhs);
709// RValue<SByte16> operator*(RValue<SByte16> lhs, RValue<SByte16> rhs);
710// RValue<SByte16> operator/(RValue<SByte16> lhs, RValue<SByte16> rhs);
711// RValue<SByte16> operator%(RValue<SByte16> lhs, RValue<SByte16> rhs);
712// RValue<SByte16> operator&(RValue<SByte16> lhs, RValue<SByte16> rhs);
713// RValue<SByte16> operator|(RValue<SByte16> lhs, RValue<SByte16> rhs);
714// RValue<SByte16> operator^(RValue<SByte16> lhs, RValue<SByte16> rhs);
715// RValue<SByte16> operator<<(RValue<SByte16> lhs, RValue<SByte16> rhs);
716// RValue<SByte16> operator>>(RValue<SByte16> lhs, RValue<SByte16> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500717// RValue<SByte16> operator+=(SByte16 &lhs, RValue<SByte16> rhs);
718// RValue<SByte16> operator-=(SByte16 &lhs, RValue<SByte16> rhs);
719// RValue<SByte16> operator*=(SByte16 &lhs, RValue<SByte16> rhs);
720// RValue<SByte16> operator/=(SByte16 &lhs, RValue<SByte16> rhs);
721// RValue<SByte16> operator%=(SByte16 &lhs, RValue<SByte16> rhs);
722// RValue<SByte16> operator&=(SByte16 &lhs, RValue<SByte16> rhs);
723// RValue<SByte16> operator|=(SByte16 &lhs, RValue<SByte16> rhs);
724// RValue<SByte16> operator^=(SByte16 &lhs, RValue<SByte16> rhs);
725// RValue<SByte16> operator<<=(SByte16 &lhs, RValue<SByte16> rhs);
726// RValue<SByte16> operator>>=(SByte16 &lhs, RValue<SByte16> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400727// RValue<SByte16> operator+(RValue<SByte16> val);
728// RValue<SByte16> operator-(RValue<SByte16> val);
729// RValue<SByte16> operator~(RValue<SByte16> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500730// RValue<SByte16> operator++(SByte16 &val, int); // Post-increment
731// const SByte16 &operator++(SByte16 &val); // Pre-increment
732// RValue<SByte16> operator--(SByte16 &val, int); // Post-decrement
733// const SByte16 &operator--(SByte16 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400734
Nicolas Capens297d26e2016-11-18 12:52:17 -0500735 class Short2 : public LValue<Short2>
Nicolas Capens16b5f152016-10-13 13:39:01 -0400736 {
737 public:
738 explicit Short2(RValue<Short4> cast);
739
740 static Type *getType();
741 };
742
Nicolas Capens297d26e2016-11-18 12:52:17 -0500743 class UShort2 : public LValue<UShort2>
Nicolas Capens16b5f152016-10-13 13:39:01 -0400744 {
745 public:
746 explicit UShort2(RValue<UShort4> cast);
747
748 static Type *getType();
749 };
750
Nicolas Capens297d26e2016-11-18 12:52:17 -0500751 class Short4 : public LValue<Short4>
Nicolas Capensd022e412016-09-26 13:30:14 -0400752 {
753 public:
754 explicit Short4(RValue<Int> cast);
755 explicit Short4(RValue<Int4> cast);
756 // explicit Short4(RValue<Float> cast);
757 explicit Short4(RValue<Float4> cast);
758
Nicolas Capensa25311a2017-01-16 17:19:00 -0500759 Short4() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -0400760 Short4(short xyzw);
761 Short4(short x, short y, short z, short w);
762 Short4(RValue<Short4> rhs);
763 Short4(const Short4 &rhs);
764 Short4(const Reference<Short4> &rhs);
765 Short4(RValue<UShort4> rhs);
766 Short4(const UShort4 &rhs);
767 Short4(const Reference<UShort4> &rhs);
768
Nicolas Capens96d4e092016-11-18 14:22:38 -0500769 RValue<Short4> operator=(RValue<Short4> rhs);
770 RValue<Short4> operator=(const Short4 &rhs);
771 RValue<Short4> operator=(const Reference<Short4> &rhs);
772 RValue<Short4> operator=(RValue<UShort4> rhs);
773 RValue<Short4> operator=(const UShort4 &rhs);
774 RValue<Short4> operator=(const Reference<UShort4> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400775
776 static Type *getType();
777 };
778
779 RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs);
780 RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs);
781 RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs);
782// RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs);
783// RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs);
784 RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs);
785 RValue<Short4> operator|(RValue<Short4> lhs, RValue<Short4> rhs);
786 RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs);
787 RValue<Short4> operator<<(RValue<Short4> lhs, unsigned char rhs);
788 RValue<Short4> operator>>(RValue<Short4> lhs, unsigned char rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500789 RValue<Short4> operator+=(Short4 &lhs, RValue<Short4> rhs);
790 RValue<Short4> operator-=(Short4 &lhs, RValue<Short4> rhs);
791 RValue<Short4> operator*=(Short4 &lhs, RValue<Short4> rhs);
792// RValue<Short4> operator/=(Short4 &lhs, RValue<Short4> rhs);
793// RValue<Short4> operator%=(Short4 &lhs, RValue<Short4> rhs);
794 RValue<Short4> operator&=(Short4 &lhs, RValue<Short4> rhs);
795 RValue<Short4> operator|=(Short4 &lhs, RValue<Short4> rhs);
796 RValue<Short4> operator^=(Short4 &lhs, RValue<Short4> rhs);
797 RValue<Short4> operator<<=(Short4 &lhs, unsigned char rhs);
798 RValue<Short4> operator>>=(Short4 &lhs, unsigned char rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400799// RValue<Short4> operator+(RValue<Short4> val);
800 RValue<Short4> operator-(RValue<Short4> val);
801 RValue<Short4> operator~(RValue<Short4> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500802// RValue<Short4> operator++(Short4 &val, int); // Post-increment
803// const Short4 &operator++(Short4 &val); // Pre-increment
804// RValue<Short4> operator--(Short4 &val, int); // Post-decrement
805// const Short4 &operator--(Short4 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400806// RValue<Bool> operator<(RValue<Short4> lhs, RValue<Short4> rhs);
807// RValue<Bool> operator<=(RValue<Short4> lhs, RValue<Short4> rhs);
808// RValue<Bool> operator>(RValue<Short4> lhs, RValue<Short4> rhs);
809// RValue<Bool> operator>=(RValue<Short4> lhs, RValue<Short4> rhs);
810// RValue<Bool> operator!=(RValue<Short4> lhs, RValue<Short4> rhs);
811// RValue<Bool> operator==(RValue<Short4> lhs, RValue<Short4> rhs);
812
813 RValue<Short4> RoundShort4(RValue<Float4> cast);
814 RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y);
815 RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y);
816 RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y);
817 RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y);
818 RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y);
819 RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y);
Nicolas Capens33438a62017-09-27 11:47:35 -0400820 RValue<SByte8> PackSigned(RValue<Short4> x, RValue<Short4> y);
821 RValue<Byte8> PackUnsigned(RValue<Short4> x, RValue<Short4> y);
Nicolas Capensd022e412016-09-26 13:30:14 -0400822 RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y);
823 RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y);
824 RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select);
825 RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i);
826 RValue<Short> Extract(RValue<Short4> val, int i);
827 RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y);
828 RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y);
829
Nicolas Capens297d26e2016-11-18 12:52:17 -0500830 class UShort4 : public LValue<UShort4>
Nicolas Capensd022e412016-09-26 13:30:14 -0400831 {
832 public:
833 explicit UShort4(RValue<Int4> cast);
834 explicit UShort4(RValue<Float4> cast, bool saturate = false);
835
Nicolas Capensa25311a2017-01-16 17:19:00 -0500836 UShort4() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -0400837 UShort4(unsigned short xyzw);
838 UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w);
839 UShort4(RValue<UShort4> rhs);
840 UShort4(const UShort4 &rhs);
841 UShort4(const Reference<UShort4> &rhs);
842 UShort4(RValue<Short4> rhs);
843 UShort4(const Short4 &rhs);
844 UShort4(const Reference<Short4> &rhs);
845
Nicolas Capens96d4e092016-11-18 14:22:38 -0500846 RValue<UShort4> operator=(RValue<UShort4> rhs);
847 RValue<UShort4> operator=(const UShort4 &rhs);
848 RValue<UShort4> operator=(const Reference<UShort4> &rhs);
849 RValue<UShort4> operator=(RValue<Short4> rhs);
850 RValue<UShort4> operator=(const Short4 &rhs);
851 RValue<UShort4> operator=(const Reference<Short4> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400852
853 static Type *getType();
854 };
855
856 RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs);
857 RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs);
858 RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs);
859// RValue<UShort4> operator/(RValue<UShort4> lhs, RValue<UShort4> rhs);
860// RValue<UShort4> operator%(RValue<UShort4> lhs, RValue<UShort4> rhs);
Nicolas Capens16b5f152016-10-13 13:39:01 -0400861 RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs);
862 RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs);
863 RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400864 RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs);
865 RValue<UShort4> operator>>(RValue<UShort4> lhs, unsigned char rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500866// RValue<UShort4> operator+=(UShort4 &lhs, RValue<UShort4> rhs);
867// RValue<UShort4> operator-=(UShort4 &lhs, RValue<UShort4> rhs);
868// RValue<UShort4> operator*=(UShort4 &lhs, RValue<UShort4> rhs);
869// RValue<UShort4> operator/=(UShort4 &lhs, RValue<UShort4> rhs);
870// RValue<UShort4> operator%=(UShort4 &lhs, RValue<UShort4> rhs);
871// RValue<UShort4> operator&=(UShort4 &lhs, RValue<UShort4> rhs);
872// RValue<UShort4> operator|=(UShort4 &lhs, RValue<UShort4> rhs);
873// RValue<UShort4> operator^=(UShort4 &lhs, RValue<UShort4> rhs);
874 RValue<UShort4> operator<<=(UShort4 &lhs, unsigned char rhs);
875 RValue<UShort4> operator>>=(UShort4 &lhs, unsigned char rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400876// RValue<UShort4> operator+(RValue<UShort4> val);
877// RValue<UShort4> operator-(RValue<UShort4> val);
878 RValue<UShort4> operator~(RValue<UShort4> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500879// RValue<UShort4> operator++(UShort4 &val, int); // Post-increment
880// const UShort4 &operator++(UShort4 &val); // Pre-increment
881// RValue<UShort4> operator--(UShort4 &val, int); // Post-decrement
882// const UShort4 &operator--(UShort4 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400883
884 RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y);
885 RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y);
886 RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y);
887 RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y);
888 RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y);
889 RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y);
Nicolas Capensd022e412016-09-26 13:30:14 -0400890
Nicolas Capens297d26e2016-11-18 12:52:17 -0500891 class Short8 : public LValue<Short8>
Nicolas Capensd022e412016-09-26 13:30:14 -0400892 {
893 public:
Nicolas Capensa25311a2017-01-16 17:19:00 -0500894 Short8() = default;
Nicolas Capens3e7062b2017-01-17 14:01:33 -0500895 Short8(short c);
Nicolas Capensd022e412016-09-26 13:30:14 -0400896 Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7);
897 Short8(RValue<Short8> rhs);
898 // Short8(const Short8 &rhs);
899 Short8(const Reference<Short8> &rhs);
900 Short8(RValue<Short4> lo, RValue<Short4> hi);
901
Nicolas Capens96d4e092016-11-18 14:22:38 -0500902 // RValue<Short8> operator=(RValue<Short8> rhs);
903 // RValue<Short8> operator=(const Short8 &rhs);
904 // RValue<Short8> operator=(const Reference<Short8> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400905
906 static Type *getType();
907 };
908
909 RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs);
910// RValue<Short8> operator-(RValue<Short8> lhs, RValue<Short8> rhs);
911// RValue<Short8> operator*(RValue<Short8> lhs, RValue<Short8> rhs);
912// RValue<Short8> operator/(RValue<Short8> lhs, RValue<Short8> rhs);
913// RValue<Short8> operator%(RValue<Short8> lhs, RValue<Short8> rhs);
914 RValue<Short8> operator&(RValue<Short8> lhs, RValue<Short8> rhs);
915// RValue<Short8> operator|(RValue<Short8> lhs, RValue<Short8> rhs);
916// RValue<Short8> operator^(RValue<Short8> lhs, RValue<Short8> rhs);
917 RValue<Short8> operator<<(RValue<Short8> lhs, unsigned char rhs);
918 RValue<Short8> operator>>(RValue<Short8> lhs, unsigned char rhs);
919// RValue<Short8> operator<<(RValue<Short8> lhs, RValue<Short8> rhs);
920// RValue<Short8> operator>>(RValue<Short8> lhs, RValue<Short8> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500921// RValue<Short8> operator+=(Short8 &lhs, RValue<Short8> rhs);
922// RValue<Short8> operator-=(Short8 &lhs, RValue<Short8> rhs);
923// RValue<Short8> operator*=(Short8 &lhs, RValue<Short8> rhs);
924// RValue<Short8> operator/=(Short8 &lhs, RValue<Short8> rhs);
925// RValue<Short8> operator%=(Short8 &lhs, RValue<Short8> rhs);
926// RValue<Short8> operator&=(Short8 &lhs, RValue<Short8> rhs);
927// RValue<Short8> operator|=(Short8 &lhs, RValue<Short8> rhs);
928// RValue<Short8> operator^=(Short8 &lhs, RValue<Short8> rhs);
929// RValue<Short8> operator<<=(Short8 &lhs, RValue<Short8> rhs);
930// RValue<Short8> operator>>=(Short8 &lhs, RValue<Short8> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400931// RValue<Short8> operator+(RValue<Short8> val);
932// RValue<Short8> operator-(RValue<Short8> val);
933// RValue<Short8> operator~(RValue<Short8> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500934// RValue<Short8> operator++(Short8 &val, int); // Post-increment
935// const Short8 &operator++(Short8 &val); // Pre-increment
936// RValue<Short8> operator--(Short8 &val, int); // Post-decrement
937// const Short8 &operator--(Short8 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400938// RValue<Bool> operator<(RValue<Short8> lhs, RValue<Short8> rhs);
939// RValue<Bool> operator<=(RValue<Short8> lhs, RValue<Short8> rhs);
940// RValue<Bool> operator>(RValue<Short8> lhs, RValue<Short8> rhs);
941// RValue<Bool> operator>=(RValue<Short8> lhs, RValue<Short8> rhs);
942// RValue<Bool> operator!=(RValue<Short8> lhs, RValue<Short8> rhs);
943// RValue<Bool> operator==(RValue<Short8> lhs, RValue<Short8> rhs);
944
945 RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y);
946 RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y);
947 RValue<Int4> Abs(RValue<Int4> x);
948
Nicolas Capens297d26e2016-11-18 12:52:17 -0500949 class UShort8 : public LValue<UShort8>
Nicolas Capensd022e412016-09-26 13:30:14 -0400950 {
951 public:
Nicolas Capensa25311a2017-01-16 17:19:00 -0500952 UShort8() = default;
Nicolas Capens3e7062b2017-01-17 14:01:33 -0500953 UShort8(unsigned short c);
Nicolas Capensd022e412016-09-26 13:30:14 -0400954 UShort8(unsigned short c0, unsigned short c1, unsigned short c2, unsigned short c3, unsigned short c4, unsigned short c5, unsigned short c6, unsigned short c7);
955 UShort8(RValue<UShort8> rhs);
956 // UShort8(const UShort8 &rhs);
957 UShort8(const Reference<UShort8> &rhs);
958 UShort8(RValue<UShort4> lo, RValue<UShort4> hi);
959
Nicolas Capens96d4e092016-11-18 14:22:38 -0500960 RValue<UShort8> operator=(RValue<UShort8> rhs);
961 RValue<UShort8> operator=(const UShort8 &rhs);
962 RValue<UShort8> operator=(const Reference<UShort8> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400963
964 static Type *getType();
965 };
966
967 RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs);
968// RValue<UShort8> operator-(RValue<UShort8> lhs, RValue<UShort8> rhs);
969 RValue<UShort8> operator*(RValue<UShort8> lhs, RValue<UShort8> rhs);
970// RValue<UShort8> operator/(RValue<UShort8> lhs, RValue<UShort8> rhs);
971// RValue<UShort8> operator%(RValue<UShort8> lhs, RValue<UShort8> rhs);
972 RValue<UShort8> operator&(RValue<UShort8> lhs, RValue<UShort8> rhs);
973// RValue<UShort8> operator|(RValue<UShort8> lhs, RValue<UShort8> rhs);
974// RValue<UShort8> operator^(RValue<UShort8> lhs, RValue<UShort8> rhs);
975 RValue<UShort8> operator<<(RValue<UShort8> lhs, unsigned char rhs);
976 RValue<UShort8> operator>>(RValue<UShort8> lhs, unsigned char rhs);
977// RValue<UShort8> operator<<(RValue<UShort8> lhs, RValue<UShort8> rhs);
978// RValue<UShort8> operator>>(RValue<UShort8> lhs, RValue<UShort8> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500979 RValue<UShort8> operator+=(UShort8 &lhs, RValue<UShort8> rhs);
980// RValue<UShort8> operator-=(UShort8 &lhs, RValue<UShort8> rhs);
981// RValue<UShort8> operator*=(UShort8 &lhs, RValue<UShort8> rhs);
982// RValue<UShort8> operator/=(UShort8 &lhs, RValue<UShort8> rhs);
983// RValue<UShort8> operator%=(UShort8 &lhs, RValue<UShort8> rhs);
984// RValue<UShort8> operator&=(UShort8 &lhs, RValue<UShort8> rhs);
985// RValue<UShort8> operator|=(UShort8 &lhs, RValue<UShort8> rhs);
986// RValue<UShort8> operator^=(UShort8 &lhs, RValue<UShort8> rhs);
987// RValue<UShort8> operator<<=(UShort8 &lhs, RValue<UShort8> rhs);
988// RValue<UShort8> operator>>=(UShort8 &lhs, RValue<UShort8> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400989// RValue<UShort8> operator+(RValue<UShort8> val);
990// RValue<UShort8> operator-(RValue<UShort8> val);
991 RValue<UShort8> operator~(RValue<UShort8> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500992// RValue<UShort8> operator++(UShort8 &val, int); // Post-increment
993// const UShort8 &operator++(UShort8 &val); // Pre-increment
994// RValue<UShort8> operator--(UShort8 &val, int); // Post-decrement
995// const UShort8 &operator--(UShort8 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400996// RValue<Bool> operator<(RValue<UShort8> lhs, RValue<UShort8> rhs);
997// RValue<Bool> operator<=(RValue<UShort8> lhs, RValue<UShort8> rhs);
998// RValue<Bool> operator>(RValue<UShort8> lhs, RValue<UShort8> rhs);
999// RValue<Bool> operator>=(RValue<UShort8> lhs, RValue<UShort8> rhs);
1000// RValue<Bool> operator!=(RValue<UShort8> lhs, RValue<UShort8> rhs);
1001// RValue<Bool> operator==(RValue<UShort8> lhs, RValue<UShort8> rhs);
1002
1003 RValue<UShort8> Swizzle(RValue<UShort8> x, char select0, char select1, char select2, char select3, char select4, char select5, char select6, char select7);
1004 RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y);
1005
Nicolas Capens297d26e2016-11-18 12:52:17 -05001006 class Int : public LValue<Int>
Nicolas Capensd022e412016-09-26 13:30:14 -04001007 {
1008 public:
1009 Int(Argument<Int> argument);
1010
1011 explicit Int(RValue<Byte> cast);
1012 explicit Int(RValue<SByte> cast);
1013 explicit Int(RValue<Short> cast);
1014 explicit Int(RValue<UShort> cast);
1015 explicit Int(RValue<Int2> cast);
1016 explicit Int(RValue<Long> cast);
1017 explicit Int(RValue<Float> cast);
1018
Nicolas Capensa25311a2017-01-16 17:19:00 -05001019 Int() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -04001020 Int(int x);
1021 Int(RValue<Int> rhs);
1022 Int(RValue<UInt> rhs);
1023 Int(const Int &rhs);
1024 Int(const UInt &rhs);
1025 Int(const Reference<Int> &rhs);
1026 Int(const Reference<UInt> &rhs);
1027
Nicolas Capens96d4e092016-11-18 14:22:38 -05001028 RValue<Int> operator=(int rhs);
1029 RValue<Int> operator=(RValue<Int> rhs);
1030 RValue<Int> operator=(RValue<UInt> rhs);
1031 RValue<Int> operator=(const Int &rhs);
1032 RValue<Int> operator=(const UInt &rhs);
1033 RValue<Int> operator=(const Reference<Int> &rhs);
1034 RValue<Int> operator=(const Reference<UInt> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001035
1036 static Type *getType();
1037 };
1038
1039 RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs);
1040 RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs);
1041 RValue<Int> operator*(RValue<Int> lhs, RValue<Int> rhs);
1042 RValue<Int> operator/(RValue<Int> lhs, RValue<Int> rhs);
1043 RValue<Int> operator%(RValue<Int> lhs, RValue<Int> rhs);
1044 RValue<Int> operator&(RValue<Int> lhs, RValue<Int> rhs);
1045 RValue<Int> operator|(RValue<Int> lhs, RValue<Int> rhs);
1046 RValue<Int> operator^(RValue<Int> lhs, RValue<Int> rhs);
1047 RValue<Int> operator<<(RValue<Int> lhs, RValue<Int> rhs);
1048 RValue<Int> operator>>(RValue<Int> lhs, RValue<Int> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001049 RValue<Int> operator+=(Int &lhs, RValue<Int> rhs);
1050 RValue<Int> operator-=(Int &lhs, RValue<Int> rhs);
1051 RValue<Int> operator*=(Int &lhs, RValue<Int> rhs);
1052 RValue<Int> operator/=(Int &lhs, RValue<Int> rhs);
1053 RValue<Int> operator%=(Int &lhs, RValue<Int> rhs);
1054 RValue<Int> operator&=(Int &lhs, RValue<Int> rhs);
1055 RValue<Int> operator|=(Int &lhs, RValue<Int> rhs);
1056 RValue<Int> operator^=(Int &lhs, RValue<Int> rhs);
1057 RValue<Int> operator<<=(Int &lhs, RValue<Int> rhs);
1058 RValue<Int> operator>>=(Int &lhs, RValue<Int> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001059 RValue<Int> operator+(RValue<Int> val);
1060 RValue<Int> operator-(RValue<Int> val);
1061 RValue<Int> operator~(RValue<Int> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001062 RValue<Int> operator++(Int &val, int); // Post-increment
1063 const Int &operator++(Int &val); // Pre-increment
1064 RValue<Int> operator--(Int &val, int); // Post-decrement
1065 const Int &operator--(Int &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -04001066 RValue<Bool> operator<(RValue<Int> lhs, RValue<Int> rhs);
1067 RValue<Bool> operator<=(RValue<Int> lhs, RValue<Int> rhs);
1068 RValue<Bool> operator>(RValue<Int> lhs, RValue<Int> rhs);
1069 RValue<Bool> operator>=(RValue<Int> lhs, RValue<Int> rhs);
1070 RValue<Bool> operator!=(RValue<Int> lhs, RValue<Int> rhs);
1071 RValue<Bool> operator==(RValue<Int> lhs, RValue<Int> rhs);
1072
1073 RValue<Int> Max(RValue<Int> x, RValue<Int> y);
1074 RValue<Int> Min(RValue<Int> x, RValue<Int> y);
1075 RValue<Int> Clamp(RValue<Int> x, RValue<Int> min, RValue<Int> max);
1076 RValue<Int> RoundInt(RValue<Float> cast);
1077
Nicolas Capens297d26e2016-11-18 12:52:17 -05001078 class Long : public LValue<Long>
Nicolas Capensd022e412016-09-26 13:30:14 -04001079 {
1080 public:
1081 // Long(Argument<Long> argument);
1082
1083 // explicit Long(RValue<Short> cast);
1084 // explicit Long(RValue<UShort> cast);
1085 explicit Long(RValue<Int> cast);
1086 explicit Long(RValue<UInt> cast);
1087 // explicit Long(RValue<Float> cast);
1088
Nicolas Capensa25311a2017-01-16 17:19:00 -05001089 Long() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -04001090 // Long(qword x);
1091 Long(RValue<Long> rhs);
1092 // Long(RValue<ULong> rhs);
1093 // Long(const Long &rhs);
1094 // Long(const Reference<Long> &rhs);
1095 // Long(const ULong &rhs);
1096 // Long(const Reference<ULong> &rhs);
1097
Nicolas Capens96d4e092016-11-18 14:22:38 -05001098 RValue<Long> operator=(int64_t rhs);
1099 RValue<Long> operator=(RValue<Long> rhs);
1100 // RValue<Long> operator=(RValue<ULong> rhs);
1101 RValue<Long> operator=(const Long &rhs);
1102 RValue<Long> operator=(const Reference<Long> &rhs);
1103 // RValue<Long> operator=(const ULong &rhs);
1104 // RValue<Long> operator=(const Reference<ULong> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001105
1106 static Type *getType();
1107 };
1108
1109 RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs);
1110 RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs);
Chris Forbesaa8f6992019-03-01 14:18:30 -08001111 RValue<Long> operator*(RValue<Long> lhs, RValue<Long> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001112// RValue<Long> operator/(RValue<Long> lhs, RValue<Long> rhs);
1113// RValue<Long> operator%(RValue<Long> lhs, RValue<Long> rhs);
1114// RValue<Long> operator&(RValue<Long> lhs, RValue<Long> rhs);
1115// RValue<Long> operator|(RValue<Long> lhs, RValue<Long> rhs);
1116// RValue<Long> operator^(RValue<Long> lhs, RValue<Long> rhs);
1117// RValue<Long> operator<<(RValue<Long> lhs, RValue<Long> rhs);
Chris Forbesaa8f6992019-03-01 14:18:30 -08001118 RValue<Long> operator>>(RValue<Long> lhs, RValue<Long> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001119 RValue<Long> operator+=(Long &lhs, RValue<Long> rhs);
1120 RValue<Long> operator-=(Long &lhs, RValue<Long> rhs);
1121// RValue<Long> operator*=(Long &lhs, RValue<Long> rhs);
1122// RValue<Long> operator/=(Long &lhs, RValue<Long> rhs);
1123// RValue<Long> operator%=(Long &lhs, RValue<Long> rhs);
1124// RValue<Long> operator&=(Long &lhs, RValue<Long> rhs);
1125// RValue<Long> operator|=(Long &lhs, RValue<Long> rhs);
1126// RValue<Long> operator^=(Long &lhs, RValue<Long> rhs);
1127// RValue<Long> operator<<=(Long &lhs, RValue<Long> rhs);
1128// RValue<Long> operator>>=(Long &lhs, RValue<Long> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001129// RValue<Long> operator+(RValue<Long> val);
1130// RValue<Long> operator-(RValue<Long> val);
1131// RValue<Long> operator~(RValue<Long> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001132// RValue<Long> operator++(Long &val, int); // Post-increment
1133// const Long &operator++(Long &val); // Pre-increment
1134// RValue<Long> operator--(Long &val, int); // Post-decrement
1135// const Long &operator--(Long &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -04001136// RValue<Bool> operator<(RValue<Long> lhs, RValue<Long> rhs);
1137// RValue<Bool> operator<=(RValue<Long> lhs, RValue<Long> rhs);
1138// RValue<Bool> operator>(RValue<Long> lhs, RValue<Long> rhs);
1139// RValue<Bool> operator>=(RValue<Long> lhs, RValue<Long> rhs);
1140// RValue<Bool> operator!=(RValue<Long> lhs, RValue<Long> rhs);
1141// RValue<Bool> operator==(RValue<Long> lhs, RValue<Long> rhs);
1142
1143// RValue<Long> RoundLong(RValue<Float> cast);
1144 RValue<Long> AddAtomic( RValue<Pointer<Long>> x, RValue<Long> y);
1145
Nicolas Capens297d26e2016-11-18 12:52:17 -05001146 class UInt : public LValue<UInt>
Nicolas Capensd022e412016-09-26 13:30:14 -04001147 {
1148 public:
1149 UInt(Argument<UInt> argument);
1150
1151 explicit UInt(RValue<UShort> cast);
1152 explicit UInt(RValue<Long> cast);
1153 explicit UInt(RValue<Float> cast);
1154
Nicolas Capensa25311a2017-01-16 17:19:00 -05001155 UInt() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -04001156 UInt(int x);
1157 UInt(unsigned int x);
1158 UInt(RValue<UInt> rhs);
1159 UInt(RValue<Int> rhs);
1160 UInt(const UInt &rhs);
1161 UInt(const Int &rhs);
1162 UInt(const Reference<UInt> &rhs);
1163 UInt(const Reference<Int> &rhs);
1164
Nicolas Capens96d4e092016-11-18 14:22:38 -05001165 RValue<UInt> operator=(unsigned int rhs);
1166 RValue<UInt> operator=(RValue<UInt> rhs);
1167 RValue<UInt> operator=(RValue<Int> rhs);
1168 RValue<UInt> operator=(const UInt &rhs);
1169 RValue<UInt> operator=(const Int &rhs);
1170 RValue<UInt> operator=(const Reference<UInt> &rhs);
1171 RValue<UInt> operator=(const Reference<Int> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001172
1173 static Type *getType();
1174 };
1175
1176 RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs);
1177 RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs);
1178 RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs);
1179 RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs);
1180 RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs);
1181 RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs);
1182 RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs);
1183 RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs);
1184 RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs);
1185 RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001186 RValue<UInt> operator+=(UInt &lhs, RValue<UInt> rhs);
1187 RValue<UInt> operator-=(UInt &lhs, RValue<UInt> rhs);
1188 RValue<UInt> operator*=(UInt &lhs, RValue<UInt> rhs);
1189 RValue<UInt> operator/=(UInt &lhs, RValue<UInt> rhs);
1190 RValue<UInt> operator%=(UInt &lhs, RValue<UInt> rhs);
1191 RValue<UInt> operator&=(UInt &lhs, RValue<UInt> rhs);
1192 RValue<UInt> operator|=(UInt &lhs, RValue<UInt> rhs);
1193 RValue<UInt> operator^=(UInt &lhs, RValue<UInt> rhs);
1194 RValue<UInt> operator<<=(UInt &lhs, RValue<UInt> rhs);
1195 RValue<UInt> operator>>=(UInt &lhs, RValue<UInt> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001196 RValue<UInt> operator+(RValue<UInt> val);
1197 RValue<UInt> operator-(RValue<UInt> val);
1198 RValue<UInt> operator~(RValue<UInt> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001199 RValue<UInt> operator++(UInt &val, int); // Post-increment
1200 const UInt &operator++(UInt &val); // Pre-increment
1201 RValue<UInt> operator--(UInt &val, int); // Post-decrement
1202 const UInt &operator--(UInt &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -04001203 RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs);
1204 RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs);
1205 RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs);
1206 RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs);
1207 RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs);
1208 RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs);
1209
1210 RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y);
1211 RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y);
1212 RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max);
1213// RValue<UInt> RoundUInt(RValue<Float> cast);
1214
Nicolas Capens297d26e2016-11-18 12:52:17 -05001215 class Int2 : public LValue<Int2>
Nicolas Capensd022e412016-09-26 13:30:14 -04001216 {
1217 public:
1218 // explicit Int2(RValue<Int> cast);
1219 explicit Int2(RValue<Int4> cast);
1220
Nicolas Capensa25311a2017-01-16 17:19:00 -05001221 Int2() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -04001222 Int2(int x, int y);
1223 Int2(RValue<Int2> rhs);
1224 Int2(const Int2 &rhs);
1225 Int2(const Reference<Int2> &rhs);
1226 Int2(RValue<Int> lo, RValue<Int> hi);
1227
Nicolas Capens96d4e092016-11-18 14:22:38 -05001228 RValue<Int2> operator=(RValue<Int2> rhs);
1229 RValue<Int2> operator=(const Int2 &rhs);
1230 RValue<Int2> operator=(const Reference<Int2> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001231
1232 static Type *getType();
1233 };
1234
1235 RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs);
1236 RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs);
1237// RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs);
1238// RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs);
1239// RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs);
1240 RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs);
1241 RValue<Int2> operator|(RValue<Int2> lhs, RValue<Int2> rhs);
1242 RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs);
1243 RValue<Int2> operator<<(RValue<Int2> lhs, unsigned char rhs);
1244 RValue<Int2> operator>>(RValue<Int2> lhs, unsigned char rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001245 RValue<Int2> operator+=(Int2 &lhs, RValue<Int2> rhs);
1246 RValue<Int2> operator-=(Int2 &lhs, RValue<Int2> rhs);
1247// RValue<Int2> operator*=(Int2 &lhs, RValue<Int2> rhs);
1248// RValue<Int2> operator/=(Int2 &lhs, RValue<Int2> rhs);
1249// RValue<Int2> operator%=(Int2 &lhs, RValue<Int2> rhs);
1250 RValue<Int2> operator&=(Int2 &lhs, RValue<Int2> rhs);
1251 RValue<Int2> operator|=(Int2 &lhs, RValue<Int2> rhs);
1252 RValue<Int2> operator^=(Int2 &lhs, RValue<Int2> rhs);
1253 RValue<Int2> operator<<=(Int2 &lhs, unsigned char rhs);
1254 RValue<Int2> operator>>=(Int2 &lhs, unsigned char rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001255// RValue<Int2> operator+(RValue<Int2> val);
1256// RValue<Int2> operator-(RValue<Int2> val);
1257 RValue<Int2> operator~(RValue<Int2> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001258// RValue<Int2> operator++(Int2 &val, int); // Post-increment
1259// const Int2 &operator++(Int2 &val); // Pre-increment
1260// RValue<Int2> operator--(Int2 &val, int); // Post-decrement
1261// const Int2 &operator--(Int2 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -04001262// RValue<Bool> operator<(RValue<Int2> lhs, RValue<Int2> rhs);
1263// RValue<Bool> operator<=(RValue<Int2> lhs, RValue<Int2> rhs);
1264// RValue<Bool> operator>(RValue<Int2> lhs, RValue<Int2> rhs);
1265// RValue<Bool> operator>=(RValue<Int2> lhs, RValue<Int2> rhs);
1266// RValue<Bool> operator!=(RValue<Int2> lhs, RValue<Int2> rhs);
1267// RValue<Bool> operator==(RValue<Int2> lhs, RValue<Int2> rhs);
1268
1269// RValue<Int2> RoundInt(RValue<Float4> cast);
Nicolas Capens45f187a2016-12-02 15:30:56 -05001270 RValue<Short4> UnpackLow(RValue<Int2> x, RValue<Int2> y);
1271 RValue<Short4> UnpackHigh(RValue<Int2> x, RValue<Int2> y);
Nicolas Capensd022e412016-09-26 13:30:14 -04001272 RValue<Int> Extract(RValue<Int2> val, int i);
1273 RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i);
1274
Nicolas Capens297d26e2016-11-18 12:52:17 -05001275 class UInt2 : public LValue<UInt2>
Nicolas Capensd022e412016-09-26 13:30:14 -04001276 {
1277 public:
Nicolas Capensa25311a2017-01-16 17:19:00 -05001278 UInt2() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -04001279 UInt2(unsigned int x, unsigned int y);
1280 UInt2(RValue<UInt2> rhs);
1281 UInt2(const UInt2 &rhs);
1282 UInt2(const Reference<UInt2> &rhs);
1283
Nicolas Capens96d4e092016-11-18 14:22:38 -05001284 RValue<UInt2> operator=(RValue<UInt2> rhs);
1285 RValue<UInt2> operator=(const UInt2 &rhs);
1286 RValue<UInt2> operator=(const Reference<UInt2> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001287
1288 static Type *getType();
1289 };
1290
1291 RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs);
1292 RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs);
1293// RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs);
1294// RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs);
1295// RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs);
1296 RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs);
1297 RValue<UInt2> operator|(RValue<UInt2> lhs, RValue<UInt2> rhs);
1298 RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs);
1299 RValue<UInt2> operator<<(RValue<UInt2> lhs, unsigned char rhs);
1300 RValue<UInt2> operator>>(RValue<UInt2> lhs, unsigned char rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001301 RValue<UInt2> operator+=(UInt2 &lhs, RValue<UInt2> rhs);
1302 RValue<UInt2> operator-=(UInt2 &lhs, RValue<UInt2> rhs);
1303// RValue<UInt2> operator*=(UInt2 &lhs, RValue<UInt2> rhs);
1304// RValue<UInt2> operator/=(UInt2 &lhs, RValue<UInt2> rhs);
1305// RValue<UInt2> operator%=(UInt2 &lhs, RValue<UInt2> rhs);
1306 RValue<UInt2> operator&=(UInt2 &lhs, RValue<UInt2> rhs);
1307 RValue<UInt2> operator|=(UInt2 &lhs, RValue<UInt2> rhs);
1308 RValue<UInt2> operator^=(UInt2 &lhs, RValue<UInt2> rhs);
1309 RValue<UInt2> operator<<=(UInt2 &lhs, unsigned char rhs);
1310 RValue<UInt2> operator>>=(UInt2 &lhs, unsigned char rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001311// RValue<UInt2> operator+(RValue<UInt2> val);
1312// RValue<UInt2> operator-(RValue<UInt2> val);
1313 RValue<UInt2> operator~(RValue<UInt2> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001314// RValue<UInt2> operator++(UInt2 &val, int); // Post-increment
1315// const UInt2 &operator++(UInt2 &val); // Pre-increment
1316// RValue<UInt2> operator--(UInt2 &val, int); // Post-decrement
1317// const UInt2 &operator--(UInt2 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -04001318// RValue<Bool> operator<(RValue<UInt2> lhs, RValue<UInt2> rhs);
1319// RValue<Bool> operator<=(RValue<UInt2> lhs, RValue<UInt2> rhs);
1320// RValue<Bool> operator>(RValue<UInt2> lhs, RValue<UInt2> rhs);
1321// RValue<Bool> operator>=(RValue<UInt2> lhs, RValue<UInt2> rhs);
1322// RValue<Bool> operator!=(RValue<UInt2> lhs, RValue<UInt2> rhs);
1323// RValue<Bool> operator==(RValue<UInt2> lhs, RValue<UInt2> rhs);
1324
1325// RValue<UInt2> RoundInt(RValue<Float4> cast);
1326
Nicolas Capenscb986762017-01-20 11:34:37 -05001327 template<class T>
1328 struct Scalar;
1329
1330 template<class Vector4>
1331 struct XYZW;
1332
1333 template<class Vector4, int T>
1334 class Swizzle2
1335 {
1336 friend Vector4;
1337
1338 public:
1339 operator RValue<Vector4>() const;
1340
1341 private:
1342 Vector4 *parent;
1343 };
1344
1345 template<class Vector4, int T>
1346 class Swizzle4
1347 {
1348 public:
1349 operator RValue<Vector4>() const;
1350
1351 private:
1352 Vector4 *parent;
1353 };
1354
1355 template<class Vector4, int T>
1356 class SwizzleMask4
1357 {
1358 friend XYZW<Vector4>;
1359
1360 public:
1361 operator RValue<Vector4>() const;
1362
1363 RValue<Vector4> operator=(RValue<Vector4> rhs);
1364 RValue<Vector4> operator=(RValue<typename Scalar<Vector4>::Type> rhs);
1365
1366 private:
1367 Vector4 *parent;
1368 };
1369
1370 template<>
1371 struct Scalar<Float4>
1372 {
1373 using Type = Float;
1374 };
1375
1376 template<>
1377 struct Scalar<Int4>
1378 {
1379 using Type = Int;
1380 };
1381
1382 template<>
1383 struct Scalar<UInt4>
1384 {
1385 using Type = UInt;
1386 };
1387
1388 template<class Vector4, int T>
1389 class SwizzleMask1
1390 {
1391 public:
1392 operator RValue<typename Scalar<Vector4>::Type>() const;
1393 operator RValue<Vector4>() const;
1394
1395 RValue<Vector4> operator=(float x);
1396 RValue<Vector4> operator=(RValue<Vector4> rhs);
1397 RValue<Vector4> operator=(RValue<typename Scalar<Vector4>::Type> rhs);
1398
1399 private:
1400 Float4 *parent;
1401 };
1402
1403 template<class Vector4, int T>
1404 class SwizzleMask2
1405 {
1406 friend class Float4;
1407
1408 public:
1409 operator RValue<Vector4>() const;
1410
1411 RValue<Vector4> operator=(RValue<Vector4> rhs);
1412
1413 private:
1414 Float4 *parent;
1415 };
1416
1417 template<class Vector4>
1418 struct XYZW
1419 {
1420 friend Vector4;
1421
1422 private:
1423 XYZW(Vector4 *parent)
1424 {
1425 xyzw.parent = parent;
1426 }
1427
1428 public:
1429 union
1430 {
1431 SwizzleMask1<Vector4, 0x00> x;
1432 SwizzleMask1<Vector4, 0x55> y;
1433 SwizzleMask1<Vector4, 0xAA> z;
1434 SwizzleMask1<Vector4, 0xFF> w;
1435 Swizzle2<Vector4, 0x00> xx;
1436 Swizzle2<Vector4, 0x01> yx;
1437 Swizzle2<Vector4, 0x02> zx;
1438 Swizzle2<Vector4, 0x03> wx;
1439 SwizzleMask2<Vector4, 0x54> xy;
1440 Swizzle2<Vector4, 0x55> yy;
1441 Swizzle2<Vector4, 0x56> zy;
1442 Swizzle2<Vector4, 0x57> wy;
1443 SwizzleMask2<Vector4, 0xA8> xz;
1444 SwizzleMask2<Vector4, 0xA9> yz;
1445 Swizzle2<Vector4, 0xAA> zz;
1446 Swizzle2<Vector4, 0xAB> wz;
1447 SwizzleMask2<Vector4, 0xFC> xw;
1448 SwizzleMask2<Vector4, 0xFD> yw;
1449 SwizzleMask2<Vector4, 0xFE> zw;
1450 Swizzle2<Vector4, 0xFF> ww;
1451 Swizzle4<Vector4, 0x00> xxx;
1452 Swizzle4<Vector4, 0x01> yxx;
1453 Swizzle4<Vector4, 0x02> zxx;
1454 Swizzle4<Vector4, 0x03> wxx;
1455 Swizzle4<Vector4, 0x04> xyx;
1456 Swizzle4<Vector4, 0x05> yyx;
1457 Swizzle4<Vector4, 0x06> zyx;
1458 Swizzle4<Vector4, 0x07> wyx;
1459 Swizzle4<Vector4, 0x08> xzx;
1460 Swizzle4<Vector4, 0x09> yzx;
1461 Swizzle4<Vector4, 0x0A> zzx;
1462 Swizzle4<Vector4, 0x0B> wzx;
1463 Swizzle4<Vector4, 0x0C> xwx;
1464 Swizzle4<Vector4, 0x0D> ywx;
1465 Swizzle4<Vector4, 0x0E> zwx;
1466 Swizzle4<Vector4, 0x0F> wwx;
1467 Swizzle4<Vector4, 0x50> xxy;
1468 Swizzle4<Vector4, 0x51> yxy;
1469 Swizzle4<Vector4, 0x52> zxy;
1470 Swizzle4<Vector4, 0x53> wxy;
1471 Swizzle4<Vector4, 0x54> xyy;
1472 Swizzle4<Vector4, 0x55> yyy;
1473 Swizzle4<Vector4, 0x56> zyy;
1474 Swizzle4<Vector4, 0x57> wyy;
1475 Swizzle4<Vector4, 0x58> xzy;
1476 Swizzle4<Vector4, 0x59> yzy;
1477 Swizzle4<Vector4, 0x5A> zzy;
1478 Swizzle4<Vector4, 0x5B> wzy;
1479 Swizzle4<Vector4, 0x5C> xwy;
1480 Swizzle4<Vector4, 0x5D> ywy;
1481 Swizzle4<Vector4, 0x5E> zwy;
1482 Swizzle4<Vector4, 0x5F> wwy;
1483 Swizzle4<Vector4, 0xA0> xxz;
1484 Swizzle4<Vector4, 0xA1> yxz;
1485 Swizzle4<Vector4, 0xA2> zxz;
1486 Swizzle4<Vector4, 0xA3> wxz;
1487 SwizzleMask4<Vector4, 0xA4> xyz;
1488 Swizzle4<Vector4, 0xA5> yyz;
1489 Swizzle4<Vector4, 0xA6> zyz;
1490 Swizzle4<Vector4, 0xA7> wyz;
1491 Swizzle4<Vector4, 0xA8> xzz;
1492 Swizzle4<Vector4, 0xA9> yzz;
1493 Swizzle4<Vector4, 0xAA> zzz;
1494 Swizzle4<Vector4, 0xAB> wzz;
1495 Swizzle4<Vector4, 0xAC> xwz;
1496 Swizzle4<Vector4, 0xAD> ywz;
1497 Swizzle4<Vector4, 0xAE> zwz;
1498 Swizzle4<Vector4, 0xAF> wwz;
1499 Swizzle4<Vector4, 0xF0> xxw;
1500 Swizzle4<Vector4, 0xF1> yxw;
1501 Swizzle4<Vector4, 0xF2> zxw;
1502 Swizzle4<Vector4, 0xF3> wxw;
1503 SwizzleMask4<Vector4, 0xF4> xyw;
1504 Swizzle4<Vector4, 0xF5> yyw;
1505 Swizzle4<Vector4, 0xF6> zyw;
1506 Swizzle4<Vector4, 0xF7> wyw;
1507 SwizzleMask4<Vector4, 0xF8> xzw;
1508 SwizzleMask4<Vector4, 0xF9> yzw;
1509 Swizzle4<Vector4, 0xFA> zzw;
1510 Swizzle4<Vector4, 0xFB> wzw;
1511 Swizzle4<Vector4, 0xFC> xww;
1512 Swizzle4<Vector4, 0xFD> yww;
1513 Swizzle4<Vector4, 0xFE> zww;
1514 Swizzle4<Vector4, 0xFF> www;
1515 Swizzle4<Vector4, 0x00> xxxx;
1516 Swizzle4<Vector4, 0x01> yxxx;
1517 Swizzle4<Vector4, 0x02> zxxx;
1518 Swizzle4<Vector4, 0x03> wxxx;
1519 Swizzle4<Vector4, 0x04> xyxx;
1520 Swizzle4<Vector4, 0x05> yyxx;
1521 Swizzle4<Vector4, 0x06> zyxx;
1522 Swizzle4<Vector4, 0x07> wyxx;
1523 Swizzle4<Vector4, 0x08> xzxx;
1524 Swizzle4<Vector4, 0x09> yzxx;
1525 Swizzle4<Vector4, 0x0A> zzxx;
1526 Swizzle4<Vector4, 0x0B> wzxx;
1527 Swizzle4<Vector4, 0x0C> xwxx;
1528 Swizzle4<Vector4, 0x0D> ywxx;
1529 Swizzle4<Vector4, 0x0E> zwxx;
1530 Swizzle4<Vector4, 0x0F> wwxx;
1531 Swizzle4<Vector4, 0x10> xxyx;
1532 Swizzle4<Vector4, 0x11> yxyx;
1533 Swizzle4<Vector4, 0x12> zxyx;
1534 Swizzle4<Vector4, 0x13> wxyx;
1535 Swizzle4<Vector4, 0x14> xyyx;
1536 Swizzle4<Vector4, 0x15> yyyx;
1537 Swizzle4<Vector4, 0x16> zyyx;
1538 Swizzle4<Vector4, 0x17> wyyx;
1539 Swizzle4<Vector4, 0x18> xzyx;
1540 Swizzle4<Vector4, 0x19> yzyx;
1541 Swizzle4<Vector4, 0x1A> zzyx;
1542 Swizzle4<Vector4, 0x1B> wzyx;
1543 Swizzle4<Vector4, 0x1C> xwyx;
1544 Swizzle4<Vector4, 0x1D> ywyx;
1545 Swizzle4<Vector4, 0x1E> zwyx;
1546 Swizzle4<Vector4, 0x1F> wwyx;
1547 Swizzle4<Vector4, 0x20> xxzx;
1548 Swizzle4<Vector4, 0x21> yxzx;
1549 Swizzle4<Vector4, 0x22> zxzx;
1550 Swizzle4<Vector4, 0x23> wxzx;
1551 Swizzle4<Vector4, 0x24> xyzx;
1552 Swizzle4<Vector4, 0x25> yyzx;
1553 Swizzle4<Vector4, 0x26> zyzx;
1554 Swizzle4<Vector4, 0x27> wyzx;
1555 Swizzle4<Vector4, 0x28> xzzx;
1556 Swizzle4<Vector4, 0x29> yzzx;
1557 Swizzle4<Vector4, 0x2A> zzzx;
1558 Swizzle4<Vector4, 0x2B> wzzx;
1559 Swizzle4<Vector4, 0x2C> xwzx;
1560 Swizzle4<Vector4, 0x2D> ywzx;
1561 Swizzle4<Vector4, 0x2E> zwzx;
1562 Swizzle4<Vector4, 0x2F> wwzx;
1563 Swizzle4<Vector4, 0x30> xxwx;
1564 Swizzle4<Vector4, 0x31> yxwx;
1565 Swizzle4<Vector4, 0x32> zxwx;
1566 Swizzle4<Vector4, 0x33> wxwx;
1567 Swizzle4<Vector4, 0x34> xywx;
1568 Swizzle4<Vector4, 0x35> yywx;
1569 Swizzle4<Vector4, 0x36> zywx;
1570 Swizzle4<Vector4, 0x37> wywx;
1571 Swizzle4<Vector4, 0x38> xzwx;
1572 Swizzle4<Vector4, 0x39> yzwx;
1573 Swizzle4<Vector4, 0x3A> zzwx;
1574 Swizzle4<Vector4, 0x3B> wzwx;
1575 Swizzle4<Vector4, 0x3C> xwwx;
1576 Swizzle4<Vector4, 0x3D> ywwx;
1577 Swizzle4<Vector4, 0x3E> zwwx;
1578 Swizzle4<Vector4, 0x3F> wwwx;
1579 Swizzle4<Vector4, 0x40> xxxy;
1580 Swizzle4<Vector4, 0x41> yxxy;
1581 Swizzle4<Vector4, 0x42> zxxy;
1582 Swizzle4<Vector4, 0x43> wxxy;
1583 Swizzle4<Vector4, 0x44> xyxy;
1584 Swizzle4<Vector4, 0x45> yyxy;
1585 Swizzle4<Vector4, 0x46> zyxy;
1586 Swizzle4<Vector4, 0x47> wyxy;
1587 Swizzle4<Vector4, 0x48> xzxy;
1588 Swizzle4<Vector4, 0x49> yzxy;
1589 Swizzle4<Vector4, 0x4A> zzxy;
1590 Swizzle4<Vector4, 0x4B> wzxy;
1591 Swizzle4<Vector4, 0x4C> xwxy;
1592 Swizzle4<Vector4, 0x4D> ywxy;
1593 Swizzle4<Vector4, 0x4E> zwxy;
1594 Swizzle4<Vector4, 0x4F> wwxy;
1595 Swizzle4<Vector4, 0x50> xxyy;
1596 Swizzle4<Vector4, 0x51> yxyy;
1597 Swizzle4<Vector4, 0x52> zxyy;
1598 Swizzle4<Vector4, 0x53> wxyy;
1599 Swizzle4<Vector4, 0x54> xyyy;
1600 Swizzle4<Vector4, 0x55> yyyy;
1601 Swizzle4<Vector4, 0x56> zyyy;
1602 Swizzle4<Vector4, 0x57> wyyy;
1603 Swizzle4<Vector4, 0x58> xzyy;
1604 Swizzle4<Vector4, 0x59> yzyy;
1605 Swizzle4<Vector4, 0x5A> zzyy;
1606 Swizzle4<Vector4, 0x5B> wzyy;
1607 Swizzle4<Vector4, 0x5C> xwyy;
1608 Swizzle4<Vector4, 0x5D> ywyy;
1609 Swizzle4<Vector4, 0x5E> zwyy;
1610 Swizzle4<Vector4, 0x5F> wwyy;
1611 Swizzle4<Vector4, 0x60> xxzy;
1612 Swizzle4<Vector4, 0x61> yxzy;
1613 Swizzle4<Vector4, 0x62> zxzy;
1614 Swizzle4<Vector4, 0x63> wxzy;
1615 Swizzle4<Vector4, 0x64> xyzy;
1616 Swizzle4<Vector4, 0x65> yyzy;
1617 Swizzle4<Vector4, 0x66> zyzy;
1618 Swizzle4<Vector4, 0x67> wyzy;
1619 Swizzle4<Vector4, 0x68> xzzy;
1620 Swizzle4<Vector4, 0x69> yzzy;
1621 Swizzle4<Vector4, 0x6A> zzzy;
1622 Swizzle4<Vector4, 0x6B> wzzy;
1623 Swizzle4<Vector4, 0x6C> xwzy;
1624 Swizzle4<Vector4, 0x6D> ywzy;
1625 Swizzle4<Vector4, 0x6E> zwzy;
1626 Swizzle4<Vector4, 0x6F> wwzy;
1627 Swizzle4<Vector4, 0x70> xxwy;
1628 Swizzle4<Vector4, 0x71> yxwy;
1629 Swizzle4<Vector4, 0x72> zxwy;
1630 Swizzle4<Vector4, 0x73> wxwy;
1631 Swizzle4<Vector4, 0x74> xywy;
1632 Swizzle4<Vector4, 0x75> yywy;
1633 Swizzle4<Vector4, 0x76> zywy;
1634 Swizzle4<Vector4, 0x77> wywy;
1635 Swizzle4<Vector4, 0x78> xzwy;
1636 Swizzle4<Vector4, 0x79> yzwy;
1637 Swizzle4<Vector4, 0x7A> zzwy;
1638 Swizzle4<Vector4, 0x7B> wzwy;
1639 Swizzle4<Vector4, 0x7C> xwwy;
1640 Swizzle4<Vector4, 0x7D> ywwy;
1641 Swizzle4<Vector4, 0x7E> zwwy;
1642 Swizzle4<Vector4, 0x7F> wwwy;
1643 Swizzle4<Vector4, 0x80> xxxz;
1644 Swizzle4<Vector4, 0x81> yxxz;
1645 Swizzle4<Vector4, 0x82> zxxz;
1646 Swizzle4<Vector4, 0x83> wxxz;
1647 Swizzle4<Vector4, 0x84> xyxz;
1648 Swizzle4<Vector4, 0x85> yyxz;
1649 Swizzle4<Vector4, 0x86> zyxz;
1650 Swizzle4<Vector4, 0x87> wyxz;
1651 Swizzle4<Vector4, 0x88> xzxz;
1652 Swizzle4<Vector4, 0x89> yzxz;
1653 Swizzle4<Vector4, 0x8A> zzxz;
1654 Swizzle4<Vector4, 0x8B> wzxz;
1655 Swizzle4<Vector4, 0x8C> xwxz;
1656 Swizzle4<Vector4, 0x8D> ywxz;
1657 Swizzle4<Vector4, 0x8E> zwxz;
1658 Swizzle4<Vector4, 0x8F> wwxz;
1659 Swizzle4<Vector4, 0x90> xxyz;
1660 Swizzle4<Vector4, 0x91> yxyz;
1661 Swizzle4<Vector4, 0x92> zxyz;
1662 Swizzle4<Vector4, 0x93> wxyz;
1663 Swizzle4<Vector4, 0x94> xyyz;
1664 Swizzle4<Vector4, 0x95> yyyz;
1665 Swizzle4<Vector4, 0x96> zyyz;
1666 Swizzle4<Vector4, 0x97> wyyz;
1667 Swizzle4<Vector4, 0x98> xzyz;
1668 Swizzle4<Vector4, 0x99> yzyz;
1669 Swizzle4<Vector4, 0x9A> zzyz;
1670 Swizzle4<Vector4, 0x9B> wzyz;
1671 Swizzle4<Vector4, 0x9C> xwyz;
1672 Swizzle4<Vector4, 0x9D> ywyz;
1673 Swizzle4<Vector4, 0x9E> zwyz;
1674 Swizzle4<Vector4, 0x9F> wwyz;
1675 Swizzle4<Vector4, 0xA0> xxzz;
1676 Swizzle4<Vector4, 0xA1> yxzz;
1677 Swizzle4<Vector4, 0xA2> zxzz;
1678 Swizzle4<Vector4, 0xA3> wxzz;
1679 Swizzle4<Vector4, 0xA4> xyzz;
1680 Swizzle4<Vector4, 0xA5> yyzz;
1681 Swizzle4<Vector4, 0xA6> zyzz;
1682 Swizzle4<Vector4, 0xA7> wyzz;
1683 Swizzle4<Vector4, 0xA8> xzzz;
1684 Swizzle4<Vector4, 0xA9> yzzz;
1685 Swizzle4<Vector4, 0xAA> zzzz;
1686 Swizzle4<Vector4, 0xAB> wzzz;
1687 Swizzle4<Vector4, 0xAC> xwzz;
1688 Swizzle4<Vector4, 0xAD> ywzz;
1689 Swizzle4<Vector4, 0xAE> zwzz;
1690 Swizzle4<Vector4, 0xAF> wwzz;
1691 Swizzle4<Vector4, 0xB0> xxwz;
1692 Swizzle4<Vector4, 0xB1> yxwz;
1693 Swizzle4<Vector4, 0xB2> zxwz;
1694 Swizzle4<Vector4, 0xB3> wxwz;
1695 Swizzle4<Vector4, 0xB4> xywz;
1696 Swizzle4<Vector4, 0xB5> yywz;
1697 Swizzle4<Vector4, 0xB6> zywz;
1698 Swizzle4<Vector4, 0xB7> wywz;
1699 Swizzle4<Vector4, 0xB8> xzwz;
1700 Swizzle4<Vector4, 0xB9> yzwz;
1701 Swizzle4<Vector4, 0xBA> zzwz;
1702 Swizzle4<Vector4, 0xBB> wzwz;
1703 Swizzle4<Vector4, 0xBC> xwwz;
1704 Swizzle4<Vector4, 0xBD> ywwz;
1705 Swizzle4<Vector4, 0xBE> zwwz;
1706 Swizzle4<Vector4, 0xBF> wwwz;
1707 Swizzle4<Vector4, 0xC0> xxxw;
1708 Swizzle4<Vector4, 0xC1> yxxw;
1709 Swizzle4<Vector4, 0xC2> zxxw;
1710 Swizzle4<Vector4, 0xC3> wxxw;
1711 Swizzle4<Vector4, 0xC4> xyxw;
1712 Swizzle4<Vector4, 0xC5> yyxw;
1713 Swizzle4<Vector4, 0xC6> zyxw;
1714 Swizzle4<Vector4, 0xC7> wyxw;
1715 Swizzle4<Vector4, 0xC8> xzxw;
1716 Swizzle4<Vector4, 0xC9> yzxw;
1717 Swizzle4<Vector4, 0xCA> zzxw;
1718 Swizzle4<Vector4, 0xCB> wzxw;
1719 Swizzle4<Vector4, 0xCC> xwxw;
1720 Swizzle4<Vector4, 0xCD> ywxw;
1721 Swizzle4<Vector4, 0xCE> zwxw;
1722 Swizzle4<Vector4, 0xCF> wwxw;
1723 Swizzle4<Vector4, 0xD0> xxyw;
1724 Swizzle4<Vector4, 0xD1> yxyw;
1725 Swizzle4<Vector4, 0xD2> zxyw;
1726 Swizzle4<Vector4, 0xD3> wxyw;
1727 Swizzle4<Vector4, 0xD4> xyyw;
1728 Swizzle4<Vector4, 0xD5> yyyw;
1729 Swizzle4<Vector4, 0xD6> zyyw;
1730 Swizzle4<Vector4, 0xD7> wyyw;
1731 Swizzle4<Vector4, 0xD8> xzyw;
1732 Swizzle4<Vector4, 0xD9> yzyw;
1733 Swizzle4<Vector4, 0xDA> zzyw;
1734 Swizzle4<Vector4, 0xDB> wzyw;
1735 Swizzle4<Vector4, 0xDC> xwyw;
1736 Swizzle4<Vector4, 0xDD> ywyw;
1737 Swizzle4<Vector4, 0xDE> zwyw;
1738 Swizzle4<Vector4, 0xDF> wwyw;
1739 Swizzle4<Vector4, 0xE0> xxzw;
1740 Swizzle4<Vector4, 0xE1> yxzw;
1741 Swizzle4<Vector4, 0xE2> zxzw;
1742 Swizzle4<Vector4, 0xE3> wxzw;
1743 SwizzleMask4<Vector4, 0xE4> xyzw;
1744 Swizzle4<Vector4, 0xE5> yyzw;
1745 Swizzle4<Vector4, 0xE6> zyzw;
1746 Swizzle4<Vector4, 0xE7> wyzw;
1747 Swizzle4<Vector4, 0xE8> xzzw;
1748 Swizzle4<Vector4, 0xE9> yzzw;
1749 Swizzle4<Vector4, 0xEA> zzzw;
1750 Swizzle4<Vector4, 0xEB> wzzw;
1751 Swizzle4<Vector4, 0xEC> xwzw;
1752 Swizzle4<Vector4, 0xED> ywzw;
1753 Swizzle4<Vector4, 0xEE> zwzw;
1754 Swizzle4<Vector4, 0xEF> wwzw;
1755 Swizzle4<Vector4, 0xF0> xxww;
1756 Swizzle4<Vector4, 0xF1> yxww;
1757 Swizzle4<Vector4, 0xF2> zxww;
1758 Swizzle4<Vector4, 0xF3> wxww;
1759 Swizzle4<Vector4, 0xF4> xyww;
1760 Swizzle4<Vector4, 0xF5> yyww;
1761 Swizzle4<Vector4, 0xF6> zyww;
1762 Swizzle4<Vector4, 0xF7> wyww;
1763 Swizzle4<Vector4, 0xF8> xzww;
1764 Swizzle4<Vector4, 0xF9> yzww;
1765 Swizzle4<Vector4, 0xFA> zzww;
1766 Swizzle4<Vector4, 0xFB> wzww;
1767 Swizzle4<Vector4, 0xFC> xwww;
1768 Swizzle4<Vector4, 0xFD> ywww;
1769 Swizzle4<Vector4, 0xFE> zwww;
1770 Swizzle4<Vector4, 0xFF> wwww;
1771 };
1772 };
1773
1774 class Int4 : public LValue<Int4>, public XYZW<Int4>
Nicolas Capensd022e412016-09-26 13:30:14 -04001775 {
1776 public:
1777 explicit Int4(RValue<Byte4> cast);
1778 explicit Int4(RValue<SByte4> cast);
1779 explicit Int4(RValue<Float4> cast);
1780 explicit Int4(RValue<Short4> cast);
1781 explicit Int4(RValue<UShort4> cast);
1782
Nicolas Capenscb986762017-01-20 11:34:37 -05001783 Int4();
Nicolas Capensd022e412016-09-26 13:30:14 -04001784 Int4(int xyzw);
1785 Int4(int x, int yzw);
1786 Int4(int x, int y, int zw);
1787 Int4(int x, int y, int z, int w);
1788 Int4(RValue<Int4> rhs);
1789 Int4(const Int4 &rhs);
1790 Int4(const Reference<Int4> &rhs);
1791 Int4(RValue<UInt4> rhs);
1792 Int4(const UInt4 &rhs);
1793 Int4(const Reference<UInt4> &rhs);
1794 Int4(RValue<Int2> lo, RValue<Int2> hi);
1795 Int4(RValue<Int> rhs);
1796 Int4(const Int &rhs);
1797 Int4(const Reference<Int> &rhs);
1798
Nicolas Capens96d4e092016-11-18 14:22:38 -05001799 RValue<Int4> operator=(RValue<Int4> rhs);
1800 RValue<Int4> operator=(const Int4 &rhs);
1801 RValue<Int4> operator=(const Reference<Int4> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001802
1803 static Type *getType();
1804
1805 private:
1806 void constant(int x, int y, int z, int w);
1807 };
1808
1809 RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs);
1810 RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs);
1811 RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs);
1812 RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs);
1813 RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs);
1814 RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs);
1815 RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs);
1816 RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs);
1817 RValue<Int4> operator<<(RValue<Int4> lhs, unsigned char rhs);
1818 RValue<Int4> operator>>(RValue<Int4> lhs, unsigned char rhs);
1819 RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs);
1820 RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001821 RValue<Int4> operator+=(Int4 &lhs, RValue<Int4> rhs);
1822 RValue<Int4> operator-=(Int4 &lhs, RValue<Int4> rhs);
1823 RValue<Int4> operator*=(Int4 &lhs, RValue<Int4> rhs);
1824// RValue<Int4> operator/=(Int4 &lhs, RValue<Int4> rhs);
1825// RValue<Int4> operator%=(Int4 &lhs, RValue<Int4> rhs);
1826 RValue<Int4> operator&=(Int4 &lhs, RValue<Int4> rhs);
1827 RValue<Int4> operator|=(Int4 &lhs, RValue<Int4> rhs);
1828 RValue<Int4> operator^=(Int4 &lhs, RValue<Int4> rhs);
1829 RValue<Int4> operator<<=(Int4 &lhs, unsigned char rhs);
1830 RValue<Int4> operator>>=(Int4 &lhs, unsigned char rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001831 RValue<Int4> operator+(RValue<Int4> val);
1832 RValue<Int4> operator-(RValue<Int4> val);
1833 RValue<Int4> operator~(RValue<Int4> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001834// RValue<Int4> operator++(Int4 &val, int); // Post-increment
1835// const Int4 &operator++(Int4 &val); // Pre-increment
1836// RValue<Int4> operator--(Int4 &val, int); // Post-decrement
1837// const Int4 &operator--(Int4 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -04001838// RValue<Bool> operator<(RValue<Int4> lhs, RValue<Int4> rhs);
1839// RValue<Bool> operator<=(RValue<Int4> lhs, RValue<Int4> rhs);
1840// RValue<Bool> operator>(RValue<Int4> lhs, RValue<Int4> rhs);
1841// RValue<Bool> operator>=(RValue<Int4> lhs, RValue<Int4> rhs);
1842// RValue<Bool> operator!=(RValue<Int4> lhs, RValue<Int4> rhs);
1843// RValue<Bool> operator==(RValue<Int4> lhs, RValue<Int4> rhs);
1844
Nicolas Capens4b743732018-05-28 13:22:07 -04001845 inline RValue<Int4> operator+(RValue<Int> lhs, RValue<Int4> rhs)
1846 {
1847 return Int4(lhs) + rhs;
1848 }
1849
1850 inline RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int> rhs)
1851 {
1852 return lhs + Int4(rhs);
1853 }
1854
Nicolas Capensd022e412016-09-26 13:30:14 -04001855 RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y);
1856 RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y);
1857 RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y);
1858 RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y);
1859 RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y);
1860 RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y);
Ben Claytone95eeb12019-03-04 16:32:09 +00001861 inline RValue<Int4> CmpGT(RValue<Int4> x, RValue<Int4> y) { return CmpNLE(x, y); }
1862 inline RValue<Int4> CmpGE(RValue<Int4> x, RValue<Int4> y) { return CmpNLT(x, y); }
Nicolas Capensd022e412016-09-26 13:30:14 -04001863 RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y);
1864 RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y);
1865 RValue<Int4> RoundInt(RValue<Float4> cast);
Nicolas Capens33438a62017-09-27 11:47:35 -04001866 RValue<Short8> PackSigned(RValue<Int4> x, RValue<Int4> y);
1867 RValue<UShort8> PackUnsigned(RValue<Int4> x, RValue<Int4> y);
Nicolas Capensc94ab742016-11-08 15:15:31 -05001868 RValue<Int> Extract(RValue<Int4> val, int i);
Nicolas Capensd022e412016-09-26 13:30:14 -04001869 RValue<Int4> Insert(RValue<Int4> val, RValue<Int> element, int i);
1870 RValue<Int> SignMask(RValue<Int4> x);
1871 RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select);
Chris Forbese86b6dc2019-03-01 09:08:47 -08001872 RValue<Int4> MulHigh(RValue<Int4> x, RValue<Int4> y);
Nicolas Capensd022e412016-09-26 13:30:14 -04001873
Nicolas Capenscb986762017-01-20 11:34:37 -05001874 class UInt4 : public LValue<UInt4>, public XYZW<UInt4>
Nicolas Capensd022e412016-09-26 13:30:14 -04001875 {
1876 public:
1877 explicit UInt4(RValue<Float4> cast);
1878
Nicolas Capenscb986762017-01-20 11:34:37 -05001879 UInt4();
Nicolas Capensd022e412016-09-26 13:30:14 -04001880 UInt4(int xyzw);
1881 UInt4(int x, int yzw);
1882 UInt4(int x, int y, int zw);
1883 UInt4(int x, int y, int z, int w);
Nicolas Capensd022e412016-09-26 13:30:14 -04001884 UInt4(RValue<UInt4> rhs);
1885 UInt4(const UInt4 &rhs);
1886 UInt4(const Reference<UInt4> &rhs);
1887 UInt4(RValue<Int4> rhs);
1888 UInt4(const Int4 &rhs);
1889 UInt4(const Reference<Int4> &rhs);
1890 UInt4(RValue<UInt2> lo, RValue<UInt2> hi);
1891
Nicolas Capens96d4e092016-11-18 14:22:38 -05001892 RValue<UInt4> operator=(RValue<UInt4> rhs);
1893 RValue<UInt4> operator=(const UInt4 &rhs);
1894 RValue<UInt4> operator=(const Reference<UInt4> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001895
1896 static Type *getType();
1897
1898 private:
1899 void constant(int x, int y, int z, int w);
1900 };
1901
1902 RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs);
1903 RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs);
1904 RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs);
1905 RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs);
1906 RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs);
1907 RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs);
1908 RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs);
1909 RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs);
1910 RValue<UInt4> operator<<(RValue<UInt4> lhs, unsigned char rhs);
1911 RValue<UInt4> operator>>(RValue<UInt4> lhs, unsigned char rhs);
1912 RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs);
1913 RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001914 RValue<UInt4> operator+=(UInt4 &lhs, RValue<UInt4> rhs);
1915 RValue<UInt4> operator-=(UInt4 &lhs, RValue<UInt4> rhs);
1916 RValue<UInt4> operator*=(UInt4 &lhs, RValue<UInt4> rhs);
1917// RValue<UInt4> operator/=(UInt4 &lhs, RValue<UInt4> rhs);
1918// RValue<UInt4> operator%=(UInt4 &lhs, RValue<UInt4> rhs);
1919 RValue<UInt4> operator&=(UInt4 &lhs, RValue<UInt4> rhs);
1920 RValue<UInt4> operator|=(UInt4 &lhs, RValue<UInt4> rhs);
1921 RValue<UInt4> operator^=(UInt4 &lhs, RValue<UInt4> rhs);
1922 RValue<UInt4> operator<<=(UInt4 &lhs, unsigned char rhs);
1923 RValue<UInt4> operator>>=(UInt4 &lhs, unsigned char rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001924 RValue<UInt4> operator+(RValue<UInt4> val);
1925 RValue<UInt4> operator-(RValue<UInt4> val);
1926 RValue<UInt4> operator~(RValue<UInt4> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001927// RValue<UInt4> operator++(UInt4 &val, int); // Post-increment
1928// const UInt4 &operator++(UInt4 &val); // Pre-increment
1929// RValue<UInt4> operator--(UInt4 &val, int); // Post-decrement
1930// const UInt4 &operator--(UInt4 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -04001931// RValue<Bool> operator<(RValue<UInt4> lhs, RValue<UInt4> rhs);
1932// RValue<Bool> operator<=(RValue<UInt4> lhs, RValue<UInt4> rhs);
1933// RValue<Bool> operator>(RValue<UInt4> lhs, RValue<UInt4> rhs);
1934// RValue<Bool> operator>=(RValue<UInt4> lhs, RValue<UInt4> rhs);
1935// RValue<Bool> operator!=(RValue<UInt4> lhs, RValue<UInt4> rhs);
1936// RValue<Bool> operator==(RValue<UInt4> lhs, RValue<UInt4> rhs);
1937
1938 RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y);
1939 RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y);
1940 RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y);
1941 RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y);
1942 RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y);
1943 RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y);
Ben Claytone95eeb12019-03-04 16:32:09 +00001944 inline RValue<UInt4> CmpGT(RValue<UInt4> x, RValue<UInt4> y) { return CmpNLE(x, y); }
1945 inline RValue<UInt4> CmpGE(RValue<UInt4> x, RValue<UInt4> y) { return CmpNLT(x, y); }
Nicolas Capensd022e412016-09-26 13:30:14 -04001946 RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y);
1947 RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y);
Chris Forbese86b6dc2019-03-01 09:08:47 -08001948 RValue<UInt4> MulHigh(RValue<UInt4> x, RValue<UInt4> y);
Nicolas Capensd022e412016-09-26 13:30:14 -04001949// RValue<UInt4> RoundInt(RValue<Float4> cast);
Nicolas Capensd022e412016-09-26 13:30:14 -04001950
Alexis Hetu734e2572018-12-20 14:00:49 -05001951 class Half : public LValue<Half>
1952 {
1953 public:
1954 explicit Half(RValue<Float> cast);
1955
1956 static Type *getType();
1957 };
1958
Nicolas Capens297d26e2016-11-18 12:52:17 -05001959 class Float : public LValue<Float>
Nicolas Capensd022e412016-09-26 13:30:14 -04001960 {
1961 public:
1962 explicit Float(RValue<Int> cast);
Alexis Hetucfd96322017-07-24 14:44:33 -04001963 explicit Float(RValue<UInt> cast);
Alexis Hetu734e2572018-12-20 14:00:49 -05001964 explicit Float(RValue<Half> cast);
Nicolas Capensd022e412016-09-26 13:30:14 -04001965
Nicolas Capensa25311a2017-01-16 17:19:00 -05001966 Float() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -04001967 Float(float x);
1968 Float(RValue<Float> rhs);
1969 Float(const Float &rhs);
1970 Float(const Reference<Float> &rhs);
Ben Claytonf3b57972019-03-15 09:56:47 +00001971 Float(Argument<Float> argument);
Nicolas Capensd022e412016-09-26 13:30:14 -04001972
1973 template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05001974 Float(const SwizzleMask1<Float4, T> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001975
Nicolas Capens96d4e092016-11-18 14:22:38 -05001976 // RValue<Float> operator=(float rhs); // FIXME: Implement
1977 RValue<Float> operator=(RValue<Float> rhs);
1978 RValue<Float> operator=(const Float &rhs);
1979 RValue<Float> operator=(const Reference<Float> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001980
1981 template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05001982 RValue<Float> operator=(const SwizzleMask1<Float4, T> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001983
1984 static Type *getType();
1985 };
1986
1987 RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs);
1988 RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs);
1989 RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs);
1990 RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001991 RValue<Float> operator+=(Float &lhs, RValue<Float> rhs);
1992 RValue<Float> operator-=(Float &lhs, RValue<Float> rhs);
1993 RValue<Float> operator*=(Float &lhs, RValue<Float> rhs);
1994 RValue<Float> operator/=(Float &lhs, RValue<Float> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001995 RValue<Float> operator+(RValue<Float> val);
1996 RValue<Float> operator-(RValue<Float> val);
1997 RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs);
1998 RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs);
1999 RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs);
2000 RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs);
2001 RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs);
2002 RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs);
2003
2004 RValue<Float> Abs(RValue<Float> x);
2005 RValue<Float> Max(RValue<Float> x, RValue<Float> y);
2006 RValue<Float> Min(RValue<Float> x, RValue<Float> y);
2007 RValue<Float> Rcp_pp(RValue<Float> val, bool exactAtPow2 = false);
2008 RValue<Float> RcpSqrt_pp(RValue<Float> val);
2009 RValue<Float> Sqrt(RValue<Float> x);
2010 RValue<Float> Round(RValue<Float> val);
2011 RValue<Float> Trunc(RValue<Float> val);
2012 RValue<Float> Frac(RValue<Float> val);
2013 RValue<Float> Floor(RValue<Float> val);
2014 RValue<Float> Ceil(RValue<Float> val);
2015
Nicolas Capens297d26e2016-11-18 12:52:17 -05002016 class Float2 : public LValue<Float2>
Nicolas Capensd022e412016-09-26 13:30:14 -04002017 {
2018 public:
2019 // explicit Float2(RValue<Byte2> cast);
2020 // explicit Float2(RValue<Short2> cast);
2021 // explicit Float2(RValue<UShort2> cast);
2022 // explicit Float2(RValue<Int2> cast);
2023 // explicit Float2(RValue<UInt2> cast);
2024 explicit Float2(RValue<Float4> cast);
2025
Nicolas Capensa25311a2017-01-16 17:19:00 -05002026 Float2() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -04002027 // Float2(float x, float y);
2028 // Float2(RValue<Float2> rhs);
2029 // Float2(const Float2 &rhs);
2030 // Float2(const Reference<Float2> &rhs);
2031 // Float2(RValue<Float> rhs);
2032 // Float2(const Float &rhs);
2033 // Float2(const Reference<Float> &rhs);
2034
2035 // template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002036 // Float2(const SwizzleMask1<T> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04002037
Nicolas Capens96d4e092016-11-18 14:22:38 -05002038 // RValue<Float2> operator=(float replicate);
2039 // RValue<Float2> operator=(RValue<Float2> rhs);
2040 // RValue<Float2> operator=(const Float2 &rhs);
2041 // RValue<Float2> operator=(const Reference<Float2> &rhs);
2042 // RValue<Float2> operator=(RValue<Float> rhs);
2043 // RValue<Float2> operator=(const Float &rhs);
2044 // RValue<Float2> operator=(const Reference<Float> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04002045
2046 // template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002047 // RValue<Float2> operator=(const SwizzleMask1<T> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04002048
2049 static Type *getType();
2050 };
2051
2052// RValue<Float2> operator+(RValue<Float2> lhs, RValue<Float2> rhs);
2053// RValue<Float2> operator-(RValue<Float2> lhs, RValue<Float2> rhs);
2054// RValue<Float2> operator*(RValue<Float2> lhs, RValue<Float2> rhs);
2055// RValue<Float2> operator/(RValue<Float2> lhs, RValue<Float2> rhs);
2056// RValue<Float2> operator%(RValue<Float2> lhs, RValue<Float2> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05002057// RValue<Float2> operator+=(Float2 &lhs, RValue<Float2> rhs);
2058// RValue<Float2> operator-=(Float2 &lhs, RValue<Float2> rhs);
2059// RValue<Float2> operator*=(Float2 &lhs, RValue<Float2> rhs);
2060// RValue<Float2> operator/=(Float2 &lhs, RValue<Float2> rhs);
2061// RValue<Float2> operator%=(Float2 &lhs, RValue<Float2> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04002062// RValue<Float2> operator+(RValue<Float2> val);
2063// RValue<Float2> operator-(RValue<Float2> val);
2064
2065// RValue<Float2> Abs(RValue<Float2> x);
2066// RValue<Float2> Max(RValue<Float2> x, RValue<Float2> y);
2067// RValue<Float2> Min(RValue<Float2> x, RValue<Float2> y);
2068// RValue<Float2> Swizzle(RValue<Float2> x, unsigned char select);
2069// RValue<Float2> Mask(Float2 &lhs, RValue<Float2> rhs, unsigned char select);
2070
Nicolas Capenscb986762017-01-20 11:34:37 -05002071 class Float4 : public LValue<Float4>, public XYZW<Float4>
Nicolas Capensa25311a2017-01-16 17:19:00 -05002072 {
2073 public:
2074 explicit Float4(RValue<Byte4> cast);
2075 explicit Float4(RValue<SByte4> cast);
2076 explicit Float4(RValue<Short4> cast);
2077 explicit Float4(RValue<UShort4> cast);
2078 explicit Float4(RValue<Int4> cast);
2079 explicit Float4(RValue<UInt4> cast);
2080
2081 Float4();
2082 Float4(float xyzw);
2083 Float4(float x, float yzw);
2084 Float4(float x, float y, float zw);
2085 Float4(float x, float y, float z, float w);
2086 Float4(RValue<Float4> rhs);
2087 Float4(const Float4 &rhs);
2088 Float4(const Reference<Float4> &rhs);
2089 Float4(RValue<Float> rhs);
2090 Float4(const Float &rhs);
2091 Float4(const Reference<Float> &rhs);
2092
2093 template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002094 Float4(const SwizzleMask1<Float4, T> &rhs);
Nicolas Capensa25311a2017-01-16 17:19:00 -05002095 template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002096 Float4(const Swizzle4<Float4, T> &rhs);
Nicolas Capensa25311a2017-01-16 17:19:00 -05002097 template<int X, int Y>
Nicolas Capenscb986762017-01-20 11:34:37 -05002098 Float4(const Swizzle2<Float4, X> &x, const Swizzle2<Float4, Y> &y);
Nicolas Capensa25311a2017-01-16 17:19:00 -05002099 template<int X, int Y>
Nicolas Capenscb986762017-01-20 11:34:37 -05002100 Float4(const SwizzleMask2<Float4, X> &x, const Swizzle2<Float4, Y> &y);
Nicolas Capensa25311a2017-01-16 17:19:00 -05002101 template<int X, int Y>
Nicolas Capenscb986762017-01-20 11:34:37 -05002102 Float4(const Swizzle2<Float4, X> &x, const SwizzleMask2<Float4, Y> &y);
Nicolas Capensa25311a2017-01-16 17:19:00 -05002103 template<int X, int Y>
Nicolas Capenscb986762017-01-20 11:34:37 -05002104 Float4(const SwizzleMask2<Float4, X> &x, const SwizzleMask2<Float4, Y> &y);
Nicolas Capensa25311a2017-01-16 17:19:00 -05002105
2106 RValue<Float4> operator=(float replicate);
2107 RValue<Float4> operator=(RValue<Float4> rhs);
2108 RValue<Float4> operator=(const Float4 &rhs);
2109 RValue<Float4> operator=(const Reference<Float4> &rhs);
2110 RValue<Float4> operator=(RValue<Float> rhs);
2111 RValue<Float4> operator=(const Float &rhs);
2112 RValue<Float4> operator=(const Reference<Float> &rhs);
2113
2114 template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002115 RValue<Float4> operator=(const SwizzleMask1<Float4, T> &rhs);
Nicolas Capensa25311a2017-01-16 17:19:00 -05002116 template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002117 RValue<Float4> operator=(const Swizzle4<Float4, T> &rhs);
Nicolas Capensa25311a2017-01-16 17:19:00 -05002118
2119 static Type *getType();
Nicolas Capensd022e412016-09-26 13:30:14 -04002120
2121 private:
2122 void constant(float x, float y, float z, float w);
2123 };
2124
2125 RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs);
2126 RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs);
2127 RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs);
2128 RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs);
2129 RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05002130 RValue<Float4> operator+=(Float4 &lhs, RValue<Float4> rhs);
2131 RValue<Float4> operator-=(Float4 &lhs, RValue<Float4> rhs);
2132 RValue<Float4> operator*=(Float4 &lhs, RValue<Float4> rhs);
2133 RValue<Float4> operator/=(Float4 &lhs, RValue<Float4> rhs);
2134 RValue<Float4> operator%=(Float4 &lhs, RValue<Float4> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04002135 RValue<Float4> operator+(RValue<Float4> val);
2136 RValue<Float4> operator-(RValue<Float4> val);
2137
2138 RValue<Float4> Abs(RValue<Float4> x);
2139 RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y);
2140 RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y);
2141 RValue<Float4> Rcp_pp(RValue<Float4> val, bool exactAtPow2 = false);
2142 RValue<Float4> RcpSqrt_pp(RValue<Float4> val);
2143 RValue<Float4> Sqrt(RValue<Float4> x);
Nicolas Capensc94ab742016-11-08 15:15:31 -05002144 RValue<Float4> Insert(RValue<Float4> val, RValue<Float> element, int i);
Nicolas Capensd022e412016-09-26 13:30:14 -04002145 RValue<Float> Extract(RValue<Float4> x, int i);
2146 RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select);
2147 RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm);
2148 RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y);
2149 RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y);
2150 RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select);
2151 RValue<Int> SignMask(RValue<Float4> x);
Ben Claytonec1aeb82019-03-04 19:33:27 +00002152
2153 // Ordered comparison functions
Nicolas Capensd022e412016-09-26 13:30:14 -04002154 RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y);
2155 RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y);
2156 RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y);
2157 RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y);
2158 RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y);
2159 RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y);
Ben Claytonec1aeb82019-03-04 19:33:27 +00002160 inline RValue<Int4> CmpGT(RValue<Float4> x, RValue<Float4> y) { return CmpNLE(x, y); }
2161 inline RValue<Int4> CmpGE(RValue<Float4> x, RValue<Float4> y) { return CmpNLT(x, y); }
2162
2163 // Unordered comparison functions
2164 RValue<Int4> CmpUEQ(RValue<Float4> x, RValue<Float4> y);
2165 RValue<Int4> CmpULT(RValue<Float4> x, RValue<Float4> y);
2166 RValue<Int4> CmpULE(RValue<Float4> x, RValue<Float4> y);
2167 RValue<Int4> CmpUNEQ(RValue<Float4> x, RValue<Float4> y);
2168 RValue<Int4> CmpUNLT(RValue<Float4> x, RValue<Float4> y);
2169 RValue<Int4> CmpUNLE(RValue<Float4> x, RValue<Float4> y);
2170 inline RValue<Int4> CmpUGT(RValue<Float4> x, RValue<Float4> y) { return CmpUNLE(x, y); }
2171 inline RValue<Int4> CmpUGE(RValue<Float4> x, RValue<Float4> y) { return CmpUNLT(x, y); }
2172
Alexis Hetu8ef6d102017-11-09 15:49:09 -05002173 RValue<Int4> IsInf(RValue<Float4> x);
2174 RValue<Int4> IsNan(RValue<Float4> x);
Nicolas Capensd022e412016-09-26 13:30:14 -04002175 RValue<Float4> Round(RValue<Float4> x);
2176 RValue<Float4> Trunc(RValue<Float4> x);
2177 RValue<Float4> Frac(RValue<Float4> x);
2178 RValue<Float4> Floor(RValue<Float4> x);
2179 RValue<Float4> Ceil(RValue<Float4> x);
2180
2181 template<class T>
Nicolas Capens297d26e2016-11-18 12:52:17 -05002182 class Pointer : public LValue<Pointer<T>>
Nicolas Capensd022e412016-09-26 13:30:14 -04002183 {
2184 public:
2185 template<class S>
2186 Pointer(RValue<Pointer<S>> pointerS, int alignment = 1) : alignment(alignment)
2187 {
2188 Value *pointerT = Nucleus::createBitCast(pointerS.value, Nucleus::getPointerType(T::getType()));
Nicolas Capens22479eb2016-09-28 22:34:26 -04002189 LValue<Pointer<T>>::storeValue(pointerT);
Nicolas Capensd022e412016-09-26 13:30:14 -04002190 }
2191
2192 template<class S>
2193 Pointer(const Pointer<S> &pointer, int alignment = 1) : alignment(alignment)
2194 {
Nicolas Capens4126b8e2017-07-26 13:34:36 -04002195 Value *pointerS = pointer.loadValue();
Nicolas Capensd022e412016-09-26 13:30:14 -04002196 Value *pointerT = Nucleus::createBitCast(pointerS, Nucleus::getPointerType(T::getType()));
Nicolas Capens22479eb2016-09-28 22:34:26 -04002197 LValue<Pointer<T>>::storeValue(pointerT);
Nicolas Capensd022e412016-09-26 13:30:14 -04002198 }
2199
2200 Pointer(Argument<Pointer<T>> argument);
Nicolas Capensd022e412016-09-26 13:30:14 -04002201
2202 Pointer();
2203 Pointer(RValue<Pointer<T>> rhs);
2204 Pointer(const Pointer<T> &rhs);
2205 Pointer(const Reference<Pointer<T>> &rhs);
2206
Nicolas Capens96d4e092016-11-18 14:22:38 -05002207 RValue<Pointer<T>> operator=(RValue<Pointer<T>> rhs);
2208 RValue<Pointer<T>> operator=(const Pointer<T> &rhs);
2209 RValue<Pointer<T>> operator=(const Reference<Pointer<T>> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04002210
2211 Reference<T> operator*();
2212 Reference<T> operator[](int index);
Nicolas Capensd294def2017-01-26 17:44:37 -08002213 Reference<T> operator[](unsigned int index);
Nicolas Capensd022e412016-09-26 13:30:14 -04002214 Reference<T> operator[](RValue<Int> index);
Nicolas Capensd294def2017-01-26 17:44:37 -08002215 Reference<T> operator[](RValue<UInt> index);
Nicolas Capensd022e412016-09-26 13:30:14 -04002216
2217 static Type *getType();
2218
2219 private:
2220 const int alignment;
2221 };
2222
2223 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset);
2224 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset);
2225 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset);
Nicolas Capens96d4e092016-11-18 14:22:38 -05002226 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, int offset);
2227 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<Int> offset);
2228 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<UInt> offset);
Nicolas Capensd022e412016-09-26 13:30:14 -04002229
2230 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset);
2231 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset);
2232 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset);
Nicolas Capens96d4e092016-11-18 14:22:38 -05002233 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, int offset);
2234 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<Int> offset);
2235 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<UInt> offset);
Nicolas Capensd022e412016-09-26 13:30:14 -04002236
2237 template<class T, int S = 1>
Nicolas Capens297d26e2016-11-18 12:52:17 -05002238 class Array : public LValue<T>
Nicolas Capensd022e412016-09-26 13:30:14 -04002239 {
2240 public:
2241 Array(int size = S);
2242
2243 Reference<T> operator[](int index);
Nicolas Capensd294def2017-01-26 17:44:37 -08002244 Reference<T> operator[](unsigned int index);
Nicolas Capensd022e412016-09-26 13:30:14 -04002245 Reference<T> operator[](RValue<Int> index);
Nicolas Capensd294def2017-01-26 17:44:37 -08002246 Reference<T> operator[](RValue<UInt> index);
Nicolas Capensd022e412016-09-26 13:30:14 -04002247 };
2248
Nicolas Capens96d4e092016-11-18 14:22:38 -05002249// RValue<Array<T>> operator++(Array<T> &val, int); // Post-increment
2250// const Array<T> &operator++(Array<T> &val); // Pre-increment
2251// RValue<Array<T>> operator--(Array<T> &val, int); // Post-decrement
2252// const Array<T> &operator--(Array<T> &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -04002253
Nicolas Capensf4eec2f2017-05-24 15:46:48 -04002254 void branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB);
Nicolas Capensd022e412016-09-26 13:30:14 -04002255
2256 void Return();
Nicolas Capenseb253d02016-11-18 14:40:40 -05002257 void Return(RValue<Int> ret);
Nicolas Capensd022e412016-09-26 13:30:14 -04002258
2259 template<class T>
2260 void Return(const Pointer<T> &ret);
2261
2262 template<class T>
2263 void Return(RValue<Pointer<T>> ret);
2264
2265 template<unsigned int index, typename... Arguments>
2266 struct ArgI;
2267
2268 template<typename Arg0, typename... Arguments>
2269 struct ArgI<0, Arg0, Arguments...>
2270 {
2271 typedef Arg0 Type;
2272 };
2273
2274 template<unsigned int index, typename Arg0, typename... Arguments>
2275 struct ArgI<index, Arg0, Arguments...>
2276 {
2277 typedef typename ArgI<index - 1, Arguments...>::Type Type;
2278 };
2279
2280 // Generic template, leave undefined!
2281 template<typename FunctionType>
2282 class Function;
2283
2284 // Specialized for function types
2285 template<typename Return, typename... Arguments>
2286 class Function<Return(Arguments...)>
2287 {
2288 public:
2289 Function();
2290
2291 virtual ~Function();
2292
2293 template<int index>
2294 Argument<typename ArgI<index, Arguments...>::Type> Arg() const
2295 {
2296 Value *arg = Nucleus::getArgument(index);
2297 return Argument<typename ArgI<index, Arguments...>::Type>(arg);
2298 }
2299
Chris Forbes878d4b02019-01-21 10:48:35 -08002300 Routine *operator()(const char *name, ...);
Nicolas Capensd022e412016-09-26 13:30:14 -04002301
2302 protected:
2303 Nucleus *core;
2304 std::vector<Type*> arguments;
2305 };
2306
2307 template<typename Return>
2308 class Function<Return()> : public Function<Return(Void)>
2309 {
2310 };
2311
2312 template<int index, typename Return, typename... Arguments>
2313 Argument<typename ArgI<index, Arguments...>::Type> Arg(Function<Return(Arguments...)> &function)
2314 {
2315 return Argument<typename ArgI<index, Arguments...>::Type>(function.arg(index));
2316 }
2317
2318 RValue<Long> Ticks();
2319}
2320
Nicolas Capens48461502018-08-06 14:20:45 -04002321namespace rr
Nicolas Capensd022e412016-09-26 13:30:14 -04002322{
2323 template<class T>
Nicolas Capens22479eb2016-09-28 22:34:26 -04002324 LValue<T>::LValue(int arraySize)
2325 {
2326 address = Nucleus::allocateStackVariable(T::getType(), arraySize);
2327 }
2328
2329 template<class T>
Nicolas Capens4126b8e2017-07-26 13:34:36 -04002330 Value *LValue<T>::loadValue() const
Nicolas Capens22479eb2016-09-28 22:34:26 -04002331 {
Nicolas Capens4126b8e2017-07-26 13:34:36 -04002332 return Nucleus::createLoad(address, T::getType(), false, 0);
Nicolas Capens22479eb2016-09-28 22:34:26 -04002333 }
2334
2335 template<class T>
Nicolas Capens4126b8e2017-07-26 13:34:36 -04002336 Value *LValue<T>::storeValue(Value *value) const
Nicolas Capens22479eb2016-09-28 22:34:26 -04002337 {
Nicolas Capens4126b8e2017-07-26 13:34:36 -04002338 return Nucleus::createStore(value, address, T::getType(), false, 0);
Nicolas Capens22479eb2016-09-28 22:34:26 -04002339 }
2340
2341 template<class T>
Nicolas Capensd294def2017-01-26 17:44:37 -08002342 Value *LValue<T>::getAddress(Value *index, bool unsignedIndex) const
Nicolas Capens22479eb2016-09-28 22:34:26 -04002343 {
Nicolas Capensd294def2017-01-26 17:44:37 -08002344 return Nucleus::createGEP(address, T::getType(), index, unsignedIndex);
Nicolas Capens22479eb2016-09-28 22:34:26 -04002345 }
2346
2347 template<class T>
Nicolas Capens297d26e2016-11-18 12:52:17 -05002348 RValue<Pointer<T>> LValue<T>::operator&()
Nicolas Capensd022e412016-09-26 13:30:14 -04002349 {
Nicolas Capens297d26e2016-11-18 12:52:17 -05002350 return RValue<Pointer<T>>(address);
Nicolas Capensd022e412016-09-26 13:30:14 -04002351 }
2352
2353 template<class T>
2354 Reference<T>::Reference(Value *pointer, int alignment) : alignment(alignment)
2355 {
2356 address = pointer;
2357 }
2358
2359 template<class T>
2360 RValue<T> Reference<T>::operator=(RValue<T> rhs) const
2361 {
Nicolas Capens6d738712016-09-30 04:15:22 -04002362 Nucleus::createStore(rhs.value, address, T::getType(), false, alignment);
Nicolas Capensd022e412016-09-26 13:30:14 -04002363
2364 return rhs;
2365 }
2366
2367 template<class T>
2368 RValue<T> Reference<T>::operator=(const Reference<T> &ref) const
2369 {
Nicolas Capense12780d2016-09-27 14:18:07 -04002370 Value *tmp = Nucleus::createLoad(ref.address, T::getType(), false, ref.alignment);
Nicolas Capens6d738712016-09-30 04:15:22 -04002371 Nucleus::createStore(tmp, address, T::getType(), false, alignment);
Nicolas Capensd022e412016-09-26 13:30:14 -04002372
2373 return RValue<T>(tmp);
2374 }
2375
2376 template<class T>
2377 RValue<T> Reference<T>::operator+=(RValue<T> rhs) const
2378 {
2379 return *this = *this + rhs;
2380 }
2381
2382 template<class T>
2383 Value *Reference<T>::loadValue() const
2384 {
Nicolas Capense12780d2016-09-27 14:18:07 -04002385 return Nucleus::createLoad(address, T::getType(), false, alignment);
Nicolas Capensd022e412016-09-26 13:30:14 -04002386 }
2387
2388 template<class T>
2389 int Reference<T>::getAlignment() const
2390 {
2391 return alignment;
2392 }
2393
2394 template<class T>
2395 RValue<T>::RValue(Value *rvalue)
2396 {
Nicolas Capensbea4dce2017-07-24 16:54:44 -04002397 assert(Nucleus::createBitCast(rvalue, T::getType()) == rvalue); // Run-time type should match T, so bitcast is no-op.
2398
Nicolas Capensd022e412016-09-26 13:30:14 -04002399 value = rvalue;
2400 }
2401
2402 template<class T>
2403 RValue<T>::RValue(const T &lvalue)
2404 {
2405 value = lvalue.loadValue();
2406 }
2407
2408 template<class T>
Ben Clayton35e90e22019-03-15 10:06:06 +00002409 RValue<T>::RValue(typename BoolLiteral<T>::type i)
2410 {
2411 value = Nucleus::createConstantBool(i);
2412 }
2413
2414 template<class T>
Nicolas Capensd022e412016-09-26 13:30:14 -04002415 RValue<T>::RValue(typename IntLiteral<T>::type i)
2416 {
Nicolas Capensa16473e2016-11-07 15:32:52 -05002417 value = Nucleus::createConstantInt(i);
Nicolas Capensd022e412016-09-26 13:30:14 -04002418 }
2419
2420 template<class T>
2421 RValue<T>::RValue(typename FloatLiteral<T>::type f)
2422 {
Nicolas Capensa16473e2016-11-07 15:32:52 -05002423 value = Nucleus::createConstantFloat(f);
Nicolas Capensd022e412016-09-26 13:30:14 -04002424 }
2425
2426 template<class T>
2427 RValue<T>::RValue(const Reference<T> &ref)
2428 {
2429 value = ref.loadValue();
2430 }
2431
Nicolas Capenscb986762017-01-20 11:34:37 -05002432 template<class Vector4, int T>
2433 Swizzle2<Vector4, T>::operator RValue<Vector4>() const
Nicolas Capensd022e412016-09-26 13:30:14 -04002434 {
2435 Value *vector = parent->loadValue();
2436
Nicolas Capenscb986762017-01-20 11:34:37 -05002437 return Swizzle(RValue<Vector4>(vector), T);
Nicolas Capensd022e412016-09-26 13:30:14 -04002438 }
2439
Nicolas Capenscb986762017-01-20 11:34:37 -05002440 template<class Vector4, int T>
2441 Swizzle4<Vector4, T>::operator RValue<Vector4>() const
Nicolas Capensd022e412016-09-26 13:30:14 -04002442 {
2443 Value *vector = parent->loadValue();
2444
Nicolas Capenscb986762017-01-20 11:34:37 -05002445 return Swizzle(RValue<Vector4>(vector), T);
Nicolas Capensd022e412016-09-26 13:30:14 -04002446 }
2447
Nicolas Capenscb986762017-01-20 11:34:37 -05002448 template<class Vector4, int T>
2449 SwizzleMask4<Vector4, T>::operator RValue<Vector4>() const
Nicolas Capensd022e412016-09-26 13:30:14 -04002450 {
2451 Value *vector = parent->loadValue();
2452
Nicolas Capenscb986762017-01-20 11:34:37 -05002453 return Swizzle(RValue<Vector4>(vector), T);
Nicolas Capensd022e412016-09-26 13:30:14 -04002454 }
2455
Nicolas Capenscb986762017-01-20 11:34:37 -05002456 template<class Vector4, int T>
2457 RValue<Vector4> SwizzleMask4<Vector4, T>::operator=(RValue<Vector4> rhs)
Nicolas Capensd022e412016-09-26 13:30:14 -04002458 {
2459 return Mask(*parent, rhs, T);
2460 }
2461
Nicolas Capenscb986762017-01-20 11:34:37 -05002462 template<class Vector4, int T>
2463 RValue<Vector4> SwizzleMask4<Vector4, T>::operator=(RValue<typename Scalar<Vector4>::Type> rhs)
Nicolas Capensd022e412016-09-26 13:30:14 -04002464 {
Nicolas Capenscb986762017-01-20 11:34:37 -05002465 return Mask(*parent, Vector4(rhs), T);
Nicolas Capensd022e412016-09-26 13:30:14 -04002466 }
2467
Nicolas Capenscb986762017-01-20 11:34:37 -05002468 template<class Vector4, int T>
2469 SwizzleMask1<Vector4, T>::operator RValue<typename Scalar<Vector4>::Type>() const // FIXME: Call a non-template function
Nicolas Capensd022e412016-09-26 13:30:14 -04002470 {
2471 return Extract(*parent, T & 0x3);
2472 }
2473
Nicolas Capenscb986762017-01-20 11:34:37 -05002474 template<class Vector4, int T>
2475 SwizzleMask1<Vector4, T>::operator RValue<Vector4>() const
Nicolas Capensd022e412016-09-26 13:30:14 -04002476 {
2477 Value *vector = parent->loadValue();
2478
Nicolas Capenscb986762017-01-20 11:34:37 -05002479 return Swizzle(RValue<Vector4>(vector), T);
Nicolas Capensd022e412016-09-26 13:30:14 -04002480 }
2481
Nicolas Capenscb986762017-01-20 11:34:37 -05002482 template<class Vector4, int T>
2483 RValue<Vector4> SwizzleMask1<Vector4, T>::operator=(float x)
Nicolas Capensd022e412016-09-26 13:30:14 -04002484 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05002485 return *parent = Insert(*parent, Float(x), T & 0x3);
Nicolas Capensd022e412016-09-26 13:30:14 -04002486 }
2487
Nicolas Capenscb986762017-01-20 11:34:37 -05002488 template<class Vector4, int T>
2489 RValue<Vector4> SwizzleMask1<Vector4, T>::operator=(RValue<Vector4> rhs)
Nicolas Capensd022e412016-09-26 13:30:14 -04002490 {
2491 return Mask(*parent, Float4(rhs), T);
2492 }
2493
Nicolas Capenscb986762017-01-20 11:34:37 -05002494 template<class Vector4, int T>
2495 RValue<Vector4> SwizzleMask1<Vector4, T>::operator=(RValue<typename Scalar<Vector4>::Type> rhs) // FIXME: Call a non-template function
Nicolas Capensd022e412016-09-26 13:30:14 -04002496 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05002497 return *parent = Insert(*parent, rhs, T & 0x3);
Nicolas Capensd022e412016-09-26 13:30:14 -04002498 }
2499
Nicolas Capenscb986762017-01-20 11:34:37 -05002500 template<class Vector4, int T>
2501 SwizzleMask2<Vector4, T>::operator RValue<Vector4>() const
Nicolas Capensd022e412016-09-26 13:30:14 -04002502 {
2503 Value *vector = parent->loadValue();
2504
Nicolas Capense95d5342016-09-30 11:37:28 -04002505 return Swizzle(RValue<Float4>(vector), T);
Nicolas Capensd022e412016-09-26 13:30:14 -04002506 }
2507
Nicolas Capenscb986762017-01-20 11:34:37 -05002508 template<class Vector4, int T>
2509 RValue<Vector4> SwizzleMask2<Vector4, T>::operator=(RValue<Vector4> rhs)
Nicolas Capensd022e412016-09-26 13:30:14 -04002510 {
2511 return Mask(*parent, Float4(rhs), T);
2512 }
2513
2514 template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002515 Float::Float(const SwizzleMask1<Float4, T> &rhs)
Nicolas Capensd022e412016-09-26 13:30:14 -04002516 {
2517 *this = rhs.operator RValue<Float>();
2518 }
2519
2520 template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002521 RValue<Float> Float::operator=(const SwizzleMask1<Float4, T> &rhs)
Nicolas Capensd022e412016-09-26 13:30:14 -04002522 {
2523 return *this = rhs.operator RValue<Float>();
2524 }
2525
2526 template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002527 Float4::Float4(const SwizzleMask1<Float4, T> &rhs) : XYZW(this)
Nicolas Capensd022e412016-09-26 13:30:14 -04002528 {
Nicolas Capensd022e412016-09-26 13:30:14 -04002529 *this = rhs.operator RValue<Float4>();
2530 }
2531
2532 template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002533 Float4::Float4(const Swizzle4<Float4, T> &rhs) : XYZW(this)
Nicolas Capensd022e412016-09-26 13:30:14 -04002534 {
Nicolas Capensd022e412016-09-26 13:30:14 -04002535 *this = rhs.operator RValue<Float4>();
2536 }
2537
2538 template<int X, int Y>
Nicolas Capenscb986762017-01-20 11:34:37 -05002539 Float4::Float4(const Swizzle2<Float4, X> &x, const Swizzle2<Float4, Y> &y) : XYZW(this)
Nicolas Capensd022e412016-09-26 13:30:14 -04002540 {
Nicolas Capensd022e412016-09-26 13:30:14 -04002541 *this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);
2542 }
2543
2544 template<int X, int Y>
Nicolas Capenscb986762017-01-20 11:34:37 -05002545 Float4::Float4(const SwizzleMask2<Float4, X> &x, const Swizzle2<Float4, Y> &y) : XYZW(this)
Nicolas Capensd022e412016-09-26 13:30:14 -04002546 {
Nicolas Capensd022e412016-09-26 13:30:14 -04002547 *this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);
2548 }
2549
2550 template<int X, int Y>
Nicolas Capenscb986762017-01-20 11:34:37 -05002551 Float4::Float4(const Swizzle2<Float4, X> &x, const SwizzleMask2<Float4, Y> &y) : XYZW(this)
Nicolas Capensd022e412016-09-26 13:30:14 -04002552 {
Nicolas Capensd022e412016-09-26 13:30:14 -04002553 *this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);
2554 }
2555
2556 template<int X, int Y>
Nicolas Capenscb986762017-01-20 11:34:37 -05002557 Float4::Float4(const SwizzleMask2<Float4, X> &x, const SwizzleMask2<Float4, Y> &y) : XYZW(this)
Nicolas Capensd022e412016-09-26 13:30:14 -04002558 {
Nicolas Capensd022e412016-09-26 13:30:14 -04002559 *this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);
2560 }
2561
2562 template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002563 RValue<Float4> Float4::operator=(const SwizzleMask1<Float4, T> &rhs)
Nicolas Capensd022e412016-09-26 13:30:14 -04002564 {
2565 return *this = rhs.operator RValue<Float4>();
2566 }
2567
2568 template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002569 RValue<Float4> Float4::operator=(const Swizzle4<Float4, T> &rhs)
Nicolas Capensd022e412016-09-26 13:30:14 -04002570 {
2571 return *this = rhs.operator RValue<Float4>();
2572 }
2573
2574 template<class T>
2575 Pointer<T>::Pointer(Argument<Pointer<T>> argument) : alignment(1)
2576 {
Nicolas Capens22479eb2016-09-28 22:34:26 -04002577 LValue<Pointer<T>>::storeValue(argument.value);
Nicolas Capensd022e412016-09-26 13:30:14 -04002578 }
2579
2580 template<class T>
Nicolas Capensd022e412016-09-26 13:30:14 -04002581 Pointer<T>::Pointer() : alignment(1)
2582 {
Nicolas Capens22479eb2016-09-28 22:34:26 -04002583 LValue<Pointer<T>>::storeValue(Nucleus::createNullPointer(T::getType()));
Nicolas Capensd022e412016-09-26 13:30:14 -04002584 }
2585
2586 template<class T>
2587 Pointer<T>::Pointer(RValue<Pointer<T>> rhs) : alignment(1)
2588 {
Nicolas Capens22479eb2016-09-28 22:34:26 -04002589 LValue<Pointer<T>>::storeValue(rhs.value);
Nicolas Capensd022e412016-09-26 13:30:14 -04002590 }
2591
2592 template<class T>
2593 Pointer<T>::Pointer(const Pointer<T> &rhs) : alignment(rhs.alignment)
2594 {
2595 Value *value = rhs.loadValue();
Nicolas Capens22479eb2016-09-28 22:34:26 -04002596 LValue<Pointer<T>>::storeValue(value);
Nicolas Capensd022e412016-09-26 13:30:14 -04002597 }
2598
2599 template<class T>
2600 Pointer<T>::Pointer(const Reference<Pointer<T>> &rhs) : alignment(rhs.getAlignment())
2601 {
2602 Value *value = rhs.loadValue();
Nicolas Capens22479eb2016-09-28 22:34:26 -04002603 LValue<Pointer<T>>::storeValue(value);
Nicolas Capensd022e412016-09-26 13:30:14 -04002604 }
2605
2606 template<class T>
Nicolas Capens96d4e092016-11-18 14:22:38 -05002607 RValue<Pointer<T>> Pointer<T>::operator=(RValue<Pointer<T>> rhs)
Nicolas Capensd022e412016-09-26 13:30:14 -04002608 {
Nicolas Capens22479eb2016-09-28 22:34:26 -04002609 LValue<Pointer<T>>::storeValue(rhs.value);
Nicolas Capensd022e412016-09-26 13:30:14 -04002610
2611 return rhs;
2612 }
2613
2614 template<class T>
Nicolas Capens96d4e092016-11-18 14:22:38 -05002615 RValue<Pointer<T>> Pointer<T>::operator=(const Pointer<T> &rhs)
Nicolas Capensd022e412016-09-26 13:30:14 -04002616 {
2617 Value *value = rhs.loadValue();
Nicolas Capens22479eb2016-09-28 22:34:26 -04002618 LValue<Pointer<T>>::storeValue(value);
Nicolas Capensd022e412016-09-26 13:30:14 -04002619
2620 return RValue<Pointer<T>>(value);
2621 }
2622
2623 template<class T>
Nicolas Capens96d4e092016-11-18 14:22:38 -05002624 RValue<Pointer<T>> Pointer<T>::operator=(const Reference<Pointer<T>> &rhs)
Nicolas Capensd022e412016-09-26 13:30:14 -04002625 {
2626 Value *value = rhs.loadValue();
Nicolas Capens22479eb2016-09-28 22:34:26 -04002627 LValue<Pointer<T>>::storeValue(value);
Nicolas Capensd022e412016-09-26 13:30:14 -04002628
2629 return RValue<Pointer<T>>(value);
2630 }
2631
2632 template<class T>
2633 Reference<T> Pointer<T>::operator*()
2634 {
Nicolas Capens22479eb2016-09-28 22:34:26 -04002635 return Reference<T>(LValue<Pointer<T>>::loadValue(), alignment);
Nicolas Capensd022e412016-09-26 13:30:14 -04002636 }
2637
2638 template<class T>
2639 Reference<T> Pointer<T>::operator[](int index)
2640 {
Nicolas Capensd294def2017-01-26 17:44:37 -08002641 Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), T::getType(), Nucleus::createConstantInt(index), false);
2642
2643 return Reference<T>(element, alignment);
2644 }
2645
2646 template<class T>
2647 Reference<T> Pointer<T>::operator[](unsigned int index)
2648 {
2649 Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), T::getType(), Nucleus::createConstantInt(index), true);
Nicolas Capensd022e412016-09-26 13:30:14 -04002650
2651 return Reference<T>(element, alignment);
2652 }
2653
2654 template<class T>
2655 Reference<T> Pointer<T>::operator[](RValue<Int> index)
2656 {
Nicolas Capensd294def2017-01-26 17:44:37 -08002657 Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), T::getType(), index.value, false);
2658
2659 return Reference<T>(element, alignment);
2660 }
2661
2662 template<class T>
2663 Reference<T> Pointer<T>::operator[](RValue<UInt> index)
2664 {
2665 Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), T::getType(), index.value, true);
Nicolas Capensd022e412016-09-26 13:30:14 -04002666
2667 return Reference<T>(element, alignment);
2668 }
2669
2670 template<class T>
2671 Type *Pointer<T>::getType()
2672 {
2673 return Nucleus::getPointerType(T::getType());
2674 }
2675
2676 template<class T, int S>
Nicolas Capens297d26e2016-11-18 12:52:17 -05002677 Array<T, S>::Array(int size) : LValue<T>(size)
Nicolas Capensd022e412016-09-26 13:30:14 -04002678 {
2679 }
2680
2681 template<class T, int S>
2682 Reference<T> Array<T, S>::operator[](int index)
2683 {
Nicolas Capensd294def2017-01-26 17:44:37 -08002684 Value *element = LValue<T>::getAddress(Nucleus::createConstantInt(index), false);
2685
2686 return Reference<T>(element);
2687 }
2688
2689 template<class T, int S>
2690 Reference<T> Array<T, S>::operator[](unsigned int index)
2691 {
2692 Value *element = LValue<T>::getAddress(Nucleus::createConstantInt(index), true);
Nicolas Capensd022e412016-09-26 13:30:14 -04002693
2694 return Reference<T>(element);
2695 }
2696
2697 template<class T, int S>
2698 Reference<T> Array<T, S>::operator[](RValue<Int> index)
2699 {
Nicolas Capensd294def2017-01-26 17:44:37 -08002700 Value *element = LValue<T>::getAddress(index.value, false);
2701
2702 return Reference<T>(element);
2703 }
2704
2705 template<class T, int S>
2706 Reference<T> Array<T, S>::operator[](RValue<UInt> index)
2707 {
2708 Value *element = LValue<T>::getAddress(index.value, true);
Nicolas Capensd022e412016-09-26 13:30:14 -04002709
2710 return Reference<T>(element);
2711 }
2712
2713// template<class T>
Nicolas Capens96d4e092016-11-18 14:22:38 -05002714// RValue<Array<T>> operator++(Array<T> &val, int)
Nicolas Capensd022e412016-09-26 13:30:14 -04002715// {
2716// // FIXME: Requires storing the address of the array
2717// }
2718
2719// template<class T>
Nicolas Capens96d4e092016-11-18 14:22:38 -05002720// const Array<T> &operator++(Array<T> &val)
Nicolas Capensd022e412016-09-26 13:30:14 -04002721// {
2722// // FIXME: Requires storing the address of the array
2723// }
2724
2725// template<class T>
Nicolas Capens96d4e092016-11-18 14:22:38 -05002726// RValue<Array<T>> operator--(Array<T> &val, int)
Nicolas Capensd022e412016-09-26 13:30:14 -04002727// {
2728// // FIXME: Requires storing the address of the array
2729// }
2730
2731// template<class T>
Nicolas Capens96d4e092016-11-18 14:22:38 -05002732// const Array<T> &operator--(Array<T> &val)
Nicolas Capensd022e412016-09-26 13:30:14 -04002733// {
2734// // FIXME: Requires storing the address of the array
2735// }
2736
2737 template<class T>
2738 RValue<T> IfThenElse(RValue<Bool> condition, RValue<T> ifTrue, RValue<T> ifFalse)
2739 {
2740 return RValue<T>(Nucleus::createSelect(condition.value, ifTrue.value, ifFalse.value));
2741 }
2742
2743 template<class T>
2744 RValue<T> IfThenElse(RValue<Bool> condition, const T &ifTrue, RValue<T> ifFalse)
2745 {
2746 Value *trueValue = ifTrue.loadValue();
2747
2748 return RValue<T>(Nucleus::createSelect(condition.value, trueValue, ifFalse.value));
2749 }
2750
2751 template<class T>
2752 RValue<T> IfThenElse(RValue<Bool> condition, RValue<T> ifTrue, const T &ifFalse)
2753 {
2754 Value *falseValue = ifFalse.loadValue();
2755
2756 return RValue<T>(Nucleus::createSelect(condition.value, ifTrue.value, falseValue));
2757 }
2758
2759 template<class T>
2760 RValue<T> IfThenElse(RValue<Bool> condition, const T &ifTrue, const T &ifFalse)
2761 {
2762 Value *trueValue = ifTrue.loadValue();
2763 Value *falseValue = ifFalse.loadValue();
2764
2765 return RValue<T>(Nucleus::createSelect(condition.value, trueValue, falseValue));
2766 }
2767
2768 template<class T>
2769 void Return(const Pointer<T> &ret)
2770 {
Nicolas Capense12780d2016-09-27 14:18:07 -04002771 Nucleus::createRet(Nucleus::createLoad(ret.address, Pointer<T>::getType()));
Nicolas Capensd022e412016-09-26 13:30:14 -04002772 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
Ben Claytonf3b57972019-03-15 09:56:47 +00002773 Nucleus::createUnreachable();
Nicolas Capensd022e412016-09-26 13:30:14 -04002774 }
2775
2776 template<class T>
2777 void Return(RValue<Pointer<T>> ret)
2778 {
2779 Nucleus::createRet(ret.value);
2780 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
Ben Claytonf3b57972019-03-15 09:56:47 +00002781 Nucleus::createUnreachable();
Nicolas Capensd022e412016-09-26 13:30:14 -04002782 }
2783
2784 template<typename Return, typename... Arguments>
2785 Function<Return(Arguments...)>::Function()
2786 {
2787 core = new Nucleus();
2788
2789 Type *types[] = {Arguments::getType()...};
2790 for(Type *type : types)
2791 {
2792 if(type != Void::getType())
2793 {
2794 arguments.push_back(type);
2795 }
2796 }
2797
2798 Nucleus::createFunction(Return::getType(), arguments);
2799 }
2800
2801 template<typename Return, typename... Arguments>
2802 Function<Return(Arguments...)>::~Function()
2803 {
2804 delete core;
2805 }
2806
2807 template<typename Return, typename... Arguments>
Chris Forbes878d4b02019-01-21 10:48:35 -08002808 Routine *Function<Return(Arguments...)>::operator()(const char *name, ...)
Nicolas Capensd022e412016-09-26 13:30:14 -04002809 {
Chris Forbes878d4b02019-01-21 10:48:35 -08002810 char fullName[1024 + 1];
Nicolas Capensd022e412016-09-26 13:30:14 -04002811
2812 va_list vararg;
2813 va_start(vararg, name);
Chris Forbes878d4b02019-01-21 10:48:35 -08002814 vsnprintf(fullName, 1024, name, vararg);
Nicolas Capensd022e412016-09-26 13:30:14 -04002815 va_end(vararg);
2816
2817 return core->acquireRoutine(fullName, true);
2818 }
2819
2820 template<class T, class S>
2821 RValue<T> ReinterpretCast(RValue<S> val)
2822 {
2823 return RValue<T>(Nucleus::createBitCast(val.value, T::getType()));
2824 }
2825
Nicolas Capens22479eb2016-09-28 22:34:26 -04002826 template<class T, class S>
2827 RValue<T> ReinterpretCast(const LValue<S> &var)
Nicolas Capensd022e412016-09-26 13:30:14 -04002828 {
2829 Value *val = var.loadValue();
2830
2831 return RValue<T>(Nucleus::createBitCast(val, T::getType()));
2832 }
2833
2834 template<class T, class S>
2835 RValue<T> ReinterpretCast(const Reference<S> &var)
2836 {
2837 return ReinterpretCast<T>(RValue<S>(var));
2838 }
2839
Nicolas Capens70dfff42016-10-27 10:20:28 -04002840 template<class T>
2841 RValue<T> As(Value *val)
2842 {
2843 return RValue<T>(Nucleus::createBitCast(val, T::getType()));
2844 }
2845
Nicolas Capensd022e412016-09-26 13:30:14 -04002846 template<class T, class S>
2847 RValue<T> As(RValue<S> val)
2848 {
2849 return ReinterpretCast<T>(val);
2850 }
2851
Nicolas Capens22479eb2016-09-28 22:34:26 -04002852 template<class T, class S>
2853 RValue<T> As(const LValue<S> &var)
Nicolas Capensd022e412016-09-26 13:30:14 -04002854 {
2855 return ReinterpretCast<T>(var);
2856 }
2857
2858 template<class T, class S>
2859 RValue<T> As(const Reference<S> &val)
2860 {
2861 return ReinterpretCast<T>(val);
2862 }
2863
Ben Clayton1bc7ee92019-02-14 18:43:22 +00002864#ifdef ENABLE_RR_PRINT
2865 // PrintValue holds the printf format and value(s) for a single argument
2866 // to Print(). A single argument can be expanded into multiple printf
2867 // values - for example a Float4 will expand to "%f %f %f %f" and four
2868 // scalar values.
2869 // The PrintValue constructor accepts the following:
2870 // * Reactor LValues, RValues, Pointers.
2871 // * Standard Plain-Old-Value types (int, float, bool, etc)
2872 // * Custom types that specialize the PrintValue::Ty template struct.
2873 // * Static arrays in the form T[N] where T can be any of the above.
2874 class PrintValue
2875 {
2876 // Ty is a template that can be specialized for printing type T.
2877 // Each specialization must expose:
2878 // * A 'static constexpr const char* fmt' field that provides the
2879 // printf format specifier.
2880 // * A 'static std::vector<rr::Value*> val(const T& v)' method that
2881 // returns all the printf format values.
2882 template <typename T> struct Ty
2883 {
2884 // static constexpr const char* fmt;
2885 // static std::vector<rr::Value*> val(const T& v)
2886 };
2887
2888 // returns the printf value(s) for the given LValue.
2889 template <typename T>
2890 static std::vector<Value*> val(const LValue<T>& v) { return val(RValue<T>(v.loadValue())); };
2891
2892 // returns the printf value(s) for the given RValue.
2893 template <typename T>
2894 static std::vector<Value*> val(const RValue<T>& v) { return Ty<T>::val(v); };
2895
2896 // returns the printf value from for the given type with a
2897 // PrintValue::Ty<T> specialization.
2898 template <typename T>
2899 static std::vector<Value*> val(const T& v) { return Ty<T>::val(v); };
2900
2901 // returns the printf values for all the values in the given array.
2902 template <typename T>
2903 static std::vector<Value*> val(const T* list, int count) {
2904 std::vector<Value*> values;
2905 values.reserve(count);
2906 for (int i = 0; i < count; i++)
2907 {
2908 auto v = val(list[i]);
2909 values.insert(values.end(), v.begin(), v.end());
2910 }
2911 return values;
2912 };
2913
2914 // fmt returns a comma-delimited list of the string el repeated count
2915 // times enclosed in square brackets.
2916 static std::string fmt(const char* el, int count)
2917 {
2918 std::string out = "[";
2919 for (int i = 0; i < count; i++)
2920 {
2921 if (i > 0) { out += ", "; }
2922 out += el;
2923 }
2924 return out + "]";
2925 }
2926
2927 public:
2928 const std::string format;
2929 const std::vector<Value*> values;
2930
2931 // Constructs a PrintValue for the given value.
2932 template <typename T>
2933 PrintValue(const T& v) : format(Ty<T>::fmt), values(val(v)) {}
2934
2935 // Constructs a PrintValue for the given static array.
2936 template <typename T, int N>
2937 PrintValue(const T (&v)[N]) : format(fmt(Ty<T>::fmt, N)), values(val(&v[0], N)) {}
2938
2939 // Constructs a PrintValue for the given array starting at arr of length
2940 // len.
2941 template <typename T>
2942 PrintValue(const T* arr, int len) : format(fmt(Ty<T>::fmt, len)), values(val(arr, len)) {}
2943
2944
2945 // PrintValue constructors for plain-old-data values.
2946 PrintValue(bool v) : format(v ? "true" : "false") {}
2947 PrintValue(int8_t v) : format(std::to_string(v)) {}
2948 PrintValue(uint8_t v) : format(std::to_string(v)) {}
2949 PrintValue(int16_t v) : format(std::to_string(v)) {}
2950 PrintValue(uint16_t v) : format(std::to_string(v)) {}
2951 PrintValue(int32_t v) : format(std::to_string(v)) {}
2952 PrintValue(uint32_t v) : format(std::to_string(v)) {}
2953 PrintValue(int64_t v) : format(std::to_string(v)) {}
2954 PrintValue(uint64_t v) : format(std::to_string(v)) {}
2955 PrintValue(float v) : format(std::to_string(v)) {}
2956 PrintValue(double v) : format(std::to_string(v)) {}
2957 PrintValue(const char* v) : format(v) {}
2958 PrintValue(const std::string& v) : format(v) {}
2959
2960 // vals is a helper to build composite value lists.
2961 // vals returns the full, sequential list of printf argument values used
2962 // to print all the provided variadic values.
2963 // vals() is intended to be used by implementations of
2964 // PrintValue::Ty<>::vals() to help declare aggregate types.
2965 // For example, if you were declaring a PrintValue::Ty<> specialization
2966 // for a custom Mat4x4 matrix formed from four Vector4 values, you'd
2967 // write:
2968 //
2969 // namespace rr
2970 // {
2971 // template <> struct PrintValue::Ty<Mat4x4>
2972 // {
2973 // static constexpr const char* fmt =
2974 // "[a: <%f, %f, %f, %f>,"
2975 // " b: <%f, %f, %f, %f>,"
2976 // " c: <%f, %f, %f, %f>,"
2977 // " d: <%f, %f, %f, %f>]";
2978 // static std::vector<rr::Value*> val(const Mat4x4& v)
2979 // {
2980 // return PrintValue::vals(v.a, v.b, v.c, v.d);
2981 // }
2982 // };
2983 // }
2984 template<typename ... ARGS>
2985 static std::vector<Value*> vals(ARGS... v)
2986 {
2987 std::vector< std::vector<Value*> > lists = {val(v)...};
2988 std::vector<Value*> joined;
2989 for (const auto& list : lists)
2990 {
2991 joined.insert(joined.end(), list.begin(), list.end());
2992 }
2993 return joined;
2994 }
2995 };
2996
2997 // PrintValue::Ty<T> specializations for standard Reactor types.
Ben Claytonca56e8b2019-03-12 20:05:43 +00002998 template <> struct PrintValue::Ty<Bool>
2999 {
3000 static constexpr const char* fmt = "%d";
3001 static std::vector<Value*> val(const RValue<Bool>& v) { return {v.value}; }
3002 };
Ben Clayton1bc7ee92019-02-14 18:43:22 +00003003 template <> struct PrintValue::Ty<Byte>
3004 {
3005 static constexpr const char* fmt = "%d";
3006 static std::vector<Value*> val(const RValue<Byte>& v) { return {v.value}; }
3007 };
3008 template <> struct PrintValue::Ty<Byte4>
3009 {
3010 static constexpr const char* fmt = "[%d, %d, %d, %d]";
3011 static std::vector<Value*> val(const RValue<Byte4>& v);
3012 };
3013 template <> struct PrintValue::Ty<Int>
3014 {
3015 static constexpr const char* fmt = "%d";
3016 static std::vector<Value*> val(const RValue<Int>& v) { return {v.value}; }
3017 };
3018 template <> struct PrintValue::Ty<Int4>
3019 {
3020 static constexpr const char* fmt = "[%d, %d, %d, %d]";
3021 static std::vector<Value*> val(const RValue<Int4>& v);
3022 };
3023 template <> struct PrintValue::Ty<UInt>
3024 {
3025 static constexpr const char* fmt = "%u";
3026 static std::vector<Value*> val(const RValue<UInt>& v) { return {v.value}; }
3027 };
3028 template <> struct PrintValue::Ty<UInt4>
3029 {
3030 static constexpr const char* fmt = "[%u, %u, %u, %u]";
3031 static std::vector<Value*> val(const RValue<UInt4>& v);
3032 };
3033 template <> struct PrintValue::Ty<Short>
3034 {
3035 static constexpr const char* fmt = "%d";
3036 static std::vector<Value*> val(const RValue<Short>& v) { return {v.value}; }
3037 };
3038 template <> struct PrintValue::Ty<Short4>
3039 {
3040 static constexpr const char* fmt = "[%d, %d, %d, %d]";
3041 static std::vector<Value*> val(const RValue<Short4>& v);
3042 };
3043 template <> struct PrintValue::Ty<UShort>
3044 {
3045 static constexpr const char* fmt = "%u";
3046 static std::vector<Value*> val(const RValue<UShort>& v) { return {v.value}; }
3047 };
3048 template <> struct PrintValue::Ty<UShort4>
3049 {
3050 static constexpr const char* fmt = "[%u, %u, %u, %u]";
3051 static std::vector<Value*> val(const RValue<UShort4>& v);
3052 };
3053 template <> struct PrintValue::Ty<Float>
3054 {
3055 static constexpr const char* fmt = "[%f]";
3056 static std::vector<Value*> val(const RValue<Float>& v);
3057 };
3058 template <> struct PrintValue::Ty<Float4>
3059 {
3060 static constexpr const char* fmt = "[%f, %f, %f, %f]";
3061 static std::vector<Value*> val(const RValue<Float4>& v);
3062 };
3063 template <typename T> struct PrintValue::Ty< Pointer<T> >
3064 {
3065 static constexpr const char* fmt = "%p";
3066 static std::vector<Value*> val(const RValue<Pointer<T>>& v) { return {v.value}; }
3067 };
3068 template <typename T> struct PrintValue::Ty< Reference<T> >
3069 {
3070 static constexpr const char* fmt = PrintValue::Ty<T>::fmt;
3071 static std::vector<Value*> val(const Reference<T>& v) { return PrintValue::Ty<T>::val(v); }
3072 };
3073 template <typename T> struct PrintValue::Ty< RValue<T> >
3074 {
3075 static constexpr const char* fmt = PrintValue::Ty<T>::fmt;
3076 static std::vector<Value*> val(const RValue<T>& v) { return PrintValue::Ty<T>::val(v); }
3077 };
3078
3079 // Printv emits a call to printf() using the function, file and line,
3080 // message and optional values.
3081 // See Printv below.
3082 void Printv(const char* function, const char* file, int line, const char* msg, std::initializer_list<PrintValue> vals);
3083
3084 // Printv emits a call to printf() using the provided message and optional
3085 // values.
3086 // Printf replaces any bracketed indices in the message with string
3087 // representations of the corresponding value in vals.
3088 // For example:
3089 // Printv("{0} and {1}", "red", "green");
3090 // Would print the string:
3091 // "red and green"
3092 // Arguments can be indexed in any order.
3093 // Invalid indices are not substituted.
3094 inline void Printv(const char* msg, std::initializer_list<PrintValue> vals)
3095 {
3096 Printv(nullptr, nullptr, 0, msg, vals);
3097 }
3098
3099 // Print is a wrapper over Printv that wraps the variadic arguments into an
3100 // initializer_list before calling Printv.
3101 template <typename ... ARGS>
3102 void Print(const char* msg, const ARGS& ... vals) { Printv(msg, {vals...}); }
3103
3104 // Print is a wrapper over Printv that wraps the variadic arguments into an
3105 // initializer_list before calling Printv.
3106 template <typename ... ARGS>
3107 void Print(const char* function, const char* file, int line, const char* msg, const ARGS& ... vals)
3108 {
3109 Printv(function, file, line, msg, {vals...});
3110 }
3111
3112 // RR_LOG is a macro that calls Print(), automatically populating the
3113 // function, file and line parameters and appending a newline to the string.
3114 //
3115 // RR_LOG() is intended to be used for debugging JIT compiled code, and is
3116 // not intended for production use.
3117 #define RR_LOG(msg, ...) Print(__PRETTY_FUNCTION__, __FILE__, __LINE__, msg "\n", ##__VA_ARGS__)
3118
3119 // Macro magic to perform variadic dispatch.
3120 // See: https://renenyffenegger.ch/notes/development/languages/C-C-plus-plus/preprocessor/macros/__VA_ARGS__/count-arguments
3121 // Note, this doesn't attempt to use the ##__VA_ARGS__ trick to handle 0
3122 // args as this appears to still be broken on certain compilers.
3123 #define RR_GET_NTH_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, N, ...) N
3124 #define RR_COUNT_ARGUMENTS(...) RR_GET_NTH_ARG(__VA_ARGS__, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
Ben Clayton60a3d6f2019-02-26 17:24:46 +00003125 static_assert(1 == RR_COUNT_ARGUMENTS(a), "RR_COUNT_ARGUMENTS broken"); // Sanity checks.
3126 static_assert(2 == RR_COUNT_ARGUMENTS(a, b), "RR_COUNT_ARGUMENTS broken");
3127 static_assert(3 == RR_COUNT_ARGUMENTS(a, b, c), "RR_COUNT_ARGUMENTS broken");
Ben Clayton1bc7ee92019-02-14 18:43:22 +00003128
3129 // RR_WATCH_FMT(...) resolves to a string literal that lists all the
3130 // arguments by name. This string can be passed to LOG() to print each of
3131 // the arguments with their name and value.
3132 //
3133 // RR_WATCH_FMT(...) uses the RR_COUNT_ARGUMENTS helper macro to delegate to a
3134 // corresponding RR_WATCH_FMT_n specialization macro below.
3135 #define RR_WATCH_CONCAT(a, b) a ## b
3136 #define RR_WATCH_CONCAT2(a, b) RR_WATCH_CONCAT(a, b)
3137 #define RR_WATCH_FMT(...) RR_WATCH_CONCAT2(RR_WATCH_FMT_, RR_COUNT_ARGUMENTS(__VA_ARGS__))(__VA_ARGS__)
3138 #define RR_WATCH_FMT_1(_1) "\n " #_1 ": {0}"
Ben Clayton644a3502019-03-13 11:24:46 +00003139 #define RR_WATCH_FMT_2(_1, _2) RR_WATCH_FMT_1(_1) "\n " #_2 ": {1}"
3140 #define RR_WATCH_FMT_3(_1, _2, _3) RR_WATCH_FMT_2(_1, _2) "\n " #_3 ": {2}"
3141 #define RR_WATCH_FMT_4(_1, _2, _3, _4) RR_WATCH_FMT_3(_1, _2, _3) "\n " #_4 ": {3}"
3142 #define RR_WATCH_FMT_5(_1, _2, _3, _4, _5) RR_WATCH_FMT_4(_1, _2, _3, _4) "\n " #_5 ": {4}"
3143 #define RR_WATCH_FMT_6(_1, _2, _3, _4, _5, _6) RR_WATCH_FMT_5(_1, _2, _3, _4, _5) "\n " #_6 ": {5}"
3144 #define RR_WATCH_FMT_7(_1, _2, _3, _4, _5, _6, _7) RR_WATCH_FMT_6(_1, _2, _3, _4, _5, _6) "\n " #_7 ": {6}"
3145 #define RR_WATCH_FMT_8(_1, _2, _3, _4, _5, _6, _7, _8) RR_WATCH_FMT_7(_1, _2, _3, _4, _5, _6, _7) "\n " #_8 ": {7}"
3146 #define RR_WATCH_FMT_9(_1, _2, _3, _4, _5, _6, _7, _8, _9) RR_WATCH_FMT_8(_1, _2, _3, _4, _5, _6, _7, _8) "\n " #_9 ": {8}"
3147 #define RR_WATCH_FMT_10(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) RR_WATCH_FMT_9(_1, _2, _3, _4, _5, _6, _7, _8, _9) "\n " #_10 ": {9}"
3148 #define RR_WATCH_FMT_11(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) RR_WATCH_FMT_10(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) "\n " #_11 ": {10}"
3149 #define RR_WATCH_FMT_12(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) RR_WATCH_FMT_11(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) "\n " #_12 ": {11}"
Ben Clayton1bc7ee92019-02-14 18:43:22 +00003150
3151 // RR_WATCH() is a helper that prints the name and value of all the supplied
3152 // arguments.
3153 // For example, if you had the Int and bool variables 'foo' and 'bar' that
3154 // you want to print, you can simply write:
3155 // RR_WATCH(foo, bar)
3156 // When this JIT compiled code is executed, it will print the string
3157 // "foo: 1, bar: true" to stdout.
3158 //
3159 // RR_WATCH() is intended to be used for debugging JIT compiled code, and
3160 // is not intended for production use.
3161 #define RR_WATCH(...) RR_LOG(RR_WATCH_FMT(__VA_ARGS__), __VA_ARGS__)
3162#endif // ENABLE_RR_PRINT
3163
Nicolas Capens37ed9082016-11-16 17:40:48 -05003164 class ForData
3165 {
3166 public:
3167 ForData(bool init) : loopOnce(init)
3168 {
3169 }
3170
3171 operator bool()
3172 {
3173 return loopOnce;
3174 }
3175
3176 bool operator=(bool value)
3177 {
3178 return loopOnce = value;
3179 }
3180
3181 bool setup()
3182 {
3183 if(Nucleus::getInsertBlock() != endBB)
3184 {
3185 testBB = Nucleus::createBasicBlock();
3186
3187 Nucleus::createBr(testBB);
3188 Nucleus::setInsertBlock(testBB);
3189
3190 return true;
3191 }
3192
3193 return false;
3194 }
3195
3196 bool test(RValue<Bool> cmp)
3197 {
3198 BasicBlock *bodyBB = Nucleus::createBasicBlock();
3199 endBB = Nucleus::createBasicBlock();
3200
3201 Nucleus::createCondBr(cmp.value, bodyBB, endBB);
3202 Nucleus::setInsertBlock(bodyBB);
3203
3204 return true;
3205 }
3206
3207 void end()
3208 {
3209 Nucleus::createBr(testBB);
3210 Nucleus::setInsertBlock(endBB);
3211 }
3212
3213 private:
3214 BasicBlock *testBB = nullptr;
3215 BasicBlock *endBB = nullptr;
3216 bool loopOnce = true;
3217 };
3218
3219 class IfElseData
3220 {
3221 public:
3222 IfElseData(RValue<Bool> cmp) : iteration(0)
3223 {
3224 condition = cmp.value;
3225
3226 beginBB = Nucleus::getInsertBlock();
3227 trueBB = Nucleus::createBasicBlock();
3228 falseBB = nullptr;
3229 endBB = Nucleus::createBasicBlock();
3230
3231 Nucleus::setInsertBlock(trueBB);
3232 }
3233
3234 ~IfElseData()
3235 {
3236 Nucleus::createBr(endBB);
3237
3238 Nucleus::setInsertBlock(beginBB);
3239 Nucleus::createCondBr(condition, trueBB, falseBB ? falseBB : endBB);
3240
3241 Nucleus::setInsertBlock(endBB);
3242 }
3243
3244 operator int()
3245 {
3246 return iteration;
3247 }
3248
3249 IfElseData &operator++()
3250 {
3251 ++iteration;
3252
3253 return *this;
3254 }
3255
3256 void elseClause()
3257 {
3258 Nucleus::createBr(endBB);
3259
3260 falseBB = Nucleus::createBasicBlock();
3261 Nucleus::setInsertBlock(falseBB);
3262 }
3263
3264 private:
3265 Value *condition;
3266 BasicBlock *beginBB;
3267 BasicBlock *trueBB;
3268 BasicBlock *falseBB;
3269 BasicBlock *endBB;
3270 int iteration;
3271 };
3272
Nicolas Capensb0eb3772016-10-24 17:49:13 -04003273 #define For(init, cond, inc) \
Nicolas Capens8884a232016-11-16 15:03:18 -05003274 for(ForData for__ = true; for__; for__ = false) \
3275 for(init; for__.setup() && for__.test(cond); inc, for__.end())
Nicolas Capens0bac2852016-05-07 06:09:58 -04003276
Nicolas Capensb0eb3772016-10-24 17:49:13 -04003277 #define While(cond) For((void)0, cond, (void)0)
Nicolas Capens0bac2852016-05-07 06:09:58 -04003278
Nicolas Capensb0eb3772016-10-24 17:49:13 -04003279 #define Do \
3280 { \
3281 BasicBlock *body__ = Nucleus::createBasicBlock(); \
3282 Nucleus::createBr(body__); \
3283 Nucleus::setInsertBlock(body__);
3284
3285 #define Until(cond) \
3286 BasicBlock *end__ = Nucleus::createBasicBlock(); \
3287 Nucleus::createCondBr((cond).value, end__, body__); \
3288 Nucleus::setInsertBlock(end__); \
Nicolas Capens0bac2852016-05-07 06:09:58 -04003289 }
3290
Nicolas Capens37ed9082016-11-16 17:40:48 -05003291 enum {IF_BLOCK__, ELSE_CLAUSE__, ELSE_BLOCK__, IFELSE_NUM__};
Nicolas Capens0bac2852016-05-07 06:09:58 -04003292
Nicolas Capens37ed9082016-11-16 17:40:48 -05003293 #define If(cond) \
3294 for(IfElseData ifElse__(cond); ifElse__ < IFELSE_NUM__; ++ifElse__) \
3295 if(ifElse__ == IF_BLOCK__)
3296
3297 #define Else \
3298 else if(ifElse__ == ELSE_CLAUSE__) \
3299 { \
3300 ifElse__.elseClause(); \
3301 } \
3302 else // ELSE_BLOCK__
Nicolas Capensd022e412016-09-26 13:30:14 -04003303}
3304
Nicolas Capens48461502018-08-06 14:20:45 -04003305#endif // rr_Reactor_hpp