OSDN Git Service

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