blob: e6f3ff2fd9f1749f4e55e62b1d96ed1f63621e56 [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>
Ben Clayton169872e2019-02-27 23:58:35 +000026#include <tuple>
Nicolas Capens0192d152019-03-27 14:46:07 -040027#include <unordered_set>
Ben Clayton1bc7ee92019-02-14 18:43:22 +000028
Chris Forbesc2968062019-03-19 16:48:03 -070029#undef Bool // b/127920555
Nicolas Capens3bbc5e12016-09-27 10:49:52 -040030
Ben Clayton1bc7ee92019-02-14 18:43:22 +000031#if !defined(NDEBUG) && (REACTOR_LLVM_VERSION >= 7)
32#define ENABLE_RR_PRINT 1 // Enables RR_PRINT(), RR_WATCH()
33#endif // !defined(NDEBUG) && (REACTOR_LLVM_VERSION >= 7)
34
Nicolas Capens48461502018-08-06 14:20:45 -040035namespace rr
Nicolas Capens0bac2852016-05-07 06:09:58 -040036{
Ben Claytonc7904162019-04-17 17:35:48 -040037 struct Capabilities
38 {
39 bool CallSupported; // Support for rr::Call()
40 };
41 extern const Capabilities Caps;
42
Nicolas Capenseb253d02016-11-18 14:40:40 -050043 class Bool;
Nicolas Capensd022e412016-09-26 13:30:14 -040044 class Byte;
45 class SByte;
46 class Byte4;
47 class SByte4;
48 class Byte8;
49 class SByte8;
50 class Byte16;
51 class SByte16;
52 class Short;
53 class UShort;
Nicolas Capens16b5f152016-10-13 13:39:01 -040054 class Short2;
55 class UShort2;
Nicolas Capensd022e412016-09-26 13:30:14 -040056 class Short4;
57 class UShort4;
58 class Short8;
59 class UShort8;
60 class Int;
61 class UInt;
62 class Int2;
63 class UInt2;
64 class Int4;
65 class UInt4;
66 class Long;
Alexis Hetu734e2572018-12-20 14:00:49 -050067 class Half;
Nicolas Capensd022e412016-09-26 13:30:14 -040068 class Float;
69 class Float2;
70 class Float4;
71
72 class Void
73 {
74 public:
75 static Type *getType();
76
77 static bool isVoid()
78 {
79 return true;
80 }
Nicolas Capensd022e412016-09-26 13:30:14 -040081 };
82
83 template<class T>
84 class RValue;
85
86 template<class T>
87 class Pointer;
88
Nicolas Capens297d26e2016-11-18 12:52:17 -050089 class Variable
90 {
Nicolas Capens0192d152019-03-27 14:46:07 -040091 friend class Nucleus;
Ben Clayton1bc7ee92019-02-14 18:43:22 +000092 friend class PrintValue;
Nicolas Capens5da8d8d2019-03-27 14:45:34 -040093
Nicolas Capens0192d152019-03-27 14:46:07 -040094 Variable() = delete;
Nicolas Capens5da8d8d2019-03-27 14:45:34 -040095 Variable &operator=(const Variable&) = delete;
96
97 public:
Nicolas Capens0192d152019-03-27 14:46:07 -040098 void materialize() const;
99
100 Value *loadValue() const;
101 Value *storeValue(Value *value) const;
102
103 Value *getBaseAddress() const;
104 Value *getElementPointer(Value *index, bool unsignedIndex) const;
Nicolas Capens5da8d8d2019-03-27 14:45:34 -0400105
106 protected:
Nicolas Capens0192d152019-03-27 14:46:07 -0400107 Variable(Type *type, int arraySize);
108 Variable(const Variable&) = default;
109
110 ~Variable();
111
112 private:
113 static void materializeAll();
114 static void killUnmaterialized();
115
116 static std::unordered_set<Variable*> unmaterializedVariables;
117
118 Type *const type;
119 const int arraySize;
120 mutable Value *rvalue = nullptr;
121 mutable Value *address = nullptr;
Nicolas Capens297d26e2016-11-18 12:52:17 -0500122 };
123
Nicolas Capens22479eb2016-09-28 22:34:26 -0400124 template<class T>
Nicolas Capens297d26e2016-11-18 12:52:17 -0500125 class LValue : public Variable
Nicolas Capensd022e412016-09-26 13:30:14 -0400126 {
127 public:
Nicolas Capens22479eb2016-09-28 22:34:26 -0400128 LValue(int arraySize = 0);
Nicolas Capensd022e412016-09-26 13:30:14 -0400129
Nicolas Capens297d26e2016-11-18 12:52:17 -0500130 RValue<Pointer<T>> operator&();
131
Nicolas Capensd022e412016-09-26 13:30:14 -0400132 static bool isVoid()
133 {
134 return false;
135 }
Nicolas Capensd022e412016-09-26 13:30:14 -0400136 };
137
138 template<class T>
139 class Reference
140 {
141 public:
142 explicit Reference(Value *pointer, int alignment = 1);
143
144 RValue<T> operator=(RValue<T> rhs) const;
145 RValue<T> operator=(const Reference<T> &ref) const;
146
147 RValue<T> operator+=(RValue<T> rhs) const;
148
Ben Claytonec255732019-02-27 13:51:22 +0000149 RValue<Pointer<T>> operator&() const { return RValue<Pointer<T>>(address); }
150
Nicolas Capensd022e412016-09-26 13:30:14 -0400151 Value *loadValue() const;
152 int getAlignment() const;
153
154 private:
155 Value *address;
156
157 const int alignment;
158 };
159
160 template<class T>
Ben Clayton35e90e22019-03-15 10:06:06 +0000161 struct BoolLiteral
Nicolas Capensd022e412016-09-26 13:30:14 -0400162 {
163 struct type;
164 };
165
Nicolas Capenseb253d02016-11-18 14:40:40 -0500166 template<>
Ben Clayton35e90e22019-03-15 10:06:06 +0000167 struct BoolLiteral<Bool>
Nicolas Capenseb253d02016-11-18 14:40:40 -0500168 {
169 typedef bool type;
170 };
171
Ben Clayton35e90e22019-03-15 10:06:06 +0000172 template<class T>
173 struct IntLiteral
174 {
175 struct type;
176 };
177
Nicolas Capenseb253d02016-11-18 14:40:40 -0500178 template<>
179 struct IntLiteral<Int>
Nicolas Capensd022e412016-09-26 13:30:14 -0400180 {
181 typedef int type;
182 };
183
Nicolas Capenseb253d02016-11-18 14:40:40 -0500184 template<>
185 struct IntLiteral<UInt>
Nicolas Capensd022e412016-09-26 13:30:14 -0400186 {
187 typedef unsigned int type;
188 };
189
Nicolas Capenseb253d02016-11-18 14:40:40 -0500190 template<>
191 struct IntLiteral<Long>
Nicolas Capensd022e412016-09-26 13:30:14 -0400192 {
193 typedef int64_t type;
194 };
195
196 template<class T>
197 struct FloatLiteral
198 {
199 struct type;
200 };
201
Nicolas Capenseb253d02016-11-18 14:40:40 -0500202 template<>
203 struct FloatLiteral<Float>
Nicolas Capensd022e412016-09-26 13:30:14 -0400204 {
205 typedef float type;
206 };
207
208 template<class T>
209 class RValue
210 {
211 public:
212 explicit RValue(Value *rvalue);
213
214 RValue(const T &lvalue);
Ben Clayton35e90e22019-03-15 10:06:06 +0000215 RValue(typename BoolLiteral<T>::type i);
Nicolas Capensd022e412016-09-26 13:30:14 -0400216 RValue(typename IntLiteral<T>::type i);
217 RValue(typename FloatLiteral<T>::type f);
218 RValue(const Reference<T> &rhs);
219
220 RValue<T> &operator=(const RValue<T>&) = delete;
221
222 Value *value; // FIXME: Make private
223 };
224
225 template<typename T>
226 struct Argument
227 {
228 explicit Argument(Value *value) : value(value) {}
229
230 Value *value;
231 };
232
Nicolas Capens297d26e2016-11-18 12:52:17 -0500233 class Bool : public LValue<Bool>
Nicolas Capensd022e412016-09-26 13:30:14 -0400234 {
235 public:
236 Bool(Argument<Bool> argument);
237
Nicolas Capensa25311a2017-01-16 17:19:00 -0500238 Bool() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -0400239 Bool(bool x);
240 Bool(RValue<Bool> rhs);
241 Bool(const Bool &rhs);
242 Bool(const Reference<Bool> &rhs);
243
Nicolas Capens96d4e092016-11-18 14:22:38 -0500244 // RValue<Bool> operator=(bool rhs); // FIXME: Implement
245 RValue<Bool> operator=(RValue<Bool> rhs);
246 RValue<Bool> operator=(const Bool &rhs);
247 RValue<Bool> operator=(const Reference<Bool> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400248
249 static Type *getType();
250 };
251
252 RValue<Bool> operator!(RValue<Bool> val);
253 RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs);
254 RValue<Bool> operator||(RValue<Bool> lhs, RValue<Bool> rhs);
Ben Claytonf3b57972019-03-15 09:56:47 +0000255 RValue<Bool> operator!=(RValue<Bool> lhs, RValue<Bool> rhs);
256 RValue<Bool> operator==(RValue<Bool> lhs, RValue<Bool> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400257
Nicolas Capens297d26e2016-11-18 12:52:17 -0500258 class Byte : public LValue<Byte>
Nicolas Capensd022e412016-09-26 13:30:14 -0400259 {
260 public:
261 Byte(Argument<Byte> argument);
262
263 explicit Byte(RValue<Int> cast);
264 explicit Byte(RValue<UInt> cast);
265 explicit Byte(RValue<UShort> cast);
266
Nicolas Capensa25311a2017-01-16 17:19:00 -0500267 Byte() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -0400268 Byte(int x);
269 Byte(unsigned char x);
270 Byte(RValue<Byte> rhs);
271 Byte(const Byte &rhs);
272 Byte(const Reference<Byte> &rhs);
273
Nicolas Capens96d4e092016-11-18 14:22:38 -0500274 // RValue<Byte> operator=(unsigned char rhs); // FIXME: Implement
275 RValue<Byte> operator=(RValue<Byte> rhs);
276 RValue<Byte> operator=(const Byte &rhs);
277 RValue<Byte> operator=(const Reference<Byte> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400278
279 static Type *getType();
280 };
281
282 RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs);
283 RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs);
284 RValue<Byte> operator*(RValue<Byte> lhs, RValue<Byte> rhs);
285 RValue<Byte> operator/(RValue<Byte> lhs, RValue<Byte> rhs);
286 RValue<Byte> operator%(RValue<Byte> lhs, RValue<Byte> rhs);
287 RValue<Byte> operator&(RValue<Byte> lhs, RValue<Byte> rhs);
288 RValue<Byte> operator|(RValue<Byte> lhs, RValue<Byte> rhs);
289 RValue<Byte> operator^(RValue<Byte> lhs, RValue<Byte> rhs);
290 RValue<Byte> operator<<(RValue<Byte> lhs, RValue<Byte> rhs);
291 RValue<Byte> operator>>(RValue<Byte> lhs, RValue<Byte> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500292 RValue<Byte> operator+=(Byte &lhs, RValue<Byte> rhs);
293 RValue<Byte> operator-=(Byte &lhs, RValue<Byte> rhs);
294 RValue<Byte> operator*=(Byte &lhs, RValue<Byte> rhs);
295 RValue<Byte> operator/=(Byte &lhs, RValue<Byte> rhs);
296 RValue<Byte> operator%=(Byte &lhs, RValue<Byte> rhs);
297 RValue<Byte> operator&=(Byte &lhs, RValue<Byte> rhs);
298 RValue<Byte> operator|=(Byte &lhs, RValue<Byte> rhs);
299 RValue<Byte> operator^=(Byte &lhs, RValue<Byte> rhs);
300 RValue<Byte> operator<<=(Byte &lhs, RValue<Byte> rhs);
301 RValue<Byte> operator>>=(Byte &lhs, RValue<Byte> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400302 RValue<Byte> operator+(RValue<Byte> val);
303 RValue<Byte> operator-(RValue<Byte> val);
304 RValue<Byte> operator~(RValue<Byte> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500305 RValue<Byte> operator++(Byte &val, int); // Post-increment
306 const Byte &operator++(Byte &val); // Pre-increment
307 RValue<Byte> operator--(Byte &val, int); // Post-decrement
308 const Byte &operator--(Byte &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400309 RValue<Bool> operator<(RValue<Byte> lhs, RValue<Byte> rhs);
310 RValue<Bool> operator<=(RValue<Byte> lhs, RValue<Byte> rhs);
311 RValue<Bool> operator>(RValue<Byte> lhs, RValue<Byte> rhs);
312 RValue<Bool> operator>=(RValue<Byte> lhs, RValue<Byte> rhs);
313 RValue<Bool> operator!=(RValue<Byte> lhs, RValue<Byte> rhs);
314 RValue<Bool> operator==(RValue<Byte> lhs, RValue<Byte> rhs);
315
Nicolas Capens297d26e2016-11-18 12:52:17 -0500316 class SByte : public LValue<SByte>
Nicolas Capensd022e412016-09-26 13:30:14 -0400317 {
318 public:
319 SByte(Argument<SByte> argument);
320
321 explicit SByte(RValue<Int> cast);
322 explicit SByte(RValue<Short> cast);
323
Nicolas Capensa25311a2017-01-16 17:19:00 -0500324 SByte() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -0400325 SByte(signed char x);
326 SByte(RValue<SByte> rhs);
327 SByte(const SByte &rhs);
328 SByte(const Reference<SByte> &rhs);
329
Nicolas Capens96d4e092016-11-18 14:22:38 -0500330 // RValue<SByte> operator=(signed char rhs); // FIXME: Implement
331 RValue<SByte> operator=(RValue<SByte> rhs);
332 RValue<SByte> operator=(const SByte &rhs);
333 RValue<SByte> operator=(const Reference<SByte> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400334
335 static Type *getType();
336 };
337
338 RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs);
339 RValue<SByte> operator-(RValue<SByte> lhs, RValue<SByte> rhs);
340 RValue<SByte> operator*(RValue<SByte> lhs, RValue<SByte> rhs);
341 RValue<SByte> operator/(RValue<SByte> lhs, RValue<SByte> rhs);
342 RValue<SByte> operator%(RValue<SByte> lhs, RValue<SByte> rhs);
343 RValue<SByte> operator&(RValue<SByte> lhs, RValue<SByte> rhs);
344 RValue<SByte> operator|(RValue<SByte> lhs, RValue<SByte> rhs);
345 RValue<SByte> operator^(RValue<SByte> lhs, RValue<SByte> rhs);
346 RValue<SByte> operator<<(RValue<SByte> lhs, RValue<SByte> rhs);
347 RValue<SByte> operator>>(RValue<SByte> lhs, RValue<SByte> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500348 RValue<SByte> operator+=(SByte &lhs, RValue<SByte> rhs);
349 RValue<SByte> operator-=(SByte &lhs, RValue<SByte> rhs);
350 RValue<SByte> operator*=(SByte &lhs, RValue<SByte> rhs);
351 RValue<SByte> operator/=(SByte &lhs, RValue<SByte> rhs);
352 RValue<SByte> operator%=(SByte &lhs, RValue<SByte> rhs);
353 RValue<SByte> operator&=(SByte &lhs, RValue<SByte> rhs);
354 RValue<SByte> operator|=(SByte &lhs, RValue<SByte> rhs);
355 RValue<SByte> operator^=(SByte &lhs, RValue<SByte> rhs);
356 RValue<SByte> operator<<=(SByte &lhs, RValue<SByte> rhs);
357 RValue<SByte> operator>>=(SByte &lhs, RValue<SByte> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400358 RValue<SByte> operator+(RValue<SByte> val);
359 RValue<SByte> operator-(RValue<SByte> val);
360 RValue<SByte> operator~(RValue<SByte> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500361 RValue<SByte> operator++(SByte &val, int); // Post-increment
362 const SByte &operator++(SByte &val); // Pre-increment
363 RValue<SByte> operator--(SByte &val, int); // Post-decrement
364 const SByte &operator--(SByte &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400365 RValue<Bool> operator<(RValue<SByte> lhs, RValue<SByte> rhs);
366 RValue<Bool> operator<=(RValue<SByte> lhs, RValue<SByte> rhs);
367 RValue<Bool> operator>(RValue<SByte> lhs, RValue<SByte> rhs);
368 RValue<Bool> operator>=(RValue<SByte> lhs, RValue<SByte> rhs);
369 RValue<Bool> operator!=(RValue<SByte> lhs, RValue<SByte> rhs);
370 RValue<Bool> operator==(RValue<SByte> lhs, RValue<SByte> rhs);
371
Nicolas Capens297d26e2016-11-18 12:52:17 -0500372 class Short : public LValue<Short>
Nicolas Capensd022e412016-09-26 13:30:14 -0400373 {
374 public:
375 Short(Argument<Short> argument);
376
377 explicit Short(RValue<Int> cast);
378
Nicolas Capensa25311a2017-01-16 17:19:00 -0500379 Short() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -0400380 Short(short x);
381 Short(RValue<Short> rhs);
382 Short(const Short &rhs);
383 Short(const Reference<Short> &rhs);
384
Nicolas Capens96d4e092016-11-18 14:22:38 -0500385 // RValue<Short> operator=(short rhs); // FIXME: Implement
386 RValue<Short> operator=(RValue<Short> rhs);
387 RValue<Short> operator=(const Short &rhs);
388 RValue<Short> operator=(const Reference<Short> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400389
390 static Type *getType();
391 };
392
393 RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs);
394 RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs);
395 RValue<Short> operator*(RValue<Short> lhs, RValue<Short> rhs);
396 RValue<Short> operator/(RValue<Short> lhs, RValue<Short> rhs);
397 RValue<Short> operator%(RValue<Short> lhs, RValue<Short> rhs);
398 RValue<Short> operator&(RValue<Short> lhs, RValue<Short> rhs);
399 RValue<Short> operator|(RValue<Short> lhs, RValue<Short> rhs);
400 RValue<Short> operator^(RValue<Short> lhs, RValue<Short> rhs);
401 RValue<Short> operator<<(RValue<Short> lhs, RValue<Short> rhs);
402 RValue<Short> operator>>(RValue<Short> lhs, RValue<Short> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500403 RValue<Short> operator+=(Short &lhs, RValue<Short> rhs);
404 RValue<Short> operator-=(Short &lhs, RValue<Short> rhs);
405 RValue<Short> operator*=(Short &lhs, RValue<Short> rhs);
406 RValue<Short> operator/=(Short &lhs, RValue<Short> rhs);
407 RValue<Short> operator%=(Short &lhs, RValue<Short> rhs);
408 RValue<Short> operator&=(Short &lhs, RValue<Short> rhs);
409 RValue<Short> operator|=(Short &lhs, RValue<Short> rhs);
410 RValue<Short> operator^=(Short &lhs, RValue<Short> rhs);
411 RValue<Short> operator<<=(Short &lhs, RValue<Short> rhs);
412 RValue<Short> operator>>=(Short &lhs, RValue<Short> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400413 RValue<Short> operator+(RValue<Short> val);
414 RValue<Short> operator-(RValue<Short> val);
415 RValue<Short> operator~(RValue<Short> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500416 RValue<Short> operator++(Short &val, int); // Post-increment
417 const Short &operator++(Short &val); // Pre-increment
418 RValue<Short> operator--(Short &val, int); // Post-decrement
419 const Short &operator--(Short &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400420 RValue<Bool> operator<(RValue<Short> lhs, RValue<Short> rhs);
421 RValue<Bool> operator<=(RValue<Short> lhs, RValue<Short> rhs);
422 RValue<Bool> operator>(RValue<Short> lhs, RValue<Short> rhs);
423 RValue<Bool> operator>=(RValue<Short> lhs, RValue<Short> rhs);
424 RValue<Bool> operator!=(RValue<Short> lhs, RValue<Short> rhs);
425 RValue<Bool> operator==(RValue<Short> lhs, RValue<Short> rhs);
426
Nicolas Capens297d26e2016-11-18 12:52:17 -0500427 class UShort : public LValue<UShort>
Nicolas Capensd022e412016-09-26 13:30:14 -0400428 {
429 public:
430 UShort(Argument<UShort> argument);
431
432 explicit UShort(RValue<UInt> cast);
433 explicit UShort(RValue<Int> cast);
434
Nicolas Capensa25311a2017-01-16 17:19:00 -0500435 UShort() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -0400436 UShort(unsigned short x);
437 UShort(RValue<UShort> rhs);
438 UShort(const UShort &rhs);
439 UShort(const Reference<UShort> &rhs);
440
Nicolas Capens96d4e092016-11-18 14:22:38 -0500441 // RValue<UShort> operator=(unsigned short rhs); // FIXME: Implement
442 RValue<UShort> operator=(RValue<UShort> rhs);
443 RValue<UShort> operator=(const UShort &rhs);
444 RValue<UShort> operator=(const Reference<UShort> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400445
446 static Type *getType();
447 };
448
449 RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs);
450 RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs);
451 RValue<UShort> operator*(RValue<UShort> lhs, RValue<UShort> rhs);
452 RValue<UShort> operator/(RValue<UShort> lhs, RValue<UShort> rhs);
453 RValue<UShort> operator%(RValue<UShort> lhs, RValue<UShort> rhs);
454 RValue<UShort> operator&(RValue<UShort> lhs, RValue<UShort> rhs);
455 RValue<UShort> operator|(RValue<UShort> lhs, RValue<UShort> rhs);
456 RValue<UShort> operator^(RValue<UShort> lhs, RValue<UShort> rhs);
457 RValue<UShort> operator<<(RValue<UShort> lhs, RValue<UShort> rhs);
458 RValue<UShort> operator>>(RValue<UShort> lhs, RValue<UShort> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500459 RValue<UShort> operator+=(UShort &lhs, RValue<UShort> rhs);
460 RValue<UShort> operator-=(UShort &lhs, RValue<UShort> rhs);
461 RValue<UShort> operator*=(UShort &lhs, RValue<UShort> rhs);
462 RValue<UShort> operator/=(UShort &lhs, RValue<UShort> rhs);
463 RValue<UShort> operator%=(UShort &lhs, RValue<UShort> rhs);
464 RValue<UShort> operator&=(UShort &lhs, RValue<UShort> rhs);
465 RValue<UShort> operator|=(UShort &lhs, RValue<UShort> rhs);
466 RValue<UShort> operator^=(UShort &lhs, RValue<UShort> rhs);
467 RValue<UShort> operator<<=(UShort &lhs, RValue<UShort> rhs);
468 RValue<UShort> operator>>=(UShort &lhs, RValue<UShort> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400469 RValue<UShort> operator+(RValue<UShort> val);
470 RValue<UShort> operator-(RValue<UShort> val);
471 RValue<UShort> operator~(RValue<UShort> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500472 RValue<UShort> operator++(UShort &val, int); // Post-increment
473 const UShort &operator++(UShort &val); // Pre-increment
474 RValue<UShort> operator--(UShort &val, int); // Post-decrement
475 const UShort &operator--(UShort &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400476 RValue<Bool> operator<(RValue<UShort> lhs, RValue<UShort> rhs);
477 RValue<Bool> operator<=(RValue<UShort> lhs, RValue<UShort> rhs);
478 RValue<Bool> operator>(RValue<UShort> lhs, RValue<UShort> rhs);
479 RValue<Bool> operator>=(RValue<UShort> lhs, RValue<UShort> rhs);
480 RValue<Bool> operator!=(RValue<UShort> lhs, RValue<UShort> rhs);
481 RValue<Bool> operator==(RValue<UShort> lhs, RValue<UShort> rhs);
482
Nicolas Capens297d26e2016-11-18 12:52:17 -0500483 class Byte4 : public LValue<Byte4>
Nicolas Capensd022e412016-09-26 13:30:14 -0400484 {
485 public:
Nicolas Capens16b5f152016-10-13 13:39:01 -0400486 explicit Byte4(RValue<Byte8> cast);
487
Nicolas Capensa25311a2017-01-16 17:19:00 -0500488 Byte4() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -0400489 // Byte4(int x, int y, int z, int w);
490 // Byte4(RValue<Byte4> rhs);
491 // Byte4(const Byte4 &rhs);
Nicolas Capens16b5f152016-10-13 13:39:01 -0400492 Byte4(const Reference<Byte4> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400493
Nicolas Capens96d4e092016-11-18 14:22:38 -0500494 // RValue<Byte4> operator=(RValue<Byte4> rhs);
495 // RValue<Byte4> operator=(const Byte4 &rhs);
496 // RValue<Byte4> operator=(const Reference<Byte4> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400497
498 static Type *getType();
499 };
500
501// RValue<Byte4> operator+(RValue<Byte4> lhs, RValue<Byte4> rhs);
502// RValue<Byte4> operator-(RValue<Byte4> lhs, RValue<Byte4> rhs);
503// RValue<Byte4> operator*(RValue<Byte4> lhs, RValue<Byte4> rhs);
504// RValue<Byte4> operator/(RValue<Byte4> lhs, RValue<Byte4> rhs);
505// RValue<Byte4> operator%(RValue<Byte4> lhs, RValue<Byte4> rhs);
506// RValue<Byte4> operator&(RValue<Byte4> lhs, RValue<Byte4> rhs);
507// RValue<Byte4> operator|(RValue<Byte4> lhs, RValue<Byte4> rhs);
508// RValue<Byte4> operator^(RValue<Byte4> lhs, RValue<Byte4> rhs);
509// RValue<Byte4> operator<<(RValue<Byte4> lhs, RValue<Byte4> rhs);
510// RValue<Byte4> operator>>(RValue<Byte4> lhs, RValue<Byte4> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500511// RValue<Byte4> operator+=(Byte4 &lhs, RValue<Byte4> rhs);
512// RValue<Byte4> operator-=(Byte4 &lhs, RValue<Byte4> rhs);
513// RValue<Byte4> operator*=(Byte4 &lhs, RValue<Byte4> rhs);
514// RValue<Byte4> operator/=(Byte4 &lhs, RValue<Byte4> rhs);
515// RValue<Byte4> operator%=(Byte4 &lhs, RValue<Byte4> rhs);
516// RValue<Byte4> operator&=(Byte4 &lhs, RValue<Byte4> rhs);
517// RValue<Byte4> operator|=(Byte4 &lhs, RValue<Byte4> rhs);
518// RValue<Byte4> operator^=(Byte4 &lhs, RValue<Byte4> rhs);
519// RValue<Byte4> operator<<=(Byte4 &lhs, RValue<Byte4> rhs);
520// RValue<Byte4> operator>>=(Byte4 &lhs, RValue<Byte4> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400521// RValue<Byte4> operator+(RValue<Byte4> val);
522// RValue<Byte4> operator-(RValue<Byte4> val);
523// RValue<Byte4> operator~(RValue<Byte4> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500524// RValue<Byte4> operator++(Byte4 &val, int); // Post-increment
525// const Byte4 &operator++(Byte4 &val); // Pre-increment
526// RValue<Byte4> operator--(Byte4 &val, int); // Post-decrement
527// const Byte4 &operator--(Byte4 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400528
Nicolas Capens297d26e2016-11-18 12:52:17 -0500529 class SByte4 : public LValue<SByte4>
Nicolas Capensd022e412016-09-26 13:30:14 -0400530 {
531 public:
Nicolas Capensa25311a2017-01-16 17:19:00 -0500532 SByte4() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -0400533 // SByte4(int x, int y, int z, int w);
534 // SByte4(RValue<SByte4> rhs);
535 // SByte4(const SByte4 &rhs);
536 // SByte4(const Reference<SByte4> &rhs);
537
Nicolas Capens96d4e092016-11-18 14:22:38 -0500538 // RValue<SByte4> operator=(RValue<SByte4> rhs);
539 // RValue<SByte4> operator=(const SByte4 &rhs);
540 // RValue<SByte4> operator=(const Reference<SByte4> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400541
542 static Type *getType();
543 };
544
545// RValue<SByte4> operator+(RValue<SByte4> lhs, RValue<SByte4> rhs);
546// RValue<SByte4> operator-(RValue<SByte4> lhs, RValue<SByte4> rhs);
547// RValue<SByte4> operator*(RValue<SByte4> lhs, RValue<SByte4> rhs);
548// RValue<SByte4> operator/(RValue<SByte4> lhs, RValue<SByte4> rhs);
549// RValue<SByte4> operator%(RValue<SByte4> lhs, RValue<SByte4> rhs);
550// RValue<SByte4> operator&(RValue<SByte4> lhs, RValue<SByte4> rhs);
551// RValue<SByte4> operator|(RValue<SByte4> lhs, RValue<SByte4> rhs);
552// RValue<SByte4> operator^(RValue<SByte4> lhs, RValue<SByte4> rhs);
553// RValue<SByte4> operator<<(RValue<SByte4> lhs, RValue<SByte4> rhs);
554// RValue<SByte4> operator>>(RValue<SByte4> lhs, RValue<SByte4> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500555// RValue<SByte4> operator+=(SByte4 &lhs, RValue<SByte4> rhs);
556// RValue<SByte4> operator-=(SByte4 &lhs, RValue<SByte4> rhs);
557// RValue<SByte4> operator*=(SByte4 &lhs, RValue<SByte4> rhs);
558// RValue<SByte4> operator/=(SByte4 &lhs, RValue<SByte4> rhs);
559// RValue<SByte4> operator%=(SByte4 &lhs, RValue<SByte4> rhs);
560// RValue<SByte4> operator&=(SByte4 &lhs, RValue<SByte4> rhs);
561// RValue<SByte4> operator|=(SByte4 &lhs, RValue<SByte4> rhs);
562// RValue<SByte4> operator^=(SByte4 &lhs, RValue<SByte4> rhs);
563// RValue<SByte4> operator<<=(SByte4 &lhs, RValue<SByte4> rhs);
564// RValue<SByte4> operator>>=(SByte4 &lhs, RValue<SByte4> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400565// RValue<SByte4> operator+(RValue<SByte4> val);
566// RValue<SByte4> operator-(RValue<SByte4> val);
567// RValue<SByte4> operator~(RValue<SByte4> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500568// RValue<SByte4> operator++(SByte4 &val, int); // Post-increment
569// const SByte4 &operator++(SByte4 &val); // Pre-increment
570// RValue<SByte4> operator--(SByte4 &val, int); // Post-decrement
571// const SByte4 &operator--(SByte4 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400572
Nicolas Capens297d26e2016-11-18 12:52:17 -0500573 class Byte8 : public LValue<Byte8>
Nicolas Capensd022e412016-09-26 13:30:14 -0400574 {
575 public:
Nicolas Capensa25311a2017-01-16 17:19:00 -0500576 Byte8() = default;
Nicolas Capens3bbc5e12016-09-27 10:49:52 -0400577 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 -0400578 Byte8(RValue<Byte8> rhs);
579 Byte8(const Byte8 &rhs);
580 Byte8(const Reference<Byte8> &rhs);
581
Nicolas Capens96d4e092016-11-18 14:22:38 -0500582 RValue<Byte8> operator=(RValue<Byte8> rhs);
583 RValue<Byte8> operator=(const Byte8 &rhs);
584 RValue<Byte8> operator=(const Reference<Byte8> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400585
586 static Type *getType();
587 };
588
589 RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs);
590 RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs);
591// RValue<Byte8> operator*(RValue<Byte8> lhs, RValue<Byte8> rhs);
592// RValue<Byte8> operator/(RValue<Byte8> lhs, RValue<Byte8> rhs);
593// RValue<Byte8> operator%(RValue<Byte8> lhs, RValue<Byte8> rhs);
594 RValue<Byte8> operator&(RValue<Byte8> lhs, RValue<Byte8> rhs);
595 RValue<Byte8> operator|(RValue<Byte8> lhs, RValue<Byte8> rhs);
596 RValue<Byte8> operator^(RValue<Byte8> lhs, RValue<Byte8> rhs);
597// RValue<Byte8> operator<<(RValue<Byte8> lhs, RValue<Byte8> rhs);
598// RValue<Byte8> operator>>(RValue<Byte8> lhs, RValue<Byte8> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500599 RValue<Byte8> operator+=(Byte8 &lhs, RValue<Byte8> rhs);
600 RValue<Byte8> operator-=(Byte8 &lhs, RValue<Byte8> rhs);
601// RValue<Byte8> operator*=(Byte8 &lhs, RValue<Byte8> rhs);
602// RValue<Byte8> operator/=(Byte8 &lhs, RValue<Byte8> rhs);
603// RValue<Byte8> operator%=(Byte8 &lhs, RValue<Byte8> rhs);
604 RValue<Byte8> operator&=(Byte8 &lhs, RValue<Byte8> rhs);
605 RValue<Byte8> operator|=(Byte8 &lhs, RValue<Byte8> rhs);
606 RValue<Byte8> operator^=(Byte8 &lhs, RValue<Byte8> rhs);
607// RValue<Byte8> operator<<=(Byte8 &lhs, RValue<Byte8> rhs);
608// RValue<Byte8> operator>>=(Byte8 &lhs, RValue<Byte8> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400609// RValue<Byte8> operator+(RValue<Byte8> val);
610// RValue<Byte8> operator-(RValue<Byte8> val);
611 RValue<Byte8> operator~(RValue<Byte8> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500612// RValue<Byte8> operator++(Byte8 &val, int); // Post-increment
613// const Byte8 &operator++(Byte8 &val); // Pre-increment
614// RValue<Byte8> operator--(Byte8 &val, int); // Post-decrement
615// const Byte8 &operator--(Byte8 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400616
617 RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y);
618 RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y);
619 RValue<Short4> Unpack(RValue<Byte4> x);
Nicolas Capens411273e2017-01-26 15:13:36 -0800620 RValue<Short4> Unpack(RValue<Byte4> x, RValue<Byte4> y);
Nicolas Capensd022e412016-09-26 13:30:14 -0400621 RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y);
622 RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y);
623 RValue<Int> SignMask(RValue<Byte8> x);
624// RValue<Byte8> CmpGT(RValue<Byte8> x, RValue<Byte8> y);
625 RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y);
626
Nicolas Capens297d26e2016-11-18 12:52:17 -0500627 class SByte8 : public LValue<SByte8>
Nicolas Capensd022e412016-09-26 13:30:14 -0400628 {
629 public:
Nicolas Capensa25311a2017-01-16 17:19:00 -0500630 SByte8() = default;
Nicolas Capens3bbc5e12016-09-27 10:49:52 -0400631 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 -0400632 SByte8(RValue<SByte8> rhs);
633 SByte8(const SByte8 &rhs);
634 SByte8(const Reference<SByte8> &rhs);
635
Nicolas Capens96d4e092016-11-18 14:22:38 -0500636 RValue<SByte8> operator=(RValue<SByte8> rhs);
637 RValue<SByte8> operator=(const SByte8 &rhs);
638 RValue<SByte8> operator=(const Reference<SByte8> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400639
640 static Type *getType();
641 };
642
643 RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs);
644 RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs);
645// RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs);
646// RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs);
647// RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs);
648 RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs);
649 RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs);
650 RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs);
651// RValue<SByte8> operator<<(RValue<SByte8> lhs, RValue<SByte8> rhs);
652// RValue<SByte8> operator>>(RValue<SByte8> lhs, RValue<SByte8> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500653 RValue<SByte8> operator+=(SByte8 &lhs, RValue<SByte8> rhs);
654 RValue<SByte8> operator-=(SByte8 &lhs, RValue<SByte8> rhs);
655// RValue<SByte8> operator*=(SByte8 &lhs, RValue<SByte8> rhs);
656// RValue<SByte8> operator/=(SByte8 &lhs, RValue<SByte8> rhs);
657// RValue<SByte8> operator%=(SByte8 &lhs, RValue<SByte8> rhs);
658 RValue<SByte8> operator&=(SByte8 &lhs, RValue<SByte8> rhs);
659 RValue<SByte8> operator|=(SByte8 &lhs, RValue<SByte8> rhs);
660 RValue<SByte8> operator^=(SByte8 &lhs, RValue<SByte8> rhs);
661// RValue<SByte8> operator<<=(SByte8 &lhs, RValue<SByte8> rhs);
662// RValue<SByte8> operator>>=(SByte8 &lhs, RValue<SByte8> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400663// RValue<SByte8> operator+(RValue<SByte8> val);
664// RValue<SByte8> operator-(RValue<SByte8> val);
665 RValue<SByte8> operator~(RValue<SByte8> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500666// RValue<SByte8> operator++(SByte8 &val, int); // Post-increment
667// const SByte8 &operator++(SByte8 &val); // Pre-increment
668// RValue<SByte8> operator--(SByte8 &val, int); // Post-decrement
669// const SByte8 &operator--(SByte8 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400670
671 RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y);
672 RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y);
673 RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y);
674 RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y);
675 RValue<Int> SignMask(RValue<SByte8> x);
676 RValue<Byte8> CmpGT(RValue<SByte8> x, RValue<SByte8> y);
677 RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y);
678
Nicolas Capens297d26e2016-11-18 12:52:17 -0500679 class Byte16 : public LValue<Byte16>
Nicolas Capensd022e412016-09-26 13:30:14 -0400680 {
681 public:
Nicolas Capensa25311a2017-01-16 17:19:00 -0500682 Byte16() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -0400683 // Byte16(int x, int y, int z, int w);
684 Byte16(RValue<Byte16> rhs);
685 Byte16(const Byte16 &rhs);
686 Byte16(const Reference<Byte16> &rhs);
687
Nicolas Capens96d4e092016-11-18 14:22:38 -0500688 RValue<Byte16> operator=(RValue<Byte16> rhs);
689 RValue<Byte16> operator=(const Byte16 &rhs);
690 RValue<Byte16> operator=(const Reference<Byte16> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400691
692 static Type *getType();
693 };
694
695// RValue<Byte16> operator+(RValue<Byte16> lhs, RValue<Byte16> rhs);
696// RValue<Byte16> operator-(RValue<Byte16> lhs, RValue<Byte16> rhs);
697// RValue<Byte16> operator*(RValue<Byte16> lhs, RValue<Byte16> rhs);
698// RValue<Byte16> operator/(RValue<Byte16> lhs, RValue<Byte16> rhs);
699// RValue<Byte16> operator%(RValue<Byte16> lhs, RValue<Byte16> rhs);
700// RValue<Byte16> operator&(RValue<Byte16> lhs, RValue<Byte16> rhs);
701// RValue<Byte16> operator|(RValue<Byte16> lhs, RValue<Byte16> rhs);
702// RValue<Byte16> operator^(RValue<Byte16> lhs, RValue<Byte16> rhs);
703// RValue<Byte16> operator<<(RValue<Byte16> lhs, RValue<Byte16> rhs);
704// RValue<Byte16> operator>>(RValue<Byte16> lhs, RValue<Byte16> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500705// RValue<Byte16> operator+=(Byte16 &lhs, RValue<Byte16> rhs);
706// RValue<Byte16> operator-=(Byte16 &lhs, RValue<Byte16> rhs);
707// RValue<Byte16> operator*=(Byte16 &lhs, RValue<Byte16> rhs);
708// RValue<Byte16> operator/=(Byte16 &lhs, RValue<Byte16> rhs);
709// RValue<Byte16> operator%=(Byte16 &lhs, RValue<Byte16> rhs);
710// RValue<Byte16> operator&=(Byte16 &lhs, RValue<Byte16> rhs);
711// RValue<Byte16> operator|=(Byte16 &lhs, RValue<Byte16> rhs);
712// RValue<Byte16> operator^=(Byte16 &lhs, RValue<Byte16> rhs);
713// RValue<Byte16> operator<<=(Byte16 &lhs, RValue<Byte16> rhs);
714// RValue<Byte16> operator>>=(Byte16 &lhs, RValue<Byte16> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400715// RValue<Byte16> operator+(RValue<Byte16> val);
716// RValue<Byte16> operator-(RValue<Byte16> val);
717// RValue<Byte16> operator~(RValue<Byte16> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500718// RValue<Byte16> operator++(Byte16 &val, int); // Post-increment
719// const Byte16 &operator++(Byte16 &val); // Pre-increment
720// RValue<Byte16> operator--(Byte16 &val, int); // Post-decrement
721// const Byte16 &operator--(Byte16 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400722
Nicolas Capens297d26e2016-11-18 12:52:17 -0500723 class SByte16 : public LValue<SByte16>
Nicolas Capensd022e412016-09-26 13:30:14 -0400724 {
725 public:
Nicolas Capensa25311a2017-01-16 17:19:00 -0500726 SByte16() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -0400727 // SByte16(int x, int y, int z, int w);
728 // SByte16(RValue<SByte16> rhs);
729 // SByte16(const SByte16 &rhs);
730 // SByte16(const Reference<SByte16> &rhs);
731
Nicolas Capens96d4e092016-11-18 14:22:38 -0500732 // RValue<SByte16> operator=(RValue<SByte16> rhs);
733 // RValue<SByte16> operator=(const SByte16 &rhs);
734 // RValue<SByte16> operator=(const Reference<SByte16> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400735
736 static Type *getType();
737 };
738
739// RValue<SByte16> operator+(RValue<SByte16> lhs, RValue<SByte16> rhs);
740// RValue<SByte16> operator-(RValue<SByte16> lhs, RValue<SByte16> rhs);
741// RValue<SByte16> operator*(RValue<SByte16> lhs, RValue<SByte16> rhs);
742// RValue<SByte16> operator/(RValue<SByte16> lhs, RValue<SByte16> rhs);
743// RValue<SByte16> operator%(RValue<SByte16> lhs, RValue<SByte16> rhs);
744// RValue<SByte16> operator&(RValue<SByte16> lhs, RValue<SByte16> rhs);
745// RValue<SByte16> operator|(RValue<SByte16> lhs, RValue<SByte16> rhs);
746// RValue<SByte16> operator^(RValue<SByte16> lhs, RValue<SByte16> rhs);
747// RValue<SByte16> operator<<(RValue<SByte16> lhs, RValue<SByte16> rhs);
748// RValue<SByte16> operator>>(RValue<SByte16> lhs, RValue<SByte16> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500749// RValue<SByte16> operator+=(SByte16 &lhs, RValue<SByte16> rhs);
750// RValue<SByte16> operator-=(SByte16 &lhs, RValue<SByte16> rhs);
751// RValue<SByte16> operator*=(SByte16 &lhs, RValue<SByte16> rhs);
752// RValue<SByte16> operator/=(SByte16 &lhs, RValue<SByte16> rhs);
753// RValue<SByte16> operator%=(SByte16 &lhs, RValue<SByte16> rhs);
754// RValue<SByte16> operator&=(SByte16 &lhs, RValue<SByte16> rhs);
755// RValue<SByte16> operator|=(SByte16 &lhs, RValue<SByte16> rhs);
756// RValue<SByte16> operator^=(SByte16 &lhs, RValue<SByte16> rhs);
757// RValue<SByte16> operator<<=(SByte16 &lhs, RValue<SByte16> rhs);
758// RValue<SByte16> operator>>=(SByte16 &lhs, RValue<SByte16> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400759// RValue<SByte16> operator+(RValue<SByte16> val);
760// RValue<SByte16> operator-(RValue<SByte16> val);
761// RValue<SByte16> operator~(RValue<SByte16> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500762// RValue<SByte16> operator++(SByte16 &val, int); // Post-increment
763// const SByte16 &operator++(SByte16 &val); // Pre-increment
764// RValue<SByte16> operator--(SByte16 &val, int); // Post-decrement
765// const SByte16 &operator--(SByte16 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400766
Nicolas Capens297d26e2016-11-18 12:52:17 -0500767 class Short2 : public LValue<Short2>
Nicolas Capens16b5f152016-10-13 13:39:01 -0400768 {
769 public:
770 explicit Short2(RValue<Short4> cast);
771
772 static Type *getType();
773 };
774
Nicolas Capens297d26e2016-11-18 12:52:17 -0500775 class UShort2 : public LValue<UShort2>
Nicolas Capens16b5f152016-10-13 13:39:01 -0400776 {
777 public:
778 explicit UShort2(RValue<UShort4> cast);
779
780 static Type *getType();
781 };
782
Nicolas Capens297d26e2016-11-18 12:52:17 -0500783 class Short4 : public LValue<Short4>
Nicolas Capensd022e412016-09-26 13:30:14 -0400784 {
785 public:
786 explicit Short4(RValue<Int> cast);
787 explicit Short4(RValue<Int4> cast);
788 // explicit Short4(RValue<Float> cast);
789 explicit Short4(RValue<Float4> cast);
790
Nicolas Capensa25311a2017-01-16 17:19:00 -0500791 Short4() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -0400792 Short4(short xyzw);
793 Short4(short x, short y, short z, short w);
794 Short4(RValue<Short4> rhs);
795 Short4(const Short4 &rhs);
796 Short4(const Reference<Short4> &rhs);
797 Short4(RValue<UShort4> rhs);
798 Short4(const UShort4 &rhs);
799 Short4(const Reference<UShort4> &rhs);
800
Nicolas Capens96d4e092016-11-18 14:22:38 -0500801 RValue<Short4> operator=(RValue<Short4> rhs);
802 RValue<Short4> operator=(const Short4 &rhs);
803 RValue<Short4> operator=(const Reference<Short4> &rhs);
804 RValue<Short4> operator=(RValue<UShort4> rhs);
805 RValue<Short4> operator=(const UShort4 &rhs);
806 RValue<Short4> operator=(const Reference<UShort4> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400807
808 static Type *getType();
809 };
810
811 RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs);
812 RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs);
813 RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs);
814// RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs);
815// RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs);
816 RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs);
817 RValue<Short4> operator|(RValue<Short4> lhs, RValue<Short4> rhs);
818 RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs);
819 RValue<Short4> operator<<(RValue<Short4> lhs, unsigned char rhs);
820 RValue<Short4> operator>>(RValue<Short4> lhs, unsigned char rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500821 RValue<Short4> operator+=(Short4 &lhs, RValue<Short4> rhs);
822 RValue<Short4> operator-=(Short4 &lhs, RValue<Short4> rhs);
823 RValue<Short4> operator*=(Short4 &lhs, RValue<Short4> rhs);
824// RValue<Short4> operator/=(Short4 &lhs, RValue<Short4> rhs);
825// RValue<Short4> operator%=(Short4 &lhs, RValue<Short4> rhs);
826 RValue<Short4> operator&=(Short4 &lhs, RValue<Short4> rhs);
827 RValue<Short4> operator|=(Short4 &lhs, RValue<Short4> rhs);
828 RValue<Short4> operator^=(Short4 &lhs, RValue<Short4> rhs);
829 RValue<Short4> operator<<=(Short4 &lhs, unsigned char rhs);
830 RValue<Short4> operator>>=(Short4 &lhs, unsigned char rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400831// RValue<Short4> operator+(RValue<Short4> val);
832 RValue<Short4> operator-(RValue<Short4> val);
833 RValue<Short4> operator~(RValue<Short4> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500834// RValue<Short4> operator++(Short4 &val, int); // Post-increment
835// const Short4 &operator++(Short4 &val); // Pre-increment
836// RValue<Short4> operator--(Short4 &val, int); // Post-decrement
837// const Short4 &operator--(Short4 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400838// RValue<Bool> operator<(RValue<Short4> lhs, RValue<Short4> rhs);
839// RValue<Bool> operator<=(RValue<Short4> lhs, RValue<Short4> rhs);
840// RValue<Bool> operator>(RValue<Short4> lhs, RValue<Short4> rhs);
841// RValue<Bool> operator>=(RValue<Short4> lhs, RValue<Short4> rhs);
842// RValue<Bool> operator!=(RValue<Short4> lhs, RValue<Short4> rhs);
843// RValue<Bool> operator==(RValue<Short4> lhs, RValue<Short4> rhs);
844
845 RValue<Short4> RoundShort4(RValue<Float4> cast);
846 RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y);
847 RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y);
848 RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y);
849 RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y);
850 RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y);
851 RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y);
Nicolas Capens33438a62017-09-27 11:47:35 -0400852 RValue<SByte8> PackSigned(RValue<Short4> x, RValue<Short4> y);
853 RValue<Byte8> PackUnsigned(RValue<Short4> x, RValue<Short4> y);
Nicolas Capensd022e412016-09-26 13:30:14 -0400854 RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y);
855 RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y);
856 RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select);
857 RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i);
858 RValue<Short> Extract(RValue<Short4> val, int i);
859 RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y);
860 RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y);
861
Nicolas Capens297d26e2016-11-18 12:52:17 -0500862 class UShort4 : public LValue<UShort4>
Nicolas Capensd022e412016-09-26 13:30:14 -0400863 {
864 public:
865 explicit UShort4(RValue<Int4> cast);
866 explicit UShort4(RValue<Float4> cast, bool saturate = false);
867
Nicolas Capensa25311a2017-01-16 17:19:00 -0500868 UShort4() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -0400869 UShort4(unsigned short xyzw);
870 UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w);
871 UShort4(RValue<UShort4> rhs);
872 UShort4(const UShort4 &rhs);
873 UShort4(const Reference<UShort4> &rhs);
874 UShort4(RValue<Short4> rhs);
875 UShort4(const Short4 &rhs);
876 UShort4(const Reference<Short4> &rhs);
877
Nicolas Capens96d4e092016-11-18 14:22:38 -0500878 RValue<UShort4> operator=(RValue<UShort4> rhs);
879 RValue<UShort4> operator=(const UShort4 &rhs);
880 RValue<UShort4> operator=(const Reference<UShort4> &rhs);
881 RValue<UShort4> operator=(RValue<Short4> rhs);
882 RValue<UShort4> operator=(const Short4 &rhs);
883 RValue<UShort4> operator=(const Reference<Short4> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400884
885 static Type *getType();
886 };
887
888 RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs);
889 RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs);
890 RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs);
891// RValue<UShort4> operator/(RValue<UShort4> lhs, RValue<UShort4> rhs);
892// RValue<UShort4> operator%(RValue<UShort4> lhs, RValue<UShort4> rhs);
Nicolas Capens16b5f152016-10-13 13:39:01 -0400893 RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs);
894 RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs);
895 RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400896 RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs);
897 RValue<UShort4> operator>>(RValue<UShort4> lhs, unsigned char rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500898// RValue<UShort4> operator+=(UShort4 &lhs, RValue<UShort4> rhs);
899// RValue<UShort4> operator-=(UShort4 &lhs, RValue<UShort4> rhs);
900// RValue<UShort4> operator*=(UShort4 &lhs, RValue<UShort4> rhs);
901// RValue<UShort4> operator/=(UShort4 &lhs, RValue<UShort4> rhs);
902// RValue<UShort4> operator%=(UShort4 &lhs, RValue<UShort4> rhs);
903// RValue<UShort4> operator&=(UShort4 &lhs, RValue<UShort4> rhs);
904// RValue<UShort4> operator|=(UShort4 &lhs, RValue<UShort4> rhs);
905// RValue<UShort4> operator^=(UShort4 &lhs, RValue<UShort4> rhs);
906 RValue<UShort4> operator<<=(UShort4 &lhs, unsigned char rhs);
907 RValue<UShort4> operator>>=(UShort4 &lhs, unsigned char rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400908// RValue<UShort4> operator+(RValue<UShort4> val);
909// RValue<UShort4> operator-(RValue<UShort4> val);
910 RValue<UShort4> operator~(RValue<UShort4> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500911// RValue<UShort4> operator++(UShort4 &val, int); // Post-increment
912// const UShort4 &operator++(UShort4 &val); // Pre-increment
913// RValue<UShort4> operator--(UShort4 &val, int); // Post-decrement
914// const UShort4 &operator--(UShort4 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400915
916 RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y);
917 RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y);
918 RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y);
919 RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y);
920 RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y);
921 RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y);
Nicolas Capensd022e412016-09-26 13:30:14 -0400922
Nicolas Capens297d26e2016-11-18 12:52:17 -0500923 class Short8 : public LValue<Short8>
Nicolas Capensd022e412016-09-26 13:30:14 -0400924 {
925 public:
Nicolas Capensa25311a2017-01-16 17:19:00 -0500926 Short8() = default;
Nicolas Capens3e7062b2017-01-17 14:01:33 -0500927 Short8(short c);
Nicolas Capensd022e412016-09-26 13:30:14 -0400928 Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7);
929 Short8(RValue<Short8> rhs);
930 // Short8(const Short8 &rhs);
931 Short8(const Reference<Short8> &rhs);
932 Short8(RValue<Short4> lo, RValue<Short4> hi);
933
Nicolas Capensf1beca42019-03-26 17:18:57 -0400934 RValue<Short8> operator=(RValue<Short8> rhs);
935 RValue<Short8> operator=(const Short8 &rhs);
936 RValue<Short8> operator=(const Reference<Short8> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400937
938 static Type *getType();
939 };
940
941 RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs);
942// RValue<Short8> operator-(RValue<Short8> lhs, RValue<Short8> rhs);
943// RValue<Short8> operator*(RValue<Short8> lhs, RValue<Short8> rhs);
944// RValue<Short8> operator/(RValue<Short8> lhs, RValue<Short8> rhs);
945// RValue<Short8> operator%(RValue<Short8> lhs, RValue<Short8> rhs);
946 RValue<Short8> operator&(RValue<Short8> lhs, RValue<Short8> rhs);
947// RValue<Short8> operator|(RValue<Short8> lhs, RValue<Short8> rhs);
948// RValue<Short8> operator^(RValue<Short8> lhs, RValue<Short8> rhs);
949 RValue<Short8> operator<<(RValue<Short8> lhs, unsigned char rhs);
950 RValue<Short8> operator>>(RValue<Short8> lhs, unsigned char rhs);
951// RValue<Short8> operator<<(RValue<Short8> lhs, RValue<Short8> rhs);
952// RValue<Short8> operator>>(RValue<Short8> lhs, RValue<Short8> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500953// RValue<Short8> operator+=(Short8 &lhs, RValue<Short8> rhs);
954// RValue<Short8> operator-=(Short8 &lhs, RValue<Short8> rhs);
955// RValue<Short8> operator*=(Short8 &lhs, RValue<Short8> rhs);
956// RValue<Short8> operator/=(Short8 &lhs, RValue<Short8> rhs);
957// RValue<Short8> operator%=(Short8 &lhs, RValue<Short8> rhs);
958// RValue<Short8> operator&=(Short8 &lhs, RValue<Short8> rhs);
959// RValue<Short8> operator|=(Short8 &lhs, RValue<Short8> rhs);
960// RValue<Short8> operator^=(Short8 &lhs, RValue<Short8> rhs);
961// RValue<Short8> operator<<=(Short8 &lhs, RValue<Short8> rhs);
962// RValue<Short8> operator>>=(Short8 &lhs, RValue<Short8> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400963// RValue<Short8> operator+(RValue<Short8> val);
964// RValue<Short8> operator-(RValue<Short8> val);
965// RValue<Short8> operator~(RValue<Short8> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -0500966// RValue<Short8> operator++(Short8 &val, int); // Post-increment
967// const Short8 &operator++(Short8 &val); // Pre-increment
968// RValue<Short8> operator--(Short8 &val, int); // Post-decrement
969// const Short8 &operator--(Short8 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -0400970// RValue<Bool> operator<(RValue<Short8> lhs, RValue<Short8> rhs);
971// RValue<Bool> operator<=(RValue<Short8> lhs, RValue<Short8> rhs);
972// RValue<Bool> operator>(RValue<Short8> lhs, RValue<Short8> rhs);
973// RValue<Bool> operator>=(RValue<Short8> lhs, RValue<Short8> rhs);
974// RValue<Bool> operator!=(RValue<Short8> lhs, RValue<Short8> rhs);
975// RValue<Bool> operator==(RValue<Short8> lhs, RValue<Short8> rhs);
976
977 RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y);
978 RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y);
979 RValue<Int4> Abs(RValue<Int4> x);
980
Nicolas Capens297d26e2016-11-18 12:52:17 -0500981 class UShort8 : public LValue<UShort8>
Nicolas Capensd022e412016-09-26 13:30:14 -0400982 {
983 public:
Nicolas Capensa25311a2017-01-16 17:19:00 -0500984 UShort8() = default;
Nicolas Capens3e7062b2017-01-17 14:01:33 -0500985 UShort8(unsigned short c);
Nicolas Capensd022e412016-09-26 13:30:14 -0400986 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);
987 UShort8(RValue<UShort8> rhs);
988 // UShort8(const UShort8 &rhs);
989 UShort8(const Reference<UShort8> &rhs);
990 UShort8(RValue<UShort4> lo, RValue<UShort4> hi);
991
Nicolas Capens96d4e092016-11-18 14:22:38 -0500992 RValue<UShort8> operator=(RValue<UShort8> rhs);
993 RValue<UShort8> operator=(const UShort8 &rhs);
994 RValue<UShort8> operator=(const Reference<UShort8> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -0400995
996 static Type *getType();
997 };
998
999 RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs);
1000// RValue<UShort8> operator-(RValue<UShort8> lhs, RValue<UShort8> rhs);
1001 RValue<UShort8> operator*(RValue<UShort8> lhs, RValue<UShort8> rhs);
1002// RValue<UShort8> operator/(RValue<UShort8> lhs, RValue<UShort8> rhs);
1003// RValue<UShort8> operator%(RValue<UShort8> lhs, RValue<UShort8> rhs);
1004 RValue<UShort8> operator&(RValue<UShort8> lhs, RValue<UShort8> rhs);
1005// RValue<UShort8> operator|(RValue<UShort8> lhs, RValue<UShort8> rhs);
1006// RValue<UShort8> operator^(RValue<UShort8> lhs, RValue<UShort8> rhs);
1007 RValue<UShort8> operator<<(RValue<UShort8> lhs, unsigned char rhs);
1008 RValue<UShort8> operator>>(RValue<UShort8> lhs, unsigned char rhs);
1009// RValue<UShort8> operator<<(RValue<UShort8> lhs, RValue<UShort8> rhs);
1010// RValue<UShort8> operator>>(RValue<UShort8> lhs, RValue<UShort8> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001011 RValue<UShort8> operator+=(UShort8 &lhs, RValue<UShort8> rhs);
1012// RValue<UShort8> operator-=(UShort8 &lhs, RValue<UShort8> rhs);
1013// RValue<UShort8> operator*=(UShort8 &lhs, RValue<UShort8> rhs);
1014// RValue<UShort8> operator/=(UShort8 &lhs, RValue<UShort8> rhs);
1015// RValue<UShort8> operator%=(UShort8 &lhs, RValue<UShort8> rhs);
1016// RValue<UShort8> operator&=(UShort8 &lhs, RValue<UShort8> rhs);
1017// RValue<UShort8> operator|=(UShort8 &lhs, RValue<UShort8> rhs);
1018// RValue<UShort8> operator^=(UShort8 &lhs, RValue<UShort8> rhs);
1019// RValue<UShort8> operator<<=(UShort8 &lhs, RValue<UShort8> rhs);
1020// RValue<UShort8> operator>>=(UShort8 &lhs, RValue<UShort8> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001021// RValue<UShort8> operator+(RValue<UShort8> val);
1022// RValue<UShort8> operator-(RValue<UShort8> val);
1023 RValue<UShort8> operator~(RValue<UShort8> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001024// RValue<UShort8> operator++(UShort8 &val, int); // Post-increment
1025// const UShort8 &operator++(UShort8 &val); // Pre-increment
1026// RValue<UShort8> operator--(UShort8 &val, int); // Post-decrement
1027// const UShort8 &operator--(UShort8 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -04001028// RValue<Bool> operator<(RValue<UShort8> lhs, RValue<UShort8> rhs);
1029// RValue<Bool> operator<=(RValue<UShort8> lhs, RValue<UShort8> rhs);
1030// RValue<Bool> operator>(RValue<UShort8> lhs, RValue<UShort8> rhs);
1031// RValue<Bool> operator>=(RValue<UShort8> lhs, RValue<UShort8> rhs);
1032// RValue<Bool> operator!=(RValue<UShort8> lhs, RValue<UShort8> rhs);
1033// RValue<Bool> operator==(RValue<UShort8> lhs, RValue<UShort8> rhs);
1034
1035 RValue<UShort8> Swizzle(RValue<UShort8> x, char select0, char select1, char select2, char select3, char select4, char select5, char select6, char select7);
1036 RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y);
1037
Nicolas Capens297d26e2016-11-18 12:52:17 -05001038 class Int : public LValue<Int>
Nicolas Capensd022e412016-09-26 13:30:14 -04001039 {
1040 public:
1041 Int(Argument<Int> argument);
1042
1043 explicit Int(RValue<Byte> cast);
1044 explicit Int(RValue<SByte> cast);
1045 explicit Int(RValue<Short> cast);
1046 explicit Int(RValue<UShort> cast);
1047 explicit Int(RValue<Int2> cast);
1048 explicit Int(RValue<Long> cast);
1049 explicit Int(RValue<Float> cast);
1050
Nicolas Capensa25311a2017-01-16 17:19:00 -05001051 Int() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -04001052 Int(int x);
1053 Int(RValue<Int> rhs);
1054 Int(RValue<UInt> rhs);
1055 Int(const Int &rhs);
1056 Int(const UInt &rhs);
1057 Int(const Reference<Int> &rhs);
1058 Int(const Reference<UInt> &rhs);
1059
Nicolas Capens96d4e092016-11-18 14:22:38 -05001060 RValue<Int> operator=(int rhs);
1061 RValue<Int> operator=(RValue<Int> rhs);
1062 RValue<Int> operator=(RValue<UInt> rhs);
1063 RValue<Int> operator=(const Int &rhs);
1064 RValue<Int> operator=(const UInt &rhs);
1065 RValue<Int> operator=(const Reference<Int> &rhs);
1066 RValue<Int> operator=(const Reference<UInt> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001067
1068 static Type *getType();
1069 };
1070
1071 RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs);
1072 RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs);
1073 RValue<Int> operator*(RValue<Int> lhs, RValue<Int> rhs);
1074 RValue<Int> operator/(RValue<Int> lhs, RValue<Int> rhs);
1075 RValue<Int> operator%(RValue<Int> lhs, RValue<Int> rhs);
1076 RValue<Int> operator&(RValue<Int> lhs, RValue<Int> rhs);
1077 RValue<Int> operator|(RValue<Int> lhs, RValue<Int> rhs);
1078 RValue<Int> operator^(RValue<Int> lhs, RValue<Int> rhs);
1079 RValue<Int> operator<<(RValue<Int> lhs, RValue<Int> rhs);
1080 RValue<Int> operator>>(RValue<Int> lhs, RValue<Int> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001081 RValue<Int> operator+=(Int &lhs, RValue<Int> rhs);
1082 RValue<Int> operator-=(Int &lhs, RValue<Int> rhs);
1083 RValue<Int> operator*=(Int &lhs, RValue<Int> rhs);
1084 RValue<Int> operator/=(Int &lhs, RValue<Int> rhs);
1085 RValue<Int> operator%=(Int &lhs, RValue<Int> rhs);
1086 RValue<Int> operator&=(Int &lhs, RValue<Int> rhs);
1087 RValue<Int> operator|=(Int &lhs, RValue<Int> rhs);
1088 RValue<Int> operator^=(Int &lhs, RValue<Int> rhs);
1089 RValue<Int> operator<<=(Int &lhs, RValue<Int> rhs);
1090 RValue<Int> operator>>=(Int &lhs, RValue<Int> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001091 RValue<Int> operator+(RValue<Int> val);
1092 RValue<Int> operator-(RValue<Int> val);
1093 RValue<Int> operator~(RValue<Int> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001094 RValue<Int> operator++(Int &val, int); // Post-increment
1095 const Int &operator++(Int &val); // Pre-increment
1096 RValue<Int> operator--(Int &val, int); // Post-decrement
1097 const Int &operator--(Int &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -04001098 RValue<Bool> operator<(RValue<Int> lhs, RValue<Int> rhs);
1099 RValue<Bool> operator<=(RValue<Int> lhs, RValue<Int> rhs);
1100 RValue<Bool> operator>(RValue<Int> lhs, RValue<Int> rhs);
1101 RValue<Bool> operator>=(RValue<Int> lhs, RValue<Int> rhs);
1102 RValue<Bool> operator!=(RValue<Int> lhs, RValue<Int> rhs);
1103 RValue<Bool> operator==(RValue<Int> lhs, RValue<Int> rhs);
1104
1105 RValue<Int> Max(RValue<Int> x, RValue<Int> y);
1106 RValue<Int> Min(RValue<Int> x, RValue<Int> y);
1107 RValue<Int> Clamp(RValue<Int> x, RValue<Int> min, RValue<Int> max);
1108 RValue<Int> RoundInt(RValue<Float> cast);
1109
Nicolas Capens297d26e2016-11-18 12:52:17 -05001110 class Long : public LValue<Long>
Nicolas Capensd022e412016-09-26 13:30:14 -04001111 {
1112 public:
1113 // Long(Argument<Long> argument);
1114
1115 // explicit Long(RValue<Short> cast);
1116 // explicit Long(RValue<UShort> cast);
1117 explicit Long(RValue<Int> cast);
1118 explicit Long(RValue<UInt> cast);
1119 // explicit Long(RValue<Float> cast);
1120
Nicolas Capensa25311a2017-01-16 17:19:00 -05001121 Long() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -04001122 // Long(qword x);
1123 Long(RValue<Long> rhs);
1124 // Long(RValue<ULong> rhs);
1125 // Long(const Long &rhs);
1126 // Long(const Reference<Long> &rhs);
1127 // Long(const ULong &rhs);
1128 // Long(const Reference<ULong> &rhs);
1129
Nicolas Capens96d4e092016-11-18 14:22:38 -05001130 RValue<Long> operator=(int64_t rhs);
1131 RValue<Long> operator=(RValue<Long> rhs);
1132 // RValue<Long> operator=(RValue<ULong> rhs);
1133 RValue<Long> operator=(const Long &rhs);
1134 RValue<Long> operator=(const Reference<Long> &rhs);
1135 // RValue<Long> operator=(const ULong &rhs);
1136 // RValue<Long> operator=(const Reference<ULong> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001137
1138 static Type *getType();
1139 };
1140
1141 RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs);
1142 RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs);
Chris Forbesaa8f6992019-03-01 14:18:30 -08001143 RValue<Long> operator*(RValue<Long> lhs, RValue<Long> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001144// RValue<Long> operator/(RValue<Long> lhs, RValue<Long> rhs);
1145// RValue<Long> operator%(RValue<Long> lhs, RValue<Long> rhs);
1146// RValue<Long> operator&(RValue<Long> lhs, RValue<Long> rhs);
1147// RValue<Long> operator|(RValue<Long> lhs, RValue<Long> rhs);
1148// RValue<Long> operator^(RValue<Long> lhs, RValue<Long> rhs);
1149// RValue<Long> operator<<(RValue<Long> lhs, RValue<Long> rhs);
Chris Forbesaa8f6992019-03-01 14:18:30 -08001150 RValue<Long> operator>>(RValue<Long> lhs, RValue<Long> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001151 RValue<Long> operator+=(Long &lhs, RValue<Long> rhs);
1152 RValue<Long> operator-=(Long &lhs, RValue<Long> rhs);
1153// RValue<Long> operator*=(Long &lhs, RValue<Long> rhs);
1154// RValue<Long> operator/=(Long &lhs, RValue<Long> rhs);
1155// RValue<Long> operator%=(Long &lhs, RValue<Long> rhs);
1156// RValue<Long> operator&=(Long &lhs, RValue<Long> rhs);
1157// RValue<Long> operator|=(Long &lhs, RValue<Long> rhs);
1158// RValue<Long> operator^=(Long &lhs, RValue<Long> rhs);
1159// RValue<Long> operator<<=(Long &lhs, RValue<Long> rhs);
1160// RValue<Long> operator>>=(Long &lhs, RValue<Long> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001161// RValue<Long> operator+(RValue<Long> val);
1162// RValue<Long> operator-(RValue<Long> val);
1163// RValue<Long> operator~(RValue<Long> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001164// RValue<Long> operator++(Long &val, int); // Post-increment
1165// const Long &operator++(Long &val); // Pre-increment
1166// RValue<Long> operator--(Long &val, int); // Post-decrement
1167// const Long &operator--(Long &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -04001168// RValue<Bool> operator<(RValue<Long> lhs, RValue<Long> rhs);
1169// RValue<Bool> operator<=(RValue<Long> lhs, RValue<Long> rhs);
1170// RValue<Bool> operator>(RValue<Long> lhs, RValue<Long> rhs);
1171// RValue<Bool> operator>=(RValue<Long> lhs, RValue<Long> rhs);
1172// RValue<Bool> operator!=(RValue<Long> lhs, RValue<Long> rhs);
1173// RValue<Bool> operator==(RValue<Long> lhs, RValue<Long> rhs);
1174
1175// RValue<Long> RoundLong(RValue<Float> cast);
1176 RValue<Long> AddAtomic( RValue<Pointer<Long>> x, RValue<Long> y);
1177
Nicolas Capens297d26e2016-11-18 12:52:17 -05001178 class UInt : public LValue<UInt>
Nicolas Capensd022e412016-09-26 13:30:14 -04001179 {
1180 public:
1181 UInt(Argument<UInt> argument);
1182
1183 explicit UInt(RValue<UShort> cast);
1184 explicit UInt(RValue<Long> cast);
1185 explicit UInt(RValue<Float> cast);
1186
Nicolas Capensa25311a2017-01-16 17:19:00 -05001187 UInt() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -04001188 UInt(int x);
1189 UInt(unsigned int x);
1190 UInt(RValue<UInt> rhs);
1191 UInt(RValue<Int> rhs);
1192 UInt(const UInt &rhs);
1193 UInt(const Int &rhs);
1194 UInt(const Reference<UInt> &rhs);
1195 UInt(const Reference<Int> &rhs);
1196
Nicolas Capens96d4e092016-11-18 14:22:38 -05001197 RValue<UInt> operator=(unsigned int rhs);
1198 RValue<UInt> operator=(RValue<UInt> rhs);
1199 RValue<UInt> operator=(RValue<Int> rhs);
1200 RValue<UInt> operator=(const UInt &rhs);
1201 RValue<UInt> operator=(const Int &rhs);
1202 RValue<UInt> operator=(const Reference<UInt> &rhs);
1203 RValue<UInt> operator=(const Reference<Int> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001204
1205 static Type *getType();
1206 };
1207
1208 RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs);
1209 RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs);
1210 RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs);
1211 RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs);
1212 RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs);
1213 RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs);
1214 RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs);
1215 RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs);
1216 RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs);
1217 RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001218 RValue<UInt> operator+=(UInt &lhs, RValue<UInt> rhs);
1219 RValue<UInt> operator-=(UInt &lhs, RValue<UInt> rhs);
1220 RValue<UInt> operator*=(UInt &lhs, RValue<UInt> rhs);
1221 RValue<UInt> operator/=(UInt &lhs, RValue<UInt> rhs);
1222 RValue<UInt> operator%=(UInt &lhs, RValue<UInt> rhs);
1223 RValue<UInt> operator&=(UInt &lhs, RValue<UInt> rhs);
1224 RValue<UInt> operator|=(UInt &lhs, RValue<UInt> rhs);
1225 RValue<UInt> operator^=(UInt &lhs, RValue<UInt> rhs);
1226 RValue<UInt> operator<<=(UInt &lhs, RValue<UInt> rhs);
1227 RValue<UInt> operator>>=(UInt &lhs, RValue<UInt> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001228 RValue<UInt> operator+(RValue<UInt> val);
1229 RValue<UInt> operator-(RValue<UInt> val);
1230 RValue<UInt> operator~(RValue<UInt> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001231 RValue<UInt> operator++(UInt &val, int); // Post-increment
1232 const UInt &operator++(UInt &val); // Pre-increment
1233 RValue<UInt> operator--(UInt &val, int); // Post-decrement
1234 const UInt &operator--(UInt &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -04001235 RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs);
1236 RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs);
1237 RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs);
1238 RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs);
1239 RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs);
1240 RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs);
1241
1242 RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y);
1243 RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y);
1244 RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max);
1245// RValue<UInt> RoundUInt(RValue<Float> cast);
1246
Nicolas Capens297d26e2016-11-18 12:52:17 -05001247 class Int2 : public LValue<Int2>
Nicolas Capensd022e412016-09-26 13:30:14 -04001248 {
1249 public:
1250 // explicit Int2(RValue<Int> cast);
1251 explicit Int2(RValue<Int4> cast);
1252
Nicolas Capensa25311a2017-01-16 17:19:00 -05001253 Int2() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -04001254 Int2(int x, int y);
1255 Int2(RValue<Int2> rhs);
1256 Int2(const Int2 &rhs);
1257 Int2(const Reference<Int2> &rhs);
1258 Int2(RValue<Int> lo, RValue<Int> hi);
1259
Nicolas Capens96d4e092016-11-18 14:22:38 -05001260 RValue<Int2> operator=(RValue<Int2> rhs);
1261 RValue<Int2> operator=(const Int2 &rhs);
1262 RValue<Int2> operator=(const Reference<Int2> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001263
1264 static Type *getType();
1265 };
1266
1267 RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs);
1268 RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs);
1269// RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs);
1270// RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs);
1271// RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs);
1272 RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs);
1273 RValue<Int2> operator|(RValue<Int2> lhs, RValue<Int2> rhs);
1274 RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs);
1275 RValue<Int2> operator<<(RValue<Int2> lhs, unsigned char rhs);
1276 RValue<Int2> operator>>(RValue<Int2> lhs, unsigned char rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001277 RValue<Int2> operator+=(Int2 &lhs, RValue<Int2> rhs);
1278 RValue<Int2> operator-=(Int2 &lhs, RValue<Int2> rhs);
1279// RValue<Int2> operator*=(Int2 &lhs, RValue<Int2> rhs);
1280// RValue<Int2> operator/=(Int2 &lhs, RValue<Int2> rhs);
1281// RValue<Int2> operator%=(Int2 &lhs, RValue<Int2> rhs);
1282 RValue<Int2> operator&=(Int2 &lhs, RValue<Int2> rhs);
1283 RValue<Int2> operator|=(Int2 &lhs, RValue<Int2> rhs);
1284 RValue<Int2> operator^=(Int2 &lhs, RValue<Int2> rhs);
1285 RValue<Int2> operator<<=(Int2 &lhs, unsigned char rhs);
1286 RValue<Int2> operator>>=(Int2 &lhs, unsigned char rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001287// RValue<Int2> operator+(RValue<Int2> val);
1288// RValue<Int2> operator-(RValue<Int2> val);
1289 RValue<Int2> operator~(RValue<Int2> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001290// RValue<Int2> operator++(Int2 &val, int); // Post-increment
1291// const Int2 &operator++(Int2 &val); // Pre-increment
1292// RValue<Int2> operator--(Int2 &val, int); // Post-decrement
1293// const Int2 &operator--(Int2 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -04001294// RValue<Bool> operator<(RValue<Int2> lhs, RValue<Int2> rhs);
1295// RValue<Bool> operator<=(RValue<Int2> lhs, RValue<Int2> rhs);
1296// RValue<Bool> operator>(RValue<Int2> lhs, RValue<Int2> rhs);
1297// RValue<Bool> operator>=(RValue<Int2> lhs, RValue<Int2> rhs);
1298// RValue<Bool> operator!=(RValue<Int2> lhs, RValue<Int2> rhs);
1299// RValue<Bool> operator==(RValue<Int2> lhs, RValue<Int2> rhs);
1300
1301// RValue<Int2> RoundInt(RValue<Float4> cast);
Nicolas Capens45f187a2016-12-02 15:30:56 -05001302 RValue<Short4> UnpackLow(RValue<Int2> x, RValue<Int2> y);
1303 RValue<Short4> UnpackHigh(RValue<Int2> x, RValue<Int2> y);
Nicolas Capensd022e412016-09-26 13:30:14 -04001304 RValue<Int> Extract(RValue<Int2> val, int i);
1305 RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i);
1306
Nicolas Capens297d26e2016-11-18 12:52:17 -05001307 class UInt2 : public LValue<UInt2>
Nicolas Capensd022e412016-09-26 13:30:14 -04001308 {
1309 public:
Nicolas Capensa25311a2017-01-16 17:19:00 -05001310 UInt2() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -04001311 UInt2(unsigned int x, unsigned int y);
1312 UInt2(RValue<UInt2> rhs);
1313 UInt2(const UInt2 &rhs);
1314 UInt2(const Reference<UInt2> &rhs);
1315
Nicolas Capens96d4e092016-11-18 14:22:38 -05001316 RValue<UInt2> operator=(RValue<UInt2> rhs);
1317 RValue<UInt2> operator=(const UInt2 &rhs);
1318 RValue<UInt2> operator=(const Reference<UInt2> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001319
1320 static Type *getType();
1321 };
1322
1323 RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs);
1324 RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs);
1325// RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs);
1326// RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs);
1327// RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs);
1328 RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs);
1329 RValue<UInt2> operator|(RValue<UInt2> lhs, RValue<UInt2> rhs);
1330 RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs);
1331 RValue<UInt2> operator<<(RValue<UInt2> lhs, unsigned char rhs);
1332 RValue<UInt2> operator>>(RValue<UInt2> lhs, unsigned char rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001333 RValue<UInt2> operator+=(UInt2 &lhs, RValue<UInt2> rhs);
1334 RValue<UInt2> operator-=(UInt2 &lhs, RValue<UInt2> rhs);
1335// RValue<UInt2> operator*=(UInt2 &lhs, RValue<UInt2> rhs);
1336// RValue<UInt2> operator/=(UInt2 &lhs, RValue<UInt2> rhs);
1337// RValue<UInt2> operator%=(UInt2 &lhs, RValue<UInt2> rhs);
1338 RValue<UInt2> operator&=(UInt2 &lhs, RValue<UInt2> rhs);
1339 RValue<UInt2> operator|=(UInt2 &lhs, RValue<UInt2> rhs);
1340 RValue<UInt2> operator^=(UInt2 &lhs, RValue<UInt2> rhs);
1341 RValue<UInt2> operator<<=(UInt2 &lhs, unsigned char rhs);
1342 RValue<UInt2> operator>>=(UInt2 &lhs, unsigned char rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001343// RValue<UInt2> operator+(RValue<UInt2> val);
1344// RValue<UInt2> operator-(RValue<UInt2> val);
1345 RValue<UInt2> operator~(RValue<UInt2> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001346// RValue<UInt2> operator++(UInt2 &val, int); // Post-increment
1347// const UInt2 &operator++(UInt2 &val); // Pre-increment
1348// RValue<UInt2> operator--(UInt2 &val, int); // Post-decrement
1349// const UInt2 &operator--(UInt2 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -04001350// RValue<Bool> operator<(RValue<UInt2> lhs, RValue<UInt2> rhs);
1351// RValue<Bool> operator<=(RValue<UInt2> lhs, RValue<UInt2> rhs);
1352// RValue<Bool> operator>(RValue<UInt2> lhs, RValue<UInt2> rhs);
1353// RValue<Bool> operator>=(RValue<UInt2> lhs, RValue<UInt2> rhs);
1354// RValue<Bool> operator!=(RValue<UInt2> lhs, RValue<UInt2> rhs);
1355// RValue<Bool> operator==(RValue<UInt2> lhs, RValue<UInt2> rhs);
1356
1357// RValue<UInt2> RoundInt(RValue<Float4> cast);
1358
Nicolas Capenscb986762017-01-20 11:34:37 -05001359 template<class T>
1360 struct Scalar;
1361
1362 template<class Vector4>
1363 struct XYZW;
1364
1365 template<class Vector4, int T>
1366 class Swizzle2
1367 {
1368 friend Vector4;
1369
1370 public:
1371 operator RValue<Vector4>() const;
1372
1373 private:
1374 Vector4 *parent;
1375 };
1376
1377 template<class Vector4, int T>
1378 class Swizzle4
1379 {
1380 public:
1381 operator RValue<Vector4>() const;
1382
1383 private:
1384 Vector4 *parent;
1385 };
1386
1387 template<class Vector4, int T>
1388 class SwizzleMask4
1389 {
1390 friend XYZW<Vector4>;
1391
1392 public:
1393 operator RValue<Vector4>() const;
1394
1395 RValue<Vector4> operator=(RValue<Vector4> rhs);
1396 RValue<Vector4> operator=(RValue<typename Scalar<Vector4>::Type> rhs);
1397
1398 private:
1399 Vector4 *parent;
1400 };
1401
1402 template<>
1403 struct Scalar<Float4>
1404 {
1405 using Type = Float;
1406 };
1407
1408 template<>
1409 struct Scalar<Int4>
1410 {
1411 using Type = Int;
1412 };
1413
1414 template<>
1415 struct Scalar<UInt4>
1416 {
1417 using Type = UInt;
1418 };
1419
1420 template<class Vector4, int T>
1421 class SwizzleMask1
1422 {
1423 public:
1424 operator RValue<typename Scalar<Vector4>::Type>() const;
1425 operator RValue<Vector4>() const;
1426
1427 RValue<Vector4> operator=(float x);
1428 RValue<Vector4> operator=(RValue<Vector4> rhs);
1429 RValue<Vector4> operator=(RValue<typename Scalar<Vector4>::Type> rhs);
1430
1431 private:
1432 Float4 *parent;
1433 };
1434
1435 template<class Vector4, int T>
1436 class SwizzleMask2
1437 {
1438 friend class Float4;
1439
1440 public:
1441 operator RValue<Vector4>() const;
1442
1443 RValue<Vector4> operator=(RValue<Vector4> rhs);
1444
1445 private:
1446 Float4 *parent;
1447 };
1448
1449 template<class Vector4>
1450 struct XYZW
1451 {
1452 friend Vector4;
1453
1454 private:
1455 XYZW(Vector4 *parent)
1456 {
1457 xyzw.parent = parent;
1458 }
1459
1460 public:
1461 union
1462 {
1463 SwizzleMask1<Vector4, 0x00> x;
1464 SwizzleMask1<Vector4, 0x55> y;
1465 SwizzleMask1<Vector4, 0xAA> z;
1466 SwizzleMask1<Vector4, 0xFF> w;
1467 Swizzle2<Vector4, 0x00> xx;
1468 Swizzle2<Vector4, 0x01> yx;
1469 Swizzle2<Vector4, 0x02> zx;
1470 Swizzle2<Vector4, 0x03> wx;
1471 SwizzleMask2<Vector4, 0x54> xy;
1472 Swizzle2<Vector4, 0x55> yy;
1473 Swizzle2<Vector4, 0x56> zy;
1474 Swizzle2<Vector4, 0x57> wy;
1475 SwizzleMask2<Vector4, 0xA8> xz;
1476 SwizzleMask2<Vector4, 0xA9> yz;
1477 Swizzle2<Vector4, 0xAA> zz;
1478 Swizzle2<Vector4, 0xAB> wz;
1479 SwizzleMask2<Vector4, 0xFC> xw;
1480 SwizzleMask2<Vector4, 0xFD> yw;
1481 SwizzleMask2<Vector4, 0xFE> zw;
1482 Swizzle2<Vector4, 0xFF> ww;
1483 Swizzle4<Vector4, 0x00> xxx;
1484 Swizzle4<Vector4, 0x01> yxx;
1485 Swizzle4<Vector4, 0x02> zxx;
1486 Swizzle4<Vector4, 0x03> wxx;
1487 Swizzle4<Vector4, 0x04> xyx;
1488 Swizzle4<Vector4, 0x05> yyx;
1489 Swizzle4<Vector4, 0x06> zyx;
1490 Swizzle4<Vector4, 0x07> wyx;
1491 Swizzle4<Vector4, 0x08> xzx;
1492 Swizzle4<Vector4, 0x09> yzx;
1493 Swizzle4<Vector4, 0x0A> zzx;
1494 Swizzle4<Vector4, 0x0B> wzx;
1495 Swizzle4<Vector4, 0x0C> xwx;
1496 Swizzle4<Vector4, 0x0D> ywx;
1497 Swizzle4<Vector4, 0x0E> zwx;
1498 Swizzle4<Vector4, 0x0F> wwx;
1499 Swizzle4<Vector4, 0x50> xxy;
1500 Swizzle4<Vector4, 0x51> yxy;
1501 Swizzle4<Vector4, 0x52> zxy;
1502 Swizzle4<Vector4, 0x53> wxy;
1503 Swizzle4<Vector4, 0x54> xyy;
1504 Swizzle4<Vector4, 0x55> yyy;
1505 Swizzle4<Vector4, 0x56> zyy;
1506 Swizzle4<Vector4, 0x57> wyy;
1507 Swizzle4<Vector4, 0x58> xzy;
1508 Swizzle4<Vector4, 0x59> yzy;
1509 Swizzle4<Vector4, 0x5A> zzy;
1510 Swizzle4<Vector4, 0x5B> wzy;
1511 Swizzle4<Vector4, 0x5C> xwy;
1512 Swizzle4<Vector4, 0x5D> ywy;
1513 Swizzle4<Vector4, 0x5E> zwy;
1514 Swizzle4<Vector4, 0x5F> wwy;
1515 Swizzle4<Vector4, 0xA0> xxz;
1516 Swizzle4<Vector4, 0xA1> yxz;
1517 Swizzle4<Vector4, 0xA2> zxz;
1518 Swizzle4<Vector4, 0xA3> wxz;
1519 SwizzleMask4<Vector4, 0xA4> xyz;
1520 Swizzle4<Vector4, 0xA5> yyz;
1521 Swizzle4<Vector4, 0xA6> zyz;
1522 Swizzle4<Vector4, 0xA7> wyz;
1523 Swizzle4<Vector4, 0xA8> xzz;
1524 Swizzle4<Vector4, 0xA9> yzz;
1525 Swizzle4<Vector4, 0xAA> zzz;
1526 Swizzle4<Vector4, 0xAB> wzz;
1527 Swizzle4<Vector4, 0xAC> xwz;
1528 Swizzle4<Vector4, 0xAD> ywz;
1529 Swizzle4<Vector4, 0xAE> zwz;
1530 Swizzle4<Vector4, 0xAF> wwz;
1531 Swizzle4<Vector4, 0xF0> xxw;
1532 Swizzle4<Vector4, 0xF1> yxw;
1533 Swizzle4<Vector4, 0xF2> zxw;
1534 Swizzle4<Vector4, 0xF3> wxw;
1535 SwizzleMask4<Vector4, 0xF4> xyw;
1536 Swizzle4<Vector4, 0xF5> yyw;
1537 Swizzle4<Vector4, 0xF6> zyw;
1538 Swizzle4<Vector4, 0xF7> wyw;
1539 SwizzleMask4<Vector4, 0xF8> xzw;
1540 SwizzleMask4<Vector4, 0xF9> yzw;
1541 Swizzle4<Vector4, 0xFA> zzw;
1542 Swizzle4<Vector4, 0xFB> wzw;
1543 Swizzle4<Vector4, 0xFC> xww;
1544 Swizzle4<Vector4, 0xFD> yww;
1545 Swizzle4<Vector4, 0xFE> zww;
1546 Swizzle4<Vector4, 0xFF> www;
1547 Swizzle4<Vector4, 0x00> xxxx;
1548 Swizzle4<Vector4, 0x01> yxxx;
1549 Swizzle4<Vector4, 0x02> zxxx;
1550 Swizzle4<Vector4, 0x03> wxxx;
1551 Swizzle4<Vector4, 0x04> xyxx;
1552 Swizzle4<Vector4, 0x05> yyxx;
1553 Swizzle4<Vector4, 0x06> zyxx;
1554 Swizzle4<Vector4, 0x07> wyxx;
1555 Swizzle4<Vector4, 0x08> xzxx;
1556 Swizzle4<Vector4, 0x09> yzxx;
1557 Swizzle4<Vector4, 0x0A> zzxx;
1558 Swizzle4<Vector4, 0x0B> wzxx;
1559 Swizzle4<Vector4, 0x0C> xwxx;
1560 Swizzle4<Vector4, 0x0D> ywxx;
1561 Swizzle4<Vector4, 0x0E> zwxx;
1562 Swizzle4<Vector4, 0x0F> wwxx;
1563 Swizzle4<Vector4, 0x10> xxyx;
1564 Swizzle4<Vector4, 0x11> yxyx;
1565 Swizzle4<Vector4, 0x12> zxyx;
1566 Swizzle4<Vector4, 0x13> wxyx;
1567 Swizzle4<Vector4, 0x14> xyyx;
1568 Swizzle4<Vector4, 0x15> yyyx;
1569 Swizzle4<Vector4, 0x16> zyyx;
1570 Swizzle4<Vector4, 0x17> wyyx;
1571 Swizzle4<Vector4, 0x18> xzyx;
1572 Swizzle4<Vector4, 0x19> yzyx;
1573 Swizzle4<Vector4, 0x1A> zzyx;
1574 Swizzle4<Vector4, 0x1B> wzyx;
1575 Swizzle4<Vector4, 0x1C> xwyx;
1576 Swizzle4<Vector4, 0x1D> ywyx;
1577 Swizzle4<Vector4, 0x1E> zwyx;
1578 Swizzle4<Vector4, 0x1F> wwyx;
1579 Swizzle4<Vector4, 0x20> xxzx;
1580 Swizzle4<Vector4, 0x21> yxzx;
1581 Swizzle4<Vector4, 0x22> zxzx;
1582 Swizzle4<Vector4, 0x23> wxzx;
1583 Swizzle4<Vector4, 0x24> xyzx;
1584 Swizzle4<Vector4, 0x25> yyzx;
1585 Swizzle4<Vector4, 0x26> zyzx;
1586 Swizzle4<Vector4, 0x27> wyzx;
1587 Swizzle4<Vector4, 0x28> xzzx;
1588 Swizzle4<Vector4, 0x29> yzzx;
1589 Swizzle4<Vector4, 0x2A> zzzx;
1590 Swizzle4<Vector4, 0x2B> wzzx;
1591 Swizzle4<Vector4, 0x2C> xwzx;
1592 Swizzle4<Vector4, 0x2D> ywzx;
1593 Swizzle4<Vector4, 0x2E> zwzx;
1594 Swizzle4<Vector4, 0x2F> wwzx;
1595 Swizzle4<Vector4, 0x30> xxwx;
1596 Swizzle4<Vector4, 0x31> yxwx;
1597 Swizzle4<Vector4, 0x32> zxwx;
1598 Swizzle4<Vector4, 0x33> wxwx;
1599 Swizzle4<Vector4, 0x34> xywx;
1600 Swizzle4<Vector4, 0x35> yywx;
1601 Swizzle4<Vector4, 0x36> zywx;
1602 Swizzle4<Vector4, 0x37> wywx;
1603 Swizzle4<Vector4, 0x38> xzwx;
1604 Swizzle4<Vector4, 0x39> yzwx;
1605 Swizzle4<Vector4, 0x3A> zzwx;
1606 Swizzle4<Vector4, 0x3B> wzwx;
1607 Swizzle4<Vector4, 0x3C> xwwx;
1608 Swizzle4<Vector4, 0x3D> ywwx;
1609 Swizzle4<Vector4, 0x3E> zwwx;
1610 Swizzle4<Vector4, 0x3F> wwwx;
1611 Swizzle4<Vector4, 0x40> xxxy;
1612 Swizzle4<Vector4, 0x41> yxxy;
1613 Swizzle4<Vector4, 0x42> zxxy;
1614 Swizzle4<Vector4, 0x43> wxxy;
1615 Swizzle4<Vector4, 0x44> xyxy;
1616 Swizzle4<Vector4, 0x45> yyxy;
1617 Swizzle4<Vector4, 0x46> zyxy;
1618 Swizzle4<Vector4, 0x47> wyxy;
1619 Swizzle4<Vector4, 0x48> xzxy;
1620 Swizzle4<Vector4, 0x49> yzxy;
1621 Swizzle4<Vector4, 0x4A> zzxy;
1622 Swizzle4<Vector4, 0x4B> wzxy;
1623 Swizzle4<Vector4, 0x4C> xwxy;
1624 Swizzle4<Vector4, 0x4D> ywxy;
1625 Swizzle4<Vector4, 0x4E> zwxy;
1626 Swizzle4<Vector4, 0x4F> wwxy;
1627 Swizzle4<Vector4, 0x50> xxyy;
1628 Swizzle4<Vector4, 0x51> yxyy;
1629 Swizzle4<Vector4, 0x52> zxyy;
1630 Swizzle4<Vector4, 0x53> wxyy;
1631 Swizzle4<Vector4, 0x54> xyyy;
1632 Swizzle4<Vector4, 0x55> yyyy;
1633 Swizzle4<Vector4, 0x56> zyyy;
1634 Swizzle4<Vector4, 0x57> wyyy;
1635 Swizzle4<Vector4, 0x58> xzyy;
1636 Swizzle4<Vector4, 0x59> yzyy;
1637 Swizzle4<Vector4, 0x5A> zzyy;
1638 Swizzle4<Vector4, 0x5B> wzyy;
1639 Swizzle4<Vector4, 0x5C> xwyy;
1640 Swizzle4<Vector4, 0x5D> ywyy;
1641 Swizzle4<Vector4, 0x5E> zwyy;
1642 Swizzle4<Vector4, 0x5F> wwyy;
1643 Swizzle4<Vector4, 0x60> xxzy;
1644 Swizzle4<Vector4, 0x61> yxzy;
1645 Swizzle4<Vector4, 0x62> zxzy;
1646 Swizzle4<Vector4, 0x63> wxzy;
1647 Swizzle4<Vector4, 0x64> xyzy;
1648 Swizzle4<Vector4, 0x65> yyzy;
1649 Swizzle4<Vector4, 0x66> zyzy;
1650 Swizzle4<Vector4, 0x67> wyzy;
1651 Swizzle4<Vector4, 0x68> xzzy;
1652 Swizzle4<Vector4, 0x69> yzzy;
1653 Swizzle4<Vector4, 0x6A> zzzy;
1654 Swizzle4<Vector4, 0x6B> wzzy;
1655 Swizzle4<Vector4, 0x6C> xwzy;
1656 Swizzle4<Vector4, 0x6D> ywzy;
1657 Swizzle4<Vector4, 0x6E> zwzy;
1658 Swizzle4<Vector4, 0x6F> wwzy;
1659 Swizzle4<Vector4, 0x70> xxwy;
1660 Swizzle4<Vector4, 0x71> yxwy;
1661 Swizzle4<Vector4, 0x72> zxwy;
1662 Swizzle4<Vector4, 0x73> wxwy;
1663 Swizzle4<Vector4, 0x74> xywy;
1664 Swizzle4<Vector4, 0x75> yywy;
1665 Swizzle4<Vector4, 0x76> zywy;
1666 Swizzle4<Vector4, 0x77> wywy;
1667 Swizzle4<Vector4, 0x78> xzwy;
1668 Swizzle4<Vector4, 0x79> yzwy;
1669 Swizzle4<Vector4, 0x7A> zzwy;
1670 Swizzle4<Vector4, 0x7B> wzwy;
1671 Swizzle4<Vector4, 0x7C> xwwy;
1672 Swizzle4<Vector4, 0x7D> ywwy;
1673 Swizzle4<Vector4, 0x7E> zwwy;
1674 Swizzle4<Vector4, 0x7F> wwwy;
1675 Swizzle4<Vector4, 0x80> xxxz;
1676 Swizzle4<Vector4, 0x81> yxxz;
1677 Swizzle4<Vector4, 0x82> zxxz;
1678 Swizzle4<Vector4, 0x83> wxxz;
1679 Swizzle4<Vector4, 0x84> xyxz;
1680 Swizzle4<Vector4, 0x85> yyxz;
1681 Swizzle4<Vector4, 0x86> zyxz;
1682 Swizzle4<Vector4, 0x87> wyxz;
1683 Swizzle4<Vector4, 0x88> xzxz;
1684 Swizzle4<Vector4, 0x89> yzxz;
1685 Swizzle4<Vector4, 0x8A> zzxz;
1686 Swizzle4<Vector4, 0x8B> wzxz;
1687 Swizzle4<Vector4, 0x8C> xwxz;
1688 Swizzle4<Vector4, 0x8D> ywxz;
1689 Swizzle4<Vector4, 0x8E> zwxz;
1690 Swizzle4<Vector4, 0x8F> wwxz;
1691 Swizzle4<Vector4, 0x90> xxyz;
1692 Swizzle4<Vector4, 0x91> yxyz;
1693 Swizzle4<Vector4, 0x92> zxyz;
1694 Swizzle4<Vector4, 0x93> wxyz;
1695 Swizzle4<Vector4, 0x94> xyyz;
1696 Swizzle4<Vector4, 0x95> yyyz;
1697 Swizzle4<Vector4, 0x96> zyyz;
1698 Swizzle4<Vector4, 0x97> wyyz;
1699 Swizzle4<Vector4, 0x98> xzyz;
1700 Swizzle4<Vector4, 0x99> yzyz;
1701 Swizzle4<Vector4, 0x9A> zzyz;
1702 Swizzle4<Vector4, 0x9B> wzyz;
1703 Swizzle4<Vector4, 0x9C> xwyz;
1704 Swizzle4<Vector4, 0x9D> ywyz;
1705 Swizzle4<Vector4, 0x9E> zwyz;
1706 Swizzle4<Vector4, 0x9F> wwyz;
1707 Swizzle4<Vector4, 0xA0> xxzz;
1708 Swizzle4<Vector4, 0xA1> yxzz;
1709 Swizzle4<Vector4, 0xA2> zxzz;
1710 Swizzle4<Vector4, 0xA3> wxzz;
1711 Swizzle4<Vector4, 0xA4> xyzz;
1712 Swizzle4<Vector4, 0xA5> yyzz;
1713 Swizzle4<Vector4, 0xA6> zyzz;
1714 Swizzle4<Vector4, 0xA7> wyzz;
1715 Swizzle4<Vector4, 0xA8> xzzz;
1716 Swizzle4<Vector4, 0xA9> yzzz;
1717 Swizzle4<Vector4, 0xAA> zzzz;
1718 Swizzle4<Vector4, 0xAB> wzzz;
1719 Swizzle4<Vector4, 0xAC> xwzz;
1720 Swizzle4<Vector4, 0xAD> ywzz;
1721 Swizzle4<Vector4, 0xAE> zwzz;
1722 Swizzle4<Vector4, 0xAF> wwzz;
1723 Swizzle4<Vector4, 0xB0> xxwz;
1724 Swizzle4<Vector4, 0xB1> yxwz;
1725 Swizzle4<Vector4, 0xB2> zxwz;
1726 Swizzle4<Vector4, 0xB3> wxwz;
1727 Swizzle4<Vector4, 0xB4> xywz;
1728 Swizzle4<Vector4, 0xB5> yywz;
1729 Swizzle4<Vector4, 0xB6> zywz;
1730 Swizzle4<Vector4, 0xB7> wywz;
1731 Swizzle4<Vector4, 0xB8> xzwz;
1732 Swizzle4<Vector4, 0xB9> yzwz;
1733 Swizzle4<Vector4, 0xBA> zzwz;
1734 Swizzle4<Vector4, 0xBB> wzwz;
1735 Swizzle4<Vector4, 0xBC> xwwz;
1736 Swizzle4<Vector4, 0xBD> ywwz;
1737 Swizzle4<Vector4, 0xBE> zwwz;
1738 Swizzle4<Vector4, 0xBF> wwwz;
1739 Swizzle4<Vector4, 0xC0> xxxw;
1740 Swizzle4<Vector4, 0xC1> yxxw;
1741 Swizzle4<Vector4, 0xC2> zxxw;
1742 Swizzle4<Vector4, 0xC3> wxxw;
1743 Swizzle4<Vector4, 0xC4> xyxw;
1744 Swizzle4<Vector4, 0xC5> yyxw;
1745 Swizzle4<Vector4, 0xC6> zyxw;
1746 Swizzle4<Vector4, 0xC7> wyxw;
1747 Swizzle4<Vector4, 0xC8> xzxw;
1748 Swizzle4<Vector4, 0xC9> yzxw;
1749 Swizzle4<Vector4, 0xCA> zzxw;
1750 Swizzle4<Vector4, 0xCB> wzxw;
1751 Swizzle4<Vector4, 0xCC> xwxw;
1752 Swizzle4<Vector4, 0xCD> ywxw;
1753 Swizzle4<Vector4, 0xCE> zwxw;
1754 Swizzle4<Vector4, 0xCF> wwxw;
1755 Swizzle4<Vector4, 0xD0> xxyw;
1756 Swizzle4<Vector4, 0xD1> yxyw;
1757 Swizzle4<Vector4, 0xD2> zxyw;
1758 Swizzle4<Vector4, 0xD3> wxyw;
1759 Swizzle4<Vector4, 0xD4> xyyw;
1760 Swizzle4<Vector4, 0xD5> yyyw;
1761 Swizzle4<Vector4, 0xD6> zyyw;
1762 Swizzle4<Vector4, 0xD7> wyyw;
1763 Swizzle4<Vector4, 0xD8> xzyw;
1764 Swizzle4<Vector4, 0xD9> yzyw;
1765 Swizzle4<Vector4, 0xDA> zzyw;
1766 Swizzle4<Vector4, 0xDB> wzyw;
1767 Swizzle4<Vector4, 0xDC> xwyw;
1768 Swizzle4<Vector4, 0xDD> ywyw;
1769 Swizzle4<Vector4, 0xDE> zwyw;
1770 Swizzle4<Vector4, 0xDF> wwyw;
1771 Swizzle4<Vector4, 0xE0> xxzw;
1772 Swizzle4<Vector4, 0xE1> yxzw;
1773 Swizzle4<Vector4, 0xE2> zxzw;
1774 Swizzle4<Vector4, 0xE3> wxzw;
1775 SwizzleMask4<Vector4, 0xE4> xyzw;
1776 Swizzle4<Vector4, 0xE5> yyzw;
1777 Swizzle4<Vector4, 0xE6> zyzw;
1778 Swizzle4<Vector4, 0xE7> wyzw;
1779 Swizzle4<Vector4, 0xE8> xzzw;
1780 Swizzle4<Vector4, 0xE9> yzzw;
1781 Swizzle4<Vector4, 0xEA> zzzw;
1782 Swizzle4<Vector4, 0xEB> wzzw;
1783 Swizzle4<Vector4, 0xEC> xwzw;
1784 Swizzle4<Vector4, 0xED> ywzw;
1785 Swizzle4<Vector4, 0xEE> zwzw;
1786 Swizzle4<Vector4, 0xEF> wwzw;
1787 Swizzle4<Vector4, 0xF0> xxww;
1788 Swizzle4<Vector4, 0xF1> yxww;
1789 Swizzle4<Vector4, 0xF2> zxww;
1790 Swizzle4<Vector4, 0xF3> wxww;
1791 Swizzle4<Vector4, 0xF4> xyww;
1792 Swizzle4<Vector4, 0xF5> yyww;
1793 Swizzle4<Vector4, 0xF6> zyww;
1794 Swizzle4<Vector4, 0xF7> wyww;
1795 Swizzle4<Vector4, 0xF8> xzww;
1796 Swizzle4<Vector4, 0xF9> yzww;
1797 Swizzle4<Vector4, 0xFA> zzww;
1798 Swizzle4<Vector4, 0xFB> wzww;
1799 Swizzle4<Vector4, 0xFC> xwww;
1800 Swizzle4<Vector4, 0xFD> ywww;
1801 Swizzle4<Vector4, 0xFE> zwww;
1802 Swizzle4<Vector4, 0xFF> wwww;
1803 };
1804 };
1805
1806 class Int4 : public LValue<Int4>, public XYZW<Int4>
Nicolas Capensd022e412016-09-26 13:30:14 -04001807 {
1808 public:
1809 explicit Int4(RValue<Byte4> cast);
1810 explicit Int4(RValue<SByte4> cast);
1811 explicit Int4(RValue<Float4> cast);
1812 explicit Int4(RValue<Short4> cast);
1813 explicit Int4(RValue<UShort4> cast);
1814
Nicolas Capenscb986762017-01-20 11:34:37 -05001815 Int4();
Nicolas Capensd022e412016-09-26 13:30:14 -04001816 Int4(int xyzw);
1817 Int4(int x, int yzw);
1818 Int4(int x, int y, int zw);
1819 Int4(int x, int y, int z, int w);
1820 Int4(RValue<Int4> rhs);
1821 Int4(const Int4 &rhs);
1822 Int4(const Reference<Int4> &rhs);
1823 Int4(RValue<UInt4> rhs);
1824 Int4(const UInt4 &rhs);
1825 Int4(const Reference<UInt4> &rhs);
1826 Int4(RValue<Int2> lo, RValue<Int2> hi);
1827 Int4(RValue<Int> rhs);
1828 Int4(const Int &rhs);
1829 Int4(const Reference<Int> &rhs);
1830
Nicolas Capens96d4e092016-11-18 14:22:38 -05001831 RValue<Int4> operator=(RValue<Int4> rhs);
1832 RValue<Int4> operator=(const Int4 &rhs);
1833 RValue<Int4> operator=(const Reference<Int4> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001834
1835 static Type *getType();
1836
1837 private:
1838 void constant(int x, int y, int z, int w);
1839 };
1840
1841 RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs);
1842 RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs);
1843 RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs);
1844 RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs);
1845 RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs);
1846 RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs);
1847 RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs);
1848 RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs);
1849 RValue<Int4> operator<<(RValue<Int4> lhs, unsigned char rhs);
1850 RValue<Int4> operator>>(RValue<Int4> lhs, unsigned char rhs);
1851 RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs);
1852 RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001853 RValue<Int4> operator+=(Int4 &lhs, RValue<Int4> rhs);
1854 RValue<Int4> operator-=(Int4 &lhs, RValue<Int4> rhs);
1855 RValue<Int4> operator*=(Int4 &lhs, RValue<Int4> rhs);
1856// RValue<Int4> operator/=(Int4 &lhs, RValue<Int4> rhs);
1857// RValue<Int4> operator%=(Int4 &lhs, RValue<Int4> rhs);
1858 RValue<Int4> operator&=(Int4 &lhs, RValue<Int4> rhs);
1859 RValue<Int4> operator|=(Int4 &lhs, RValue<Int4> rhs);
1860 RValue<Int4> operator^=(Int4 &lhs, RValue<Int4> rhs);
1861 RValue<Int4> operator<<=(Int4 &lhs, unsigned char rhs);
1862 RValue<Int4> operator>>=(Int4 &lhs, unsigned char rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001863 RValue<Int4> operator+(RValue<Int4> val);
1864 RValue<Int4> operator-(RValue<Int4> val);
1865 RValue<Int4> operator~(RValue<Int4> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001866// RValue<Int4> operator++(Int4 &val, int); // Post-increment
1867// const Int4 &operator++(Int4 &val); // Pre-increment
1868// RValue<Int4> operator--(Int4 &val, int); // Post-decrement
1869// const Int4 &operator--(Int4 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -04001870// RValue<Bool> operator<(RValue<Int4> lhs, RValue<Int4> rhs);
1871// RValue<Bool> operator<=(RValue<Int4> lhs, RValue<Int4> rhs);
1872// RValue<Bool> operator>(RValue<Int4> lhs, RValue<Int4> rhs);
1873// RValue<Bool> operator>=(RValue<Int4> lhs, RValue<Int4> rhs);
1874// RValue<Bool> operator!=(RValue<Int4> lhs, RValue<Int4> rhs);
1875// RValue<Bool> operator==(RValue<Int4> lhs, RValue<Int4> rhs);
1876
Nicolas Capens4b743732018-05-28 13:22:07 -04001877 inline RValue<Int4> operator+(RValue<Int> lhs, RValue<Int4> rhs)
1878 {
1879 return Int4(lhs) + rhs;
1880 }
1881
1882 inline RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int> rhs)
1883 {
1884 return lhs + Int4(rhs);
1885 }
1886
Nicolas Capensd022e412016-09-26 13:30:14 -04001887 RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y);
1888 RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y);
1889 RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y);
1890 RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y);
1891 RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y);
1892 RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y);
Ben Claytone95eeb12019-03-04 16:32:09 +00001893 inline RValue<Int4> CmpGT(RValue<Int4> x, RValue<Int4> y) { return CmpNLE(x, y); }
1894 inline RValue<Int4> CmpGE(RValue<Int4> x, RValue<Int4> y) { return CmpNLT(x, y); }
Nicolas Capensd022e412016-09-26 13:30:14 -04001895 RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y);
1896 RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y);
1897 RValue<Int4> RoundInt(RValue<Float4> cast);
Nicolas Capens33438a62017-09-27 11:47:35 -04001898 RValue<Short8> PackSigned(RValue<Int4> x, RValue<Int4> y);
1899 RValue<UShort8> PackUnsigned(RValue<Int4> x, RValue<Int4> y);
Nicolas Capensc94ab742016-11-08 15:15:31 -05001900 RValue<Int> Extract(RValue<Int4> val, int i);
Nicolas Capensd022e412016-09-26 13:30:14 -04001901 RValue<Int4> Insert(RValue<Int4> val, RValue<Int> element, int i);
1902 RValue<Int> SignMask(RValue<Int4> x);
1903 RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select);
Chris Forbese86b6dc2019-03-01 09:08:47 -08001904 RValue<Int4> MulHigh(RValue<Int4> x, RValue<Int4> y);
Nicolas Capensd022e412016-09-26 13:30:14 -04001905
Nicolas Capenscb986762017-01-20 11:34:37 -05001906 class UInt4 : public LValue<UInt4>, public XYZW<UInt4>
Nicolas Capensd022e412016-09-26 13:30:14 -04001907 {
1908 public:
1909 explicit UInt4(RValue<Float4> cast);
1910
Nicolas Capenscb986762017-01-20 11:34:37 -05001911 UInt4();
Nicolas Capensd022e412016-09-26 13:30:14 -04001912 UInt4(int xyzw);
1913 UInt4(int x, int yzw);
1914 UInt4(int x, int y, int zw);
1915 UInt4(int x, int y, int z, int w);
Nicolas Capensd022e412016-09-26 13:30:14 -04001916 UInt4(RValue<UInt4> rhs);
1917 UInt4(const UInt4 &rhs);
1918 UInt4(const Reference<UInt4> &rhs);
1919 UInt4(RValue<Int4> rhs);
1920 UInt4(const Int4 &rhs);
1921 UInt4(const Reference<Int4> &rhs);
1922 UInt4(RValue<UInt2> lo, RValue<UInt2> hi);
1923
Nicolas Capens96d4e092016-11-18 14:22:38 -05001924 RValue<UInt4> operator=(RValue<UInt4> rhs);
1925 RValue<UInt4> operator=(const UInt4 &rhs);
1926 RValue<UInt4> operator=(const Reference<UInt4> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001927
1928 static Type *getType();
1929
1930 private:
1931 void constant(int x, int y, int z, int w);
1932 };
1933
1934 RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs);
1935 RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs);
1936 RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs);
1937 RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs);
1938 RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs);
1939 RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs);
1940 RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs);
1941 RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs);
1942 RValue<UInt4> operator<<(RValue<UInt4> lhs, unsigned char rhs);
1943 RValue<UInt4> operator>>(RValue<UInt4> lhs, unsigned char rhs);
1944 RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs);
1945 RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001946 RValue<UInt4> operator+=(UInt4 &lhs, RValue<UInt4> rhs);
1947 RValue<UInt4> operator-=(UInt4 &lhs, RValue<UInt4> rhs);
1948 RValue<UInt4> operator*=(UInt4 &lhs, RValue<UInt4> rhs);
1949// RValue<UInt4> operator/=(UInt4 &lhs, RValue<UInt4> rhs);
1950// RValue<UInt4> operator%=(UInt4 &lhs, RValue<UInt4> rhs);
1951 RValue<UInt4> operator&=(UInt4 &lhs, RValue<UInt4> rhs);
1952 RValue<UInt4> operator|=(UInt4 &lhs, RValue<UInt4> rhs);
1953 RValue<UInt4> operator^=(UInt4 &lhs, RValue<UInt4> rhs);
1954 RValue<UInt4> operator<<=(UInt4 &lhs, unsigned char rhs);
1955 RValue<UInt4> operator>>=(UInt4 &lhs, unsigned char rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04001956 RValue<UInt4> operator+(RValue<UInt4> val);
1957 RValue<UInt4> operator-(RValue<UInt4> val);
1958 RValue<UInt4> operator~(RValue<UInt4> val);
Nicolas Capens96d4e092016-11-18 14:22:38 -05001959// RValue<UInt4> operator++(UInt4 &val, int); // Post-increment
1960// const UInt4 &operator++(UInt4 &val); // Pre-increment
1961// RValue<UInt4> operator--(UInt4 &val, int); // Post-decrement
1962// const UInt4 &operator--(UInt4 &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -04001963// RValue<Bool> operator<(RValue<UInt4> lhs, RValue<UInt4> rhs);
1964// RValue<Bool> operator<=(RValue<UInt4> lhs, RValue<UInt4> rhs);
1965// RValue<Bool> operator>(RValue<UInt4> lhs, RValue<UInt4> rhs);
1966// RValue<Bool> operator>=(RValue<UInt4> lhs, RValue<UInt4> rhs);
1967// RValue<Bool> operator!=(RValue<UInt4> lhs, RValue<UInt4> rhs);
1968// RValue<Bool> operator==(RValue<UInt4> lhs, RValue<UInt4> rhs);
1969
1970 RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y);
1971 RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y);
1972 RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y);
1973 RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y);
1974 RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y);
1975 RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y);
Ben Claytone95eeb12019-03-04 16:32:09 +00001976 inline RValue<UInt4> CmpGT(RValue<UInt4> x, RValue<UInt4> y) { return CmpNLE(x, y); }
1977 inline RValue<UInt4> CmpGE(RValue<UInt4> x, RValue<UInt4> y) { return CmpNLT(x, y); }
Nicolas Capensd022e412016-09-26 13:30:14 -04001978 RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y);
1979 RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y);
Chris Forbese86b6dc2019-03-01 09:08:47 -08001980 RValue<UInt4> MulHigh(RValue<UInt4> x, RValue<UInt4> y);
Ben Claytonfc77af12019-04-09 10:48:00 -04001981 RValue<UInt> Extract(RValue<UInt4> val, int i);
1982 RValue<UInt4> Insert(RValue<UInt4> val, RValue<UInt> element, int i);
Nicolas Capensd022e412016-09-26 13:30:14 -04001983// RValue<UInt4> RoundInt(RValue<Float4> cast);
Nicolas Capensd022e412016-09-26 13:30:14 -04001984
Alexis Hetu734e2572018-12-20 14:00:49 -05001985 class Half : public LValue<Half>
1986 {
1987 public:
1988 explicit Half(RValue<Float> cast);
1989
1990 static Type *getType();
1991 };
1992
Nicolas Capens297d26e2016-11-18 12:52:17 -05001993 class Float : public LValue<Float>
Nicolas Capensd022e412016-09-26 13:30:14 -04001994 {
1995 public:
1996 explicit Float(RValue<Int> cast);
Alexis Hetucfd96322017-07-24 14:44:33 -04001997 explicit Float(RValue<UInt> cast);
Alexis Hetu734e2572018-12-20 14:00:49 -05001998 explicit Float(RValue<Half> cast);
Nicolas Capensd022e412016-09-26 13:30:14 -04001999
Nicolas Capensa25311a2017-01-16 17:19:00 -05002000 Float() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -04002001 Float(float x);
2002 Float(RValue<Float> rhs);
2003 Float(const Float &rhs);
2004 Float(const Reference<Float> &rhs);
Ben Claytonf3b57972019-03-15 09:56:47 +00002005 Float(Argument<Float> argument);
Nicolas Capensd022e412016-09-26 13:30:14 -04002006
2007 template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002008 Float(const SwizzleMask1<Float4, T> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04002009
Nicolas Capens96d4e092016-11-18 14:22:38 -05002010 // RValue<Float> operator=(float rhs); // FIXME: Implement
2011 RValue<Float> operator=(RValue<Float> rhs);
2012 RValue<Float> operator=(const Float &rhs);
2013 RValue<Float> operator=(const Reference<Float> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04002014
2015 template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002016 RValue<Float> operator=(const SwizzleMask1<Float4, T> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04002017
2018 static Type *getType();
2019 };
2020
2021 RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs);
2022 RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs);
2023 RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs);
2024 RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05002025 RValue<Float> operator+=(Float &lhs, RValue<Float> rhs);
2026 RValue<Float> operator-=(Float &lhs, RValue<Float> rhs);
2027 RValue<Float> operator*=(Float &lhs, RValue<Float> rhs);
2028 RValue<Float> operator/=(Float &lhs, RValue<Float> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04002029 RValue<Float> operator+(RValue<Float> val);
2030 RValue<Float> operator-(RValue<Float> val);
2031 RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs);
2032 RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs);
2033 RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs);
2034 RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs);
2035 RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs);
2036 RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs);
2037
2038 RValue<Float> Abs(RValue<Float> x);
2039 RValue<Float> Max(RValue<Float> x, RValue<Float> y);
2040 RValue<Float> Min(RValue<Float> x, RValue<Float> y);
2041 RValue<Float> Rcp_pp(RValue<Float> val, bool exactAtPow2 = false);
2042 RValue<Float> RcpSqrt_pp(RValue<Float> val);
2043 RValue<Float> Sqrt(RValue<Float> x);
2044 RValue<Float> Round(RValue<Float> val);
2045 RValue<Float> Trunc(RValue<Float> val);
2046 RValue<Float> Frac(RValue<Float> val);
2047 RValue<Float> Floor(RValue<Float> val);
2048 RValue<Float> Ceil(RValue<Float> val);
2049
Nicolas Capens297d26e2016-11-18 12:52:17 -05002050 class Float2 : public LValue<Float2>
Nicolas Capensd022e412016-09-26 13:30:14 -04002051 {
2052 public:
2053 // explicit Float2(RValue<Byte2> cast);
2054 // explicit Float2(RValue<Short2> cast);
2055 // explicit Float2(RValue<UShort2> cast);
2056 // explicit Float2(RValue<Int2> cast);
2057 // explicit Float2(RValue<UInt2> cast);
2058 explicit Float2(RValue<Float4> cast);
2059
Nicolas Capensa25311a2017-01-16 17:19:00 -05002060 Float2() = default;
Nicolas Capensd022e412016-09-26 13:30:14 -04002061 // Float2(float x, float y);
2062 // Float2(RValue<Float2> rhs);
2063 // Float2(const Float2 &rhs);
2064 // Float2(const Reference<Float2> &rhs);
2065 // Float2(RValue<Float> rhs);
2066 // Float2(const Float &rhs);
2067 // Float2(const Reference<Float> &rhs);
2068
2069 // template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002070 // Float2(const SwizzleMask1<T> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04002071
Nicolas Capens96d4e092016-11-18 14:22:38 -05002072 // RValue<Float2> operator=(float replicate);
2073 // RValue<Float2> operator=(RValue<Float2> rhs);
2074 // RValue<Float2> operator=(const Float2 &rhs);
2075 // RValue<Float2> operator=(const Reference<Float2> &rhs);
2076 // RValue<Float2> operator=(RValue<Float> rhs);
2077 // RValue<Float2> operator=(const Float &rhs);
2078 // RValue<Float2> operator=(const Reference<Float> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04002079
2080 // template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002081 // RValue<Float2> operator=(const SwizzleMask1<T> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04002082
2083 static Type *getType();
2084 };
2085
2086// RValue<Float2> operator+(RValue<Float2> lhs, RValue<Float2> rhs);
2087// RValue<Float2> operator-(RValue<Float2> lhs, RValue<Float2> rhs);
2088// RValue<Float2> operator*(RValue<Float2> lhs, RValue<Float2> rhs);
2089// RValue<Float2> operator/(RValue<Float2> lhs, RValue<Float2> rhs);
2090// RValue<Float2> operator%(RValue<Float2> lhs, RValue<Float2> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05002091// RValue<Float2> operator+=(Float2 &lhs, RValue<Float2> rhs);
2092// RValue<Float2> operator-=(Float2 &lhs, RValue<Float2> rhs);
2093// RValue<Float2> operator*=(Float2 &lhs, RValue<Float2> rhs);
2094// RValue<Float2> operator/=(Float2 &lhs, RValue<Float2> rhs);
2095// RValue<Float2> operator%=(Float2 &lhs, RValue<Float2> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04002096// RValue<Float2> operator+(RValue<Float2> val);
2097// RValue<Float2> operator-(RValue<Float2> val);
2098
2099// RValue<Float2> Abs(RValue<Float2> x);
2100// RValue<Float2> Max(RValue<Float2> x, RValue<Float2> y);
2101// RValue<Float2> Min(RValue<Float2> x, RValue<Float2> y);
2102// RValue<Float2> Swizzle(RValue<Float2> x, unsigned char select);
2103// RValue<Float2> Mask(Float2 &lhs, RValue<Float2> rhs, unsigned char select);
2104
Nicolas Capenscb986762017-01-20 11:34:37 -05002105 class Float4 : public LValue<Float4>, public XYZW<Float4>
Nicolas Capensa25311a2017-01-16 17:19:00 -05002106 {
2107 public:
2108 explicit Float4(RValue<Byte4> cast);
2109 explicit Float4(RValue<SByte4> cast);
2110 explicit Float4(RValue<Short4> cast);
2111 explicit Float4(RValue<UShort4> cast);
2112 explicit Float4(RValue<Int4> cast);
2113 explicit Float4(RValue<UInt4> cast);
2114
2115 Float4();
2116 Float4(float xyzw);
2117 Float4(float x, float yzw);
2118 Float4(float x, float y, float zw);
2119 Float4(float x, float y, float z, float w);
2120 Float4(RValue<Float4> rhs);
2121 Float4(const Float4 &rhs);
2122 Float4(const Reference<Float4> &rhs);
2123 Float4(RValue<Float> rhs);
2124 Float4(const Float &rhs);
2125 Float4(const Reference<Float> &rhs);
2126
2127 template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002128 Float4(const SwizzleMask1<Float4, T> &rhs);
Nicolas Capensa25311a2017-01-16 17:19:00 -05002129 template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002130 Float4(const Swizzle4<Float4, T> &rhs);
Nicolas Capensa25311a2017-01-16 17:19:00 -05002131 template<int X, int Y>
Nicolas Capenscb986762017-01-20 11:34:37 -05002132 Float4(const Swizzle2<Float4, X> &x, const Swizzle2<Float4, Y> &y);
Nicolas Capensa25311a2017-01-16 17:19:00 -05002133 template<int X, int Y>
Nicolas Capenscb986762017-01-20 11:34:37 -05002134 Float4(const SwizzleMask2<Float4, X> &x, const Swizzle2<Float4, Y> &y);
Nicolas Capensa25311a2017-01-16 17:19:00 -05002135 template<int X, int Y>
Nicolas Capenscb986762017-01-20 11:34:37 -05002136 Float4(const Swizzle2<Float4, X> &x, const SwizzleMask2<Float4, Y> &y);
Nicolas Capensa25311a2017-01-16 17:19:00 -05002137 template<int X, int Y>
Nicolas Capenscb986762017-01-20 11:34:37 -05002138 Float4(const SwizzleMask2<Float4, X> &x, const SwizzleMask2<Float4, Y> &y);
Nicolas Capensa25311a2017-01-16 17:19:00 -05002139
2140 RValue<Float4> operator=(float replicate);
2141 RValue<Float4> operator=(RValue<Float4> rhs);
2142 RValue<Float4> operator=(const Float4 &rhs);
2143 RValue<Float4> operator=(const Reference<Float4> &rhs);
2144 RValue<Float4> operator=(RValue<Float> rhs);
2145 RValue<Float4> operator=(const Float &rhs);
2146 RValue<Float4> operator=(const Reference<Float> &rhs);
2147
2148 template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002149 RValue<Float4> operator=(const SwizzleMask1<Float4, T> &rhs);
Nicolas Capensa25311a2017-01-16 17:19:00 -05002150 template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002151 RValue<Float4> operator=(const Swizzle4<Float4, T> &rhs);
Nicolas Capensa25311a2017-01-16 17:19:00 -05002152
2153 static Type *getType();
Nicolas Capensd022e412016-09-26 13:30:14 -04002154
2155 private:
2156 void constant(float x, float y, float z, float w);
2157 };
2158
2159 RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs);
2160 RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs);
2161 RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs);
2162 RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs);
2163 RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs);
Nicolas Capens96d4e092016-11-18 14:22:38 -05002164 RValue<Float4> operator+=(Float4 &lhs, RValue<Float4> rhs);
2165 RValue<Float4> operator-=(Float4 &lhs, RValue<Float4> rhs);
2166 RValue<Float4> operator*=(Float4 &lhs, RValue<Float4> rhs);
2167 RValue<Float4> operator/=(Float4 &lhs, RValue<Float4> rhs);
2168 RValue<Float4> operator%=(Float4 &lhs, RValue<Float4> rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04002169 RValue<Float4> operator+(RValue<Float4> val);
2170 RValue<Float4> operator-(RValue<Float4> val);
2171
2172 RValue<Float4> Abs(RValue<Float4> x);
2173 RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y);
2174 RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y);
2175 RValue<Float4> Rcp_pp(RValue<Float4> val, bool exactAtPow2 = false);
2176 RValue<Float4> RcpSqrt_pp(RValue<Float4> val);
2177 RValue<Float4> Sqrt(RValue<Float4> x);
Nicolas Capensc94ab742016-11-08 15:15:31 -05002178 RValue<Float4> Insert(RValue<Float4> val, RValue<Float> element, int i);
Nicolas Capensd022e412016-09-26 13:30:14 -04002179 RValue<Float> Extract(RValue<Float4> x, int i);
2180 RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select);
2181 RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm);
2182 RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y);
2183 RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y);
2184 RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select);
2185 RValue<Int> SignMask(RValue<Float4> x);
Ben Claytonec1aeb82019-03-04 19:33:27 +00002186
2187 // Ordered comparison functions
Nicolas Capensd022e412016-09-26 13:30:14 -04002188 RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y);
2189 RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y);
2190 RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y);
2191 RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y);
2192 RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y);
2193 RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y);
Ben Claytonec1aeb82019-03-04 19:33:27 +00002194 inline RValue<Int4> CmpGT(RValue<Float4> x, RValue<Float4> y) { return CmpNLE(x, y); }
2195 inline RValue<Int4> CmpGE(RValue<Float4> x, RValue<Float4> y) { return CmpNLT(x, y); }
2196
2197 // Unordered comparison functions
2198 RValue<Int4> CmpUEQ(RValue<Float4> x, RValue<Float4> y);
2199 RValue<Int4> CmpULT(RValue<Float4> x, RValue<Float4> y);
2200 RValue<Int4> CmpULE(RValue<Float4> x, RValue<Float4> y);
2201 RValue<Int4> CmpUNEQ(RValue<Float4> x, RValue<Float4> y);
2202 RValue<Int4> CmpUNLT(RValue<Float4> x, RValue<Float4> y);
2203 RValue<Int4> CmpUNLE(RValue<Float4> x, RValue<Float4> y);
2204 inline RValue<Int4> CmpUGT(RValue<Float4> x, RValue<Float4> y) { return CmpUNLE(x, y); }
2205 inline RValue<Int4> CmpUGE(RValue<Float4> x, RValue<Float4> y) { return CmpUNLT(x, y); }
2206
Alexis Hetu8ef6d102017-11-09 15:49:09 -05002207 RValue<Int4> IsInf(RValue<Float4> x);
2208 RValue<Int4> IsNan(RValue<Float4> x);
Nicolas Capensd022e412016-09-26 13:30:14 -04002209 RValue<Float4> Round(RValue<Float4> x);
2210 RValue<Float4> Trunc(RValue<Float4> x);
2211 RValue<Float4> Frac(RValue<Float4> x);
2212 RValue<Float4> Floor(RValue<Float4> x);
2213 RValue<Float4> Ceil(RValue<Float4> x);
2214
Ben Claytona2c8b772019-04-09 13:42:36 -04002215 // Trigonometric functions
2216 // TODO: Currentlhy unimplemented for Subzero.
2217 RValue<Float4> Sin(RValue<Float4> x);
Ben Clayton1b6f8c72019-04-09 13:47:43 -04002218 RValue<Float4> Cos(RValue<Float4> x);
Ben Clayton14740062019-04-09 13:48:41 -04002219 RValue<Float4> Tan(RValue<Float4> x);
Ben Claytonf9350d72019-04-09 14:19:02 -04002220 RValue<Float4> Asin(RValue<Float4> x);
Ben Claytoneafae472019-04-09 14:22:38 -04002221 RValue<Float4> Acos(RValue<Float4> x);
Ben Clayton749b4e02019-04-09 14:27:43 -04002222 RValue<Float4> Atan(RValue<Float4> x);
Ben Claytond9636972019-04-09 15:09:54 -04002223 RValue<Float4> Sinh(RValue<Float4> x);
Ben Clayton900ea2c2019-04-09 15:25:36 -04002224 RValue<Float4> Cosh(RValue<Float4> x);
Ben Clayton3928bd92019-04-09 15:27:41 -04002225 RValue<Float4> Tanh(RValue<Float4> x);
Ben Claytonf6d77ab2019-04-09 15:30:04 -04002226 RValue<Float4> Asinh(RValue<Float4> x);
Ben Clayton28ebcb02019-04-09 15:33:38 -04002227 RValue<Float4> Acosh(RValue<Float4> x);
Ben Claytonfa6a5392019-04-09 15:35:24 -04002228 RValue<Float4> Atanh(RValue<Float4> x);
Ben Claytona520c3e2019-04-09 15:43:45 -04002229 RValue<Float4> Atan2(RValue<Float4> x, RValue<Float4> y);
Ben Claytona2c8b772019-04-09 13:42:36 -04002230
Ben Claytonbfe94f02019-04-09 15:52:12 -04002231 // Exponential functions
2232 // TODO: Currentlhy unimplemented for Subzero.
2233 RValue<Float4> Pow(RValue<Float4> x, RValue<Float4> y);
Ben Clayton242f0022019-04-09 16:00:53 -04002234 RValue<Float4> Exp(RValue<Float4> x);
Ben Clayton2c1da722019-04-09 16:03:03 -04002235 RValue<Float4> Log(RValue<Float4> x);
Ben Claytonf40b56c2019-04-09 16:06:55 -04002236 RValue<Float4> Exp2(RValue<Float4> x);
Ben Claytone17acfe2019-04-09 16:09:13 -04002237 RValue<Float4> Log2(RValue<Float4> x);
Ben Claytonbfe94f02019-04-09 15:52:12 -04002238
Ben Clayton60958262019-04-10 14:53:30 -04002239 // Bit Manipulation functions.
2240 // TODO: Currentlhy unimplemented for Subzero.
2241
2242 // Count leading zeros.
2243 // Returns 32 when: isZeroUndef && x == 0.
2244 // Returns an undefined value when: !isZeroUndef && x == 0.
2245 RValue<UInt4> Ctlz(RValue<UInt4> x, bool isZeroUndef);
2246
Ben Clayton3f007c42019-04-10 14:54:23 -04002247 // Count trailing zeros.
2248 // Returns 32 when: isZeroUndef && x == 0.
2249 // Returns an undefined value when: !isZeroUndef && x == 0.
2250 RValue<UInt4> Cttz(RValue<UInt4> x, bool isZeroUndef);
2251
Nicolas Capensd022e412016-09-26 13:30:14 -04002252 template<class T>
Nicolas Capens297d26e2016-11-18 12:52:17 -05002253 class Pointer : public LValue<Pointer<T>>
Nicolas Capensd022e412016-09-26 13:30:14 -04002254 {
2255 public:
2256 template<class S>
2257 Pointer(RValue<Pointer<S>> pointerS, int alignment = 1) : alignment(alignment)
2258 {
2259 Value *pointerT = Nucleus::createBitCast(pointerS.value, Nucleus::getPointerType(T::getType()));
Nicolas Capens22479eb2016-09-28 22:34:26 -04002260 LValue<Pointer<T>>::storeValue(pointerT);
Nicolas Capensd022e412016-09-26 13:30:14 -04002261 }
2262
2263 template<class S>
2264 Pointer(const Pointer<S> &pointer, int alignment = 1) : alignment(alignment)
2265 {
Nicolas Capens4126b8e2017-07-26 13:34:36 -04002266 Value *pointerS = pointer.loadValue();
Nicolas Capensd022e412016-09-26 13:30:14 -04002267 Value *pointerT = Nucleus::createBitCast(pointerS, Nucleus::getPointerType(T::getType()));
Nicolas Capens22479eb2016-09-28 22:34:26 -04002268 LValue<Pointer<T>>::storeValue(pointerT);
Nicolas Capensd022e412016-09-26 13:30:14 -04002269 }
2270
2271 Pointer(Argument<Pointer<T>> argument);
Nicolas Capensd022e412016-09-26 13:30:14 -04002272
2273 Pointer();
2274 Pointer(RValue<Pointer<T>> rhs);
2275 Pointer(const Pointer<T> &rhs);
2276 Pointer(const Reference<Pointer<T>> &rhs);
2277
Nicolas Capens96d4e092016-11-18 14:22:38 -05002278 RValue<Pointer<T>> operator=(RValue<Pointer<T>> rhs);
2279 RValue<Pointer<T>> operator=(const Pointer<T> &rhs);
2280 RValue<Pointer<T>> operator=(const Reference<Pointer<T>> &rhs);
Nicolas Capensd022e412016-09-26 13:30:14 -04002281
2282 Reference<T> operator*();
2283 Reference<T> operator[](int index);
Nicolas Capensd294def2017-01-26 17:44:37 -08002284 Reference<T> operator[](unsigned int index);
Nicolas Capensd022e412016-09-26 13:30:14 -04002285 Reference<T> operator[](RValue<Int> index);
Nicolas Capensd294def2017-01-26 17:44:37 -08002286 Reference<T> operator[](RValue<UInt> index);
Nicolas Capensd022e412016-09-26 13:30:14 -04002287
2288 static Type *getType();
2289
2290 private:
2291 const int alignment;
2292 };
2293
2294 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset);
2295 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset);
2296 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset);
Nicolas Capens96d4e092016-11-18 14:22:38 -05002297 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, int offset);
2298 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<Int> offset);
2299 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<UInt> offset);
Nicolas Capensd022e412016-09-26 13:30:14 -04002300
2301 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset);
2302 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset);
2303 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset);
Nicolas Capens96d4e092016-11-18 14:22:38 -05002304 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, int offset);
2305 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<Int> offset);
2306 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<UInt> offset);
Nicolas Capensd022e412016-09-26 13:30:14 -04002307
Nicolas Capens86509d92019-03-21 13:23:50 -04002308 template<typename T>
2309 RValue<T> Load(RValue<Pointer<T>> pointer, unsigned int alignment, bool atomic, std::memory_order memoryOrder)
2310 {
2311 return RValue<T>(Nucleus::createLoad(pointer.value, T::getType(), false, alignment, atomic, memoryOrder));
2312 }
2313
2314 template<typename T>
2315 void Store(RValue<T> value, RValue<Pointer<T>> pointer, unsigned int alignment, bool atomic, std::memory_order memoryOrder)
2316 {
2317 Nucleus::createStore(value.value, pointer.value, T::getType(), false, alignment, atomic, memoryOrder);
2318 }
2319
Nicolas Capensd022e412016-09-26 13:30:14 -04002320 template<class T, int S = 1>
Nicolas Capens297d26e2016-11-18 12:52:17 -05002321 class Array : public LValue<T>
Nicolas Capensd022e412016-09-26 13:30:14 -04002322 {
2323 public:
2324 Array(int size = S);
2325
2326 Reference<T> operator[](int index);
Nicolas Capensd294def2017-01-26 17:44:37 -08002327 Reference<T> operator[](unsigned int index);
Nicolas Capensd022e412016-09-26 13:30:14 -04002328 Reference<T> operator[](RValue<Int> index);
Nicolas Capensd294def2017-01-26 17:44:37 -08002329 Reference<T> operator[](RValue<UInt> index);
Nicolas Capensd022e412016-09-26 13:30:14 -04002330 };
2331
Nicolas Capens96d4e092016-11-18 14:22:38 -05002332// RValue<Array<T>> operator++(Array<T> &val, int); // Post-increment
2333// const Array<T> &operator++(Array<T> &val); // Pre-increment
2334// RValue<Array<T>> operator--(Array<T> &val, int); // Post-decrement
2335// const Array<T> &operator--(Array<T> &val); // Pre-decrement
Nicolas Capensd022e412016-09-26 13:30:14 -04002336
Nicolas Capensf4eec2f2017-05-24 15:46:48 -04002337 void branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB);
Nicolas Capensd022e412016-09-26 13:30:14 -04002338
2339 void Return();
Nicolas Capenseb253d02016-11-18 14:40:40 -05002340 void Return(RValue<Int> ret);
Nicolas Capensd022e412016-09-26 13:30:14 -04002341
2342 template<class T>
2343 void Return(const Pointer<T> &ret);
2344
2345 template<class T>
2346 void Return(RValue<Pointer<T>> ret);
2347
Nicolas Capensd022e412016-09-26 13:30:14 -04002348 // Generic template, leave undefined!
2349 template<typename FunctionType>
2350 class Function;
2351
2352 // Specialized for function types
2353 template<typename Return, typename... Arguments>
2354 class Function<Return(Arguments...)>
2355 {
2356 public:
2357 Function();
2358
2359 virtual ~Function();
2360
2361 template<int index>
Ben Clayton169872e2019-02-27 23:58:35 +00002362 Argument<typename std::tuple_element<index, std::tuple<Arguments...>>::type> Arg() const
Nicolas Capensd022e412016-09-26 13:30:14 -04002363 {
2364 Value *arg = Nucleus::getArgument(index);
Ben Clayton169872e2019-02-27 23:58:35 +00002365 return Argument<typename std::tuple_element<index, std::tuple<Arguments...>>::type>(arg);
Nicolas Capensd022e412016-09-26 13:30:14 -04002366 }
2367
Chris Forbes878d4b02019-01-21 10:48:35 -08002368 Routine *operator()(const char *name, ...);
Nicolas Capensd022e412016-09-26 13:30:14 -04002369
2370 protected:
2371 Nucleus *core;
2372 std::vector<Type*> arguments;
2373 };
2374
2375 template<typename Return>
2376 class Function<Return()> : public Function<Return(Void)>
2377 {
2378 };
2379
Nicolas Capensd022e412016-09-26 13:30:14 -04002380 RValue<Long> Ticks();
2381}
2382
Nicolas Capens48461502018-08-06 14:20:45 -04002383namespace rr
Nicolas Capensd022e412016-09-26 13:30:14 -04002384{
2385 template<class T>
Nicolas Capens0192d152019-03-27 14:46:07 -04002386 LValue<T>::LValue(int arraySize) : Variable(T::getType(), arraySize)
Nicolas Capens22479eb2016-09-28 22:34:26 -04002387 {
Nicolas Capens22479eb2016-09-28 22:34:26 -04002388 }
2389
Nicolas Capens0192d152019-03-27 14:46:07 -04002390 inline void Variable::materialize() const
Nicolas Capens22479eb2016-09-28 22:34:26 -04002391 {
Nicolas Capens0192d152019-03-27 14:46:07 -04002392 if(!address)
2393 {
2394 address = Nucleus::allocateStackVariable(type, arraySize);
2395
2396 if(rvalue)
2397 {
2398 storeValue(rvalue);
2399 rvalue = nullptr;
2400 }
2401 }
Nicolas Capens22479eb2016-09-28 22:34:26 -04002402 }
2403
Nicolas Capens0192d152019-03-27 14:46:07 -04002404 inline Value *Variable::loadValue() const
Nicolas Capens22479eb2016-09-28 22:34:26 -04002405 {
Nicolas Capens0192d152019-03-27 14:46:07 -04002406 if(rvalue)
2407 {
2408 return rvalue;
2409 }
2410
2411 if(!address)
2412 {
2413 // TODO: Return undef instead.
2414 materialize();
2415 }
2416
2417 return Nucleus::createLoad(address, type, false, 0);
Nicolas Capens22479eb2016-09-28 22:34:26 -04002418 }
2419
Nicolas Capens0192d152019-03-27 14:46:07 -04002420 inline Value *Variable::storeValue(Value *value) const
Nicolas Capens22479eb2016-09-28 22:34:26 -04002421 {
Nicolas Capens0192d152019-03-27 14:46:07 -04002422 if(address)
2423 {
2424 return Nucleus::createStore(value, address, type, false, 0);
2425 }
2426
2427 rvalue = value;
2428
2429 return value;
2430 }
2431
2432 inline Value *Variable::getBaseAddress() const
2433 {
2434 materialize();
2435
2436 return address;
2437 }
2438
2439 inline Value *Variable::getElementPointer(Value *index, bool unsignedIndex) const
2440 {
2441 return Nucleus::createGEP(getBaseAddress(), type, index, unsignedIndex);
Nicolas Capens22479eb2016-09-28 22:34:26 -04002442 }
2443
2444 template<class T>
Nicolas Capens297d26e2016-11-18 12:52:17 -05002445 RValue<Pointer<T>> LValue<T>::operator&()
Nicolas Capensd022e412016-09-26 13:30:14 -04002446 {
Nicolas Capens0192d152019-03-27 14:46:07 -04002447 return RValue<Pointer<T>>(getBaseAddress());
Nicolas Capensd022e412016-09-26 13:30:14 -04002448 }
2449
2450 template<class T>
2451 Reference<T>::Reference(Value *pointer, int alignment) : alignment(alignment)
2452 {
2453 address = pointer;
2454 }
2455
2456 template<class T>
2457 RValue<T> Reference<T>::operator=(RValue<T> rhs) const
2458 {
Nicolas Capens6d738712016-09-30 04:15:22 -04002459 Nucleus::createStore(rhs.value, address, T::getType(), false, alignment);
Nicolas Capensd022e412016-09-26 13:30:14 -04002460
2461 return rhs;
2462 }
2463
2464 template<class T>
2465 RValue<T> Reference<T>::operator=(const Reference<T> &ref) const
2466 {
Nicolas Capense12780d2016-09-27 14:18:07 -04002467 Value *tmp = Nucleus::createLoad(ref.address, T::getType(), false, ref.alignment);
Nicolas Capens6d738712016-09-30 04:15:22 -04002468 Nucleus::createStore(tmp, address, T::getType(), false, alignment);
Nicolas Capensd022e412016-09-26 13:30:14 -04002469
2470 return RValue<T>(tmp);
2471 }
2472
2473 template<class T>
2474 RValue<T> Reference<T>::operator+=(RValue<T> rhs) const
2475 {
2476 return *this = *this + rhs;
2477 }
2478
2479 template<class T>
2480 Value *Reference<T>::loadValue() const
2481 {
Nicolas Capense12780d2016-09-27 14:18:07 -04002482 return Nucleus::createLoad(address, T::getType(), false, alignment);
Nicolas Capensd022e412016-09-26 13:30:14 -04002483 }
2484
2485 template<class T>
2486 int Reference<T>::getAlignment() const
2487 {
2488 return alignment;
2489 }
2490
2491 template<class T>
2492 RValue<T>::RValue(Value *rvalue)
2493 {
Nicolas Capensbea4dce2017-07-24 16:54:44 -04002494 assert(Nucleus::createBitCast(rvalue, T::getType()) == rvalue); // Run-time type should match T, so bitcast is no-op.
2495
Nicolas Capensd022e412016-09-26 13:30:14 -04002496 value = rvalue;
2497 }
2498
2499 template<class T>
2500 RValue<T>::RValue(const T &lvalue)
2501 {
2502 value = lvalue.loadValue();
2503 }
2504
2505 template<class T>
Ben Clayton35e90e22019-03-15 10:06:06 +00002506 RValue<T>::RValue(typename BoolLiteral<T>::type i)
2507 {
2508 value = Nucleus::createConstantBool(i);
2509 }
2510
2511 template<class T>
Nicolas Capensd022e412016-09-26 13:30:14 -04002512 RValue<T>::RValue(typename IntLiteral<T>::type i)
2513 {
Nicolas Capensa16473e2016-11-07 15:32:52 -05002514 value = Nucleus::createConstantInt(i);
Nicolas Capensd022e412016-09-26 13:30:14 -04002515 }
2516
2517 template<class T>
2518 RValue<T>::RValue(typename FloatLiteral<T>::type f)
2519 {
Nicolas Capensa16473e2016-11-07 15:32:52 -05002520 value = Nucleus::createConstantFloat(f);
Nicolas Capensd022e412016-09-26 13:30:14 -04002521 }
2522
2523 template<class T>
2524 RValue<T>::RValue(const Reference<T> &ref)
2525 {
2526 value = ref.loadValue();
2527 }
2528
Nicolas Capenscb986762017-01-20 11:34:37 -05002529 template<class Vector4, int T>
2530 Swizzle2<Vector4, T>::operator RValue<Vector4>() const
Nicolas Capensd022e412016-09-26 13:30:14 -04002531 {
2532 Value *vector = parent->loadValue();
2533
Nicolas Capenscb986762017-01-20 11:34:37 -05002534 return Swizzle(RValue<Vector4>(vector), T);
Nicolas Capensd022e412016-09-26 13:30:14 -04002535 }
2536
Nicolas Capenscb986762017-01-20 11:34:37 -05002537 template<class Vector4, int T>
2538 Swizzle4<Vector4, T>::operator RValue<Vector4>() const
Nicolas Capensd022e412016-09-26 13:30:14 -04002539 {
2540 Value *vector = parent->loadValue();
2541
Nicolas Capenscb986762017-01-20 11:34:37 -05002542 return Swizzle(RValue<Vector4>(vector), T);
Nicolas Capensd022e412016-09-26 13:30:14 -04002543 }
2544
Nicolas Capenscb986762017-01-20 11:34:37 -05002545 template<class Vector4, int T>
2546 SwizzleMask4<Vector4, T>::operator RValue<Vector4>() const
Nicolas Capensd022e412016-09-26 13:30:14 -04002547 {
2548 Value *vector = parent->loadValue();
2549
Nicolas Capenscb986762017-01-20 11:34:37 -05002550 return Swizzle(RValue<Vector4>(vector), T);
Nicolas Capensd022e412016-09-26 13:30:14 -04002551 }
2552
Nicolas Capenscb986762017-01-20 11:34:37 -05002553 template<class Vector4, int T>
2554 RValue<Vector4> SwizzleMask4<Vector4, T>::operator=(RValue<Vector4> rhs)
Nicolas Capensd022e412016-09-26 13:30:14 -04002555 {
2556 return Mask(*parent, rhs, T);
2557 }
2558
Nicolas Capenscb986762017-01-20 11:34:37 -05002559 template<class Vector4, int T>
2560 RValue<Vector4> SwizzleMask4<Vector4, T>::operator=(RValue<typename Scalar<Vector4>::Type> rhs)
Nicolas Capensd022e412016-09-26 13:30:14 -04002561 {
Nicolas Capenscb986762017-01-20 11:34:37 -05002562 return Mask(*parent, Vector4(rhs), T);
Nicolas Capensd022e412016-09-26 13:30:14 -04002563 }
2564
Nicolas Capenscb986762017-01-20 11:34:37 -05002565 template<class Vector4, int T>
2566 SwizzleMask1<Vector4, T>::operator RValue<typename Scalar<Vector4>::Type>() const // FIXME: Call a non-template function
Nicolas Capensd022e412016-09-26 13:30:14 -04002567 {
2568 return Extract(*parent, T & 0x3);
2569 }
2570
Nicolas Capenscb986762017-01-20 11:34:37 -05002571 template<class Vector4, int T>
2572 SwizzleMask1<Vector4, T>::operator RValue<Vector4>() const
Nicolas Capensd022e412016-09-26 13:30:14 -04002573 {
2574 Value *vector = parent->loadValue();
2575
Nicolas Capenscb986762017-01-20 11:34:37 -05002576 return Swizzle(RValue<Vector4>(vector), T);
Nicolas Capensd022e412016-09-26 13:30:14 -04002577 }
2578
Nicolas Capenscb986762017-01-20 11:34:37 -05002579 template<class Vector4, int T>
2580 RValue<Vector4> SwizzleMask1<Vector4, T>::operator=(float x)
Nicolas Capensd022e412016-09-26 13:30:14 -04002581 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05002582 return *parent = Insert(*parent, Float(x), T & 0x3);
Nicolas Capensd022e412016-09-26 13:30:14 -04002583 }
2584
Nicolas Capenscb986762017-01-20 11:34:37 -05002585 template<class Vector4, int T>
2586 RValue<Vector4> SwizzleMask1<Vector4, T>::operator=(RValue<Vector4> rhs)
Nicolas Capensd022e412016-09-26 13:30:14 -04002587 {
2588 return Mask(*parent, Float4(rhs), T);
2589 }
2590
Nicolas Capenscb986762017-01-20 11:34:37 -05002591 template<class Vector4, int T>
2592 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 -04002593 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05002594 return *parent = Insert(*parent, rhs, T & 0x3);
Nicolas Capensd022e412016-09-26 13:30:14 -04002595 }
2596
Nicolas Capenscb986762017-01-20 11:34:37 -05002597 template<class Vector4, int T>
2598 SwizzleMask2<Vector4, T>::operator RValue<Vector4>() const
Nicolas Capensd022e412016-09-26 13:30:14 -04002599 {
2600 Value *vector = parent->loadValue();
2601
Nicolas Capense95d5342016-09-30 11:37:28 -04002602 return Swizzle(RValue<Float4>(vector), T);
Nicolas Capensd022e412016-09-26 13:30:14 -04002603 }
2604
Nicolas Capenscb986762017-01-20 11:34:37 -05002605 template<class Vector4, int T>
2606 RValue<Vector4> SwizzleMask2<Vector4, T>::operator=(RValue<Vector4> rhs)
Nicolas Capensd022e412016-09-26 13:30:14 -04002607 {
2608 return Mask(*parent, Float4(rhs), T);
2609 }
2610
2611 template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002612 Float::Float(const SwizzleMask1<Float4, T> &rhs)
Nicolas Capensd022e412016-09-26 13:30:14 -04002613 {
2614 *this = rhs.operator RValue<Float>();
2615 }
2616
2617 template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002618 RValue<Float> Float::operator=(const SwizzleMask1<Float4, T> &rhs)
Nicolas Capensd022e412016-09-26 13:30:14 -04002619 {
2620 return *this = rhs.operator RValue<Float>();
2621 }
2622
2623 template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002624 Float4::Float4(const SwizzleMask1<Float4, T> &rhs) : XYZW(this)
Nicolas Capensd022e412016-09-26 13:30:14 -04002625 {
Nicolas Capensd022e412016-09-26 13:30:14 -04002626 *this = rhs.operator RValue<Float4>();
2627 }
2628
2629 template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002630 Float4::Float4(const Swizzle4<Float4, T> &rhs) : XYZW(this)
Nicolas Capensd022e412016-09-26 13:30:14 -04002631 {
Nicolas Capensd022e412016-09-26 13:30:14 -04002632 *this = rhs.operator RValue<Float4>();
2633 }
2634
2635 template<int X, int Y>
Nicolas Capenscb986762017-01-20 11:34:37 -05002636 Float4::Float4(const Swizzle2<Float4, X> &x, const Swizzle2<Float4, Y> &y) : XYZW(this)
Nicolas Capensd022e412016-09-26 13:30:14 -04002637 {
Nicolas Capensd022e412016-09-26 13:30:14 -04002638 *this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);
2639 }
2640
2641 template<int X, int Y>
Nicolas Capenscb986762017-01-20 11:34:37 -05002642 Float4::Float4(const SwizzleMask2<Float4, X> &x, const Swizzle2<Float4, Y> &y) : XYZW(this)
Nicolas Capensd022e412016-09-26 13:30:14 -04002643 {
Nicolas Capensd022e412016-09-26 13:30:14 -04002644 *this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);
2645 }
2646
2647 template<int X, int Y>
Nicolas Capenscb986762017-01-20 11:34:37 -05002648 Float4::Float4(const Swizzle2<Float4, X> &x, const SwizzleMask2<Float4, Y> &y) : XYZW(this)
Nicolas Capensd022e412016-09-26 13:30:14 -04002649 {
Nicolas Capensd022e412016-09-26 13:30:14 -04002650 *this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);
2651 }
2652
2653 template<int X, int Y>
Nicolas Capenscb986762017-01-20 11:34:37 -05002654 Float4::Float4(const SwizzleMask2<Float4, X> &x, const SwizzleMask2<Float4, Y> &y) : XYZW(this)
Nicolas Capensd022e412016-09-26 13:30:14 -04002655 {
Nicolas Capensd022e412016-09-26 13:30:14 -04002656 *this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);
2657 }
2658
2659 template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002660 RValue<Float4> Float4::operator=(const SwizzleMask1<Float4, T> &rhs)
Nicolas Capensd022e412016-09-26 13:30:14 -04002661 {
2662 return *this = rhs.operator RValue<Float4>();
2663 }
2664
2665 template<int T>
Nicolas Capenscb986762017-01-20 11:34:37 -05002666 RValue<Float4> Float4::operator=(const Swizzle4<Float4, T> &rhs)
Nicolas Capensd022e412016-09-26 13:30:14 -04002667 {
2668 return *this = rhs.operator RValue<Float4>();
2669 }
2670
2671 template<class T>
2672 Pointer<T>::Pointer(Argument<Pointer<T>> argument) : alignment(1)
2673 {
Nicolas Capens51d98672019-04-02 12:05:40 -04002674 LValue<Pointer<T>>::materialize(); // FIXME(b/129757459)
Nicolas Capens22479eb2016-09-28 22:34:26 -04002675 LValue<Pointer<T>>::storeValue(argument.value);
Nicolas Capensd022e412016-09-26 13:30:14 -04002676 }
2677
2678 template<class T>
Nicolas Capensd022e412016-09-26 13:30:14 -04002679 Pointer<T>::Pointer() : alignment(1)
2680 {
Nicolas Capens22479eb2016-09-28 22:34:26 -04002681 LValue<Pointer<T>>::storeValue(Nucleus::createNullPointer(T::getType()));
Nicolas Capensd022e412016-09-26 13:30:14 -04002682 }
2683
2684 template<class T>
2685 Pointer<T>::Pointer(RValue<Pointer<T>> rhs) : alignment(1)
2686 {
Nicolas Capens22479eb2016-09-28 22:34:26 -04002687 LValue<Pointer<T>>::storeValue(rhs.value);
Nicolas Capensd022e412016-09-26 13:30:14 -04002688 }
2689
2690 template<class T>
2691 Pointer<T>::Pointer(const Pointer<T> &rhs) : alignment(rhs.alignment)
2692 {
2693 Value *value = rhs.loadValue();
Nicolas Capens22479eb2016-09-28 22:34:26 -04002694 LValue<Pointer<T>>::storeValue(value);
Nicolas Capensd022e412016-09-26 13:30:14 -04002695 }
2696
2697 template<class T>
2698 Pointer<T>::Pointer(const Reference<Pointer<T>> &rhs) : alignment(rhs.getAlignment())
2699 {
2700 Value *value = rhs.loadValue();
Nicolas Capens22479eb2016-09-28 22:34:26 -04002701 LValue<Pointer<T>>::storeValue(value);
Nicolas Capensd022e412016-09-26 13:30:14 -04002702 }
2703
2704 template<class T>
Nicolas Capens96d4e092016-11-18 14:22:38 -05002705 RValue<Pointer<T>> Pointer<T>::operator=(RValue<Pointer<T>> rhs)
Nicolas Capensd022e412016-09-26 13:30:14 -04002706 {
Nicolas Capens22479eb2016-09-28 22:34:26 -04002707 LValue<Pointer<T>>::storeValue(rhs.value);
Nicolas Capensd022e412016-09-26 13:30:14 -04002708
2709 return rhs;
2710 }
2711
2712 template<class T>
Nicolas Capens96d4e092016-11-18 14:22:38 -05002713 RValue<Pointer<T>> Pointer<T>::operator=(const Pointer<T> &rhs)
Nicolas Capensd022e412016-09-26 13:30:14 -04002714 {
2715 Value *value = rhs.loadValue();
Nicolas Capens22479eb2016-09-28 22:34:26 -04002716 LValue<Pointer<T>>::storeValue(value);
Nicolas Capensd022e412016-09-26 13:30:14 -04002717
2718 return RValue<Pointer<T>>(value);
2719 }
2720
2721 template<class T>
Nicolas Capens96d4e092016-11-18 14:22:38 -05002722 RValue<Pointer<T>> Pointer<T>::operator=(const Reference<Pointer<T>> &rhs)
Nicolas Capensd022e412016-09-26 13:30:14 -04002723 {
2724 Value *value = rhs.loadValue();
Nicolas Capens22479eb2016-09-28 22:34:26 -04002725 LValue<Pointer<T>>::storeValue(value);
Nicolas Capensd022e412016-09-26 13:30:14 -04002726
2727 return RValue<Pointer<T>>(value);
2728 }
2729
2730 template<class T>
2731 Reference<T> Pointer<T>::operator*()
2732 {
Nicolas Capens22479eb2016-09-28 22:34:26 -04002733 return Reference<T>(LValue<Pointer<T>>::loadValue(), alignment);
Nicolas Capensd022e412016-09-26 13:30:14 -04002734 }
2735
2736 template<class T>
2737 Reference<T> Pointer<T>::operator[](int index)
2738 {
Nicolas Capensd294def2017-01-26 17:44:37 -08002739 Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), T::getType(), Nucleus::createConstantInt(index), false);
2740
2741 return Reference<T>(element, alignment);
2742 }
2743
2744 template<class T>
2745 Reference<T> Pointer<T>::operator[](unsigned int index)
2746 {
2747 Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), T::getType(), Nucleus::createConstantInt(index), true);
Nicolas Capensd022e412016-09-26 13:30:14 -04002748
2749 return Reference<T>(element, alignment);
2750 }
2751
2752 template<class T>
2753 Reference<T> Pointer<T>::operator[](RValue<Int> index)
2754 {
Nicolas Capensd294def2017-01-26 17:44:37 -08002755 Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), T::getType(), index.value, false);
2756
2757 return Reference<T>(element, alignment);
2758 }
2759
2760 template<class T>
2761 Reference<T> Pointer<T>::operator[](RValue<UInt> index)
2762 {
2763 Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), T::getType(), index.value, true);
Nicolas Capensd022e412016-09-26 13:30:14 -04002764
2765 return Reference<T>(element, alignment);
2766 }
2767
2768 template<class T>
2769 Type *Pointer<T>::getType()
2770 {
2771 return Nucleus::getPointerType(T::getType());
2772 }
2773
2774 template<class T, int S>
Nicolas Capens297d26e2016-11-18 12:52:17 -05002775 Array<T, S>::Array(int size) : LValue<T>(size)
Nicolas Capensd022e412016-09-26 13:30:14 -04002776 {
2777 }
2778
2779 template<class T, int S>
2780 Reference<T> Array<T, S>::operator[](int index)
2781 {
Nicolas Capens0192d152019-03-27 14:46:07 -04002782 Value *element = LValue<T>::getElementPointer(Nucleus::createConstantInt(index), false);
Nicolas Capensd294def2017-01-26 17:44:37 -08002783
2784 return Reference<T>(element);
2785 }
2786
2787 template<class T, int S>
2788 Reference<T> Array<T, S>::operator[](unsigned int index)
2789 {
Nicolas Capens0192d152019-03-27 14:46:07 -04002790 Value *element = LValue<T>::getElementPointer(Nucleus::createConstantInt(index), true);
Nicolas Capensd022e412016-09-26 13:30:14 -04002791
2792 return Reference<T>(element);
2793 }
2794
2795 template<class T, int S>
2796 Reference<T> Array<T, S>::operator[](RValue<Int> index)
2797 {
Nicolas Capens0192d152019-03-27 14:46:07 -04002798 Value *element = LValue<T>::getElementPointer(index.value, false);
Nicolas Capensd294def2017-01-26 17:44:37 -08002799
2800 return Reference<T>(element);
2801 }
2802
2803 template<class T, int S>
2804 Reference<T> Array<T, S>::operator[](RValue<UInt> index)
2805 {
Nicolas Capens0192d152019-03-27 14:46:07 -04002806 Value *element = LValue<T>::getElementPointer(index.value, true);
Nicolas Capensd022e412016-09-26 13:30:14 -04002807
2808 return Reference<T>(element);
2809 }
2810
2811// template<class T>
Nicolas Capens96d4e092016-11-18 14:22:38 -05002812// RValue<Array<T>> operator++(Array<T> &val, int)
Nicolas Capensd022e412016-09-26 13:30:14 -04002813// {
2814// // FIXME: Requires storing the address of the array
2815// }
2816
2817// template<class T>
Nicolas Capens96d4e092016-11-18 14:22:38 -05002818// const Array<T> &operator++(Array<T> &val)
Nicolas Capensd022e412016-09-26 13:30:14 -04002819// {
2820// // FIXME: Requires storing the address of the array
2821// }
2822
2823// template<class T>
Nicolas Capens96d4e092016-11-18 14:22:38 -05002824// RValue<Array<T>> operator--(Array<T> &val, int)
Nicolas Capensd022e412016-09-26 13:30:14 -04002825// {
2826// // FIXME: Requires storing the address of the array
2827// }
2828
2829// template<class T>
Nicolas Capens96d4e092016-11-18 14:22:38 -05002830// const Array<T> &operator--(Array<T> &val)
Nicolas Capensd022e412016-09-26 13:30:14 -04002831// {
2832// // FIXME: Requires storing the address of the array
2833// }
2834
2835 template<class T>
2836 RValue<T> IfThenElse(RValue<Bool> condition, RValue<T> ifTrue, RValue<T> ifFalse)
2837 {
2838 return RValue<T>(Nucleus::createSelect(condition.value, ifTrue.value, ifFalse.value));
2839 }
2840
2841 template<class T>
2842 RValue<T> IfThenElse(RValue<Bool> condition, const T &ifTrue, RValue<T> ifFalse)
2843 {
2844 Value *trueValue = ifTrue.loadValue();
2845
2846 return RValue<T>(Nucleus::createSelect(condition.value, trueValue, ifFalse.value));
2847 }
2848
2849 template<class T>
2850 RValue<T> IfThenElse(RValue<Bool> condition, RValue<T> ifTrue, const T &ifFalse)
2851 {
2852 Value *falseValue = ifFalse.loadValue();
2853
2854 return RValue<T>(Nucleus::createSelect(condition.value, ifTrue.value, falseValue));
2855 }
2856
2857 template<class T>
2858 RValue<T> IfThenElse(RValue<Bool> condition, const T &ifTrue, const T &ifFalse)
2859 {
2860 Value *trueValue = ifTrue.loadValue();
2861 Value *falseValue = ifFalse.loadValue();
2862
2863 return RValue<T>(Nucleus::createSelect(condition.value, trueValue, falseValue));
2864 }
2865
2866 template<class T>
2867 void Return(const Pointer<T> &ret)
2868 {
Nicolas Capense12780d2016-09-27 14:18:07 -04002869 Nucleus::createRet(Nucleus::createLoad(ret.address, Pointer<T>::getType()));
Nicolas Capensd022e412016-09-26 13:30:14 -04002870 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
Ben Claytonf3b57972019-03-15 09:56:47 +00002871 Nucleus::createUnreachable();
Nicolas Capensd022e412016-09-26 13:30:14 -04002872 }
2873
2874 template<class T>
2875 void Return(RValue<Pointer<T>> ret)
2876 {
2877 Nucleus::createRet(ret.value);
2878 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
Ben Claytonf3b57972019-03-15 09:56:47 +00002879 Nucleus::createUnreachable();
Nicolas Capensd022e412016-09-26 13:30:14 -04002880 }
2881
2882 template<typename Return, typename... Arguments>
2883 Function<Return(Arguments...)>::Function()
2884 {
2885 core = new Nucleus();
2886
2887 Type *types[] = {Arguments::getType()...};
2888 for(Type *type : types)
2889 {
2890 if(type != Void::getType())
2891 {
2892 arguments.push_back(type);
2893 }
2894 }
2895
2896 Nucleus::createFunction(Return::getType(), arguments);
2897 }
2898
2899 template<typename Return, typename... Arguments>
2900 Function<Return(Arguments...)>::~Function()
2901 {
2902 delete core;
2903 }
2904
2905 template<typename Return, typename... Arguments>
Chris Forbes878d4b02019-01-21 10:48:35 -08002906 Routine *Function<Return(Arguments...)>::operator()(const char *name, ...)
Nicolas Capensd022e412016-09-26 13:30:14 -04002907 {
Chris Forbes878d4b02019-01-21 10:48:35 -08002908 char fullName[1024 + 1];
Nicolas Capensd022e412016-09-26 13:30:14 -04002909
2910 va_list vararg;
2911 va_start(vararg, name);
Chris Forbes878d4b02019-01-21 10:48:35 -08002912 vsnprintf(fullName, 1024, name, vararg);
Nicolas Capensd022e412016-09-26 13:30:14 -04002913 va_end(vararg);
2914
2915 return core->acquireRoutine(fullName, true);
2916 }
2917
2918 template<class T, class S>
2919 RValue<T> ReinterpretCast(RValue<S> val)
2920 {
2921 return RValue<T>(Nucleus::createBitCast(val.value, T::getType()));
2922 }
2923
Nicolas Capens22479eb2016-09-28 22:34:26 -04002924 template<class T, class S>
2925 RValue<T> ReinterpretCast(const LValue<S> &var)
Nicolas Capensd022e412016-09-26 13:30:14 -04002926 {
2927 Value *val = var.loadValue();
2928
2929 return RValue<T>(Nucleus::createBitCast(val, T::getType()));
2930 }
2931
2932 template<class T, class S>
2933 RValue<T> ReinterpretCast(const Reference<S> &var)
2934 {
2935 return ReinterpretCast<T>(RValue<S>(var));
2936 }
2937
Nicolas Capens70dfff42016-10-27 10:20:28 -04002938 template<class T>
2939 RValue<T> As(Value *val)
2940 {
2941 return RValue<T>(Nucleus::createBitCast(val, T::getType()));
2942 }
2943
Nicolas Capensd022e412016-09-26 13:30:14 -04002944 template<class T, class S>
2945 RValue<T> As(RValue<S> val)
2946 {
2947 return ReinterpretCast<T>(val);
2948 }
2949
Nicolas Capens22479eb2016-09-28 22:34:26 -04002950 template<class T, class S>
2951 RValue<T> As(const LValue<S> &var)
Nicolas Capensd022e412016-09-26 13:30:14 -04002952 {
2953 return ReinterpretCast<T>(var);
2954 }
2955
2956 template<class T, class S>
2957 RValue<T> As(const Reference<S> &val)
2958 {
2959 return ReinterpretCast<T>(val);
2960 }
2961
Ben Clayton1bc7ee92019-02-14 18:43:22 +00002962#ifdef ENABLE_RR_PRINT
2963 // PrintValue holds the printf format and value(s) for a single argument
2964 // to Print(). A single argument can be expanded into multiple printf
2965 // values - for example a Float4 will expand to "%f %f %f %f" and four
2966 // scalar values.
2967 // The PrintValue constructor accepts the following:
2968 // * Reactor LValues, RValues, Pointers.
2969 // * Standard Plain-Old-Value types (int, float, bool, etc)
2970 // * Custom types that specialize the PrintValue::Ty template struct.
2971 // * Static arrays in the form T[N] where T can be any of the above.
2972 class PrintValue
2973 {
2974 // Ty is a template that can be specialized for printing type T.
2975 // Each specialization must expose:
2976 // * A 'static constexpr const char* fmt' field that provides the
2977 // printf format specifier.
2978 // * A 'static std::vector<rr::Value*> val(const T& v)' method that
2979 // returns all the printf format values.
2980 template <typename T> struct Ty
2981 {
2982 // static constexpr const char* fmt;
2983 // static std::vector<rr::Value*> val(const T& v)
2984 };
2985
2986 // returns the printf value(s) for the given LValue.
2987 template <typename T>
2988 static std::vector<Value*> val(const LValue<T>& v) { return val(RValue<T>(v.loadValue())); };
2989
2990 // returns the printf value(s) for the given RValue.
2991 template <typename T>
2992 static std::vector<Value*> val(const RValue<T>& v) { return Ty<T>::val(v); };
2993
2994 // returns the printf value from for the given type with a
2995 // PrintValue::Ty<T> specialization.
2996 template <typename T>
2997 static std::vector<Value*> val(const T& v) { return Ty<T>::val(v); };
2998
2999 // returns the printf values for all the values in the given array.
3000 template <typename T>
3001 static std::vector<Value*> val(const T* list, int count) {
3002 std::vector<Value*> values;
3003 values.reserve(count);
3004 for (int i = 0; i < count; i++)
3005 {
3006 auto v = val(list[i]);
3007 values.insert(values.end(), v.begin(), v.end());
3008 }
3009 return values;
3010 };
3011
3012 // fmt returns a comma-delimited list of the string el repeated count
3013 // times enclosed in square brackets.
3014 static std::string fmt(const char* el, int count)
3015 {
3016 std::string out = "[";
3017 for (int i = 0; i < count; i++)
3018 {
3019 if (i > 0) { out += ", "; }
3020 out += el;
3021 }
3022 return out + "]";
3023 }
3024
Ben Clayton3ed8ba02019-04-04 22:01:51 +01003025 static std::string addr(const void* ptr)
3026 {
3027 char buf[32];
3028 snprintf(buf, sizeof(buf), "%p", ptr);
3029 return buf;
3030 }
3031
Ben Clayton1bc7ee92019-02-14 18:43:22 +00003032 public:
3033 const std::string format;
3034 const std::vector<Value*> values;
3035
3036 // Constructs a PrintValue for the given value.
3037 template <typename T>
3038 PrintValue(const T& v) : format(Ty<T>::fmt), values(val(v)) {}
3039
3040 // Constructs a PrintValue for the given static array.
3041 template <typename T, int N>
3042 PrintValue(const T (&v)[N]) : format(fmt(Ty<T>::fmt, N)), values(val(&v[0], N)) {}
3043
3044 // Constructs a PrintValue for the given array starting at arr of length
3045 // len.
3046 template <typename T>
3047 PrintValue(const T* arr, int len) : format(fmt(Ty<T>::fmt, len)), values(val(arr, len)) {}
3048
Ben Clayton1bc7ee92019-02-14 18:43:22 +00003049 // PrintValue constructors for plain-old-data values.
3050 PrintValue(bool v) : format(v ? "true" : "false") {}
3051 PrintValue(int8_t v) : format(std::to_string(v)) {}
3052 PrintValue(uint8_t v) : format(std::to_string(v)) {}
3053 PrintValue(int16_t v) : format(std::to_string(v)) {}
3054 PrintValue(uint16_t v) : format(std::to_string(v)) {}
3055 PrintValue(int32_t v) : format(std::to_string(v)) {}
3056 PrintValue(uint32_t v) : format(std::to_string(v)) {}
3057 PrintValue(int64_t v) : format(std::to_string(v)) {}
3058 PrintValue(uint64_t v) : format(std::to_string(v)) {}
3059 PrintValue(float v) : format(std::to_string(v)) {}
3060 PrintValue(double v) : format(std::to_string(v)) {}
3061 PrintValue(const char* v) : format(v) {}
3062 PrintValue(const std::string& v) : format(v) {}
3063
Ben Clayton3ed8ba02019-04-04 22:01:51 +01003064 template <typename T>
3065 PrintValue(const T* v) : format(addr(v)) {}
3066
Ben Clayton1bc7ee92019-02-14 18:43:22 +00003067 // vals is a helper to build composite value lists.
3068 // vals returns the full, sequential list of printf argument values used
3069 // to print all the provided variadic values.
3070 // vals() is intended to be used by implementations of
3071 // PrintValue::Ty<>::vals() to help declare aggregate types.
3072 // For example, if you were declaring a PrintValue::Ty<> specialization
3073 // for a custom Mat4x4 matrix formed from four Vector4 values, you'd
3074 // write:
3075 //
3076 // namespace rr
3077 // {
3078 // template <> struct PrintValue::Ty<Mat4x4>
3079 // {
3080 // static constexpr const char* fmt =
3081 // "[a: <%f, %f, %f, %f>,"
3082 // " b: <%f, %f, %f, %f>,"
3083 // " c: <%f, %f, %f, %f>,"
3084 // " d: <%f, %f, %f, %f>]";
3085 // static std::vector<rr::Value*> val(const Mat4x4& v)
3086 // {
3087 // return PrintValue::vals(v.a, v.b, v.c, v.d);
3088 // }
3089 // };
3090 // }
3091 template<typename ... ARGS>
3092 static std::vector<Value*> vals(ARGS... v)
3093 {
3094 std::vector< std::vector<Value*> > lists = {val(v)...};
3095 std::vector<Value*> joined;
3096 for (const auto& list : lists)
3097 {
3098 joined.insert(joined.end(), list.begin(), list.end());
3099 }
3100 return joined;
3101 }
3102 };
3103
3104 // PrintValue::Ty<T> specializations for standard Reactor types.
Ben Claytonca56e8b2019-03-12 20:05:43 +00003105 template <> struct PrintValue::Ty<Bool>
3106 {
3107 static constexpr const char* fmt = "%d";
3108 static std::vector<Value*> val(const RValue<Bool>& v) { return {v.value}; }
3109 };
Ben Clayton1bc7ee92019-02-14 18:43:22 +00003110 template <> struct PrintValue::Ty<Byte>
3111 {
3112 static constexpr const char* fmt = "%d";
3113 static std::vector<Value*> val(const RValue<Byte>& v) { return {v.value}; }
3114 };
3115 template <> struct PrintValue::Ty<Byte4>
3116 {
3117 static constexpr const char* fmt = "[%d, %d, %d, %d]";
3118 static std::vector<Value*> val(const RValue<Byte4>& v);
3119 };
3120 template <> struct PrintValue::Ty<Int>
3121 {
3122 static constexpr const char* fmt = "%d";
3123 static std::vector<Value*> val(const RValue<Int>& v) { return {v.value}; }
3124 };
3125 template <> struct PrintValue::Ty<Int4>
3126 {
3127 static constexpr const char* fmt = "[%d, %d, %d, %d]";
3128 static std::vector<Value*> val(const RValue<Int4>& v);
3129 };
3130 template <> struct PrintValue::Ty<UInt>
3131 {
3132 static constexpr const char* fmt = "%u";
3133 static std::vector<Value*> val(const RValue<UInt>& v) { return {v.value}; }
3134 };
3135 template <> struct PrintValue::Ty<UInt4>
3136 {
3137 static constexpr const char* fmt = "[%u, %u, %u, %u]";
3138 static std::vector<Value*> val(const RValue<UInt4>& v);
3139 };
3140 template <> struct PrintValue::Ty<Short>
3141 {
3142 static constexpr const char* fmt = "%d";
3143 static std::vector<Value*> val(const RValue<Short>& v) { return {v.value}; }
3144 };
3145 template <> struct PrintValue::Ty<Short4>
3146 {
3147 static constexpr const char* fmt = "[%d, %d, %d, %d]";
3148 static std::vector<Value*> val(const RValue<Short4>& v);
3149 };
3150 template <> struct PrintValue::Ty<UShort>
3151 {
3152 static constexpr const char* fmt = "%u";
3153 static std::vector<Value*> val(const RValue<UShort>& v) { return {v.value}; }
3154 };
3155 template <> struct PrintValue::Ty<UShort4>
3156 {
3157 static constexpr const char* fmt = "[%u, %u, %u, %u]";
3158 static std::vector<Value*> val(const RValue<UShort4>& v);
3159 };
3160 template <> struct PrintValue::Ty<Float>
3161 {
3162 static constexpr const char* fmt = "[%f]";
3163 static std::vector<Value*> val(const RValue<Float>& v);
3164 };
3165 template <> struct PrintValue::Ty<Float4>
3166 {
3167 static constexpr const char* fmt = "[%f, %f, %f, %f]";
3168 static std::vector<Value*> val(const RValue<Float4>& v);
3169 };
Ben Clayton7945a512019-04-15 23:00:43 -04003170 template <> struct PrintValue::Ty<Long>
3171 {
3172 static constexpr const char* fmt = "%lld";
3173 static std::vector<Value*> val(const RValue<Long>& v) { return {v.value}; }
3174 };
Ben Clayton1bc7ee92019-02-14 18:43:22 +00003175 template <typename T> struct PrintValue::Ty< Pointer<T> >
3176 {
3177 static constexpr const char* fmt = "%p";
3178 static std::vector<Value*> val(const RValue<Pointer<T>>& v) { return {v.value}; }
3179 };
3180 template <typename T> struct PrintValue::Ty< Reference<T> >
3181 {
3182 static constexpr const char* fmt = PrintValue::Ty<T>::fmt;
3183 static std::vector<Value*> val(const Reference<T>& v) { return PrintValue::Ty<T>::val(v); }
3184 };
3185 template <typename T> struct PrintValue::Ty< RValue<T> >
3186 {
3187 static constexpr const char* fmt = PrintValue::Ty<T>::fmt;
3188 static std::vector<Value*> val(const RValue<T>& v) { return PrintValue::Ty<T>::val(v); }
3189 };
3190
3191 // Printv emits a call to printf() using the function, file and line,
3192 // message and optional values.
3193 // See Printv below.
3194 void Printv(const char* function, const char* file, int line, const char* msg, std::initializer_list<PrintValue> vals);
3195
3196 // Printv emits a call to printf() using the provided message and optional
3197 // values.
3198 // Printf replaces any bracketed indices in the message with string
3199 // representations of the corresponding value in vals.
3200 // For example:
3201 // Printv("{0} and {1}", "red", "green");
3202 // Would print the string:
3203 // "red and green"
3204 // Arguments can be indexed in any order.
3205 // Invalid indices are not substituted.
3206 inline void Printv(const char* msg, std::initializer_list<PrintValue> vals)
3207 {
3208 Printv(nullptr, nullptr, 0, msg, vals);
3209 }
3210
3211 // Print is a wrapper over Printv that wraps the variadic arguments into an
3212 // initializer_list before calling Printv.
3213 template <typename ... ARGS>
3214 void Print(const char* msg, const ARGS& ... vals) { Printv(msg, {vals...}); }
3215
3216 // Print is a wrapper over Printv that wraps the variadic arguments into an
3217 // initializer_list before calling Printv.
3218 template <typename ... ARGS>
3219 void Print(const char* function, const char* file, int line, const char* msg, const ARGS& ... vals)
3220 {
3221 Printv(function, file, line, msg, {vals...});
3222 }
3223
3224 // RR_LOG is a macro that calls Print(), automatically populating the
3225 // function, file and line parameters and appending a newline to the string.
3226 //
3227 // RR_LOG() is intended to be used for debugging JIT compiled code, and is
3228 // not intended for production use.
3229 #define RR_LOG(msg, ...) Print(__PRETTY_FUNCTION__, __FILE__, __LINE__, msg "\n", ##__VA_ARGS__)
3230
3231 // Macro magic to perform variadic dispatch.
3232 // See: https://renenyffenegger.ch/notes/development/languages/C-C-plus-plus/preprocessor/macros/__VA_ARGS__/count-arguments
3233 // Note, this doesn't attempt to use the ##__VA_ARGS__ trick to handle 0
3234 // args as this appears to still be broken on certain compilers.
Ben Clayton221459f2019-03-25 15:14:45 +00003235 // MSVC also has issues with variadic macros which requires the RR_VA_MSVC_BUG() work-around.
3236 // See: https://stackoverflow.com/a/48711060
3237 #define RR_VA_MSVC_BUG(MACRO, ARGS) MACRO ARGS
3238 #define RR_GET_NTH_ARG_EX(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, N, ...) N
3239 #define RR_GET_NTH_ARG(...) RR_VA_MSVC_BUG(RR_GET_NTH_ARG_EX, (__VA_ARGS__))
Ben Clayton1bc7ee92019-02-14 18:43:22 +00003240 #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 +00003241 static_assert(1 == RR_COUNT_ARGUMENTS(a), "RR_COUNT_ARGUMENTS broken"); // Sanity checks.
3242 static_assert(2 == RR_COUNT_ARGUMENTS(a, b), "RR_COUNT_ARGUMENTS broken");
3243 static_assert(3 == RR_COUNT_ARGUMENTS(a, b, c), "RR_COUNT_ARGUMENTS broken");
Ben Clayton1bc7ee92019-02-14 18:43:22 +00003244
3245 // RR_WATCH_FMT(...) resolves to a string literal that lists all the
3246 // arguments by name. This string can be passed to LOG() to print each of
3247 // the arguments with their name and value.
3248 //
3249 // RR_WATCH_FMT(...) uses the RR_COUNT_ARGUMENTS helper macro to delegate to a
3250 // corresponding RR_WATCH_FMT_n specialization macro below.
3251 #define RR_WATCH_CONCAT(a, b) a ## b
3252 #define RR_WATCH_CONCAT2(a, b) RR_WATCH_CONCAT(a, b)
3253 #define RR_WATCH_FMT(...) RR_WATCH_CONCAT2(RR_WATCH_FMT_, RR_COUNT_ARGUMENTS(__VA_ARGS__))(__VA_ARGS__)
3254 #define RR_WATCH_FMT_1(_1) "\n " #_1 ": {0}"
Ben Clayton644a3502019-03-13 11:24:46 +00003255 #define RR_WATCH_FMT_2(_1, _2) RR_WATCH_FMT_1(_1) "\n " #_2 ": {1}"
3256 #define RR_WATCH_FMT_3(_1, _2, _3) RR_WATCH_FMT_2(_1, _2) "\n " #_3 ": {2}"
3257 #define RR_WATCH_FMT_4(_1, _2, _3, _4) RR_WATCH_FMT_3(_1, _2, _3) "\n " #_4 ": {3}"
3258 #define RR_WATCH_FMT_5(_1, _2, _3, _4, _5) RR_WATCH_FMT_4(_1, _2, _3, _4) "\n " #_5 ": {4}"
3259 #define RR_WATCH_FMT_6(_1, _2, _3, _4, _5, _6) RR_WATCH_FMT_5(_1, _2, _3, _4, _5) "\n " #_6 ": {5}"
3260 #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}"
3261 #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}"
3262 #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}"
3263 #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}"
3264 #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}"
3265 #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 +00003266
3267 // RR_WATCH() is a helper that prints the name and value of all the supplied
3268 // arguments.
3269 // For example, if you had the Int and bool variables 'foo' and 'bar' that
3270 // you want to print, you can simply write:
3271 // RR_WATCH(foo, bar)
3272 // When this JIT compiled code is executed, it will print the string
3273 // "foo: 1, bar: true" to stdout.
3274 //
3275 // RR_WATCH() is intended to be used for debugging JIT compiled code, and
3276 // is not intended for production use.
3277 #define RR_WATCH(...) RR_LOG(RR_WATCH_FMT(__VA_ARGS__), __VA_ARGS__)
3278#endif // ENABLE_RR_PRINT
3279
Nicolas Capens37ed9082016-11-16 17:40:48 -05003280 class ForData
3281 {
3282 public:
3283 ForData(bool init) : loopOnce(init)
3284 {
3285 }
3286
3287 operator bool()
3288 {
3289 return loopOnce;
3290 }
3291
3292 bool operator=(bool value)
3293 {
3294 return loopOnce = value;
3295 }
3296
3297 bool setup()
3298 {
3299 if(Nucleus::getInsertBlock() != endBB)
3300 {
3301 testBB = Nucleus::createBasicBlock();
3302
3303 Nucleus::createBr(testBB);
3304 Nucleus::setInsertBlock(testBB);
3305
3306 return true;
3307 }
3308
3309 return false;
3310 }
3311
3312 bool test(RValue<Bool> cmp)
3313 {
3314 BasicBlock *bodyBB = Nucleus::createBasicBlock();
3315 endBB = Nucleus::createBasicBlock();
3316
3317 Nucleus::createCondBr(cmp.value, bodyBB, endBB);
3318 Nucleus::setInsertBlock(bodyBB);
3319
3320 return true;
3321 }
3322
3323 void end()
3324 {
3325 Nucleus::createBr(testBB);
3326 Nucleus::setInsertBlock(endBB);
3327 }
3328
3329 private:
3330 BasicBlock *testBB = nullptr;
3331 BasicBlock *endBB = nullptr;
3332 bool loopOnce = true;
3333 };
3334
3335 class IfElseData
3336 {
3337 public:
3338 IfElseData(RValue<Bool> cmp) : iteration(0)
3339 {
3340 condition = cmp.value;
3341
3342 beginBB = Nucleus::getInsertBlock();
3343 trueBB = Nucleus::createBasicBlock();
3344 falseBB = nullptr;
3345 endBB = Nucleus::createBasicBlock();
3346
3347 Nucleus::setInsertBlock(trueBB);
3348 }
3349
3350 ~IfElseData()
3351 {
3352 Nucleus::createBr(endBB);
3353
3354 Nucleus::setInsertBlock(beginBB);
3355 Nucleus::createCondBr(condition, trueBB, falseBB ? falseBB : endBB);
3356
3357 Nucleus::setInsertBlock(endBB);
3358 }
3359
3360 operator int()
3361 {
3362 return iteration;
3363 }
3364
3365 IfElseData &operator++()
3366 {
3367 ++iteration;
3368
3369 return *this;
3370 }
3371
3372 void elseClause()
3373 {
3374 Nucleus::createBr(endBB);
3375
3376 falseBB = Nucleus::createBasicBlock();
3377 Nucleus::setInsertBlock(falseBB);
3378 }
3379
3380 private:
3381 Value *condition;
3382 BasicBlock *beginBB;
3383 BasicBlock *trueBB;
3384 BasicBlock *falseBB;
3385 BasicBlock *endBB;
3386 int iteration;
3387 };
3388
Nicolas Capensb0eb3772016-10-24 17:49:13 -04003389 #define For(init, cond, inc) \
Nicolas Capens8884a232016-11-16 15:03:18 -05003390 for(ForData for__ = true; for__; for__ = false) \
3391 for(init; for__.setup() && for__.test(cond); inc, for__.end())
Nicolas Capens0bac2852016-05-07 06:09:58 -04003392
Nicolas Capensb0eb3772016-10-24 17:49:13 -04003393 #define While(cond) For((void)0, cond, (void)0)
Nicolas Capens0bac2852016-05-07 06:09:58 -04003394
Nicolas Capensb0eb3772016-10-24 17:49:13 -04003395 #define Do \
3396 { \
3397 BasicBlock *body__ = Nucleus::createBasicBlock(); \
3398 Nucleus::createBr(body__); \
3399 Nucleus::setInsertBlock(body__);
3400
3401 #define Until(cond) \
3402 BasicBlock *end__ = Nucleus::createBasicBlock(); \
3403 Nucleus::createCondBr((cond).value, end__, body__); \
3404 Nucleus::setInsertBlock(end__); \
Nicolas Capens0bac2852016-05-07 06:09:58 -04003405 }
3406
Nicolas Capens37ed9082016-11-16 17:40:48 -05003407 enum {IF_BLOCK__, ELSE_CLAUSE__, ELSE_BLOCK__, IFELSE_NUM__};
Nicolas Capens0bac2852016-05-07 06:09:58 -04003408
Nicolas Capens37ed9082016-11-16 17:40:48 -05003409 #define If(cond) \
3410 for(IfElseData ifElse__(cond); ifElse__ < IFELSE_NUM__; ++ifElse__) \
3411 if(ifElse__ == IF_BLOCK__)
3412
3413 #define Else \
3414 else if(ifElse__ == ELSE_CLAUSE__) \
3415 { \
3416 ifElse__.elseClause(); \
3417 } \
3418 else // ELSE_BLOCK__
Nicolas Capensd022e412016-09-26 13:30:14 -04003419}
3420
Nicolas Capens48461502018-08-06 14:20:45 -04003421#endif // rr_Reactor_hpp