OSDN Git Service

ebf2a7a0a96d5c3565df3b0b1e7233e257795d00
[android-x86/external-swiftshader.git] / src / Reactor / Reactor.hpp
1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #ifndef rr_Reactor_hpp
16 #define rr_Reactor_hpp
17
18 #include "Nucleus.hpp"
19 #include "Routine.hpp"
20
21 #include <cassert>
22 #include <cstddef>
23 #include <cstdio>
24
25 #include <string>
26 #include <tuple>
27
28 #undef Bool // b/127920555
29
30 #if !defined(NDEBUG) && (REACTOR_LLVM_VERSION >= 7)
31 #define ENABLE_RR_PRINT 1 // Enables RR_PRINT(), RR_WATCH()
32 #endif // !defined(NDEBUG) && (REACTOR_LLVM_VERSION >= 7)
33
34 namespace rr
35 {
36         class Bool;
37         class Byte;
38         class SByte;
39         class Byte4;
40         class SByte4;
41         class Byte8;
42         class SByte8;
43         class Byte16;
44         class SByte16;
45         class Short;
46         class UShort;
47         class Short2;
48         class UShort2;
49         class Short4;
50         class UShort4;
51         class Short8;
52         class UShort8;
53         class Int;
54         class UInt;
55         class Int2;
56         class UInt2;
57         class Int4;
58         class UInt4;
59         class Long;
60         class Half;
61         class Float;
62         class Float2;
63         class Float4;
64
65         class Void
66         {
67         public:
68                 static Type *getType();
69
70                 static bool isVoid()
71                 {
72                         return true;
73                 }
74         };
75
76         template<class T>
77         class RValue;
78
79         template<class T>
80         class Pointer;
81
82         class Variable
83         {
84                 friend class PrintValue;
85
86                 Variable &operator=(const Variable&) = delete;
87
88         public:
89                 Variable() = default;
90                 Variable(const Variable&) = default;
91
92         protected:
93                 Value *address;
94         };
95
96         template<class T>
97         class LValue : public Variable
98         {
99         public:
100                 LValue(int arraySize = 0);
101
102                 RValue<Pointer<T>> operator&();
103
104                 static bool isVoid()
105                 {
106                         return false;
107                 }
108
109                 Value *loadValue() const;
110                 Value *storeValue(Value *value) const;
111                 Value *getAddress(Value *index, bool unsignedIndex) const;
112         };
113
114         template<class T>
115         class Reference
116         {
117         public:
118                 explicit Reference(Value *pointer, int alignment = 1);
119
120                 RValue<T> operator=(RValue<T> rhs) const;
121                 RValue<T> operator=(const Reference<T> &ref) const;
122
123                 RValue<T> operator+=(RValue<T> rhs) const;
124
125                 RValue<Pointer<T>> operator&() const { return RValue<Pointer<T>>(address); }
126
127                 Value *loadValue() const;
128                 int getAlignment() const;
129
130         private:
131                 Value *address;
132
133                 const int alignment;
134         };
135
136         template<class T>
137         struct BoolLiteral
138         {
139                 struct type;
140         };
141
142         template<>
143         struct BoolLiteral<Bool>
144         {
145                 typedef bool type;
146         };
147
148         template<class T>
149         struct IntLiteral
150         {
151                 struct type;
152         };
153
154         template<>
155         struct IntLiteral<Int>
156         {
157                 typedef int type;
158         };
159
160         template<>
161         struct IntLiteral<UInt>
162         {
163                 typedef unsigned int type;
164         };
165
166         template<>
167         struct IntLiteral<Long>
168         {
169                 typedef int64_t type;
170         };
171
172         template<class T>
173         struct FloatLiteral
174         {
175                 struct type;
176         };
177
178         template<>
179         struct FloatLiteral<Float>
180         {
181                 typedef float type;
182         };
183
184         template<class T>
185         class RValue
186         {
187         public:
188                 explicit RValue(Value *rvalue);
189
190                 RValue(const T &lvalue);
191                 RValue(typename BoolLiteral<T>::type i);
192                 RValue(typename IntLiteral<T>::type i);
193                 RValue(typename FloatLiteral<T>::type f);
194                 RValue(const Reference<T> &rhs);
195
196                 RValue<T> &operator=(const RValue<T>&) = delete;
197
198                 Value *value;   // FIXME: Make private
199         };
200
201         template<typename T>
202         struct Argument
203         {
204                 explicit Argument(Value *value) : value(value) {}
205
206                 Value *value;
207         };
208
209         class Bool : public LValue<Bool>
210         {
211         public:
212                 Bool(Argument<Bool> argument);
213
214                 Bool() = default;
215                 Bool(bool x);
216                 Bool(RValue<Bool> rhs);
217                 Bool(const Bool &rhs);
218                 Bool(const Reference<Bool> &rhs);
219
220         //      RValue<Bool> operator=(bool rhs);   // FIXME: Implement
221                 RValue<Bool> operator=(RValue<Bool> rhs);
222                 RValue<Bool> operator=(const Bool &rhs);
223                 RValue<Bool> operator=(const Reference<Bool> &rhs);
224
225                 static Type *getType();
226         };
227
228         RValue<Bool> operator!(RValue<Bool> val);
229         RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs);
230         RValue<Bool> operator||(RValue<Bool> lhs, RValue<Bool> rhs);
231         RValue<Bool> operator!=(RValue<Bool> lhs, RValue<Bool> rhs);
232         RValue<Bool> operator==(RValue<Bool> lhs, RValue<Bool> rhs);
233
234         class Byte : public LValue<Byte>
235         {
236         public:
237                 Byte(Argument<Byte> argument);
238
239                 explicit Byte(RValue<Int> cast);
240                 explicit Byte(RValue<UInt> cast);
241                 explicit Byte(RValue<UShort> cast);
242
243                 Byte() = default;
244                 Byte(int x);
245                 Byte(unsigned char x);
246                 Byte(RValue<Byte> rhs);
247                 Byte(const Byte &rhs);
248                 Byte(const Reference<Byte> &rhs);
249
250         //      RValue<Byte> operator=(unsigned char rhs);   // FIXME: Implement
251                 RValue<Byte> operator=(RValue<Byte> rhs);
252                 RValue<Byte> operator=(const Byte &rhs);
253                 RValue<Byte> operator=(const Reference<Byte> &rhs);
254
255                 static Type *getType();
256         };
257
258         RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs);
259         RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs);
260         RValue<Byte> operator*(RValue<Byte> lhs, RValue<Byte> rhs);
261         RValue<Byte> operator/(RValue<Byte> lhs, RValue<Byte> rhs);
262         RValue<Byte> operator%(RValue<Byte> lhs, RValue<Byte> rhs);
263         RValue<Byte> operator&(RValue<Byte> lhs, RValue<Byte> rhs);
264         RValue<Byte> operator|(RValue<Byte> lhs, RValue<Byte> rhs);
265         RValue<Byte> operator^(RValue<Byte> lhs, RValue<Byte> rhs);
266         RValue<Byte> operator<<(RValue<Byte> lhs, RValue<Byte> rhs);
267         RValue<Byte> operator>>(RValue<Byte> lhs, RValue<Byte> rhs);
268         RValue<Byte> operator+=(Byte &lhs, RValue<Byte> rhs);
269         RValue<Byte> operator-=(Byte &lhs, RValue<Byte> rhs);
270         RValue<Byte> operator*=(Byte &lhs, RValue<Byte> rhs);
271         RValue<Byte> operator/=(Byte &lhs, RValue<Byte> rhs);
272         RValue<Byte> operator%=(Byte &lhs, RValue<Byte> rhs);
273         RValue<Byte> operator&=(Byte &lhs, RValue<Byte> rhs);
274         RValue<Byte> operator|=(Byte &lhs, RValue<Byte> rhs);
275         RValue<Byte> operator^=(Byte &lhs, RValue<Byte> rhs);
276         RValue<Byte> operator<<=(Byte &lhs, RValue<Byte> rhs);
277         RValue<Byte> operator>>=(Byte &lhs, RValue<Byte> rhs);
278         RValue<Byte> operator+(RValue<Byte> val);
279         RValue<Byte> operator-(RValue<Byte> val);
280         RValue<Byte> operator~(RValue<Byte> val);
281         RValue<Byte> operator++(Byte &val, int);   // Post-increment
282         const Byte &operator++(Byte &val);   // Pre-increment
283         RValue<Byte> operator--(Byte &val, int);   // Post-decrement
284         const Byte &operator--(Byte &val);   // Pre-decrement
285         RValue<Bool> operator<(RValue<Byte> lhs, RValue<Byte> rhs);
286         RValue<Bool> operator<=(RValue<Byte> lhs, RValue<Byte> rhs);
287         RValue<Bool> operator>(RValue<Byte> lhs, RValue<Byte> rhs);
288         RValue<Bool> operator>=(RValue<Byte> lhs, RValue<Byte> rhs);
289         RValue<Bool> operator!=(RValue<Byte> lhs, RValue<Byte> rhs);
290         RValue<Bool> operator==(RValue<Byte> lhs, RValue<Byte> rhs);
291
292         class SByte : public LValue<SByte>
293         {
294         public:
295                 SByte(Argument<SByte> argument);
296
297                 explicit SByte(RValue<Int> cast);
298                 explicit SByte(RValue<Short> cast);
299
300                 SByte() = default;
301                 SByte(signed char x);
302                 SByte(RValue<SByte> rhs);
303                 SByte(const SByte &rhs);
304                 SByte(const Reference<SByte> &rhs);
305
306         //      RValue<SByte> operator=(signed char rhs);   // FIXME: Implement
307                 RValue<SByte> operator=(RValue<SByte> rhs);
308                 RValue<SByte> operator=(const SByte &rhs);
309                 RValue<SByte> operator=(const Reference<SByte> &rhs);
310
311                 static Type *getType();
312         };
313
314         RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs);
315         RValue<SByte> operator-(RValue<SByte> lhs, RValue<SByte> rhs);
316         RValue<SByte> operator*(RValue<SByte> lhs, RValue<SByte> rhs);
317         RValue<SByte> operator/(RValue<SByte> lhs, RValue<SByte> rhs);
318         RValue<SByte> operator%(RValue<SByte> lhs, RValue<SByte> rhs);
319         RValue<SByte> operator&(RValue<SByte> lhs, RValue<SByte> rhs);
320         RValue<SByte> operator|(RValue<SByte> lhs, RValue<SByte> rhs);
321         RValue<SByte> operator^(RValue<SByte> lhs, RValue<SByte> rhs);
322         RValue<SByte> operator<<(RValue<SByte> lhs, RValue<SByte> rhs);
323         RValue<SByte> operator>>(RValue<SByte> lhs, RValue<SByte> rhs);
324         RValue<SByte> operator+=(SByte &lhs, RValue<SByte> rhs);
325         RValue<SByte> operator-=(SByte &lhs, RValue<SByte> rhs);
326         RValue<SByte> operator*=(SByte &lhs, RValue<SByte> rhs);
327         RValue<SByte> operator/=(SByte &lhs, RValue<SByte> rhs);
328         RValue<SByte> operator%=(SByte &lhs, RValue<SByte> rhs);
329         RValue<SByte> operator&=(SByte &lhs, RValue<SByte> rhs);
330         RValue<SByte> operator|=(SByte &lhs, RValue<SByte> rhs);
331         RValue<SByte> operator^=(SByte &lhs, RValue<SByte> rhs);
332         RValue<SByte> operator<<=(SByte &lhs, RValue<SByte> rhs);
333         RValue<SByte> operator>>=(SByte &lhs, RValue<SByte> rhs);
334         RValue<SByte> operator+(RValue<SByte> val);
335         RValue<SByte> operator-(RValue<SByte> val);
336         RValue<SByte> operator~(RValue<SByte> val);
337         RValue<SByte> operator++(SByte &val, int);   // Post-increment
338         const SByte &operator++(SByte &val);   // Pre-increment
339         RValue<SByte> operator--(SByte &val, int);   // Post-decrement
340         const SByte &operator--(SByte &val);   // Pre-decrement
341         RValue<Bool> operator<(RValue<SByte> lhs, RValue<SByte> rhs);
342         RValue<Bool> operator<=(RValue<SByte> lhs, RValue<SByte> rhs);
343         RValue<Bool> operator>(RValue<SByte> lhs, RValue<SByte> rhs);
344         RValue<Bool> operator>=(RValue<SByte> lhs, RValue<SByte> rhs);
345         RValue<Bool> operator!=(RValue<SByte> lhs, RValue<SByte> rhs);
346         RValue<Bool> operator==(RValue<SByte> lhs, RValue<SByte> rhs);
347
348         class Short : public LValue<Short>
349         {
350         public:
351                 Short(Argument<Short> argument);
352
353                 explicit Short(RValue<Int> cast);
354
355                 Short() = default;
356                 Short(short x);
357                 Short(RValue<Short> rhs);
358                 Short(const Short &rhs);
359                 Short(const Reference<Short> &rhs);
360
361         //      RValue<Short> operator=(short rhs);   // FIXME: Implement
362                 RValue<Short> operator=(RValue<Short> rhs);
363                 RValue<Short> operator=(const Short &rhs);
364                 RValue<Short> operator=(const Reference<Short> &rhs);
365
366                 static Type *getType();
367         };
368
369         RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs);
370         RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs);
371         RValue<Short> operator*(RValue<Short> lhs, RValue<Short> rhs);
372         RValue<Short> operator/(RValue<Short> lhs, RValue<Short> rhs);
373         RValue<Short> operator%(RValue<Short> lhs, RValue<Short> rhs);
374         RValue<Short> operator&(RValue<Short> lhs, RValue<Short> rhs);
375         RValue<Short> operator|(RValue<Short> lhs, RValue<Short> rhs);
376         RValue<Short> operator^(RValue<Short> lhs, RValue<Short> rhs);
377         RValue<Short> operator<<(RValue<Short> lhs, RValue<Short> rhs);
378         RValue<Short> operator>>(RValue<Short> lhs, RValue<Short> rhs);
379         RValue<Short> operator+=(Short &lhs, RValue<Short> rhs);
380         RValue<Short> operator-=(Short &lhs, RValue<Short> rhs);
381         RValue<Short> operator*=(Short &lhs, RValue<Short> rhs);
382         RValue<Short> operator/=(Short &lhs, RValue<Short> rhs);
383         RValue<Short> operator%=(Short &lhs, RValue<Short> rhs);
384         RValue<Short> operator&=(Short &lhs, RValue<Short> rhs);
385         RValue<Short> operator|=(Short &lhs, RValue<Short> rhs);
386         RValue<Short> operator^=(Short &lhs, RValue<Short> rhs);
387         RValue<Short> operator<<=(Short &lhs, RValue<Short> rhs);
388         RValue<Short> operator>>=(Short &lhs, RValue<Short> rhs);
389         RValue<Short> operator+(RValue<Short> val);
390         RValue<Short> operator-(RValue<Short> val);
391         RValue<Short> operator~(RValue<Short> val);
392         RValue<Short> operator++(Short &val, int);   // Post-increment
393         const Short &operator++(Short &val);   // Pre-increment
394         RValue<Short> operator--(Short &val, int);   // Post-decrement
395         const Short &operator--(Short &val);   // Pre-decrement
396         RValue<Bool> operator<(RValue<Short> lhs, RValue<Short> rhs);
397         RValue<Bool> operator<=(RValue<Short> lhs, RValue<Short> rhs);
398         RValue<Bool> operator>(RValue<Short> lhs, RValue<Short> rhs);
399         RValue<Bool> operator>=(RValue<Short> lhs, RValue<Short> rhs);
400         RValue<Bool> operator!=(RValue<Short> lhs, RValue<Short> rhs);
401         RValue<Bool> operator==(RValue<Short> lhs, RValue<Short> rhs);
402
403         class UShort : public LValue<UShort>
404         {
405         public:
406                 UShort(Argument<UShort> argument);
407
408                 explicit UShort(RValue<UInt> cast);
409                 explicit UShort(RValue<Int> cast);
410
411                 UShort() = default;
412                 UShort(unsigned short x);
413                 UShort(RValue<UShort> rhs);
414                 UShort(const UShort &rhs);
415                 UShort(const Reference<UShort> &rhs);
416
417         //      RValue<UShort> operator=(unsigned short rhs);   // FIXME: Implement
418                 RValue<UShort> operator=(RValue<UShort> rhs);
419                 RValue<UShort> operator=(const UShort &rhs);
420                 RValue<UShort> operator=(const Reference<UShort> &rhs);
421
422                 static Type *getType();
423         };
424
425         RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs);
426         RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs);
427         RValue<UShort> operator*(RValue<UShort> lhs, RValue<UShort> rhs);
428         RValue<UShort> operator/(RValue<UShort> lhs, RValue<UShort> rhs);
429         RValue<UShort> operator%(RValue<UShort> lhs, RValue<UShort> rhs);
430         RValue<UShort> operator&(RValue<UShort> lhs, RValue<UShort> rhs);
431         RValue<UShort> operator|(RValue<UShort> lhs, RValue<UShort> rhs);
432         RValue<UShort> operator^(RValue<UShort> lhs, RValue<UShort> rhs);
433         RValue<UShort> operator<<(RValue<UShort> lhs, RValue<UShort> rhs);
434         RValue<UShort> operator>>(RValue<UShort> lhs, RValue<UShort> rhs);
435         RValue<UShort> operator+=(UShort &lhs, RValue<UShort> rhs);
436         RValue<UShort> operator-=(UShort &lhs, RValue<UShort> rhs);
437         RValue<UShort> operator*=(UShort &lhs, RValue<UShort> rhs);
438         RValue<UShort> operator/=(UShort &lhs, RValue<UShort> rhs);
439         RValue<UShort> operator%=(UShort &lhs, RValue<UShort> rhs);
440         RValue<UShort> operator&=(UShort &lhs, RValue<UShort> rhs);
441         RValue<UShort> operator|=(UShort &lhs, RValue<UShort> rhs);
442         RValue<UShort> operator^=(UShort &lhs, RValue<UShort> rhs);
443         RValue<UShort> operator<<=(UShort &lhs, RValue<UShort> rhs);
444         RValue<UShort> operator>>=(UShort &lhs, RValue<UShort> rhs);
445         RValue<UShort> operator+(RValue<UShort> val);
446         RValue<UShort> operator-(RValue<UShort> val);
447         RValue<UShort> operator~(RValue<UShort> val);
448         RValue<UShort> operator++(UShort &val, int);   // Post-increment
449         const UShort &operator++(UShort &val);   // Pre-increment
450         RValue<UShort> operator--(UShort &val, int);   // Post-decrement
451         const UShort &operator--(UShort &val);   // Pre-decrement
452         RValue<Bool> operator<(RValue<UShort> lhs, RValue<UShort> rhs);
453         RValue<Bool> operator<=(RValue<UShort> lhs, RValue<UShort> rhs);
454         RValue<Bool> operator>(RValue<UShort> lhs, RValue<UShort> rhs);
455         RValue<Bool> operator>=(RValue<UShort> lhs, RValue<UShort> rhs);
456         RValue<Bool> operator!=(RValue<UShort> lhs, RValue<UShort> rhs);
457         RValue<Bool> operator==(RValue<UShort> lhs, RValue<UShort> rhs);
458
459         class Byte4 : public LValue<Byte4>
460         {
461         public:
462                 explicit Byte4(RValue<Byte8> cast);
463
464                 Byte4() = default;
465         //      Byte4(int x, int y, int z, int w);
466         //      Byte4(RValue<Byte4> rhs);
467         //      Byte4(const Byte4 &rhs);
468                 Byte4(const Reference<Byte4> &rhs);
469
470         //      RValue<Byte4> operator=(RValue<Byte4> rhs);
471         //      RValue<Byte4> operator=(const Byte4 &rhs);
472         //      RValue<Byte4> operator=(const Reference<Byte4> &rhs);
473
474                 static Type *getType();
475         };
476
477 //      RValue<Byte4> operator+(RValue<Byte4> lhs, RValue<Byte4> rhs);
478 //      RValue<Byte4> operator-(RValue<Byte4> lhs, RValue<Byte4> rhs);
479 //      RValue<Byte4> operator*(RValue<Byte4> lhs, RValue<Byte4> rhs);
480 //      RValue<Byte4> operator/(RValue<Byte4> lhs, RValue<Byte4> rhs);
481 //      RValue<Byte4> operator%(RValue<Byte4> lhs, RValue<Byte4> rhs);
482 //      RValue<Byte4> operator&(RValue<Byte4> lhs, RValue<Byte4> rhs);
483 //      RValue<Byte4> operator|(RValue<Byte4> lhs, RValue<Byte4> rhs);
484 //      RValue<Byte4> operator^(RValue<Byte4> lhs, RValue<Byte4> rhs);
485 //      RValue<Byte4> operator<<(RValue<Byte4> lhs, RValue<Byte4> rhs);
486 //      RValue<Byte4> operator>>(RValue<Byte4> lhs, RValue<Byte4> rhs);
487 //      RValue<Byte4> operator+=(Byte4 &lhs, RValue<Byte4> rhs);
488 //      RValue<Byte4> operator-=(Byte4 &lhs, RValue<Byte4> rhs);
489 //      RValue<Byte4> operator*=(Byte4 &lhs, RValue<Byte4> rhs);
490 //      RValue<Byte4> operator/=(Byte4 &lhs, RValue<Byte4> rhs);
491 //      RValue<Byte4> operator%=(Byte4 &lhs, RValue<Byte4> rhs);
492 //      RValue<Byte4> operator&=(Byte4 &lhs, RValue<Byte4> rhs);
493 //      RValue<Byte4> operator|=(Byte4 &lhs, RValue<Byte4> rhs);
494 //      RValue<Byte4> operator^=(Byte4 &lhs, RValue<Byte4> rhs);
495 //      RValue<Byte4> operator<<=(Byte4 &lhs, RValue<Byte4> rhs);
496 //      RValue<Byte4> operator>>=(Byte4 &lhs, RValue<Byte4> rhs);
497 //      RValue<Byte4> operator+(RValue<Byte4> val);
498 //      RValue<Byte4> operator-(RValue<Byte4> val);
499 //      RValue<Byte4> operator~(RValue<Byte4> val);
500 //      RValue<Byte4> operator++(Byte4 &val, int);   // Post-increment
501 //      const Byte4 &operator++(Byte4 &val);   // Pre-increment
502 //      RValue<Byte4> operator--(Byte4 &val, int);   // Post-decrement
503 //      const Byte4 &operator--(Byte4 &val);   // Pre-decrement
504
505         class SByte4 : public LValue<SByte4>
506         {
507         public:
508                 SByte4() = default;
509         //      SByte4(int x, int y, int z, int w);
510         //      SByte4(RValue<SByte4> rhs);
511         //      SByte4(const SByte4 &rhs);
512         //      SByte4(const Reference<SByte4> &rhs);
513
514         //      RValue<SByte4> operator=(RValue<SByte4> rhs);
515         //      RValue<SByte4> operator=(const SByte4 &rhs);
516         //      RValue<SByte4> operator=(const Reference<SByte4> &rhs);
517
518                 static Type *getType();
519         };
520
521 //      RValue<SByte4> operator+(RValue<SByte4> lhs, RValue<SByte4> rhs);
522 //      RValue<SByte4> operator-(RValue<SByte4> lhs, RValue<SByte4> rhs);
523 //      RValue<SByte4> operator*(RValue<SByte4> lhs, RValue<SByte4> rhs);
524 //      RValue<SByte4> operator/(RValue<SByte4> lhs, RValue<SByte4> rhs);
525 //      RValue<SByte4> operator%(RValue<SByte4> lhs, RValue<SByte4> rhs);
526 //      RValue<SByte4> operator&(RValue<SByte4> lhs, RValue<SByte4> rhs);
527 //      RValue<SByte4> operator|(RValue<SByte4> lhs, RValue<SByte4> rhs);
528 //      RValue<SByte4> operator^(RValue<SByte4> lhs, RValue<SByte4> rhs);
529 //      RValue<SByte4> operator<<(RValue<SByte4> lhs, RValue<SByte4> rhs);
530 //      RValue<SByte4> operator>>(RValue<SByte4> lhs, RValue<SByte4> rhs);
531 //      RValue<SByte4> operator+=(SByte4 &lhs, RValue<SByte4> rhs);
532 //      RValue<SByte4> operator-=(SByte4 &lhs, RValue<SByte4> rhs);
533 //      RValue<SByte4> operator*=(SByte4 &lhs, RValue<SByte4> rhs);
534 //      RValue<SByte4> operator/=(SByte4 &lhs, RValue<SByte4> rhs);
535 //      RValue<SByte4> operator%=(SByte4 &lhs, RValue<SByte4> rhs);
536 //      RValue<SByte4> operator&=(SByte4 &lhs, RValue<SByte4> rhs);
537 //      RValue<SByte4> operator|=(SByte4 &lhs, RValue<SByte4> rhs);
538 //      RValue<SByte4> operator^=(SByte4 &lhs, RValue<SByte4> rhs);
539 //      RValue<SByte4> operator<<=(SByte4 &lhs, RValue<SByte4> rhs);
540 //      RValue<SByte4> operator>>=(SByte4 &lhs, RValue<SByte4> rhs);
541 //      RValue<SByte4> operator+(RValue<SByte4> val);
542 //      RValue<SByte4> operator-(RValue<SByte4> val);
543 //      RValue<SByte4> operator~(RValue<SByte4> val);
544 //      RValue<SByte4> operator++(SByte4 &val, int);   // Post-increment
545 //      const SByte4 &operator++(SByte4 &val);   // Pre-increment
546 //      RValue<SByte4> operator--(SByte4 &val, int);   // Post-decrement
547 //      const SByte4 &operator--(SByte4 &val);   // Pre-decrement
548
549         class Byte8 : public LValue<Byte8>
550         {
551         public:
552                 Byte8() = default;
553                 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);
554                 Byte8(RValue<Byte8> rhs);
555                 Byte8(const Byte8 &rhs);
556                 Byte8(const Reference<Byte8> &rhs);
557
558                 RValue<Byte8> operator=(RValue<Byte8> rhs);
559                 RValue<Byte8> operator=(const Byte8 &rhs);
560                 RValue<Byte8> operator=(const Reference<Byte8> &rhs);
561
562                 static Type *getType();
563         };
564
565         RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs);
566         RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs);
567 //      RValue<Byte8> operator*(RValue<Byte8> lhs, RValue<Byte8> rhs);
568 //      RValue<Byte8> operator/(RValue<Byte8> lhs, RValue<Byte8> rhs);
569 //      RValue<Byte8> operator%(RValue<Byte8> lhs, RValue<Byte8> rhs);
570         RValue<Byte8> operator&(RValue<Byte8> lhs, RValue<Byte8> rhs);
571         RValue<Byte8> operator|(RValue<Byte8> lhs, RValue<Byte8> rhs);
572         RValue<Byte8> operator^(RValue<Byte8> lhs, RValue<Byte8> rhs);
573 //      RValue<Byte8> operator<<(RValue<Byte8> lhs, RValue<Byte8> rhs);
574 //      RValue<Byte8> operator>>(RValue<Byte8> lhs, RValue<Byte8> rhs);
575         RValue<Byte8> operator+=(Byte8 &lhs, RValue<Byte8> rhs);
576         RValue<Byte8> operator-=(Byte8 &lhs, RValue<Byte8> rhs);
577 //      RValue<Byte8> operator*=(Byte8 &lhs, RValue<Byte8> rhs);
578 //      RValue<Byte8> operator/=(Byte8 &lhs, RValue<Byte8> rhs);
579 //      RValue<Byte8> operator%=(Byte8 &lhs, RValue<Byte8> rhs);
580         RValue<Byte8> operator&=(Byte8 &lhs, RValue<Byte8> rhs);
581         RValue<Byte8> operator|=(Byte8 &lhs, RValue<Byte8> rhs);
582         RValue<Byte8> operator^=(Byte8 &lhs, RValue<Byte8> rhs);
583 //      RValue<Byte8> operator<<=(Byte8 &lhs, RValue<Byte8> rhs);
584 //      RValue<Byte8> operator>>=(Byte8 &lhs, RValue<Byte8> rhs);
585 //      RValue<Byte8> operator+(RValue<Byte8> val);
586 //      RValue<Byte8> operator-(RValue<Byte8> val);
587         RValue<Byte8> operator~(RValue<Byte8> val);
588 //      RValue<Byte8> operator++(Byte8 &val, int);   // Post-increment
589 //      const Byte8 &operator++(Byte8 &val);   // Pre-increment
590 //      RValue<Byte8> operator--(Byte8 &val, int);   // Post-decrement
591 //      const Byte8 &operator--(Byte8 &val);   // Pre-decrement
592
593         RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y);
594         RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y);
595         RValue<Short4> Unpack(RValue<Byte4> x);
596         RValue<Short4> Unpack(RValue<Byte4> x, RValue<Byte4> y);
597         RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y);
598         RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y);
599         RValue<Int> SignMask(RValue<Byte8> x);
600 //      RValue<Byte8> CmpGT(RValue<Byte8> x, RValue<Byte8> y);
601         RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y);
602
603         class SByte8 : public LValue<SByte8>
604         {
605         public:
606                 SByte8() = default;
607                 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);
608                 SByte8(RValue<SByte8> rhs);
609                 SByte8(const SByte8 &rhs);
610                 SByte8(const Reference<SByte8> &rhs);
611
612                 RValue<SByte8> operator=(RValue<SByte8> rhs);
613                 RValue<SByte8> operator=(const SByte8 &rhs);
614                 RValue<SByte8> operator=(const Reference<SByte8> &rhs);
615
616                 static Type *getType();
617         };
618
619         RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs);
620         RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs);
621 //      RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs);
622 //      RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs);
623 //      RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs);
624         RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs);
625         RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs);
626         RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs);
627 //      RValue<SByte8> operator<<(RValue<SByte8> lhs, RValue<SByte8> rhs);
628 //      RValue<SByte8> operator>>(RValue<SByte8> lhs, RValue<SByte8> rhs);
629         RValue<SByte8> operator+=(SByte8 &lhs, RValue<SByte8> rhs);
630         RValue<SByte8> operator-=(SByte8 &lhs, RValue<SByte8> rhs);
631 //      RValue<SByte8> operator*=(SByte8 &lhs, RValue<SByte8> rhs);
632 //      RValue<SByte8> operator/=(SByte8 &lhs, RValue<SByte8> rhs);
633 //      RValue<SByte8> operator%=(SByte8 &lhs, RValue<SByte8> rhs);
634         RValue<SByte8> operator&=(SByte8 &lhs, RValue<SByte8> rhs);
635         RValue<SByte8> operator|=(SByte8 &lhs, RValue<SByte8> rhs);
636         RValue<SByte8> operator^=(SByte8 &lhs, RValue<SByte8> rhs);
637 //      RValue<SByte8> operator<<=(SByte8 &lhs, RValue<SByte8> rhs);
638 //      RValue<SByte8> operator>>=(SByte8 &lhs, RValue<SByte8> rhs);
639 //      RValue<SByte8> operator+(RValue<SByte8> val);
640 //      RValue<SByte8> operator-(RValue<SByte8> val);
641         RValue<SByte8> operator~(RValue<SByte8> val);
642 //      RValue<SByte8> operator++(SByte8 &val, int);   // Post-increment
643 //      const SByte8 &operator++(SByte8 &val);   // Pre-increment
644 //      RValue<SByte8> operator--(SByte8 &val, int);   // Post-decrement
645 //      const SByte8 &operator--(SByte8 &val);   // Pre-decrement
646
647         RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y);
648         RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y);
649         RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y);
650         RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y);
651         RValue<Int> SignMask(RValue<SByte8> x);
652         RValue<Byte8> CmpGT(RValue<SByte8> x, RValue<SByte8> y);
653         RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y);
654
655         class Byte16 : public LValue<Byte16>
656         {
657         public:
658                 Byte16() = default;
659         //      Byte16(int x, int y, int z, int w);
660                 Byte16(RValue<Byte16> rhs);
661                 Byte16(const Byte16 &rhs);
662                 Byte16(const Reference<Byte16> &rhs);
663
664                 RValue<Byte16> operator=(RValue<Byte16> rhs);
665                 RValue<Byte16> operator=(const Byte16 &rhs);
666                 RValue<Byte16> operator=(const Reference<Byte16> &rhs);
667
668                 static Type *getType();
669         };
670
671 //      RValue<Byte16> operator+(RValue<Byte16> lhs, RValue<Byte16> rhs);
672 //      RValue<Byte16> operator-(RValue<Byte16> lhs, RValue<Byte16> rhs);
673 //      RValue<Byte16> operator*(RValue<Byte16> lhs, RValue<Byte16> rhs);
674 //      RValue<Byte16> operator/(RValue<Byte16> lhs, RValue<Byte16> rhs);
675 //      RValue<Byte16> operator%(RValue<Byte16> lhs, RValue<Byte16> rhs);
676 //      RValue<Byte16> operator&(RValue<Byte16> lhs, RValue<Byte16> rhs);
677 //      RValue<Byte16> operator|(RValue<Byte16> lhs, RValue<Byte16> rhs);
678 //      RValue<Byte16> operator^(RValue<Byte16> lhs, RValue<Byte16> rhs);
679 //      RValue<Byte16> operator<<(RValue<Byte16> lhs, RValue<Byte16> rhs);
680 //      RValue<Byte16> operator>>(RValue<Byte16> lhs, RValue<Byte16> rhs);
681 //      RValue<Byte16> operator+=(Byte16 &lhs, RValue<Byte16> rhs);
682 //      RValue<Byte16> operator-=(Byte16 &lhs, RValue<Byte16> rhs);
683 //      RValue<Byte16> operator*=(Byte16 &lhs, RValue<Byte16> rhs);
684 //      RValue<Byte16> operator/=(Byte16 &lhs, RValue<Byte16> rhs);
685 //      RValue<Byte16> operator%=(Byte16 &lhs, RValue<Byte16> rhs);
686 //      RValue<Byte16> operator&=(Byte16 &lhs, RValue<Byte16> rhs);
687 //      RValue<Byte16> operator|=(Byte16 &lhs, RValue<Byte16> rhs);
688 //      RValue<Byte16> operator^=(Byte16 &lhs, RValue<Byte16> rhs);
689 //      RValue<Byte16> operator<<=(Byte16 &lhs, RValue<Byte16> rhs);
690 //      RValue<Byte16> operator>>=(Byte16 &lhs, RValue<Byte16> rhs);
691 //      RValue<Byte16> operator+(RValue<Byte16> val);
692 //      RValue<Byte16> operator-(RValue<Byte16> val);
693 //      RValue<Byte16> operator~(RValue<Byte16> val);
694 //      RValue<Byte16> operator++(Byte16 &val, int);   // Post-increment
695 //      const Byte16 &operator++(Byte16 &val);   // Pre-increment
696 //      RValue<Byte16> operator--(Byte16 &val, int);   // Post-decrement
697 //      const Byte16 &operator--(Byte16 &val);   // Pre-decrement
698
699         class SByte16 : public LValue<SByte16>
700         {
701         public:
702                 SByte16() = default;
703         //      SByte16(int x, int y, int z, int w);
704         //      SByte16(RValue<SByte16> rhs);
705         //      SByte16(const SByte16 &rhs);
706         //      SByte16(const Reference<SByte16> &rhs);
707
708         //      RValue<SByte16> operator=(RValue<SByte16> rhs);
709         //      RValue<SByte16> operator=(const SByte16 &rhs);
710         //      RValue<SByte16> operator=(const Reference<SByte16> &rhs);
711
712                 static Type *getType();
713         };
714
715 //      RValue<SByte16> operator+(RValue<SByte16> lhs, RValue<SByte16> rhs);
716 //      RValue<SByte16> operator-(RValue<SByte16> lhs, RValue<SByte16> rhs);
717 //      RValue<SByte16> operator*(RValue<SByte16> lhs, RValue<SByte16> rhs);
718 //      RValue<SByte16> operator/(RValue<SByte16> lhs, RValue<SByte16> rhs);
719 //      RValue<SByte16> operator%(RValue<SByte16> lhs, RValue<SByte16> rhs);
720 //      RValue<SByte16> operator&(RValue<SByte16> lhs, RValue<SByte16> rhs);
721 //      RValue<SByte16> operator|(RValue<SByte16> lhs, RValue<SByte16> rhs);
722 //      RValue<SByte16> operator^(RValue<SByte16> lhs, RValue<SByte16> rhs);
723 //      RValue<SByte16> operator<<(RValue<SByte16> lhs, RValue<SByte16> rhs);
724 //      RValue<SByte16> operator>>(RValue<SByte16> lhs, RValue<SByte16> rhs);
725 //      RValue<SByte16> operator+=(SByte16 &lhs, RValue<SByte16> rhs);
726 //      RValue<SByte16> operator-=(SByte16 &lhs, RValue<SByte16> rhs);
727 //      RValue<SByte16> operator*=(SByte16 &lhs, RValue<SByte16> rhs);
728 //      RValue<SByte16> operator/=(SByte16 &lhs, RValue<SByte16> rhs);
729 //      RValue<SByte16> operator%=(SByte16 &lhs, RValue<SByte16> rhs);
730 //      RValue<SByte16> operator&=(SByte16 &lhs, RValue<SByte16> rhs);
731 //      RValue<SByte16> operator|=(SByte16 &lhs, RValue<SByte16> rhs);
732 //      RValue<SByte16> operator^=(SByte16 &lhs, RValue<SByte16> rhs);
733 //      RValue<SByte16> operator<<=(SByte16 &lhs, RValue<SByte16> rhs);
734 //      RValue<SByte16> operator>>=(SByte16 &lhs, RValue<SByte16> rhs);
735 //      RValue<SByte16> operator+(RValue<SByte16> val);
736 //      RValue<SByte16> operator-(RValue<SByte16> val);
737 //      RValue<SByte16> operator~(RValue<SByte16> val);
738 //      RValue<SByte16> operator++(SByte16 &val, int);   // Post-increment
739 //      const SByte16 &operator++(SByte16 &val);   // Pre-increment
740 //      RValue<SByte16> operator--(SByte16 &val, int);   // Post-decrement
741 //      const SByte16 &operator--(SByte16 &val);   // Pre-decrement
742
743         class Short2 : public LValue<Short2>
744         {
745         public:
746                 explicit Short2(RValue<Short4> cast);
747
748                 static Type *getType();
749         };
750
751         class UShort2 : public LValue<UShort2>
752         {
753         public:
754                 explicit UShort2(RValue<UShort4> cast);
755
756                 static Type *getType();
757         };
758
759         class Short4 : public LValue<Short4>
760         {
761         public:
762                 explicit Short4(RValue<Int> cast);
763                 explicit Short4(RValue<Int4> cast);
764         //      explicit Short4(RValue<Float> cast);
765                 explicit Short4(RValue<Float4> cast);
766
767                 Short4() = default;
768                 Short4(short xyzw);
769                 Short4(short x, short y, short z, short w);
770                 Short4(RValue<Short4> rhs);
771                 Short4(const Short4 &rhs);
772                 Short4(const Reference<Short4> &rhs);
773                 Short4(RValue<UShort4> rhs);
774                 Short4(const UShort4 &rhs);
775                 Short4(const Reference<UShort4> &rhs);
776
777                 RValue<Short4> operator=(RValue<Short4> rhs);
778                 RValue<Short4> operator=(const Short4 &rhs);
779                 RValue<Short4> operator=(const Reference<Short4> &rhs);
780                 RValue<Short4> operator=(RValue<UShort4> rhs);
781                 RValue<Short4> operator=(const UShort4 &rhs);
782                 RValue<Short4> operator=(const Reference<UShort4> &rhs);
783
784                 static Type *getType();
785         };
786
787         RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs);
788         RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs);
789         RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs);
790 //      RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs);
791 //      RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs);
792         RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs);
793         RValue<Short4> operator|(RValue<Short4> lhs, RValue<Short4> rhs);
794         RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs);
795         RValue<Short4> operator<<(RValue<Short4> lhs, unsigned char rhs);
796         RValue<Short4> operator>>(RValue<Short4> lhs, unsigned char rhs);
797         RValue<Short4> operator+=(Short4 &lhs, RValue<Short4> rhs);
798         RValue<Short4> operator-=(Short4 &lhs, RValue<Short4> rhs);
799         RValue<Short4> operator*=(Short4 &lhs, RValue<Short4> rhs);
800 //      RValue<Short4> operator/=(Short4 &lhs, RValue<Short4> rhs);
801 //      RValue<Short4> operator%=(Short4 &lhs, RValue<Short4> rhs);
802         RValue<Short4> operator&=(Short4 &lhs, RValue<Short4> rhs);
803         RValue<Short4> operator|=(Short4 &lhs, RValue<Short4> rhs);
804         RValue<Short4> operator^=(Short4 &lhs, RValue<Short4> rhs);
805         RValue<Short4> operator<<=(Short4 &lhs, unsigned char rhs);
806         RValue<Short4> operator>>=(Short4 &lhs, unsigned char rhs);
807 //      RValue<Short4> operator+(RValue<Short4> val);
808         RValue<Short4> operator-(RValue<Short4> val);
809         RValue<Short4> operator~(RValue<Short4> val);
810 //      RValue<Short4> operator++(Short4 &val, int);   // Post-increment
811 //      const Short4 &operator++(Short4 &val);   // Pre-increment
812 //      RValue<Short4> operator--(Short4 &val, int);   // Post-decrement
813 //      const Short4 &operator--(Short4 &val);   // Pre-decrement
814 //      RValue<Bool> operator<(RValue<Short4> lhs, RValue<Short4> rhs);
815 //      RValue<Bool> operator<=(RValue<Short4> lhs, RValue<Short4> rhs);
816 //      RValue<Bool> operator>(RValue<Short4> lhs, RValue<Short4> rhs);
817 //      RValue<Bool> operator>=(RValue<Short4> lhs, RValue<Short4> rhs);
818 //      RValue<Bool> operator!=(RValue<Short4> lhs, RValue<Short4> rhs);
819 //      RValue<Bool> operator==(RValue<Short4> lhs, RValue<Short4> rhs);
820
821         RValue<Short4> RoundShort4(RValue<Float4> cast);
822         RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y);
823         RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y);
824         RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y);
825         RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y);
826         RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y);
827         RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y);
828         RValue<SByte8> PackSigned(RValue<Short4> x, RValue<Short4> y);
829         RValue<Byte8> PackUnsigned(RValue<Short4> x, RValue<Short4> y);
830         RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y);
831         RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y);
832         RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select);
833         RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i);
834         RValue<Short> Extract(RValue<Short4> val, int i);
835         RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y);
836         RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y);
837
838         class UShort4 : public LValue<UShort4>
839         {
840         public:
841                 explicit UShort4(RValue<Int4> cast);
842                 explicit UShort4(RValue<Float4> cast, bool saturate = false);
843
844                 UShort4() = default;
845                 UShort4(unsigned short xyzw);
846                 UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w);
847                 UShort4(RValue<UShort4> rhs);
848                 UShort4(const UShort4 &rhs);
849                 UShort4(const Reference<UShort4> &rhs);
850                 UShort4(RValue<Short4> rhs);
851                 UShort4(const Short4 &rhs);
852                 UShort4(const Reference<Short4> &rhs);
853
854                 RValue<UShort4> operator=(RValue<UShort4> rhs);
855                 RValue<UShort4> operator=(const UShort4 &rhs);
856                 RValue<UShort4> operator=(const Reference<UShort4> &rhs);
857                 RValue<UShort4> operator=(RValue<Short4> rhs);
858                 RValue<UShort4> operator=(const Short4 &rhs);
859                 RValue<UShort4> operator=(const Reference<Short4> &rhs);
860
861                 static Type *getType();
862         };
863
864         RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs);
865         RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs);
866         RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs);
867 //      RValue<UShort4> operator/(RValue<UShort4> lhs, RValue<UShort4> rhs);
868 //      RValue<UShort4> operator%(RValue<UShort4> lhs, RValue<UShort4> rhs);
869         RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs);
870         RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs);
871         RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs);
872         RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs);
873         RValue<UShort4> operator>>(RValue<UShort4> lhs, unsigned char rhs);
874 //      RValue<UShort4> operator+=(UShort4 &lhs, RValue<UShort4> rhs);
875 //      RValue<UShort4> operator-=(UShort4 &lhs, RValue<UShort4> rhs);
876 //      RValue<UShort4> operator*=(UShort4 &lhs, RValue<UShort4> rhs);
877 //      RValue<UShort4> operator/=(UShort4 &lhs, RValue<UShort4> rhs);
878 //      RValue<UShort4> operator%=(UShort4 &lhs, RValue<UShort4> rhs);
879 //      RValue<UShort4> operator&=(UShort4 &lhs, RValue<UShort4> rhs);
880 //      RValue<UShort4> operator|=(UShort4 &lhs, RValue<UShort4> rhs);
881 //      RValue<UShort4> operator^=(UShort4 &lhs, RValue<UShort4> rhs);
882         RValue<UShort4> operator<<=(UShort4 &lhs, unsigned char rhs);
883         RValue<UShort4> operator>>=(UShort4 &lhs, unsigned char rhs);
884 //      RValue<UShort4> operator+(RValue<UShort4> val);
885 //      RValue<UShort4> operator-(RValue<UShort4> val);
886         RValue<UShort4> operator~(RValue<UShort4> val);
887 //      RValue<UShort4> operator++(UShort4 &val, int);   // Post-increment
888 //      const UShort4 &operator++(UShort4 &val);   // Pre-increment
889 //      RValue<UShort4> operator--(UShort4 &val, int);   // Post-decrement
890 //      const UShort4 &operator--(UShort4 &val);   // Pre-decrement
891
892         RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y);
893         RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y);
894         RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y);
895         RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y);
896         RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y);
897         RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y);
898
899         class Short8 : public LValue<Short8>
900         {
901         public:
902                 Short8() = default;
903                 Short8(short c);
904                 Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7);
905                 Short8(RValue<Short8> rhs);
906         //      Short8(const Short8 &rhs);
907                 Short8(const Reference<Short8> &rhs);
908                 Short8(RValue<Short4> lo, RValue<Short4> hi);
909
910                 RValue<Short8> operator=(RValue<Short8> rhs);
911                 RValue<Short8> operator=(const Short8 &rhs);
912                 RValue<Short8> operator=(const Reference<Short8> &rhs);
913
914                 static Type *getType();
915         };
916
917         RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs);
918 //      RValue<Short8> operator-(RValue<Short8> lhs, RValue<Short8> rhs);
919 //      RValue<Short8> operator*(RValue<Short8> lhs, RValue<Short8> rhs);
920 //      RValue<Short8> operator/(RValue<Short8> lhs, RValue<Short8> rhs);
921 //      RValue<Short8> operator%(RValue<Short8> lhs, RValue<Short8> rhs);
922         RValue<Short8> operator&(RValue<Short8> lhs, RValue<Short8> rhs);
923 //      RValue<Short8> operator|(RValue<Short8> lhs, RValue<Short8> rhs);
924 //      RValue<Short8> operator^(RValue<Short8> lhs, RValue<Short8> rhs);
925         RValue<Short8> operator<<(RValue<Short8> lhs, unsigned char rhs);
926         RValue<Short8> operator>>(RValue<Short8> lhs, unsigned char rhs);
927 //      RValue<Short8> operator<<(RValue<Short8> lhs, RValue<Short8> rhs);
928 //      RValue<Short8> operator>>(RValue<Short8> lhs, RValue<Short8> rhs);
929 //      RValue<Short8> operator+=(Short8 &lhs, RValue<Short8> rhs);
930 //      RValue<Short8> operator-=(Short8 &lhs, RValue<Short8> rhs);
931 //      RValue<Short8> operator*=(Short8 &lhs, RValue<Short8> rhs);
932 //      RValue<Short8> operator/=(Short8 &lhs, RValue<Short8> rhs);
933 //      RValue<Short8> operator%=(Short8 &lhs, RValue<Short8> rhs);
934 //      RValue<Short8> operator&=(Short8 &lhs, RValue<Short8> rhs);
935 //      RValue<Short8> operator|=(Short8 &lhs, RValue<Short8> rhs);
936 //      RValue<Short8> operator^=(Short8 &lhs, RValue<Short8> rhs);
937 //      RValue<Short8> operator<<=(Short8 &lhs, RValue<Short8> rhs);
938 //      RValue<Short8> operator>>=(Short8 &lhs, RValue<Short8> rhs);
939 //      RValue<Short8> operator+(RValue<Short8> val);
940 //      RValue<Short8> operator-(RValue<Short8> val);
941 //      RValue<Short8> operator~(RValue<Short8> val);
942 //      RValue<Short8> operator++(Short8 &val, int);   // Post-increment
943 //      const Short8 &operator++(Short8 &val);   // Pre-increment
944 //      RValue<Short8> operator--(Short8 &val, int);   // Post-decrement
945 //      const Short8 &operator--(Short8 &val);   // Pre-decrement
946 //      RValue<Bool> operator<(RValue<Short8> lhs, RValue<Short8> rhs);
947 //      RValue<Bool> operator<=(RValue<Short8> lhs, RValue<Short8> rhs);
948 //      RValue<Bool> operator>(RValue<Short8> lhs, RValue<Short8> rhs);
949 //      RValue<Bool> operator>=(RValue<Short8> lhs, RValue<Short8> rhs);
950 //      RValue<Bool> operator!=(RValue<Short8> lhs, RValue<Short8> rhs);
951 //      RValue<Bool> operator==(RValue<Short8> lhs, RValue<Short8> rhs);
952
953         RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y);
954         RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y);
955         RValue<Int4> Abs(RValue<Int4> x);
956
957         class UShort8 : public LValue<UShort8>
958         {
959         public:
960                 UShort8() = default;
961                 UShort8(unsigned short c);
962                 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);
963                 UShort8(RValue<UShort8> rhs);
964         //      UShort8(const UShort8 &rhs);
965                 UShort8(const Reference<UShort8> &rhs);
966                 UShort8(RValue<UShort4> lo, RValue<UShort4> hi);
967
968                 RValue<UShort8> operator=(RValue<UShort8> rhs);
969                 RValue<UShort8> operator=(const UShort8 &rhs);
970                 RValue<UShort8> operator=(const Reference<UShort8> &rhs);
971
972                 static Type *getType();
973         };
974
975         RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs);
976 //      RValue<UShort8> operator-(RValue<UShort8> lhs, RValue<UShort8> rhs);
977         RValue<UShort8> operator*(RValue<UShort8> lhs, RValue<UShort8> rhs);
978 //      RValue<UShort8> operator/(RValue<UShort8> lhs, RValue<UShort8> rhs);
979 //      RValue<UShort8> operator%(RValue<UShort8> lhs, RValue<UShort8> rhs);
980         RValue<UShort8> operator&(RValue<UShort8> lhs, RValue<UShort8> rhs);
981 //      RValue<UShort8> operator|(RValue<UShort8> lhs, RValue<UShort8> rhs);
982 //      RValue<UShort8> operator^(RValue<UShort8> lhs, RValue<UShort8> rhs);
983         RValue<UShort8> operator<<(RValue<UShort8> lhs, unsigned char rhs);
984         RValue<UShort8> operator>>(RValue<UShort8> lhs, unsigned char rhs);
985 //      RValue<UShort8> operator<<(RValue<UShort8> lhs, RValue<UShort8> rhs);
986 //      RValue<UShort8> operator>>(RValue<UShort8> lhs, RValue<UShort8> rhs);
987         RValue<UShort8> operator+=(UShort8 &lhs, RValue<UShort8> rhs);
988 //      RValue<UShort8> operator-=(UShort8 &lhs, RValue<UShort8> rhs);
989 //      RValue<UShort8> operator*=(UShort8 &lhs, RValue<UShort8> rhs);
990 //      RValue<UShort8> operator/=(UShort8 &lhs, RValue<UShort8> rhs);
991 //      RValue<UShort8> operator%=(UShort8 &lhs, RValue<UShort8> rhs);
992 //      RValue<UShort8> operator&=(UShort8 &lhs, RValue<UShort8> rhs);
993 //      RValue<UShort8> operator|=(UShort8 &lhs, RValue<UShort8> rhs);
994 //      RValue<UShort8> operator^=(UShort8 &lhs, RValue<UShort8> rhs);
995 //      RValue<UShort8> operator<<=(UShort8 &lhs, RValue<UShort8> rhs);
996 //      RValue<UShort8> operator>>=(UShort8 &lhs, RValue<UShort8> rhs);
997 //      RValue<UShort8> operator+(RValue<UShort8> val);
998 //      RValue<UShort8> operator-(RValue<UShort8> val);
999         RValue<UShort8> operator~(RValue<UShort8> val);
1000 //      RValue<UShort8> operator++(UShort8 &val, int);   // Post-increment
1001 //      const UShort8 &operator++(UShort8 &val);   // Pre-increment
1002 //      RValue<UShort8> operator--(UShort8 &val, int);   // Post-decrement
1003 //      const UShort8 &operator--(UShort8 &val);   // Pre-decrement
1004 //      RValue<Bool> operator<(RValue<UShort8> lhs, RValue<UShort8> rhs);
1005 //      RValue<Bool> operator<=(RValue<UShort8> lhs, RValue<UShort8> rhs);
1006 //      RValue<Bool> operator>(RValue<UShort8> lhs, RValue<UShort8> rhs);
1007 //      RValue<Bool> operator>=(RValue<UShort8> lhs, RValue<UShort8> rhs);
1008 //      RValue<Bool> operator!=(RValue<UShort8> lhs, RValue<UShort8> rhs);
1009 //      RValue<Bool> operator==(RValue<UShort8> lhs, RValue<UShort8> rhs);
1010
1011         RValue<UShort8> Swizzle(RValue<UShort8> x, char select0, char select1, char select2, char select3, char select4, char select5, char select6, char select7);
1012         RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y);
1013
1014         class Int : public LValue<Int>
1015         {
1016         public:
1017                 Int(Argument<Int> argument);
1018
1019                 explicit Int(RValue<Byte> cast);
1020                 explicit Int(RValue<SByte> cast);
1021                 explicit Int(RValue<Short> cast);
1022                 explicit Int(RValue<UShort> cast);
1023                 explicit Int(RValue<Int2> cast);
1024                 explicit Int(RValue<Long> cast);
1025                 explicit Int(RValue<Float> cast);
1026
1027                 Int() = default;
1028                 Int(int x);
1029                 Int(RValue<Int> rhs);
1030                 Int(RValue<UInt> rhs);
1031                 Int(const Int &rhs);
1032                 Int(const UInt &rhs);
1033                 Int(const Reference<Int> &rhs);
1034                 Int(const Reference<UInt> &rhs);
1035
1036                 RValue<Int> operator=(int rhs);
1037                 RValue<Int> operator=(RValue<Int> rhs);
1038                 RValue<Int> operator=(RValue<UInt> rhs);
1039                 RValue<Int> operator=(const Int &rhs);
1040                 RValue<Int> operator=(const UInt &rhs);
1041                 RValue<Int> operator=(const Reference<Int> &rhs);
1042                 RValue<Int> operator=(const Reference<UInt> &rhs);
1043
1044                 static Type *getType();
1045         };
1046
1047         RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs);
1048         RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs);
1049         RValue<Int> operator*(RValue<Int> lhs, RValue<Int> rhs);
1050         RValue<Int> operator/(RValue<Int> lhs, RValue<Int> rhs);
1051         RValue<Int> operator%(RValue<Int> lhs, RValue<Int> rhs);
1052         RValue<Int> operator&(RValue<Int> lhs, RValue<Int> rhs);
1053         RValue<Int> operator|(RValue<Int> lhs, RValue<Int> rhs);
1054         RValue<Int> operator^(RValue<Int> lhs, RValue<Int> rhs);
1055         RValue<Int> operator<<(RValue<Int> lhs, RValue<Int> rhs);
1056         RValue<Int> operator>>(RValue<Int> lhs, RValue<Int> rhs);
1057         RValue<Int> operator+=(Int &lhs, RValue<Int> rhs);
1058         RValue<Int> operator-=(Int &lhs, RValue<Int> rhs);
1059         RValue<Int> operator*=(Int &lhs, RValue<Int> rhs);
1060         RValue<Int> operator/=(Int &lhs, RValue<Int> rhs);
1061         RValue<Int> operator%=(Int &lhs, RValue<Int> rhs);
1062         RValue<Int> operator&=(Int &lhs, RValue<Int> rhs);
1063         RValue<Int> operator|=(Int &lhs, RValue<Int> rhs);
1064         RValue<Int> operator^=(Int &lhs, RValue<Int> rhs);
1065         RValue<Int> operator<<=(Int &lhs, RValue<Int> rhs);
1066         RValue<Int> operator>>=(Int &lhs, RValue<Int> rhs);
1067         RValue<Int> operator+(RValue<Int> val);
1068         RValue<Int> operator-(RValue<Int> val);
1069         RValue<Int> operator~(RValue<Int> val);
1070         RValue<Int> operator++(Int &val, int);   // Post-increment
1071         const Int &operator++(Int &val);   // Pre-increment
1072         RValue<Int> operator--(Int &val, int);   // Post-decrement
1073         const Int &operator--(Int &val);   // Pre-decrement
1074         RValue<Bool> operator<(RValue<Int> lhs, RValue<Int> rhs);
1075         RValue<Bool> operator<=(RValue<Int> lhs, RValue<Int> rhs);
1076         RValue<Bool> operator>(RValue<Int> lhs, RValue<Int> rhs);
1077         RValue<Bool> operator>=(RValue<Int> lhs, RValue<Int> rhs);
1078         RValue<Bool> operator!=(RValue<Int> lhs, RValue<Int> rhs);
1079         RValue<Bool> operator==(RValue<Int> lhs, RValue<Int> rhs);
1080
1081         RValue<Int> Max(RValue<Int> x, RValue<Int> y);
1082         RValue<Int> Min(RValue<Int> x, RValue<Int> y);
1083         RValue<Int> Clamp(RValue<Int> x, RValue<Int> min, RValue<Int> max);
1084         RValue<Int> RoundInt(RValue<Float> cast);
1085
1086         class Long : public LValue<Long>
1087         {
1088         public:
1089         //      Long(Argument<Long> argument);
1090
1091         //      explicit Long(RValue<Short> cast);
1092         //      explicit Long(RValue<UShort> cast);
1093                 explicit Long(RValue<Int> cast);
1094                 explicit Long(RValue<UInt> cast);
1095         //      explicit Long(RValue<Float> cast);
1096
1097                 Long() = default;
1098         //      Long(qword x);
1099                 Long(RValue<Long> rhs);
1100         //      Long(RValue<ULong> rhs);
1101         //      Long(const Long &rhs);
1102         //      Long(const Reference<Long> &rhs);
1103         //      Long(const ULong &rhs);
1104         //      Long(const Reference<ULong> &rhs);
1105
1106                 RValue<Long> operator=(int64_t rhs);
1107                 RValue<Long> operator=(RValue<Long> rhs);
1108         //      RValue<Long> operator=(RValue<ULong> rhs);
1109                 RValue<Long> operator=(const Long &rhs);
1110                 RValue<Long> operator=(const Reference<Long> &rhs);
1111         //      RValue<Long> operator=(const ULong &rhs);
1112         //      RValue<Long> operator=(const Reference<ULong> &rhs);
1113
1114                 static Type *getType();
1115         };
1116
1117         RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs);
1118         RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs);
1119         RValue<Long> operator*(RValue<Long> lhs, RValue<Long> rhs);
1120 //      RValue<Long> operator/(RValue<Long> lhs, RValue<Long> rhs);
1121 //      RValue<Long> operator%(RValue<Long> lhs, RValue<Long> rhs);
1122 //      RValue<Long> operator&(RValue<Long> lhs, RValue<Long> rhs);
1123 //      RValue<Long> operator|(RValue<Long> lhs, RValue<Long> rhs);
1124 //      RValue<Long> operator^(RValue<Long> lhs, RValue<Long> rhs);
1125 //      RValue<Long> operator<<(RValue<Long> lhs, RValue<Long> rhs);
1126         RValue<Long> operator>>(RValue<Long> lhs, RValue<Long> rhs);
1127         RValue<Long> operator+=(Long &lhs, RValue<Long> rhs);
1128         RValue<Long> operator-=(Long &lhs, RValue<Long> rhs);
1129 //      RValue<Long> operator*=(Long &lhs, RValue<Long> rhs);
1130 //      RValue<Long> operator/=(Long &lhs, RValue<Long> rhs);
1131 //      RValue<Long> operator%=(Long &lhs, RValue<Long> rhs);
1132 //      RValue<Long> operator&=(Long &lhs, RValue<Long> rhs);
1133 //      RValue<Long> operator|=(Long &lhs, RValue<Long> rhs);
1134 //      RValue<Long> operator^=(Long &lhs, RValue<Long> rhs);
1135 //      RValue<Long> operator<<=(Long &lhs, RValue<Long> rhs);
1136 //      RValue<Long> operator>>=(Long &lhs, RValue<Long> rhs);
1137 //      RValue<Long> operator+(RValue<Long> val);
1138 //      RValue<Long> operator-(RValue<Long> val);
1139 //      RValue<Long> operator~(RValue<Long> val);
1140 //      RValue<Long> operator++(Long &val, int);   // Post-increment
1141 //      const Long &operator++(Long &val);   // Pre-increment
1142 //      RValue<Long> operator--(Long &val, int);   // Post-decrement
1143 //      const Long &operator--(Long &val);   // Pre-decrement
1144 //      RValue<Bool> operator<(RValue<Long> lhs, RValue<Long> rhs);
1145 //      RValue<Bool> operator<=(RValue<Long> lhs, RValue<Long> rhs);
1146 //      RValue<Bool> operator>(RValue<Long> lhs, RValue<Long> rhs);
1147 //      RValue<Bool> operator>=(RValue<Long> lhs, RValue<Long> rhs);
1148 //      RValue<Bool> operator!=(RValue<Long> lhs, RValue<Long> rhs);
1149 //      RValue<Bool> operator==(RValue<Long> lhs, RValue<Long> rhs);
1150
1151 //      RValue<Long> RoundLong(RValue<Float> cast);
1152         RValue<Long> AddAtomic( RValue<Pointer<Long>> x, RValue<Long> y);
1153
1154         class UInt : public LValue<UInt>
1155         {
1156         public:
1157                 UInt(Argument<UInt> argument);
1158
1159                 explicit UInt(RValue<UShort> cast);
1160                 explicit UInt(RValue<Long> cast);
1161                 explicit UInt(RValue<Float> cast);
1162
1163                 UInt() = default;
1164                 UInt(int x);
1165                 UInt(unsigned int x);
1166                 UInt(RValue<UInt> rhs);
1167                 UInt(RValue<Int> rhs);
1168                 UInt(const UInt &rhs);
1169                 UInt(const Int &rhs);
1170                 UInt(const Reference<UInt> &rhs);
1171                 UInt(const Reference<Int> &rhs);
1172
1173                 RValue<UInt> operator=(unsigned int rhs);
1174                 RValue<UInt> operator=(RValue<UInt> rhs);
1175                 RValue<UInt> operator=(RValue<Int> rhs);
1176                 RValue<UInt> operator=(const UInt &rhs);
1177                 RValue<UInt> operator=(const Int &rhs);
1178                 RValue<UInt> operator=(const Reference<UInt> &rhs);
1179                 RValue<UInt> operator=(const Reference<Int> &rhs);
1180
1181                 static Type *getType();
1182         };
1183
1184         RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs);
1185         RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs);
1186         RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs);
1187         RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs);
1188         RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs);
1189         RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs);
1190         RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs);
1191         RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs);
1192         RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs);
1193         RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs);
1194         RValue<UInt> operator+=(UInt &lhs, RValue<UInt> rhs);
1195         RValue<UInt> operator-=(UInt &lhs, RValue<UInt> rhs);
1196         RValue<UInt> operator*=(UInt &lhs, RValue<UInt> rhs);
1197         RValue<UInt> operator/=(UInt &lhs, RValue<UInt> rhs);
1198         RValue<UInt> operator%=(UInt &lhs, RValue<UInt> rhs);
1199         RValue<UInt> operator&=(UInt &lhs, RValue<UInt> rhs);
1200         RValue<UInt> operator|=(UInt &lhs, RValue<UInt> rhs);
1201         RValue<UInt> operator^=(UInt &lhs, RValue<UInt> rhs);
1202         RValue<UInt> operator<<=(UInt &lhs, RValue<UInt> rhs);
1203         RValue<UInt> operator>>=(UInt &lhs, RValue<UInt> rhs);
1204         RValue<UInt> operator+(RValue<UInt> val);
1205         RValue<UInt> operator-(RValue<UInt> val);
1206         RValue<UInt> operator~(RValue<UInt> val);
1207         RValue<UInt> operator++(UInt &val, int);   // Post-increment
1208         const UInt &operator++(UInt &val);   // Pre-increment
1209         RValue<UInt> operator--(UInt &val, int);   // Post-decrement
1210         const UInt &operator--(UInt &val);   // Pre-decrement
1211         RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs);
1212         RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs);
1213         RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs);
1214         RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs);
1215         RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs);
1216         RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs);
1217
1218         RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y);
1219         RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y);
1220         RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max);
1221 //      RValue<UInt> RoundUInt(RValue<Float> cast);
1222
1223         class Int2 : public LValue<Int2>
1224         {
1225         public:
1226         //      explicit Int2(RValue<Int> cast);
1227                 explicit Int2(RValue<Int4> cast);
1228
1229                 Int2() = default;
1230                 Int2(int x, int y);
1231                 Int2(RValue<Int2> rhs);
1232                 Int2(const Int2 &rhs);
1233                 Int2(const Reference<Int2> &rhs);
1234                 Int2(RValue<Int> lo, RValue<Int> hi);
1235
1236                 RValue<Int2> operator=(RValue<Int2> rhs);
1237                 RValue<Int2> operator=(const Int2 &rhs);
1238                 RValue<Int2> operator=(const Reference<Int2> &rhs);
1239
1240                 static Type *getType();
1241         };
1242
1243         RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs);
1244         RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs);
1245 //      RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs);
1246 //      RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs);
1247 //      RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs);
1248         RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs);
1249         RValue<Int2> operator|(RValue<Int2> lhs, RValue<Int2> rhs);
1250         RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs);
1251         RValue<Int2> operator<<(RValue<Int2> lhs, unsigned char rhs);
1252         RValue<Int2> operator>>(RValue<Int2> lhs, unsigned char rhs);
1253         RValue<Int2> operator+=(Int2 &lhs, RValue<Int2> rhs);
1254         RValue<Int2> operator-=(Int2 &lhs, RValue<Int2> rhs);
1255 //      RValue<Int2> operator*=(Int2 &lhs, RValue<Int2> rhs);
1256 //      RValue<Int2> operator/=(Int2 &lhs, RValue<Int2> rhs);
1257 //      RValue<Int2> operator%=(Int2 &lhs, RValue<Int2> rhs);
1258         RValue<Int2> operator&=(Int2 &lhs, RValue<Int2> rhs);
1259         RValue<Int2> operator|=(Int2 &lhs, RValue<Int2> rhs);
1260         RValue<Int2> operator^=(Int2 &lhs, RValue<Int2> rhs);
1261         RValue<Int2> operator<<=(Int2 &lhs, unsigned char rhs);
1262         RValue<Int2> operator>>=(Int2 &lhs, unsigned char rhs);
1263 //      RValue<Int2> operator+(RValue<Int2> val);
1264 //      RValue<Int2> operator-(RValue<Int2> val);
1265         RValue<Int2> operator~(RValue<Int2> val);
1266 //      RValue<Int2> operator++(Int2 &val, int);   // Post-increment
1267 //      const Int2 &operator++(Int2 &val);   // Pre-increment
1268 //      RValue<Int2> operator--(Int2 &val, int);   // Post-decrement
1269 //      const Int2 &operator--(Int2 &val);   // Pre-decrement
1270 //      RValue<Bool> operator<(RValue<Int2> lhs, RValue<Int2> rhs);
1271 //      RValue<Bool> operator<=(RValue<Int2> lhs, RValue<Int2> rhs);
1272 //      RValue<Bool> operator>(RValue<Int2> lhs, RValue<Int2> rhs);
1273 //      RValue<Bool> operator>=(RValue<Int2> lhs, RValue<Int2> rhs);
1274 //      RValue<Bool> operator!=(RValue<Int2> lhs, RValue<Int2> rhs);
1275 //      RValue<Bool> operator==(RValue<Int2> lhs, RValue<Int2> rhs);
1276
1277 //      RValue<Int2> RoundInt(RValue<Float4> cast);
1278         RValue<Short4> UnpackLow(RValue<Int2> x, RValue<Int2> y);
1279         RValue<Short4> UnpackHigh(RValue<Int2> x, RValue<Int2> y);
1280         RValue<Int> Extract(RValue<Int2> val, int i);
1281         RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i);
1282
1283         class UInt2 : public LValue<UInt2>
1284         {
1285         public:
1286                 UInt2() = default;
1287                 UInt2(unsigned int x, unsigned int y);
1288                 UInt2(RValue<UInt2> rhs);
1289                 UInt2(const UInt2 &rhs);
1290                 UInt2(const Reference<UInt2> &rhs);
1291
1292                 RValue<UInt2> operator=(RValue<UInt2> rhs);
1293                 RValue<UInt2> operator=(const UInt2 &rhs);
1294                 RValue<UInt2> operator=(const Reference<UInt2> &rhs);
1295
1296                 static Type *getType();
1297         };
1298
1299         RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs);
1300         RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs);
1301 //      RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs);
1302 //      RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs);
1303 //      RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs);
1304         RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs);
1305         RValue<UInt2> operator|(RValue<UInt2> lhs, RValue<UInt2> rhs);
1306         RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs);
1307         RValue<UInt2> operator<<(RValue<UInt2> lhs, unsigned char rhs);
1308         RValue<UInt2> operator>>(RValue<UInt2> lhs, unsigned char rhs);
1309         RValue<UInt2> operator+=(UInt2 &lhs, RValue<UInt2> rhs);
1310         RValue<UInt2> operator-=(UInt2 &lhs, RValue<UInt2> rhs);
1311 //      RValue<UInt2> operator*=(UInt2 &lhs, RValue<UInt2> rhs);
1312 //      RValue<UInt2> operator/=(UInt2 &lhs, RValue<UInt2> rhs);
1313 //      RValue<UInt2> operator%=(UInt2 &lhs, RValue<UInt2> rhs);
1314         RValue<UInt2> operator&=(UInt2 &lhs, RValue<UInt2> rhs);
1315         RValue<UInt2> operator|=(UInt2 &lhs, RValue<UInt2> rhs);
1316         RValue<UInt2> operator^=(UInt2 &lhs, RValue<UInt2> rhs);
1317         RValue<UInt2> operator<<=(UInt2 &lhs, unsigned char rhs);
1318         RValue<UInt2> operator>>=(UInt2 &lhs, unsigned char rhs);
1319 //      RValue<UInt2> operator+(RValue<UInt2> val);
1320 //      RValue<UInt2> operator-(RValue<UInt2> val);
1321         RValue<UInt2> operator~(RValue<UInt2> val);
1322 //      RValue<UInt2> operator++(UInt2 &val, int);   // Post-increment
1323 //      const UInt2 &operator++(UInt2 &val);   // Pre-increment
1324 //      RValue<UInt2> operator--(UInt2 &val, int);   // Post-decrement
1325 //      const UInt2 &operator--(UInt2 &val);   // Pre-decrement
1326 //      RValue<Bool> operator<(RValue<UInt2> lhs, RValue<UInt2> rhs);
1327 //      RValue<Bool> operator<=(RValue<UInt2> lhs, RValue<UInt2> rhs);
1328 //      RValue<Bool> operator>(RValue<UInt2> lhs, RValue<UInt2> rhs);
1329 //      RValue<Bool> operator>=(RValue<UInt2> lhs, RValue<UInt2> rhs);
1330 //      RValue<Bool> operator!=(RValue<UInt2> lhs, RValue<UInt2> rhs);
1331 //      RValue<Bool> operator==(RValue<UInt2> lhs, RValue<UInt2> rhs);
1332
1333 //      RValue<UInt2> RoundInt(RValue<Float4> cast);
1334
1335         template<class T>
1336         struct Scalar;
1337
1338         template<class Vector4>
1339         struct XYZW;
1340
1341         template<class Vector4, int T>
1342         class Swizzle2
1343         {
1344                 friend Vector4;
1345
1346         public:
1347                 operator RValue<Vector4>() const;
1348
1349         private:
1350                 Vector4 *parent;
1351         };
1352
1353         template<class Vector4, int T>
1354         class Swizzle4
1355         {
1356         public:
1357                 operator RValue<Vector4>() const;
1358
1359         private:
1360                 Vector4 *parent;
1361         };
1362
1363         template<class Vector4, int T>
1364         class SwizzleMask4
1365         {
1366                 friend XYZW<Vector4>;
1367
1368         public:
1369                 operator RValue<Vector4>() const;
1370
1371                 RValue<Vector4> operator=(RValue<Vector4> rhs);
1372                 RValue<Vector4> operator=(RValue<typename Scalar<Vector4>::Type> rhs);
1373
1374         private:
1375                 Vector4 *parent;
1376         };
1377
1378         template<>
1379         struct Scalar<Float4>
1380         {
1381                 using Type = Float;
1382         };
1383
1384         template<>
1385         struct Scalar<Int4>
1386         {
1387                 using Type = Int;
1388         };
1389
1390         template<>
1391         struct Scalar<UInt4>
1392         {
1393                 using Type = UInt;
1394         };
1395
1396         template<class Vector4, int T>
1397         class SwizzleMask1
1398         {
1399         public:
1400                 operator RValue<typename Scalar<Vector4>::Type>() const;
1401                 operator RValue<Vector4>() const;
1402
1403                 RValue<Vector4> operator=(float x);
1404                 RValue<Vector4> operator=(RValue<Vector4> rhs);
1405                 RValue<Vector4> operator=(RValue<typename Scalar<Vector4>::Type> rhs);
1406
1407         private:
1408                 Float4 *parent;
1409         };
1410
1411         template<class Vector4, int T>
1412         class SwizzleMask2
1413         {
1414                 friend class Float4;
1415
1416         public:
1417                 operator RValue<Vector4>() const;
1418
1419                 RValue<Vector4> operator=(RValue<Vector4> rhs);
1420
1421         private:
1422                 Float4 *parent;
1423         };
1424
1425         template<class Vector4>
1426         struct XYZW
1427         {
1428                 friend Vector4;
1429
1430         private:
1431                 XYZW(Vector4 *parent)
1432                 {
1433                         xyzw.parent = parent;
1434                 }
1435
1436         public:
1437                 union
1438                 {
1439                         SwizzleMask1<Vector4, 0x00> x;
1440                         SwizzleMask1<Vector4, 0x55> y;
1441                         SwizzleMask1<Vector4, 0xAA> z;
1442                         SwizzleMask1<Vector4, 0xFF> w;
1443                         Swizzle2<Vector4, 0x00>     xx;
1444                         Swizzle2<Vector4, 0x01>     yx;
1445                         Swizzle2<Vector4, 0x02>     zx;
1446                         Swizzle2<Vector4, 0x03>     wx;
1447                         SwizzleMask2<Vector4, 0x54> xy;
1448                         Swizzle2<Vector4, 0x55>     yy;
1449                         Swizzle2<Vector4, 0x56>     zy;
1450                         Swizzle2<Vector4, 0x57>     wy;
1451                         SwizzleMask2<Vector4, 0xA8> xz;
1452                         SwizzleMask2<Vector4, 0xA9> yz;
1453                         Swizzle2<Vector4, 0xAA>     zz;
1454                         Swizzle2<Vector4, 0xAB>     wz;
1455                         SwizzleMask2<Vector4, 0xFC> xw;
1456                         SwizzleMask2<Vector4, 0xFD> yw;
1457                         SwizzleMask2<Vector4, 0xFE> zw;
1458                         Swizzle2<Vector4, 0xFF>     ww;
1459                         Swizzle4<Vector4, 0x00>     xxx;
1460                         Swizzle4<Vector4, 0x01>     yxx;
1461                         Swizzle4<Vector4, 0x02>     zxx;
1462                         Swizzle4<Vector4, 0x03>     wxx;
1463                         Swizzle4<Vector4, 0x04>     xyx;
1464                         Swizzle4<Vector4, 0x05>     yyx;
1465                         Swizzle4<Vector4, 0x06>     zyx;
1466                         Swizzle4<Vector4, 0x07>     wyx;
1467                         Swizzle4<Vector4, 0x08>     xzx;
1468                         Swizzle4<Vector4, 0x09>     yzx;
1469                         Swizzle4<Vector4, 0x0A>     zzx;
1470                         Swizzle4<Vector4, 0x0B>     wzx;
1471                         Swizzle4<Vector4, 0x0C>     xwx;
1472                         Swizzle4<Vector4, 0x0D>     ywx;
1473                         Swizzle4<Vector4, 0x0E>     zwx;
1474                         Swizzle4<Vector4, 0x0F>     wwx;
1475                         Swizzle4<Vector4, 0x50>     xxy;
1476                         Swizzle4<Vector4, 0x51>     yxy;
1477                         Swizzle4<Vector4, 0x52>     zxy;
1478                         Swizzle4<Vector4, 0x53>     wxy;
1479                         Swizzle4<Vector4, 0x54>     xyy;
1480                         Swizzle4<Vector4, 0x55>     yyy;
1481                         Swizzle4<Vector4, 0x56>     zyy;
1482                         Swizzle4<Vector4, 0x57>     wyy;
1483                         Swizzle4<Vector4, 0x58>     xzy;
1484                         Swizzle4<Vector4, 0x59>     yzy;
1485                         Swizzle4<Vector4, 0x5A>     zzy;
1486                         Swizzle4<Vector4, 0x5B>     wzy;
1487                         Swizzle4<Vector4, 0x5C>     xwy;
1488                         Swizzle4<Vector4, 0x5D>     ywy;
1489                         Swizzle4<Vector4, 0x5E>     zwy;
1490                         Swizzle4<Vector4, 0x5F>     wwy;
1491                         Swizzle4<Vector4, 0xA0>     xxz;
1492                         Swizzle4<Vector4, 0xA1>     yxz;
1493                         Swizzle4<Vector4, 0xA2>     zxz;
1494                         Swizzle4<Vector4, 0xA3>     wxz;
1495                         SwizzleMask4<Vector4, 0xA4> xyz;
1496                         Swizzle4<Vector4, 0xA5>     yyz;
1497                         Swizzle4<Vector4, 0xA6>     zyz;
1498                         Swizzle4<Vector4, 0xA7>     wyz;
1499                         Swizzle4<Vector4, 0xA8>     xzz;
1500                         Swizzle4<Vector4, 0xA9>     yzz;
1501                         Swizzle4<Vector4, 0xAA>     zzz;
1502                         Swizzle4<Vector4, 0xAB>     wzz;
1503                         Swizzle4<Vector4, 0xAC>     xwz;
1504                         Swizzle4<Vector4, 0xAD>     ywz;
1505                         Swizzle4<Vector4, 0xAE>     zwz;
1506                         Swizzle4<Vector4, 0xAF>     wwz;
1507                         Swizzle4<Vector4, 0xF0>     xxw;
1508                         Swizzle4<Vector4, 0xF1>     yxw;
1509                         Swizzle4<Vector4, 0xF2>     zxw;
1510                         Swizzle4<Vector4, 0xF3>     wxw;
1511                         SwizzleMask4<Vector4, 0xF4> xyw;
1512                         Swizzle4<Vector4, 0xF5>     yyw;
1513                         Swizzle4<Vector4, 0xF6>     zyw;
1514                         Swizzle4<Vector4, 0xF7>     wyw;
1515                         SwizzleMask4<Vector4, 0xF8> xzw;
1516                         SwizzleMask4<Vector4, 0xF9> yzw;
1517                         Swizzle4<Vector4, 0xFA>     zzw;
1518                         Swizzle4<Vector4, 0xFB>     wzw;
1519                         Swizzle4<Vector4, 0xFC>     xww;
1520                         Swizzle4<Vector4, 0xFD>     yww;
1521                         Swizzle4<Vector4, 0xFE>     zww;
1522                         Swizzle4<Vector4, 0xFF>     www;
1523                         Swizzle4<Vector4, 0x00>     xxxx;
1524                         Swizzle4<Vector4, 0x01>     yxxx;
1525                         Swizzle4<Vector4, 0x02>     zxxx;
1526                         Swizzle4<Vector4, 0x03>     wxxx;
1527                         Swizzle4<Vector4, 0x04>     xyxx;
1528                         Swizzle4<Vector4, 0x05>     yyxx;
1529                         Swizzle4<Vector4, 0x06>     zyxx;
1530                         Swizzle4<Vector4, 0x07>     wyxx;
1531                         Swizzle4<Vector4, 0x08>     xzxx;
1532                         Swizzle4<Vector4, 0x09>     yzxx;
1533                         Swizzle4<Vector4, 0x0A>     zzxx;
1534                         Swizzle4<Vector4, 0x0B>     wzxx;
1535                         Swizzle4<Vector4, 0x0C>     xwxx;
1536                         Swizzle4<Vector4, 0x0D>     ywxx;
1537                         Swizzle4<Vector4, 0x0E>     zwxx;
1538                         Swizzle4<Vector4, 0x0F>     wwxx;
1539                         Swizzle4<Vector4, 0x10>     xxyx;
1540                         Swizzle4<Vector4, 0x11>     yxyx;
1541                         Swizzle4<Vector4, 0x12>     zxyx;
1542                         Swizzle4<Vector4, 0x13>     wxyx;
1543                         Swizzle4<Vector4, 0x14>     xyyx;
1544                         Swizzle4<Vector4, 0x15>     yyyx;
1545                         Swizzle4<Vector4, 0x16>     zyyx;
1546                         Swizzle4<Vector4, 0x17>     wyyx;
1547                         Swizzle4<Vector4, 0x18>     xzyx;
1548                         Swizzle4<Vector4, 0x19>     yzyx;
1549                         Swizzle4<Vector4, 0x1A>     zzyx;
1550                         Swizzle4<Vector4, 0x1B>     wzyx;
1551                         Swizzle4<Vector4, 0x1C>     xwyx;
1552                         Swizzle4<Vector4, 0x1D>     ywyx;
1553                         Swizzle4<Vector4, 0x1E>     zwyx;
1554                         Swizzle4<Vector4, 0x1F>     wwyx;
1555                         Swizzle4<Vector4, 0x20>     xxzx;
1556                         Swizzle4<Vector4, 0x21>     yxzx;
1557                         Swizzle4<Vector4, 0x22>     zxzx;
1558                         Swizzle4<Vector4, 0x23>     wxzx;
1559                         Swizzle4<Vector4, 0x24>     xyzx;
1560                         Swizzle4<Vector4, 0x25>     yyzx;
1561                         Swizzle4<Vector4, 0x26>     zyzx;
1562                         Swizzle4<Vector4, 0x27>     wyzx;
1563                         Swizzle4<Vector4, 0x28>     xzzx;
1564                         Swizzle4<Vector4, 0x29>     yzzx;
1565                         Swizzle4<Vector4, 0x2A>     zzzx;
1566                         Swizzle4<Vector4, 0x2B>     wzzx;
1567                         Swizzle4<Vector4, 0x2C>     xwzx;
1568                         Swizzle4<Vector4, 0x2D>     ywzx;
1569                         Swizzle4<Vector4, 0x2E>     zwzx;
1570                         Swizzle4<Vector4, 0x2F>     wwzx;
1571                         Swizzle4<Vector4, 0x30>     xxwx;
1572                         Swizzle4<Vector4, 0x31>     yxwx;
1573                         Swizzle4<Vector4, 0x32>     zxwx;
1574                         Swizzle4<Vector4, 0x33>     wxwx;
1575                         Swizzle4<Vector4, 0x34>     xywx;
1576                         Swizzle4<Vector4, 0x35>     yywx;
1577                         Swizzle4<Vector4, 0x36>     zywx;
1578                         Swizzle4<Vector4, 0x37>     wywx;
1579                         Swizzle4<Vector4, 0x38>     xzwx;
1580                         Swizzle4<Vector4, 0x39>     yzwx;
1581                         Swizzle4<Vector4, 0x3A>     zzwx;
1582                         Swizzle4<Vector4, 0x3B>     wzwx;
1583                         Swizzle4<Vector4, 0x3C>     xwwx;
1584                         Swizzle4<Vector4, 0x3D>     ywwx;
1585                         Swizzle4<Vector4, 0x3E>     zwwx;
1586                         Swizzle4<Vector4, 0x3F>     wwwx;
1587                         Swizzle4<Vector4, 0x40>     xxxy;
1588                         Swizzle4<Vector4, 0x41>     yxxy;
1589                         Swizzle4<Vector4, 0x42>     zxxy;
1590                         Swizzle4<Vector4, 0x43>     wxxy;
1591                         Swizzle4<Vector4, 0x44>     xyxy;
1592                         Swizzle4<Vector4, 0x45>     yyxy;
1593                         Swizzle4<Vector4, 0x46>     zyxy;
1594                         Swizzle4<Vector4, 0x47>     wyxy;
1595                         Swizzle4<Vector4, 0x48>     xzxy;
1596                         Swizzle4<Vector4, 0x49>     yzxy;
1597                         Swizzle4<Vector4, 0x4A>     zzxy;
1598                         Swizzle4<Vector4, 0x4B>     wzxy;
1599                         Swizzle4<Vector4, 0x4C>     xwxy;
1600                         Swizzle4<Vector4, 0x4D>     ywxy;
1601                         Swizzle4<Vector4, 0x4E>     zwxy;
1602                         Swizzle4<Vector4, 0x4F>     wwxy;
1603                         Swizzle4<Vector4, 0x50>     xxyy;
1604                         Swizzle4<Vector4, 0x51>     yxyy;
1605                         Swizzle4<Vector4, 0x52>     zxyy;
1606                         Swizzle4<Vector4, 0x53>     wxyy;
1607                         Swizzle4<Vector4, 0x54>     xyyy;
1608                         Swizzle4<Vector4, 0x55>     yyyy;
1609                         Swizzle4<Vector4, 0x56>     zyyy;
1610                         Swizzle4<Vector4, 0x57>     wyyy;
1611                         Swizzle4<Vector4, 0x58>     xzyy;
1612                         Swizzle4<Vector4, 0x59>     yzyy;
1613                         Swizzle4<Vector4, 0x5A>     zzyy;
1614                         Swizzle4<Vector4, 0x5B>     wzyy;
1615                         Swizzle4<Vector4, 0x5C>     xwyy;
1616                         Swizzle4<Vector4, 0x5D>     ywyy;
1617                         Swizzle4<Vector4, 0x5E>     zwyy;
1618                         Swizzle4<Vector4, 0x5F>     wwyy;
1619                         Swizzle4<Vector4, 0x60>     xxzy;
1620                         Swizzle4<Vector4, 0x61>     yxzy;
1621                         Swizzle4<Vector4, 0x62>     zxzy;
1622                         Swizzle4<Vector4, 0x63>     wxzy;
1623                         Swizzle4<Vector4, 0x64>     xyzy;
1624                         Swizzle4<Vector4, 0x65>     yyzy;
1625                         Swizzle4<Vector4, 0x66>     zyzy;
1626                         Swizzle4<Vector4, 0x67>     wyzy;
1627                         Swizzle4<Vector4, 0x68>     xzzy;
1628                         Swizzle4<Vector4, 0x69>     yzzy;
1629                         Swizzle4<Vector4, 0x6A>     zzzy;
1630                         Swizzle4<Vector4, 0x6B>     wzzy;
1631                         Swizzle4<Vector4, 0x6C>     xwzy;
1632                         Swizzle4<Vector4, 0x6D>     ywzy;
1633                         Swizzle4<Vector4, 0x6E>     zwzy;
1634                         Swizzle4<Vector4, 0x6F>     wwzy;
1635                         Swizzle4<Vector4, 0x70>     xxwy;
1636                         Swizzle4<Vector4, 0x71>     yxwy;
1637                         Swizzle4<Vector4, 0x72>     zxwy;
1638                         Swizzle4<Vector4, 0x73>     wxwy;
1639                         Swizzle4<Vector4, 0x74>     xywy;
1640                         Swizzle4<Vector4, 0x75>     yywy;
1641                         Swizzle4<Vector4, 0x76>     zywy;
1642                         Swizzle4<Vector4, 0x77>     wywy;
1643                         Swizzle4<Vector4, 0x78>     xzwy;
1644                         Swizzle4<Vector4, 0x79>     yzwy;
1645                         Swizzle4<Vector4, 0x7A>     zzwy;
1646                         Swizzle4<Vector4, 0x7B>     wzwy;
1647                         Swizzle4<Vector4, 0x7C>     xwwy;
1648                         Swizzle4<Vector4, 0x7D>     ywwy;
1649                         Swizzle4<Vector4, 0x7E>     zwwy;
1650                         Swizzle4<Vector4, 0x7F>     wwwy;
1651                         Swizzle4<Vector4, 0x80>     xxxz;
1652                         Swizzle4<Vector4, 0x81>     yxxz;
1653                         Swizzle4<Vector4, 0x82>     zxxz;
1654                         Swizzle4<Vector4, 0x83>     wxxz;
1655                         Swizzle4<Vector4, 0x84>     xyxz;
1656                         Swizzle4<Vector4, 0x85>     yyxz;
1657                         Swizzle4<Vector4, 0x86>     zyxz;
1658                         Swizzle4<Vector4, 0x87>     wyxz;
1659                         Swizzle4<Vector4, 0x88>     xzxz;
1660                         Swizzle4<Vector4, 0x89>     yzxz;
1661                         Swizzle4<Vector4, 0x8A>     zzxz;
1662                         Swizzle4<Vector4, 0x8B>     wzxz;
1663                         Swizzle4<Vector4, 0x8C>     xwxz;
1664                         Swizzle4<Vector4, 0x8D>     ywxz;
1665                         Swizzle4<Vector4, 0x8E>     zwxz;
1666                         Swizzle4<Vector4, 0x8F>     wwxz;
1667                         Swizzle4<Vector4, 0x90>     xxyz;
1668                         Swizzle4<Vector4, 0x91>     yxyz;
1669                         Swizzle4<Vector4, 0x92>     zxyz;
1670                         Swizzle4<Vector4, 0x93>     wxyz;
1671                         Swizzle4<Vector4, 0x94>     xyyz;
1672                         Swizzle4<Vector4, 0x95>     yyyz;
1673                         Swizzle4<Vector4, 0x96>     zyyz;
1674                         Swizzle4<Vector4, 0x97>     wyyz;
1675                         Swizzle4<Vector4, 0x98>     xzyz;
1676                         Swizzle4<Vector4, 0x99>     yzyz;
1677                         Swizzle4<Vector4, 0x9A>     zzyz;
1678                         Swizzle4<Vector4, 0x9B>     wzyz;
1679                         Swizzle4<Vector4, 0x9C>     xwyz;
1680                         Swizzle4<Vector4, 0x9D>     ywyz;
1681                         Swizzle4<Vector4, 0x9E>     zwyz;
1682                         Swizzle4<Vector4, 0x9F>     wwyz;
1683                         Swizzle4<Vector4, 0xA0>     xxzz;
1684                         Swizzle4<Vector4, 0xA1>     yxzz;
1685                         Swizzle4<Vector4, 0xA2>     zxzz;
1686                         Swizzle4<Vector4, 0xA3>     wxzz;
1687                         Swizzle4<Vector4, 0xA4>     xyzz;
1688                         Swizzle4<Vector4, 0xA5>     yyzz;
1689                         Swizzle4<Vector4, 0xA6>     zyzz;
1690                         Swizzle4<Vector4, 0xA7>     wyzz;
1691                         Swizzle4<Vector4, 0xA8>     xzzz;
1692                         Swizzle4<Vector4, 0xA9>     yzzz;
1693                         Swizzle4<Vector4, 0xAA>     zzzz;
1694                         Swizzle4<Vector4, 0xAB>     wzzz;
1695                         Swizzle4<Vector4, 0xAC>     xwzz;
1696                         Swizzle4<Vector4, 0xAD>     ywzz;
1697                         Swizzle4<Vector4, 0xAE>     zwzz;
1698                         Swizzle4<Vector4, 0xAF>     wwzz;
1699                         Swizzle4<Vector4, 0xB0>     xxwz;
1700                         Swizzle4<Vector4, 0xB1>     yxwz;
1701                         Swizzle4<Vector4, 0xB2>     zxwz;
1702                         Swizzle4<Vector4, 0xB3>     wxwz;
1703                         Swizzle4<Vector4, 0xB4>     xywz;
1704                         Swizzle4<Vector4, 0xB5>     yywz;
1705                         Swizzle4<Vector4, 0xB6>     zywz;
1706                         Swizzle4<Vector4, 0xB7>     wywz;
1707                         Swizzle4<Vector4, 0xB8>     xzwz;
1708                         Swizzle4<Vector4, 0xB9>     yzwz;
1709                         Swizzle4<Vector4, 0xBA>     zzwz;
1710                         Swizzle4<Vector4, 0xBB>     wzwz;
1711                         Swizzle4<Vector4, 0xBC>     xwwz;
1712                         Swizzle4<Vector4, 0xBD>     ywwz;
1713                         Swizzle4<Vector4, 0xBE>     zwwz;
1714                         Swizzle4<Vector4, 0xBF>     wwwz;
1715                         Swizzle4<Vector4, 0xC0>     xxxw;
1716                         Swizzle4<Vector4, 0xC1>     yxxw;
1717                         Swizzle4<Vector4, 0xC2>     zxxw;
1718                         Swizzle4<Vector4, 0xC3>     wxxw;
1719                         Swizzle4<Vector4, 0xC4>     xyxw;
1720                         Swizzle4<Vector4, 0xC5>     yyxw;
1721                         Swizzle4<Vector4, 0xC6>     zyxw;
1722                         Swizzle4<Vector4, 0xC7>     wyxw;
1723                         Swizzle4<Vector4, 0xC8>     xzxw;
1724                         Swizzle4<Vector4, 0xC9>     yzxw;
1725                         Swizzle4<Vector4, 0xCA>     zzxw;
1726                         Swizzle4<Vector4, 0xCB>     wzxw;
1727                         Swizzle4<Vector4, 0xCC>     xwxw;
1728                         Swizzle4<Vector4, 0xCD>     ywxw;
1729                         Swizzle4<Vector4, 0xCE>     zwxw;
1730                         Swizzle4<Vector4, 0xCF>     wwxw;
1731                         Swizzle4<Vector4, 0xD0>     xxyw;
1732                         Swizzle4<Vector4, 0xD1>     yxyw;
1733                         Swizzle4<Vector4, 0xD2>     zxyw;
1734                         Swizzle4<Vector4, 0xD3>     wxyw;
1735                         Swizzle4<Vector4, 0xD4>     xyyw;
1736                         Swizzle4<Vector4, 0xD5>     yyyw;
1737                         Swizzle4<Vector4, 0xD6>     zyyw;
1738                         Swizzle4<Vector4, 0xD7>     wyyw;
1739                         Swizzle4<Vector4, 0xD8>     xzyw;
1740                         Swizzle4<Vector4, 0xD9>     yzyw;
1741                         Swizzle4<Vector4, 0xDA>     zzyw;
1742                         Swizzle4<Vector4, 0xDB>     wzyw;
1743                         Swizzle4<Vector4, 0xDC>     xwyw;
1744                         Swizzle4<Vector4, 0xDD>     ywyw;
1745                         Swizzle4<Vector4, 0xDE>     zwyw;
1746                         Swizzle4<Vector4, 0xDF>     wwyw;
1747                         Swizzle4<Vector4, 0xE0>     xxzw;
1748                         Swizzle4<Vector4, 0xE1>     yxzw;
1749                         Swizzle4<Vector4, 0xE2>     zxzw;
1750                         Swizzle4<Vector4, 0xE3>     wxzw;
1751                         SwizzleMask4<Vector4, 0xE4> xyzw;
1752                         Swizzle4<Vector4, 0xE5>     yyzw;
1753                         Swizzle4<Vector4, 0xE6>     zyzw;
1754                         Swizzle4<Vector4, 0xE7>     wyzw;
1755                         Swizzle4<Vector4, 0xE8>     xzzw;
1756                         Swizzle4<Vector4, 0xE9>     yzzw;
1757                         Swizzle4<Vector4, 0xEA>     zzzw;
1758                         Swizzle4<Vector4, 0xEB>     wzzw;
1759                         Swizzle4<Vector4, 0xEC>     xwzw;
1760                         Swizzle4<Vector4, 0xED>     ywzw;
1761                         Swizzle4<Vector4, 0xEE>     zwzw;
1762                         Swizzle4<Vector4, 0xEF>     wwzw;
1763                         Swizzle4<Vector4, 0xF0>     xxww;
1764                         Swizzle4<Vector4, 0xF1>     yxww;
1765                         Swizzle4<Vector4, 0xF2>     zxww;
1766                         Swizzle4<Vector4, 0xF3>     wxww;
1767                         Swizzle4<Vector4, 0xF4>     xyww;
1768                         Swizzle4<Vector4, 0xF5>     yyww;
1769                         Swizzle4<Vector4, 0xF6>     zyww;
1770                         Swizzle4<Vector4, 0xF7>     wyww;
1771                         Swizzle4<Vector4, 0xF8>     xzww;
1772                         Swizzle4<Vector4, 0xF9>     yzww;
1773                         Swizzle4<Vector4, 0xFA>     zzww;
1774                         Swizzle4<Vector4, 0xFB>     wzww;
1775                         Swizzle4<Vector4, 0xFC>     xwww;
1776                         Swizzle4<Vector4, 0xFD>     ywww;
1777                         Swizzle4<Vector4, 0xFE>     zwww;
1778                         Swizzle4<Vector4, 0xFF>     wwww;
1779                 };
1780         };
1781
1782         class Int4 : public LValue<Int4>, public XYZW<Int4>
1783         {
1784         public:
1785                 explicit Int4(RValue<Byte4> cast);
1786                 explicit Int4(RValue<SByte4> cast);
1787                 explicit Int4(RValue<Float4> cast);
1788                 explicit Int4(RValue<Short4> cast);
1789                 explicit Int4(RValue<UShort4> cast);
1790
1791                 Int4();
1792                 Int4(int xyzw);
1793                 Int4(int x, int yzw);
1794                 Int4(int x, int y, int zw);
1795                 Int4(int x, int y, int z, int w);
1796                 Int4(RValue<Int4> rhs);
1797                 Int4(const Int4 &rhs);
1798                 Int4(const Reference<Int4> &rhs);
1799                 Int4(RValue<UInt4> rhs);
1800                 Int4(const UInt4 &rhs);
1801                 Int4(const Reference<UInt4> &rhs);
1802                 Int4(RValue<Int2> lo, RValue<Int2> hi);
1803                 Int4(RValue<Int> rhs);
1804                 Int4(const Int &rhs);
1805                 Int4(const Reference<Int> &rhs);
1806
1807                 RValue<Int4> operator=(RValue<Int4> rhs);
1808                 RValue<Int4> operator=(const Int4 &rhs);
1809                 RValue<Int4> operator=(const Reference<Int4> &rhs);
1810
1811                 static Type *getType();
1812
1813         private:
1814                 void constant(int x, int y, int z, int w);
1815         };
1816
1817         RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs);
1818         RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs);
1819         RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs);
1820         RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs);
1821         RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs);
1822         RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs);
1823         RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs);
1824         RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs);
1825         RValue<Int4> operator<<(RValue<Int4> lhs, unsigned char rhs);
1826         RValue<Int4> operator>>(RValue<Int4> lhs, unsigned char rhs);
1827         RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs);
1828         RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs);
1829         RValue<Int4> operator+=(Int4 &lhs, RValue<Int4> rhs);
1830         RValue<Int4> operator-=(Int4 &lhs, RValue<Int4> rhs);
1831         RValue<Int4> operator*=(Int4 &lhs, RValue<Int4> rhs);
1832 //      RValue<Int4> operator/=(Int4 &lhs, RValue<Int4> rhs);
1833 //      RValue<Int4> operator%=(Int4 &lhs, RValue<Int4> rhs);
1834         RValue<Int4> operator&=(Int4 &lhs, RValue<Int4> rhs);
1835         RValue<Int4> operator|=(Int4 &lhs, RValue<Int4> rhs);
1836         RValue<Int4> operator^=(Int4 &lhs, RValue<Int4> rhs);
1837         RValue<Int4> operator<<=(Int4 &lhs, unsigned char rhs);
1838         RValue<Int4> operator>>=(Int4 &lhs, unsigned char rhs);
1839         RValue<Int4> operator+(RValue<Int4> val);
1840         RValue<Int4> operator-(RValue<Int4> val);
1841         RValue<Int4> operator~(RValue<Int4> val);
1842 //      RValue<Int4> operator++(Int4 &val, int);   // Post-increment
1843 //      const Int4 &operator++(Int4 &val);   // Pre-increment
1844 //      RValue<Int4> operator--(Int4 &val, int);   // Post-decrement
1845 //      const Int4 &operator--(Int4 &val);   // Pre-decrement
1846 //      RValue<Bool> operator<(RValue<Int4> lhs, RValue<Int4> rhs);
1847 //      RValue<Bool> operator<=(RValue<Int4> lhs, RValue<Int4> rhs);
1848 //      RValue<Bool> operator>(RValue<Int4> lhs, RValue<Int4> rhs);
1849 //      RValue<Bool> operator>=(RValue<Int4> lhs, RValue<Int4> rhs);
1850 //      RValue<Bool> operator!=(RValue<Int4> lhs, RValue<Int4> rhs);
1851 //      RValue<Bool> operator==(RValue<Int4> lhs, RValue<Int4> rhs);
1852
1853         inline RValue<Int4> operator+(RValue<Int> lhs, RValue<Int4> rhs)
1854         {
1855                 return Int4(lhs) + rhs;
1856         }
1857
1858         inline RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int> rhs)
1859         {
1860                 return lhs + Int4(rhs);
1861         }
1862
1863         RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y);
1864         RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y);
1865         RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y);
1866         RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y);
1867         RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y);
1868         RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y);
1869         inline RValue<Int4> CmpGT(RValue<Int4> x, RValue<Int4> y) { return CmpNLE(x, y); }
1870         inline RValue<Int4> CmpGE(RValue<Int4> x, RValue<Int4> y) { return CmpNLT(x, y); }
1871         RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y);
1872         RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y);
1873         RValue<Int4> RoundInt(RValue<Float4> cast);
1874         RValue<Short8> PackSigned(RValue<Int4> x, RValue<Int4> y);
1875         RValue<UShort8> PackUnsigned(RValue<Int4> x, RValue<Int4> y);
1876         RValue<Int> Extract(RValue<Int4> val, int i);
1877         RValue<Int4> Insert(RValue<Int4> val, RValue<Int> element, int i);
1878         RValue<Int> SignMask(RValue<Int4> x);
1879         RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select);
1880         RValue<Int4> MulHigh(RValue<Int4> x, RValue<Int4> y);
1881
1882         class UInt4 : public LValue<UInt4>, public XYZW<UInt4>
1883         {
1884         public:
1885                 explicit UInt4(RValue<Float4> cast);
1886
1887                 UInt4();
1888                 UInt4(int xyzw);
1889                 UInt4(int x, int yzw);
1890                 UInt4(int x, int y, int zw);
1891                 UInt4(int x, int y, int z, int w);
1892                 UInt4(RValue<UInt4> rhs);
1893                 UInt4(const UInt4 &rhs);
1894                 UInt4(const Reference<UInt4> &rhs);
1895                 UInt4(RValue<Int4> rhs);
1896                 UInt4(const Int4 &rhs);
1897                 UInt4(const Reference<Int4> &rhs);
1898                 UInt4(RValue<UInt2> lo, RValue<UInt2> hi);
1899
1900                 RValue<UInt4> operator=(RValue<UInt4> rhs);
1901                 RValue<UInt4> operator=(const UInt4 &rhs);
1902                 RValue<UInt4> operator=(const Reference<UInt4> &rhs);
1903
1904                 static Type *getType();
1905
1906         private:
1907                 void constant(int x, int y, int z, int w);
1908         };
1909
1910         RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs);
1911         RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs);
1912         RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs);
1913         RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs);
1914         RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs);
1915         RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs);
1916         RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs);
1917         RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs);
1918         RValue<UInt4> operator<<(RValue<UInt4> lhs, unsigned char rhs);
1919         RValue<UInt4> operator>>(RValue<UInt4> lhs, unsigned char rhs);
1920         RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs);
1921         RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs);
1922         RValue<UInt4> operator+=(UInt4 &lhs, RValue<UInt4> rhs);
1923         RValue<UInt4> operator-=(UInt4 &lhs, RValue<UInt4> rhs);
1924         RValue<UInt4> operator*=(UInt4 &lhs, RValue<UInt4> rhs);
1925 //      RValue<UInt4> operator/=(UInt4 &lhs, RValue<UInt4> rhs);
1926 //      RValue<UInt4> operator%=(UInt4 &lhs, RValue<UInt4> rhs);
1927         RValue<UInt4> operator&=(UInt4 &lhs, RValue<UInt4> rhs);
1928         RValue<UInt4> operator|=(UInt4 &lhs, RValue<UInt4> rhs);
1929         RValue<UInt4> operator^=(UInt4 &lhs, RValue<UInt4> rhs);
1930         RValue<UInt4> operator<<=(UInt4 &lhs, unsigned char rhs);
1931         RValue<UInt4> operator>>=(UInt4 &lhs, unsigned char rhs);
1932         RValue<UInt4> operator+(RValue<UInt4> val);
1933         RValue<UInt4> operator-(RValue<UInt4> val);
1934         RValue<UInt4> operator~(RValue<UInt4> val);
1935 //      RValue<UInt4> operator++(UInt4 &val, int);   // Post-increment
1936 //      const UInt4 &operator++(UInt4 &val);   // Pre-increment
1937 //      RValue<UInt4> operator--(UInt4 &val, int);   // Post-decrement
1938 //      const UInt4 &operator--(UInt4 &val);   // Pre-decrement
1939 //      RValue<Bool> operator<(RValue<UInt4> lhs, RValue<UInt4> rhs);
1940 //      RValue<Bool> operator<=(RValue<UInt4> lhs, RValue<UInt4> rhs);
1941 //      RValue<Bool> operator>(RValue<UInt4> lhs, RValue<UInt4> rhs);
1942 //      RValue<Bool> operator>=(RValue<UInt4> lhs, RValue<UInt4> rhs);
1943 //      RValue<Bool> operator!=(RValue<UInt4> lhs, RValue<UInt4> rhs);
1944 //      RValue<Bool> operator==(RValue<UInt4> lhs, RValue<UInt4> rhs);
1945
1946         RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y);
1947         RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y);
1948         RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y);
1949         RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y);
1950         RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y);
1951         RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y);
1952         inline RValue<UInt4> CmpGT(RValue<UInt4> x, RValue<UInt4> y) { return CmpNLE(x, y); }
1953         inline RValue<UInt4> CmpGE(RValue<UInt4> x, RValue<UInt4> y) { return CmpNLT(x, y); }
1954         RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y);
1955         RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y);
1956         RValue<UInt4> MulHigh(RValue<UInt4> x, RValue<UInt4> y);
1957 //      RValue<UInt4> RoundInt(RValue<Float4> cast);
1958
1959         class Half : public LValue<Half>
1960         {
1961         public:
1962                 explicit Half(RValue<Float> cast);
1963
1964                 static Type *getType();
1965         };
1966
1967         class Float : public LValue<Float>
1968         {
1969         public:
1970                 explicit Float(RValue<Int> cast);
1971                 explicit Float(RValue<UInt> cast);
1972                 explicit Float(RValue<Half> cast);
1973
1974                 Float() = default;
1975                 Float(float x);
1976                 Float(RValue<Float> rhs);
1977                 Float(const Float &rhs);
1978                 Float(const Reference<Float> &rhs);
1979                 Float(Argument<Float> argument);
1980
1981                 template<int T>
1982                 Float(const SwizzleMask1<Float4, T> &rhs);
1983
1984         //      RValue<Float> operator=(float rhs);   // FIXME: Implement
1985                 RValue<Float> operator=(RValue<Float> rhs);
1986                 RValue<Float> operator=(const Float &rhs);
1987                 RValue<Float> operator=(const Reference<Float> &rhs);
1988
1989                 template<int T>
1990                 RValue<Float> operator=(const SwizzleMask1<Float4, T> &rhs);
1991
1992                 static Type *getType();
1993         };
1994
1995         RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs);
1996         RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs);
1997         RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs);
1998         RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs);
1999         RValue<Float> operator+=(Float &lhs, RValue<Float> rhs);
2000         RValue<Float> operator-=(Float &lhs, RValue<Float> rhs);
2001         RValue<Float> operator*=(Float &lhs, RValue<Float> rhs);
2002         RValue<Float> operator/=(Float &lhs, RValue<Float> rhs);
2003         RValue<Float> operator+(RValue<Float> val);
2004         RValue<Float> operator-(RValue<Float> val);
2005         RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs);
2006         RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs);
2007         RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs);
2008         RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs);
2009         RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs);
2010         RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs);
2011
2012         RValue<Float> Abs(RValue<Float> x);
2013         RValue<Float> Max(RValue<Float> x, RValue<Float> y);
2014         RValue<Float> Min(RValue<Float> x, RValue<Float> y);
2015         RValue<Float> Rcp_pp(RValue<Float> val, bool exactAtPow2 = false);
2016         RValue<Float> RcpSqrt_pp(RValue<Float> val);
2017         RValue<Float> Sqrt(RValue<Float> x);
2018         RValue<Float> Round(RValue<Float> val);
2019         RValue<Float> Trunc(RValue<Float> val);
2020         RValue<Float> Frac(RValue<Float> val);
2021         RValue<Float> Floor(RValue<Float> val);
2022         RValue<Float> Ceil(RValue<Float> val);
2023
2024         class Float2 : public LValue<Float2>
2025         {
2026         public:
2027         //      explicit Float2(RValue<Byte2> cast);
2028         //      explicit Float2(RValue<Short2> cast);
2029         //      explicit Float2(RValue<UShort2> cast);
2030         //      explicit Float2(RValue<Int2> cast);
2031         //      explicit Float2(RValue<UInt2> cast);
2032                 explicit Float2(RValue<Float4> cast);
2033
2034                 Float2() = default;
2035         //      Float2(float x, float y);
2036         //      Float2(RValue<Float2> rhs);
2037         //      Float2(const Float2 &rhs);
2038         //      Float2(const Reference<Float2> &rhs);
2039         //      Float2(RValue<Float> rhs);
2040         //      Float2(const Float &rhs);
2041         //      Float2(const Reference<Float> &rhs);
2042
2043         //      template<int T>
2044         //      Float2(const SwizzleMask1<T> &rhs);
2045
2046         //      RValue<Float2> operator=(float replicate);
2047         //      RValue<Float2> operator=(RValue<Float2> rhs);
2048         //      RValue<Float2> operator=(const Float2 &rhs);
2049         //      RValue<Float2> operator=(const Reference<Float2> &rhs);
2050         //      RValue<Float2> operator=(RValue<Float> rhs);
2051         //      RValue<Float2> operator=(const Float &rhs);
2052         //      RValue<Float2> operator=(const Reference<Float> &rhs);
2053
2054         //      template<int T>
2055         //      RValue<Float2> operator=(const SwizzleMask1<T> &rhs);
2056
2057                 static Type *getType();
2058         };
2059
2060 //      RValue<Float2> operator+(RValue<Float2> lhs, RValue<Float2> rhs);
2061 //      RValue<Float2> operator-(RValue<Float2> lhs, RValue<Float2> rhs);
2062 //      RValue<Float2> operator*(RValue<Float2> lhs, RValue<Float2> rhs);
2063 //      RValue<Float2> operator/(RValue<Float2> lhs, RValue<Float2> rhs);
2064 //      RValue<Float2> operator%(RValue<Float2> lhs, RValue<Float2> rhs);
2065 //      RValue<Float2> operator+=(Float2 &lhs, RValue<Float2> rhs);
2066 //      RValue<Float2> operator-=(Float2 &lhs, RValue<Float2> rhs);
2067 //      RValue<Float2> operator*=(Float2 &lhs, RValue<Float2> rhs);
2068 //      RValue<Float2> operator/=(Float2 &lhs, RValue<Float2> rhs);
2069 //      RValue<Float2> operator%=(Float2 &lhs, RValue<Float2> rhs);
2070 //      RValue<Float2> operator+(RValue<Float2> val);
2071 //      RValue<Float2> operator-(RValue<Float2> val);
2072
2073 //      RValue<Float2> Abs(RValue<Float2> x);
2074 //      RValue<Float2> Max(RValue<Float2> x, RValue<Float2> y);
2075 //      RValue<Float2> Min(RValue<Float2> x, RValue<Float2> y);
2076 //      RValue<Float2> Swizzle(RValue<Float2> x, unsigned char select);
2077 //      RValue<Float2> Mask(Float2 &lhs, RValue<Float2> rhs, unsigned char select);
2078
2079         class Float4 : public LValue<Float4>, public XYZW<Float4>
2080         {
2081         public:
2082                 explicit Float4(RValue<Byte4> cast);
2083                 explicit Float4(RValue<SByte4> cast);
2084                 explicit Float4(RValue<Short4> cast);
2085                 explicit Float4(RValue<UShort4> cast);
2086                 explicit Float4(RValue<Int4> cast);
2087                 explicit Float4(RValue<UInt4> cast);
2088
2089                 Float4();
2090                 Float4(float xyzw);
2091                 Float4(float x, float yzw);
2092                 Float4(float x, float y, float zw);
2093                 Float4(float x, float y, float z, float w);
2094                 Float4(RValue<Float4> rhs);
2095                 Float4(const Float4 &rhs);
2096                 Float4(const Reference<Float4> &rhs);
2097                 Float4(RValue<Float> rhs);
2098                 Float4(const Float &rhs);
2099                 Float4(const Reference<Float> &rhs);
2100
2101                 template<int T>
2102                 Float4(const SwizzleMask1<Float4, T> &rhs);
2103                 template<int T>
2104                 Float4(const Swizzle4<Float4, T> &rhs);
2105                 template<int X, int Y>
2106                 Float4(const Swizzle2<Float4, X> &x, const Swizzle2<Float4, Y> &y);
2107                 template<int X, int Y>
2108                 Float4(const SwizzleMask2<Float4, X> &x, const Swizzle2<Float4, Y> &y);
2109                 template<int X, int Y>
2110                 Float4(const Swizzle2<Float4, X> &x, const SwizzleMask2<Float4, Y> &y);
2111                 template<int X, int Y>
2112                 Float4(const SwizzleMask2<Float4, X> &x, const SwizzleMask2<Float4, Y> &y);
2113
2114                 RValue<Float4> operator=(float replicate);
2115                 RValue<Float4> operator=(RValue<Float4> rhs);
2116                 RValue<Float4> operator=(const Float4 &rhs);
2117                 RValue<Float4> operator=(const Reference<Float4> &rhs);
2118                 RValue<Float4> operator=(RValue<Float> rhs);
2119                 RValue<Float4> operator=(const Float &rhs);
2120                 RValue<Float4> operator=(const Reference<Float> &rhs);
2121
2122                 template<int T>
2123                 RValue<Float4> operator=(const SwizzleMask1<Float4, T> &rhs);
2124                 template<int T>
2125                 RValue<Float4> operator=(const Swizzle4<Float4, T> &rhs);
2126
2127                 static Type *getType();
2128
2129         private:
2130                 void constant(float x, float y, float z, float w);
2131         };
2132
2133         RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs);
2134         RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs);
2135         RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs);
2136         RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs);
2137         RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs);
2138         RValue<Float4> operator+=(Float4 &lhs, RValue<Float4> rhs);
2139         RValue<Float4> operator-=(Float4 &lhs, RValue<Float4> rhs);
2140         RValue<Float4> operator*=(Float4 &lhs, RValue<Float4> rhs);
2141         RValue<Float4> operator/=(Float4 &lhs, RValue<Float4> rhs);
2142         RValue<Float4> operator%=(Float4 &lhs, RValue<Float4> rhs);
2143         RValue<Float4> operator+(RValue<Float4> val);
2144         RValue<Float4> operator-(RValue<Float4> val);
2145
2146         RValue<Float4> Abs(RValue<Float4> x);
2147         RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y);
2148         RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y);
2149         RValue<Float4> Rcp_pp(RValue<Float4> val, bool exactAtPow2 = false);
2150         RValue<Float4> RcpSqrt_pp(RValue<Float4> val);
2151         RValue<Float4> Sqrt(RValue<Float4> x);
2152         RValue<Float4> Insert(RValue<Float4> val, RValue<Float> element, int i);
2153         RValue<Float> Extract(RValue<Float4> x, int i);
2154         RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select);
2155         RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm);
2156         RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y);
2157         RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y);
2158         RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select);
2159         RValue<Int> SignMask(RValue<Float4> x);
2160
2161         // Ordered comparison functions
2162         RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y);
2163         RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y);
2164         RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y);
2165         RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y);
2166         RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y);
2167         RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y);
2168         inline RValue<Int4> CmpGT(RValue<Float4> x, RValue<Float4> y) { return CmpNLE(x, y); }
2169         inline RValue<Int4> CmpGE(RValue<Float4> x, RValue<Float4> y) { return CmpNLT(x, y); }
2170
2171         // Unordered comparison functions
2172         RValue<Int4> CmpUEQ(RValue<Float4> x, RValue<Float4> y);
2173         RValue<Int4> CmpULT(RValue<Float4> x, RValue<Float4> y);
2174         RValue<Int4> CmpULE(RValue<Float4> x, RValue<Float4> y);
2175         RValue<Int4> CmpUNEQ(RValue<Float4> x, RValue<Float4> y);
2176         RValue<Int4> CmpUNLT(RValue<Float4> x, RValue<Float4> y);
2177         RValue<Int4> CmpUNLE(RValue<Float4> x, RValue<Float4> y);
2178         inline RValue<Int4> CmpUGT(RValue<Float4> x, RValue<Float4> y) { return CmpUNLE(x, y); }
2179         inline RValue<Int4> CmpUGE(RValue<Float4> x, RValue<Float4> y) { return CmpUNLT(x, y); }
2180
2181         RValue<Int4> IsInf(RValue<Float4> x);
2182         RValue<Int4> IsNan(RValue<Float4> x);
2183         RValue<Float4> Round(RValue<Float4> x);
2184         RValue<Float4> Trunc(RValue<Float4> x);
2185         RValue<Float4> Frac(RValue<Float4> x);
2186         RValue<Float4> Floor(RValue<Float4> x);
2187         RValue<Float4> Ceil(RValue<Float4> x);
2188
2189         template<class T>
2190         class Pointer : public LValue<Pointer<T>>
2191         {
2192         public:
2193                 template<class S>
2194                 Pointer(RValue<Pointer<S>> pointerS, int alignment = 1) : alignment(alignment)
2195                 {
2196                         Value *pointerT = Nucleus::createBitCast(pointerS.value, Nucleus::getPointerType(T::getType()));
2197                         LValue<Pointer<T>>::storeValue(pointerT);
2198                 }
2199
2200                 template<class S>
2201                 Pointer(const Pointer<S> &pointer, int alignment = 1) : alignment(alignment)
2202                 {
2203                         Value *pointerS = pointer.loadValue();
2204                         Value *pointerT = Nucleus::createBitCast(pointerS, Nucleus::getPointerType(T::getType()));
2205                         LValue<Pointer<T>>::storeValue(pointerT);
2206                 }
2207
2208                 Pointer(Argument<Pointer<T>> argument);
2209
2210                 Pointer();
2211                 Pointer(RValue<Pointer<T>> rhs);
2212                 Pointer(const Pointer<T> &rhs);
2213                 Pointer(const Reference<Pointer<T>> &rhs);
2214
2215                 RValue<Pointer<T>> operator=(RValue<Pointer<T>> rhs);
2216                 RValue<Pointer<T>> operator=(const Pointer<T> &rhs);
2217                 RValue<Pointer<T>> operator=(const Reference<Pointer<T>> &rhs);
2218
2219                 Reference<T> operator*();
2220                 Reference<T> operator[](int index);
2221                 Reference<T> operator[](unsigned int index);
2222                 Reference<T> operator[](RValue<Int> index);
2223                 Reference<T> operator[](RValue<UInt> index);
2224
2225                 static Type *getType();
2226
2227         private:
2228                 const int alignment;
2229         };
2230
2231         RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset);
2232         RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset);
2233         RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset);
2234         RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, int offset);
2235         RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<Int> offset);
2236         RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<UInt> offset);
2237
2238         RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset);
2239         RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset);
2240         RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset);
2241         RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, int offset);
2242         RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<Int> offset);
2243         RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<UInt> offset);
2244
2245         template<typename T>
2246         RValue<T> Load(RValue<Pointer<T>> pointer, unsigned int alignment, bool atomic, std::memory_order memoryOrder)
2247         {
2248                 return RValue<T>(Nucleus::createLoad(pointer.value, T::getType(), false, alignment, atomic, memoryOrder));
2249         }
2250
2251         template<typename T>
2252         void Store(RValue<T> value, RValue<Pointer<T>> pointer, unsigned int alignment, bool atomic, std::memory_order memoryOrder)
2253         {
2254                 Nucleus::createStore(value.value, pointer.value, T::getType(), false, alignment, atomic, memoryOrder);
2255         }
2256
2257         template<class T, int S = 1>
2258         class Array : public LValue<T>
2259         {
2260         public:
2261                 Array(int size = S);
2262
2263                 Reference<T> operator[](int index);
2264                 Reference<T> operator[](unsigned int index);
2265                 Reference<T> operator[](RValue<Int> index);
2266                 Reference<T> operator[](RValue<UInt> index);
2267         };
2268
2269 //      RValue<Array<T>> operator++(Array<T> &val, int);   // Post-increment
2270 //      const Array<T> &operator++(Array<T> &val);   // Pre-increment
2271 //      RValue<Array<T>> operator--(Array<T> &val, int);   // Post-decrement
2272 //      const Array<T> &operator--(Array<T> &val);   // Pre-decrement
2273
2274         void branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB);
2275
2276         void Return();
2277         void Return(RValue<Int> ret);
2278
2279         template<class T>
2280         void Return(const Pointer<T> &ret);
2281
2282         template<class T>
2283         void Return(RValue<Pointer<T>> ret);
2284
2285         // Generic template, leave undefined!
2286         template<typename FunctionType>
2287         class Function;
2288
2289         // Specialized for function types
2290         template<typename Return, typename... Arguments>
2291         class Function<Return(Arguments...)>
2292         {
2293         public:
2294                 Function();
2295
2296                 virtual ~Function();
2297
2298                 template<int index>
2299                 Argument<typename std::tuple_element<index, std::tuple<Arguments...>>::type> Arg() const
2300                 {
2301                         Value *arg = Nucleus::getArgument(index);
2302                         return Argument<typename std::tuple_element<index, std::tuple<Arguments...>>::type>(arg);
2303                 }
2304
2305                 Routine *operator()(const char *name, ...);
2306
2307         protected:
2308                 Nucleus *core;
2309                 std::vector<Type*> arguments;
2310         };
2311
2312         template<typename Return>
2313         class Function<Return()> : public Function<Return(Void)>
2314         {
2315         };
2316
2317         RValue<Long> Ticks();
2318 }
2319
2320 namespace rr
2321 {
2322         template<class T>
2323         LValue<T>::LValue(int arraySize)
2324         {
2325                 address = Nucleus::allocateStackVariable(T::getType(), arraySize);
2326         }
2327
2328         template<class T>
2329         Value *LValue<T>::loadValue() const
2330         {
2331                 return Nucleus::createLoad(address, T::getType(), false, 0);
2332         }
2333
2334         template<class T>
2335         Value *LValue<T>::storeValue(Value *value) const
2336         {
2337                 return Nucleus::createStore(value, address, T::getType(), false, 0);
2338         }
2339
2340         template<class T>
2341         Value *LValue<T>::getAddress(Value *index, bool unsignedIndex) const
2342         {
2343                 return Nucleus::createGEP(address, T::getType(), index, unsignedIndex);
2344         }
2345
2346         template<class T>
2347         RValue<Pointer<T>> LValue<T>::operator&()
2348         {
2349                 return RValue<Pointer<T>>(address);
2350         }
2351
2352         template<class T>
2353         Reference<T>::Reference(Value *pointer, int alignment) : alignment(alignment)
2354         {
2355                 address = pointer;
2356         }
2357
2358         template<class T>
2359         RValue<T> Reference<T>::operator=(RValue<T> rhs) const
2360         {
2361                 Nucleus::createStore(rhs.value, address, T::getType(), false, alignment);
2362
2363                 return rhs;
2364         }
2365
2366         template<class T>
2367         RValue<T> Reference<T>::operator=(const Reference<T> &ref) const
2368         {
2369                 Value *tmp = Nucleus::createLoad(ref.address, T::getType(), false, ref.alignment);
2370                 Nucleus::createStore(tmp, address, T::getType(), false, alignment);
2371
2372                 return RValue<T>(tmp);
2373         }
2374
2375         template<class T>
2376         RValue<T> Reference<T>::operator+=(RValue<T> rhs) const
2377         {
2378                 return *this = *this + rhs;
2379         }
2380
2381         template<class T>
2382         Value *Reference<T>::loadValue() const
2383         {
2384                 return Nucleus::createLoad(address, T::getType(), false, alignment);
2385         }
2386
2387         template<class T>
2388         int Reference<T>::getAlignment() const
2389         {
2390                 return alignment;
2391         }
2392
2393         template<class T>
2394         RValue<T>::RValue(Value *rvalue)
2395         {
2396                 assert(Nucleus::createBitCast(rvalue, T::getType()) == rvalue);   // Run-time type should match T, so bitcast is no-op.
2397
2398                 value = rvalue;
2399         }
2400
2401         template<class T>
2402         RValue<T>::RValue(const T &lvalue)
2403         {
2404                 value = lvalue.loadValue();
2405         }
2406
2407         template<class T>
2408         RValue<T>::RValue(typename BoolLiteral<T>::type i)
2409         {
2410                 value = Nucleus::createConstantBool(i);
2411         }
2412
2413         template<class T>
2414         RValue<T>::RValue(typename IntLiteral<T>::type i)
2415         {
2416                 value = Nucleus::createConstantInt(i);
2417         }
2418
2419         template<class T>
2420         RValue<T>::RValue(typename FloatLiteral<T>::type f)
2421         {
2422                 value = Nucleus::createConstantFloat(f);
2423         }
2424
2425         template<class T>
2426         RValue<T>::RValue(const Reference<T> &ref)
2427         {
2428                 value = ref.loadValue();
2429         }
2430
2431         template<class Vector4, int T>
2432         Swizzle2<Vector4, T>::operator RValue<Vector4>() const
2433         {
2434                 Value *vector = parent->loadValue();
2435
2436                 return Swizzle(RValue<Vector4>(vector), T);
2437         }
2438
2439         template<class Vector4, int T>
2440         Swizzle4<Vector4, T>::operator RValue<Vector4>() const
2441         {
2442                 Value *vector = parent->loadValue();
2443
2444                 return Swizzle(RValue<Vector4>(vector), T);
2445         }
2446
2447         template<class Vector4, int T>
2448         SwizzleMask4<Vector4, T>::operator RValue<Vector4>() const
2449         {
2450                 Value *vector = parent->loadValue();
2451
2452                 return Swizzle(RValue<Vector4>(vector), T);
2453         }
2454
2455         template<class Vector4, int T>
2456         RValue<Vector4> SwizzleMask4<Vector4, T>::operator=(RValue<Vector4> rhs)
2457         {
2458                 return Mask(*parent, rhs, T);
2459         }
2460
2461         template<class Vector4, int T>
2462         RValue<Vector4> SwizzleMask4<Vector4, T>::operator=(RValue<typename Scalar<Vector4>::Type> rhs)
2463         {
2464                 return Mask(*parent, Vector4(rhs), T);
2465         }
2466
2467         template<class Vector4, int T>
2468         SwizzleMask1<Vector4, T>::operator RValue<typename Scalar<Vector4>::Type>() const   // FIXME: Call a non-template function
2469         {
2470                 return Extract(*parent, T & 0x3);
2471         }
2472
2473         template<class Vector4, int T>
2474         SwizzleMask1<Vector4, T>::operator RValue<Vector4>() const
2475         {
2476                 Value *vector = parent->loadValue();
2477
2478                 return Swizzle(RValue<Vector4>(vector), T);
2479         }
2480
2481         template<class Vector4, int T>
2482         RValue<Vector4> SwizzleMask1<Vector4, T>::operator=(float x)
2483         {
2484                 return *parent = Insert(*parent, Float(x), T & 0x3);
2485         }
2486
2487         template<class Vector4, int T>
2488         RValue<Vector4> SwizzleMask1<Vector4, T>::operator=(RValue<Vector4> rhs)
2489         {
2490                 return Mask(*parent, Float4(rhs), T);
2491         }
2492
2493         template<class Vector4, int T>
2494         RValue<Vector4> SwizzleMask1<Vector4, T>::operator=(RValue<typename Scalar<Vector4>::Type> rhs)   // FIXME: Call a non-template function
2495         {
2496                 return *parent = Insert(*parent, rhs, T & 0x3);
2497         }
2498
2499         template<class Vector4, int T>
2500         SwizzleMask2<Vector4, T>::operator RValue<Vector4>() const
2501         {
2502                 Value *vector = parent->loadValue();
2503
2504                 return Swizzle(RValue<Float4>(vector), T);
2505         }
2506
2507         template<class Vector4, int T>
2508         RValue<Vector4> SwizzleMask2<Vector4, T>::operator=(RValue<Vector4> rhs)
2509         {
2510                 return Mask(*parent, Float4(rhs), T);
2511         }
2512
2513         template<int T>
2514         Float::Float(const SwizzleMask1<Float4, T> &rhs)
2515         {
2516                 *this = rhs.operator RValue<Float>();
2517         }
2518
2519         template<int T>
2520         RValue<Float> Float::operator=(const SwizzleMask1<Float4, T> &rhs)
2521         {
2522                 return *this = rhs.operator RValue<Float>();
2523         }
2524
2525         template<int T>
2526         Float4::Float4(const SwizzleMask1<Float4, T> &rhs) : XYZW(this)
2527         {
2528                 *this = rhs.operator RValue<Float4>();
2529         }
2530
2531         template<int T>
2532         Float4::Float4(const Swizzle4<Float4, T> &rhs) : XYZW(this)
2533         {
2534                 *this = rhs.operator RValue<Float4>();
2535         }
2536
2537         template<int X, int Y>
2538         Float4::Float4(const Swizzle2<Float4, X> &x, const Swizzle2<Float4, Y> &y) : XYZW(this)
2539         {
2540                 *this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);
2541         }
2542
2543         template<int X, int Y>
2544         Float4::Float4(const SwizzleMask2<Float4, X> &x, const Swizzle2<Float4, Y> &y) : XYZW(this)
2545         {
2546                 *this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);
2547         }
2548
2549         template<int X, int Y>
2550         Float4::Float4(const Swizzle2<Float4, X> &x, const SwizzleMask2<Float4, Y> &y) : XYZW(this)
2551         {
2552                 *this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);
2553         }
2554
2555         template<int X, int Y>
2556         Float4::Float4(const SwizzleMask2<Float4, X> &x, const SwizzleMask2<Float4, Y> &y) : XYZW(this)
2557         {
2558                 *this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);
2559         }
2560
2561         template<int T>
2562         RValue<Float4> Float4::operator=(const SwizzleMask1<Float4, T> &rhs)
2563         {
2564                 return *this = rhs.operator RValue<Float4>();
2565         }
2566
2567         template<int T>
2568         RValue<Float4> Float4::operator=(const Swizzle4<Float4, T> &rhs)
2569         {
2570                 return *this = rhs.operator RValue<Float4>();
2571         }
2572
2573         template<class T>
2574         Pointer<T>::Pointer(Argument<Pointer<T>> argument) : alignment(1)
2575         {
2576                 LValue<Pointer<T>>::storeValue(argument.value);
2577         }
2578
2579         template<class T>
2580         Pointer<T>::Pointer() : alignment(1)
2581         {
2582                 LValue<Pointer<T>>::storeValue(Nucleus::createNullPointer(T::getType()));
2583         }
2584
2585         template<class T>
2586         Pointer<T>::Pointer(RValue<Pointer<T>> rhs) : alignment(1)
2587         {
2588                 LValue<Pointer<T>>::storeValue(rhs.value);
2589         }
2590
2591         template<class T>
2592         Pointer<T>::Pointer(const Pointer<T> &rhs) : alignment(rhs.alignment)
2593         {
2594                 Value *value = rhs.loadValue();
2595                 LValue<Pointer<T>>::storeValue(value);
2596         }
2597
2598         template<class T>
2599         Pointer<T>::Pointer(const Reference<Pointer<T>> &rhs) : alignment(rhs.getAlignment())
2600         {
2601                 Value *value = rhs.loadValue();
2602                 LValue<Pointer<T>>::storeValue(value);
2603         }
2604
2605         template<class T>
2606         RValue<Pointer<T>> Pointer<T>::operator=(RValue<Pointer<T>> rhs)
2607         {
2608                 LValue<Pointer<T>>::storeValue(rhs.value);
2609
2610                 return rhs;
2611         }
2612
2613         template<class T>
2614         RValue<Pointer<T>> Pointer<T>::operator=(const Pointer<T> &rhs)
2615         {
2616                 Value *value = rhs.loadValue();
2617                 LValue<Pointer<T>>::storeValue(value);
2618
2619                 return RValue<Pointer<T>>(value);
2620         }
2621
2622         template<class T>
2623         RValue<Pointer<T>> Pointer<T>::operator=(const Reference<Pointer<T>> &rhs)
2624         {
2625                 Value *value = rhs.loadValue();
2626                 LValue<Pointer<T>>::storeValue(value);
2627
2628                 return RValue<Pointer<T>>(value);
2629         }
2630
2631         template<class T>
2632         Reference<T> Pointer<T>::operator*()
2633         {
2634                 return Reference<T>(LValue<Pointer<T>>::loadValue(), alignment);
2635         }
2636
2637         template<class T>
2638         Reference<T> Pointer<T>::operator[](int index)
2639         {
2640                 Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), T::getType(), Nucleus::createConstantInt(index), false);
2641
2642                 return Reference<T>(element, alignment);
2643         }
2644
2645         template<class T>
2646         Reference<T> Pointer<T>::operator[](unsigned int index)
2647         {
2648                 Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), T::getType(), Nucleus::createConstantInt(index), true);
2649
2650                 return Reference<T>(element, alignment);
2651         }
2652
2653         template<class T>
2654         Reference<T> Pointer<T>::operator[](RValue<Int> index)
2655         {
2656                 Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), T::getType(), index.value, false);
2657
2658                 return Reference<T>(element, alignment);
2659         }
2660
2661         template<class T>
2662         Reference<T> Pointer<T>::operator[](RValue<UInt> index)
2663         {
2664                 Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), T::getType(), index.value, true);
2665
2666                 return Reference<T>(element, alignment);
2667         }
2668
2669         template<class T>
2670         Type *Pointer<T>::getType()
2671         {
2672                 return Nucleus::getPointerType(T::getType());
2673         }
2674
2675         template<class T, int S>
2676         Array<T, S>::Array(int size) : LValue<T>(size)
2677         {
2678         }
2679
2680         template<class T, int S>
2681         Reference<T> Array<T, S>::operator[](int index)
2682         {
2683                 Value *element = LValue<T>::getAddress(Nucleus::createConstantInt(index), false);
2684
2685                 return Reference<T>(element);
2686         }
2687
2688         template<class T, int S>
2689         Reference<T> Array<T, S>::operator[](unsigned int index)
2690         {
2691                 Value *element = LValue<T>::getAddress(Nucleus::createConstantInt(index), true);
2692
2693                 return Reference<T>(element);
2694         }
2695
2696         template<class T, int S>
2697         Reference<T> Array<T, S>::operator[](RValue<Int> index)
2698         {
2699                 Value *element = LValue<T>::getAddress(index.value, false);
2700
2701                 return Reference<T>(element);
2702         }
2703
2704         template<class T, int S>
2705         Reference<T> Array<T, S>::operator[](RValue<UInt> index)
2706         {
2707                 Value *element = LValue<T>::getAddress(index.value, true);
2708
2709                 return Reference<T>(element);
2710         }
2711
2712 //      template<class T>
2713 //      RValue<Array<T>> operator++(Array<T> &val, int)
2714 //      {
2715 //              // FIXME: Requires storing the address of the array
2716 //      }
2717
2718 //      template<class T>
2719 //      const Array<T> &operator++(Array<T> &val)
2720 //      {
2721 //              // FIXME: Requires storing the address of the array
2722 //      }
2723
2724 //      template<class T>
2725 //      RValue<Array<T>> operator--(Array<T> &val, int)
2726 //      {
2727 //              // FIXME: Requires storing the address of the array
2728 //      }
2729
2730 //      template<class T>
2731 //      const Array<T> &operator--(Array<T> &val)
2732 //      {
2733 //              // FIXME: Requires storing the address of the array
2734 //      }
2735
2736         template<class T>
2737         RValue<T> IfThenElse(RValue<Bool> condition, RValue<T> ifTrue, RValue<T> ifFalse)
2738         {
2739                 return RValue<T>(Nucleus::createSelect(condition.value, ifTrue.value, ifFalse.value));
2740         }
2741
2742         template<class T>
2743         RValue<T> IfThenElse(RValue<Bool> condition, const T &ifTrue, RValue<T> ifFalse)
2744         {
2745                 Value *trueValue = ifTrue.loadValue();
2746
2747                 return RValue<T>(Nucleus::createSelect(condition.value, trueValue, ifFalse.value));
2748         }
2749
2750         template<class T>
2751         RValue<T> IfThenElse(RValue<Bool> condition, RValue<T> ifTrue, const T &ifFalse)
2752         {
2753                 Value *falseValue = ifFalse.loadValue();
2754
2755                 return RValue<T>(Nucleus::createSelect(condition.value, ifTrue.value, falseValue));
2756         }
2757
2758         template<class T>
2759         RValue<T> IfThenElse(RValue<Bool> condition, const T &ifTrue, const T &ifFalse)
2760         {
2761                 Value *trueValue = ifTrue.loadValue();
2762                 Value *falseValue = ifFalse.loadValue();
2763
2764                 return RValue<T>(Nucleus::createSelect(condition.value, trueValue, falseValue));
2765         }
2766
2767         template<class T>
2768         void Return(const Pointer<T> &ret)
2769         {
2770                 Nucleus::createRet(Nucleus::createLoad(ret.address, Pointer<T>::getType()));
2771                 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
2772                 Nucleus::createUnreachable();
2773         }
2774
2775         template<class T>
2776         void Return(RValue<Pointer<T>> ret)
2777         {
2778                 Nucleus::createRet(ret.value);
2779                 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
2780                 Nucleus::createUnreachable();
2781         }
2782
2783         template<typename Return, typename... Arguments>
2784         Function<Return(Arguments...)>::Function()
2785         {
2786                 core = new Nucleus();
2787
2788                 Type *types[] = {Arguments::getType()...};
2789                 for(Type *type : types)
2790                 {
2791                         if(type != Void::getType())
2792                         {
2793                                 arguments.push_back(type);
2794                         }
2795                 }
2796
2797                 Nucleus::createFunction(Return::getType(), arguments);
2798         }
2799
2800         template<typename Return, typename... Arguments>
2801         Function<Return(Arguments...)>::~Function()
2802         {
2803                 delete core;
2804         }
2805
2806         template<typename Return, typename... Arguments>
2807         Routine *Function<Return(Arguments...)>::operator()(const char *name, ...)
2808         {
2809                 char fullName[1024 + 1];
2810
2811                 va_list vararg;
2812                 va_start(vararg, name);
2813                 vsnprintf(fullName, 1024, name, vararg);
2814                 va_end(vararg);
2815
2816                 return core->acquireRoutine(fullName, true);
2817         }
2818
2819         template<class T, class S>
2820         RValue<T> ReinterpretCast(RValue<S> val)
2821         {
2822                 return RValue<T>(Nucleus::createBitCast(val.value, T::getType()));
2823         }
2824
2825         template<class T, class S>
2826         RValue<T> ReinterpretCast(const LValue<S> &var)
2827         {
2828                 Value *val = var.loadValue();
2829
2830                 return RValue<T>(Nucleus::createBitCast(val, T::getType()));
2831         }
2832
2833         template<class T, class S>
2834         RValue<T> ReinterpretCast(const Reference<S> &var)
2835         {
2836                 return ReinterpretCast<T>(RValue<S>(var));
2837         }
2838
2839         template<class T>
2840         RValue<T> As(Value *val)
2841         {
2842                 return RValue<T>(Nucleus::createBitCast(val, T::getType()));
2843         }
2844
2845         template<class T, class S>
2846         RValue<T> As(RValue<S> val)
2847         {
2848                 return ReinterpretCast<T>(val);
2849         }
2850
2851         template<class T, class S>
2852         RValue<T> As(const LValue<S> &var)
2853         {
2854                 return ReinterpretCast<T>(var);
2855         }
2856
2857         template<class T, class S>
2858         RValue<T> As(const Reference<S> &val)
2859         {
2860                 return ReinterpretCast<T>(val);
2861         }
2862
2863 #ifdef ENABLE_RR_PRINT
2864         // PrintValue holds the printf format and value(s) for a single argument
2865         // to Print(). A single argument can be expanded into multiple printf
2866         // values - for example a Float4 will expand to "%f %f %f %f" and four
2867         // scalar values.
2868         // The PrintValue constructor accepts the following:
2869         //   * Reactor LValues, RValues, Pointers.
2870         //   * Standard Plain-Old-Value types (int, float, bool, etc)
2871         //   * Custom types that specialize the PrintValue::Ty template struct.
2872         //   * Static arrays in the form T[N] where T can be any of the above.
2873         class PrintValue
2874         {
2875                 // Ty is a template that can be specialized for printing type T.
2876                 // Each specialization must expose:
2877                 //  * A 'static constexpr const char* fmt' field that provides the
2878                 //    printf format specifier.
2879                 //  * A 'static std::vector<rr::Value*> val(const T& v)' method that
2880                 //    returns all the printf format values.
2881                 template <typename T> struct Ty
2882                 {
2883                         // static constexpr const char* fmt;
2884                         // static std::vector<rr::Value*> val(const T& v)
2885                 };
2886
2887                 // returns the printf value(s) for the given LValue.
2888                 template <typename T>
2889                 static std::vector<Value*> val(const LValue<T>& v) { return val(RValue<T>(v.loadValue())); };
2890
2891                 // returns the printf value(s) for the given RValue.
2892                 template <typename T>
2893                 static std::vector<Value*> val(const RValue<T>& v) { return Ty<T>::val(v); };
2894
2895                 // returns the printf value from for the given type with a
2896                 // PrintValue::Ty<T> specialization.
2897                 template <typename T>
2898                 static std::vector<Value*> val(const T& v) { return Ty<T>::val(v); };
2899
2900                 // returns the printf values for all the values in the given array.
2901                 template <typename T>
2902                 static std::vector<Value*> val(const T* list, int count) {
2903                         std::vector<Value*> values;
2904                         values.reserve(count);
2905                         for (int i = 0; i < count; i++)
2906                         {
2907                                 auto v = val(list[i]);
2908                                 values.insert(values.end(), v.begin(), v.end());
2909                         }
2910                         return values;
2911                 };
2912
2913                 // fmt returns a comma-delimited list of the string el repeated count
2914                 // times enclosed in square brackets.
2915                 static std::string fmt(const char* el, int count)
2916                 {
2917                         std::string out = "[";
2918                         for (int i = 0; i < count; i++)
2919                         {
2920                                 if (i > 0) { out += ", "; }
2921                                 out += el;
2922                         }
2923                         return out + "]";
2924                 }
2925
2926         public:
2927                 const std::string format;
2928                 const std::vector<Value*> values;
2929
2930                 // Constructs a PrintValue for the given value.
2931                 template <typename T>
2932                 PrintValue(const T& v) : format(Ty<T>::fmt), values(val(v)) {}
2933
2934                 // Constructs a PrintValue for the given static array.
2935                 template <typename T, int N>
2936                 PrintValue(const T (&v)[N]) : format(fmt(Ty<T>::fmt, N)), values(val(&v[0], N)) {}
2937
2938                 // Constructs a PrintValue for the given array starting at arr of length
2939                 // len.
2940                 template <typename T>
2941                 PrintValue(const T* arr, int len) : format(fmt(Ty<T>::fmt, len)), values(val(arr, len)) {}
2942
2943
2944                 // PrintValue constructors for plain-old-data values.
2945                 PrintValue(bool v) : format(v ? "true" : "false") {}
2946                 PrintValue(int8_t v) : format(std::to_string(v)) {}
2947                 PrintValue(uint8_t v) : format(std::to_string(v)) {}
2948                 PrintValue(int16_t v) : format(std::to_string(v)) {}
2949                 PrintValue(uint16_t v) : format(std::to_string(v)) {}
2950                 PrintValue(int32_t v) : format(std::to_string(v)) {}
2951                 PrintValue(uint32_t v) : format(std::to_string(v)) {}
2952                 PrintValue(int64_t v) : format(std::to_string(v)) {}
2953                 PrintValue(uint64_t v) : format(std::to_string(v)) {}
2954                 PrintValue(float v) : format(std::to_string(v)) {}
2955                 PrintValue(double v) : format(std::to_string(v)) {}
2956                 PrintValue(const char* v) : format(v) {}
2957                 PrintValue(const std::string& v) : format(v) {}
2958
2959                 // vals is a helper to build composite value lists.
2960                 // vals returns the full, sequential list of printf argument values used
2961                 // to print all the provided variadic values.
2962                 // vals() is intended to be used by implementations of
2963                 // PrintValue::Ty<>::vals() to help declare aggregate types.
2964                 // For example, if you were declaring a PrintValue::Ty<> specialization
2965                 // for a custom Mat4x4 matrix formed from four Vector4 values, you'd
2966                 // write:
2967                 //
2968                 // namespace rr
2969                 // {
2970                 //              template <> struct PrintValue::Ty<Mat4x4>
2971                 //              {
2972                 //                      static constexpr const char* fmt =
2973                 //                              "[a: <%f, %f, %f, %f>,"
2974                 //                              " b: <%f, %f, %f, %f>,"
2975                 //                              " c: <%f, %f, %f, %f>,"
2976                 //                              " d: <%f, %f, %f, %f>]";
2977                 //                      static std::vector<rr::Value*> val(const Mat4x4& v)
2978                 //                      {
2979                 //                              return PrintValue::vals(v.a, v.b, v.c, v.d);
2980                 //                      }
2981                 //              };
2982                 //      }
2983                 template<typename ... ARGS>
2984                 static std::vector<Value*> vals(ARGS... v)
2985                 {
2986                         std::vector< std::vector<Value*> > lists = {val(v)...};
2987                         std::vector<Value*> joined;
2988                         for (const auto& list : lists)
2989                         {
2990                                 joined.insert(joined.end(), list.begin(), list.end());
2991                         }
2992                         return joined;
2993                 }
2994         };
2995
2996         // PrintValue::Ty<T> specializations for standard Reactor types.
2997         template <> struct PrintValue::Ty<Bool>
2998         {
2999                 static constexpr const char* fmt = "%d";
3000                 static std::vector<Value*> val(const RValue<Bool>& v) { return {v.value}; }
3001         };
3002         template <> struct PrintValue::Ty<Byte>
3003         {
3004                 static constexpr const char* fmt = "%d";
3005                 static std::vector<Value*> val(const RValue<Byte>& v) { return {v.value}; }
3006         };
3007         template <> struct PrintValue::Ty<Byte4>
3008         {
3009                 static constexpr const char* fmt = "[%d, %d, %d, %d]";
3010                 static std::vector<Value*> val(const RValue<Byte4>& v);
3011         };
3012         template <> struct PrintValue::Ty<Int>
3013         {
3014                 static constexpr const char* fmt = "%d";
3015                 static std::vector<Value*> val(const RValue<Int>& v) { return {v.value}; }
3016         };
3017         template <> struct PrintValue::Ty<Int4>
3018         {
3019                 static constexpr const char* fmt = "[%d, %d, %d, %d]";
3020                 static std::vector<Value*> val(const RValue<Int4>& v);
3021         };
3022         template <> struct PrintValue::Ty<UInt>
3023         {
3024                 static constexpr const char* fmt = "%u";
3025                 static std::vector<Value*> val(const RValue<UInt>& v) { return {v.value}; }
3026         };
3027         template <> struct PrintValue::Ty<UInt4>
3028         {
3029                 static constexpr const char* fmt = "[%u, %u, %u, %u]";
3030                 static std::vector<Value*> val(const RValue<UInt4>& v);
3031         };
3032         template <> struct PrintValue::Ty<Short>
3033         {
3034                 static constexpr const char* fmt = "%d";
3035                 static std::vector<Value*> val(const RValue<Short>& v) { return {v.value}; }
3036         };
3037         template <> struct PrintValue::Ty<Short4>
3038         {
3039                 static constexpr const char* fmt = "[%d, %d, %d, %d]";
3040                 static std::vector<Value*> val(const RValue<Short4>& v);
3041         };
3042         template <> struct PrintValue::Ty<UShort>
3043         {
3044                 static constexpr const char* fmt = "%u";
3045                 static std::vector<Value*> val(const RValue<UShort>& v) { return {v.value}; }
3046         };
3047         template <> struct PrintValue::Ty<UShort4>
3048         {
3049                 static constexpr const char* fmt = "[%u, %u, %u, %u]";
3050                 static std::vector<Value*> val(const RValue<UShort4>& v);
3051         };
3052         template <> struct PrintValue::Ty<Float>
3053         {
3054                 static constexpr const char* fmt = "[%f]";
3055                 static std::vector<Value*> val(const RValue<Float>& v);
3056         };
3057         template <> struct PrintValue::Ty<Float4>
3058         {
3059                 static constexpr const char* fmt = "[%f, %f, %f, %f]";
3060                 static std::vector<Value*> val(const RValue<Float4>& v);
3061         };
3062         template <typename T> struct PrintValue::Ty< Pointer<T> >
3063         {
3064                 static constexpr const char* fmt = "%p";
3065                 static std::vector<Value*> val(const RValue<Pointer<T>>& v) { return {v.value}; }
3066         };
3067         template <typename T> struct PrintValue::Ty< Reference<T> >
3068         {
3069                 static constexpr const char* fmt = PrintValue::Ty<T>::fmt;
3070                 static std::vector<Value*> val(const Reference<T>& v) { return PrintValue::Ty<T>::val(v); }
3071         };
3072         template <typename T> struct PrintValue::Ty< RValue<T> >
3073         {
3074                 static constexpr const char* fmt = PrintValue::Ty<T>::fmt;
3075                 static std::vector<Value*> val(const RValue<T>& v) { return PrintValue::Ty<T>::val(v); }
3076         };
3077
3078         // Printv emits a call to printf() using the function, file and line,
3079         // message and optional values.
3080         // See Printv below.
3081         void Printv(const char* function, const char* file, int line, const char* msg, std::initializer_list<PrintValue> vals);
3082
3083         // Printv emits a call to printf() using the provided message and optional
3084         // values.
3085         // Printf replaces any bracketed indices in the message with string
3086         // representations of the corresponding value in vals.
3087         // For example:
3088         //   Printv("{0} and {1}", "red", "green");
3089         // Would print the string:
3090         //   "red and green"
3091         // Arguments can be indexed in any order.
3092         // Invalid indices are not substituted.
3093         inline void Printv(const char* msg, std::initializer_list<PrintValue> vals)
3094         {
3095                 Printv(nullptr, nullptr, 0, msg, vals);
3096         }
3097
3098         // Print is a wrapper over Printv that wraps the variadic arguments into an
3099         // initializer_list before calling Printv.
3100         template <typename ... ARGS>
3101         void Print(const char* msg, const ARGS& ... vals) { Printv(msg, {vals...}); }
3102
3103         // Print is a wrapper over Printv that wraps the variadic arguments into an
3104         // initializer_list before calling Printv.
3105         template <typename ... ARGS>
3106         void Print(const char* function, const char* file, int line, const char* msg, const ARGS& ... vals)
3107         {
3108                 Printv(function, file, line, msg, {vals...});
3109         }
3110
3111         // RR_LOG is a macro that calls Print(), automatically populating the
3112         // function, file and line parameters and appending a newline to the string.
3113         //
3114         // RR_LOG() is intended to be used for debugging JIT compiled code, and is
3115         // not intended for production use.
3116         #define RR_LOG(msg, ...) Print(__PRETTY_FUNCTION__, __FILE__, __LINE__, msg "\n", ##__VA_ARGS__)
3117
3118         // Macro magic to perform variadic dispatch.
3119         // See: https://renenyffenegger.ch/notes/development/languages/C-C-plus-plus/preprocessor/macros/__VA_ARGS__/count-arguments
3120         // Note, this doesn't attempt to use the ##__VA_ARGS__ trick to handle 0
3121         // args as this appears to still be broken on certain compilers.
3122         // MSVC also has issues with variadic macros which requires the RR_VA_MSVC_BUG() work-around.
3123         // See: https://stackoverflow.com/a/48711060
3124         #define RR_VA_MSVC_BUG(MACRO, ARGS) MACRO ARGS
3125         #define RR_GET_NTH_ARG_EX(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, N, ...) N
3126         #define RR_GET_NTH_ARG(...) RR_VA_MSVC_BUG(RR_GET_NTH_ARG_EX, (__VA_ARGS__))
3127         #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)
3128         static_assert(1 == RR_COUNT_ARGUMENTS(a), "RR_COUNT_ARGUMENTS broken"); // Sanity checks.
3129         static_assert(2 == RR_COUNT_ARGUMENTS(a, b), "RR_COUNT_ARGUMENTS broken");
3130         static_assert(3 == RR_COUNT_ARGUMENTS(a, b, c), "RR_COUNT_ARGUMENTS broken");
3131
3132         // RR_WATCH_FMT(...) resolves to a string literal that lists all the
3133         // arguments by name. This string can be passed to LOG() to print each of
3134         // the arguments with their name and value.
3135         //
3136         // RR_WATCH_FMT(...) uses the RR_COUNT_ARGUMENTS helper macro to delegate to a
3137         // corresponding RR_WATCH_FMT_n specialization macro below.
3138         #define RR_WATCH_CONCAT(a, b) a ## b
3139         #define RR_WATCH_CONCAT2(a, b) RR_WATCH_CONCAT(a, b)
3140         #define RR_WATCH_FMT(...) RR_WATCH_CONCAT2(RR_WATCH_FMT_, RR_COUNT_ARGUMENTS(__VA_ARGS__))(__VA_ARGS__)
3141         #define RR_WATCH_FMT_1(_1) "\n  " #_1 ": {0}"
3142         #define RR_WATCH_FMT_2(_1, _2)                                             RR_WATCH_FMT_1(_1) "\n  " #_2 ": {1}"
3143         #define RR_WATCH_FMT_3(_1, _2, _3)                                         RR_WATCH_FMT_2(_1, _2) "\n  " #_3 ": {2}"
3144         #define RR_WATCH_FMT_4(_1, _2, _3, _4)                                     RR_WATCH_FMT_3(_1, _2, _3) "\n  " #_4 ": {3}"
3145         #define RR_WATCH_FMT_5(_1, _2, _3, _4, _5)                                 RR_WATCH_FMT_4(_1, _2, _3, _4) "\n  " #_5 ": {4}"
3146         #define RR_WATCH_FMT_6(_1, _2, _3, _4, _5, _6)                             RR_WATCH_FMT_5(_1, _2, _3, _4, _5) "\n  " #_6 ": {5}"
3147         #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}"
3148         #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}"
3149         #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}"
3150         #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}"
3151         #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}"
3152         #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}"
3153
3154         // RR_WATCH() is a helper that prints the name and value of all the supplied
3155         // arguments.
3156         // For example, if you had the Int and bool variables 'foo' and 'bar' that
3157         // you want to print, you can simply write:
3158         //    RR_WATCH(foo, bar)
3159         // When this JIT compiled code is executed, it will print the string
3160         // "foo: 1, bar: true" to stdout.
3161         //
3162         // RR_WATCH() is intended to be used for debugging JIT compiled code, and
3163         // is not intended for production use.
3164         #define RR_WATCH(...) RR_LOG(RR_WATCH_FMT(__VA_ARGS__), __VA_ARGS__)
3165 #endif // ENABLE_RR_PRINT
3166
3167         class ForData
3168         {
3169         public:
3170                 ForData(bool init) : loopOnce(init)
3171                 {
3172                 }
3173
3174                 operator bool()
3175                 {
3176                         return loopOnce;
3177                 }
3178
3179                 bool operator=(bool value)
3180                 {
3181                         return loopOnce = value;
3182                 }
3183
3184                 bool setup()
3185                 {
3186                         if(Nucleus::getInsertBlock() != endBB)
3187                         {
3188                                 testBB = Nucleus::createBasicBlock();
3189
3190                                 Nucleus::createBr(testBB);
3191                                 Nucleus::setInsertBlock(testBB);
3192
3193                                 return true;
3194                         }
3195
3196                         return false;
3197                 }
3198
3199                 bool test(RValue<Bool> cmp)
3200                 {
3201                         BasicBlock *bodyBB = Nucleus::createBasicBlock();
3202                         endBB = Nucleus::createBasicBlock();
3203
3204                         Nucleus::createCondBr(cmp.value, bodyBB, endBB);
3205                         Nucleus::setInsertBlock(bodyBB);
3206
3207                         return true;
3208                 }
3209
3210                 void end()
3211                 {
3212                         Nucleus::createBr(testBB);
3213                         Nucleus::setInsertBlock(endBB);
3214                 }
3215
3216         private:
3217                 BasicBlock *testBB = nullptr;
3218                 BasicBlock *endBB = nullptr;
3219                 bool loopOnce = true;
3220         };
3221
3222         class IfElseData
3223         {
3224         public:
3225                 IfElseData(RValue<Bool> cmp) : iteration(0)
3226                 {
3227                         condition = cmp.value;
3228
3229                         beginBB = Nucleus::getInsertBlock();
3230                         trueBB = Nucleus::createBasicBlock();
3231                         falseBB = nullptr;
3232                         endBB = Nucleus::createBasicBlock();
3233
3234                         Nucleus::setInsertBlock(trueBB);
3235                 }
3236
3237                 ~IfElseData()
3238                 {
3239                         Nucleus::createBr(endBB);
3240
3241                         Nucleus::setInsertBlock(beginBB);
3242                         Nucleus::createCondBr(condition, trueBB, falseBB ? falseBB : endBB);
3243
3244                         Nucleus::setInsertBlock(endBB);
3245                 }
3246
3247                 operator int()
3248                 {
3249                         return iteration;
3250                 }
3251
3252                 IfElseData &operator++()
3253                 {
3254                         ++iteration;
3255
3256                         return *this;
3257                 }
3258
3259                 void elseClause()
3260                 {
3261                         Nucleus::createBr(endBB);
3262
3263                         falseBB = Nucleus::createBasicBlock();
3264                         Nucleus::setInsertBlock(falseBB);
3265                 }
3266
3267         private:
3268                 Value *condition;
3269                 BasicBlock *beginBB;
3270                 BasicBlock *trueBB;
3271                 BasicBlock *falseBB;
3272                 BasicBlock *endBB;
3273                 int iteration;
3274         };
3275
3276         #define For(init, cond, inc) \
3277         for(ForData for__ = true; for__; for__ = false) \
3278         for(init; for__.setup() && for__.test(cond); inc, for__.end())
3279
3280         #define While(cond) For((void)0, cond, (void)0)
3281
3282         #define Do                                            \
3283         {                                                     \
3284                 BasicBlock *body__ = Nucleus::createBasicBlock(); \
3285                 Nucleus::createBr(body__);                        \
3286                 Nucleus::setInsertBlock(body__);
3287
3288         #define Until(cond)                                     \
3289                 BasicBlock *end__ = Nucleus::createBasicBlock();    \
3290                 Nucleus::createCondBr((cond).value, end__, body__); \
3291                 Nucleus::setInsertBlock(end__);                     \
3292         }
3293
3294         enum {IF_BLOCK__, ELSE_CLAUSE__, ELSE_BLOCK__, IFELSE_NUM__};
3295
3296         #define If(cond)                                                    \
3297         for(IfElseData ifElse__(cond); ifElse__ < IFELSE_NUM__; ++ifElse__) \
3298         if(ifElse__ == IF_BLOCK__)
3299
3300         #define Else                       \
3301         else if(ifElse__ == ELSE_CLAUSE__) \
3302         {                                  \
3303                  ifElse__.elseClause();        \
3304         }                                  \
3305         else   // ELSE_BLOCK__
3306 }
3307
3308 #endif   // rr_Reactor_hpp