OSDN Git Service

Elide single basic block variable materialization
[android-x86/external-swiftshader.git] / src / Reactor / Reactor.cpp
1 // Copyright 2019 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "Reactor.hpp"
16
17 // Define REACTOR_MATERIALIZE_LVALUES_ON_DEFINITION to non-zero to ensure all
18 // variables have a stack location obtained throuch alloca().
19 #ifndef REACTOR_MATERIALIZE_LVALUES_ON_DEFINITION
20 #define REACTOR_MATERIALIZE_LVALUES_ON_DEFINITION 0
21 #endif
22
23 namespace rr
24 {
25         // Set of variables that do not have a stack location yet.
26         std::unordered_set<Variable*> Variable::unmaterializedVariables;
27
28         Variable::Variable(Type *type, int arraySize) : type(type), arraySize(arraySize)
29         {
30                 #if REACTOR_MATERIALIZE_LVALUES_ON_DEFINITION
31                         materialize();
32                 #else
33                         unmaterializedVariables.emplace(this);
34                 #endif
35         }
36
37         Variable::~Variable()
38         {
39                 unmaterializedVariables.erase(this);
40         }
41
42         void Variable::materializeAll()
43         {
44                 for(auto *var : unmaterializedVariables)
45                 {
46                         var->materialize();
47                 }
48
49                 unmaterializedVariables.clear();
50         }
51
52         void Variable::killUnmaterialized()
53         {
54                 unmaterializedVariables.clear();
55         }
56
57         static Value *createSwizzle4(Value *val, unsigned char select)
58         {
59                 int swizzle[4] =
60                 {
61                         (select >> 0) & 0x03,
62                         (select >> 2) & 0x03,
63                         (select >> 4) & 0x03,
64                         (select >> 6) & 0x03,
65                 };
66
67                 return Nucleus::createShuffleVector(val, val, swizzle);
68         }
69
70         static Value *createMask4(Value *lhs, Value *rhs, unsigned char select)
71         {
72                 bool mask[4] = {false, false, false, false};
73
74                 mask[(select >> 0) & 0x03] = true;
75                 mask[(select >> 2) & 0x03] = true;
76                 mask[(select >> 4) & 0x03] = true;
77                 mask[(select >> 6) & 0x03] = true;
78
79                 int swizzle[4] =
80                 {
81                         mask[0] ? 4 : 0,
82                         mask[1] ? 5 : 1,
83                         mask[2] ? 6 : 2,
84                         mask[3] ? 7 : 3,
85                 };
86
87                 return Nucleus::createShuffleVector(lhs, rhs, swizzle);
88         }
89
90         Bool::Bool(Argument<Bool> argument)
91         {
92                 storeValue(argument.value);
93         }
94
95         Bool::Bool(bool x)
96         {
97                 storeValue(Nucleus::createConstantBool(x));
98         }
99
100         Bool::Bool(RValue<Bool> rhs)
101         {
102                 storeValue(rhs.value);
103         }
104
105         Bool::Bool(const Bool &rhs)
106         {
107                 Value *value = rhs.loadValue();
108                 storeValue(value);
109         }
110
111         Bool::Bool(const Reference<Bool> &rhs)
112         {
113                 Value *value = rhs.loadValue();
114                 storeValue(value);
115         }
116
117         RValue<Bool> Bool::operator=(RValue<Bool> rhs)
118         {
119                 storeValue(rhs.value);
120
121                 return rhs;
122         }
123
124         RValue<Bool> Bool::operator=(const Bool &rhs)
125         {
126                 Value *value = rhs.loadValue();
127                 storeValue(value);
128
129                 return RValue<Bool>(value);
130         }
131
132         RValue<Bool> Bool::operator=(const Reference<Bool> &rhs)
133         {
134                 Value *value = rhs.loadValue();
135                 storeValue(value);
136
137                 return RValue<Bool>(value);
138         }
139
140         RValue<Bool> operator!(RValue<Bool> val)
141         {
142                 return RValue<Bool>(Nucleus::createNot(val.value));
143         }
144
145         RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs)
146         {
147                 return RValue<Bool>(Nucleus::createAnd(lhs.value, rhs.value));
148         }
149
150         RValue<Bool> operator||(RValue<Bool> lhs, RValue<Bool> rhs)
151         {
152                 return RValue<Bool>(Nucleus::createOr(lhs.value, rhs.value));
153         }
154
155         RValue<Bool> operator!=(RValue<Bool> lhs, RValue<Bool> rhs)
156         {
157                 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
158         }
159
160         RValue<Bool> operator==(RValue<Bool> lhs, RValue<Bool> rhs)
161         {
162                 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
163         }
164
165         Byte::Byte(Argument<Byte> argument)
166         {
167                 storeValue(argument.value);
168         }
169
170         Byte::Byte(RValue<Int> cast)
171         {
172                 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
173
174                 storeValue(integer);
175         }
176
177         Byte::Byte(RValue<UInt> cast)
178         {
179                 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
180
181                 storeValue(integer);
182         }
183
184         Byte::Byte(RValue<UShort> cast)
185         {
186                 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
187
188                 storeValue(integer);
189         }
190
191         Byte::Byte(int x)
192         {
193                 storeValue(Nucleus::createConstantByte((unsigned char)x));
194         }
195
196         Byte::Byte(unsigned char x)
197         {
198                 storeValue(Nucleus::createConstantByte(x));
199         }
200
201         Byte::Byte(RValue<Byte> rhs)
202         {
203                 storeValue(rhs.value);
204         }
205
206         Byte::Byte(const Byte &rhs)
207         {
208                 Value *value = rhs.loadValue();
209                 storeValue(value);
210         }
211
212         Byte::Byte(const Reference<Byte> &rhs)
213         {
214                 Value *value = rhs.loadValue();
215                 storeValue(value);
216         }
217
218         RValue<Byte> Byte::operator=(RValue<Byte> rhs)
219         {
220                 storeValue(rhs.value);
221
222                 return rhs;
223         }
224
225         RValue<Byte> Byte::operator=(const Byte &rhs)
226         {
227                 Value *value = rhs.loadValue();
228                 storeValue(value);
229
230                 return RValue<Byte>(value);
231         }
232
233         RValue<Byte> Byte::operator=(const Reference<Byte> &rhs)
234         {
235                 Value *value = rhs.loadValue();
236                 storeValue(value);
237
238                 return RValue<Byte>(value);
239         }
240
241         RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs)
242         {
243                 return RValue<Byte>(Nucleus::createAdd(lhs.value, rhs.value));
244         }
245
246         RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs)
247         {
248                 return RValue<Byte>(Nucleus::createSub(lhs.value, rhs.value));
249         }
250
251         RValue<Byte> operator*(RValue<Byte> lhs, RValue<Byte> rhs)
252         {
253                 return RValue<Byte>(Nucleus::createMul(lhs.value, rhs.value));
254         }
255
256         RValue<Byte> operator/(RValue<Byte> lhs, RValue<Byte> rhs)
257         {
258                 return RValue<Byte>(Nucleus::createUDiv(lhs.value, rhs.value));
259         }
260
261         RValue<Byte> operator%(RValue<Byte> lhs, RValue<Byte> rhs)
262         {
263                 return RValue<Byte>(Nucleus::createURem(lhs.value, rhs.value));
264         }
265
266         RValue<Byte> operator&(RValue<Byte> lhs, RValue<Byte> rhs)
267         {
268                 return RValue<Byte>(Nucleus::createAnd(lhs.value, rhs.value));
269         }
270
271         RValue<Byte> operator|(RValue<Byte> lhs, RValue<Byte> rhs)
272         {
273                 return RValue<Byte>(Nucleus::createOr(lhs.value, rhs.value));
274         }
275
276         RValue<Byte> operator^(RValue<Byte> lhs, RValue<Byte> rhs)
277         {
278                 return RValue<Byte>(Nucleus::createXor(lhs.value, rhs.value));
279         }
280
281         RValue<Byte> operator<<(RValue<Byte> lhs, RValue<Byte> rhs)
282         {
283                 return RValue<Byte>(Nucleus::createShl(lhs.value, rhs.value));
284         }
285
286         RValue<Byte> operator>>(RValue<Byte> lhs, RValue<Byte> rhs)
287         {
288                 return RValue<Byte>(Nucleus::createLShr(lhs.value, rhs.value));
289         }
290
291         RValue<Byte> operator+=(Byte &lhs, RValue<Byte> rhs)
292         {
293                 return lhs = lhs + rhs;
294         }
295
296         RValue<Byte> operator-=(Byte &lhs, RValue<Byte> rhs)
297         {
298                 return lhs = lhs - rhs;
299         }
300
301         RValue<Byte> operator*=(Byte &lhs, RValue<Byte> rhs)
302         {
303                 return lhs = lhs * rhs;
304         }
305
306         RValue<Byte> operator/=(Byte &lhs, RValue<Byte> rhs)
307         {
308                 return lhs = lhs / rhs;
309         }
310
311         RValue<Byte> operator%=(Byte &lhs, RValue<Byte> rhs)
312         {
313                 return lhs = lhs % rhs;
314         }
315
316         RValue<Byte> operator&=(Byte &lhs, RValue<Byte> rhs)
317         {
318                 return lhs = lhs & rhs;
319         }
320
321         RValue<Byte> operator|=(Byte &lhs, RValue<Byte> rhs)
322         {
323                 return lhs = lhs | rhs;
324         }
325
326         RValue<Byte> operator^=(Byte &lhs, RValue<Byte> rhs)
327         {
328                 return lhs = lhs ^ rhs;
329         }
330
331         RValue<Byte> operator<<=(Byte &lhs, RValue<Byte> rhs)
332         {
333                 return lhs = lhs << rhs;
334         }
335
336         RValue<Byte> operator>>=(Byte &lhs, RValue<Byte> rhs)
337         {
338                 return lhs = lhs >> rhs;
339         }
340
341         RValue<Byte> operator+(RValue<Byte> val)
342         {
343                 return val;
344         }
345
346         RValue<Byte> operator-(RValue<Byte> val)
347         {
348                 return RValue<Byte>(Nucleus::createNeg(val.value));
349         }
350
351         RValue<Byte> operator~(RValue<Byte> val)
352         {
353                 return RValue<Byte>(Nucleus::createNot(val.value));
354         }
355
356         RValue<Byte> operator++(Byte &val, int)   // Post-increment
357         {
358                 RValue<Byte> res = val;
359
360                 Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantByte((unsigned char)1));
361                 val.storeValue(inc);
362
363                 return res;
364         }
365
366         const Byte &operator++(Byte &val)   // Pre-increment
367         {
368                 Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantByte((unsigned char)1));
369                 val.storeValue(inc);
370
371                 return val;
372         }
373
374         RValue<Byte> operator--(Byte &val, int)   // Post-decrement
375         {
376                 RValue<Byte> res = val;
377
378                 Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantByte((unsigned char)1));
379                 val.storeValue(inc);
380
381                 return res;
382         }
383
384         const Byte &operator--(Byte &val)   // Pre-decrement
385         {
386                 Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantByte((unsigned char)1));
387                 val.storeValue(inc);
388
389                 return val;
390         }
391
392         RValue<Bool> operator<(RValue<Byte> lhs, RValue<Byte> rhs)
393         {
394                 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
395         }
396
397         RValue<Bool> operator<=(RValue<Byte> lhs, RValue<Byte> rhs)
398         {
399                 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
400         }
401
402         RValue<Bool> operator>(RValue<Byte> lhs, RValue<Byte> rhs)
403         {
404                 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
405         }
406
407         RValue<Bool> operator>=(RValue<Byte> lhs, RValue<Byte> rhs)
408         {
409                 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
410         }
411
412         RValue<Bool> operator!=(RValue<Byte> lhs, RValue<Byte> rhs)
413         {
414                 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
415         }
416
417         RValue<Bool> operator==(RValue<Byte> lhs, RValue<Byte> rhs)
418         {
419                 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
420         }
421
422         SByte::SByte(Argument<SByte> argument)
423         {
424                 storeValue(argument.value);
425         }
426
427         SByte::SByte(RValue<Int> cast)
428         {
429                 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
430
431                 storeValue(integer);
432         }
433
434         SByte::SByte(RValue<Short> cast)
435         {
436                 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
437
438                 storeValue(integer);
439         }
440
441         SByte::SByte(signed char x)
442         {
443                 storeValue(Nucleus::createConstantByte(x));
444         }
445
446         SByte::SByte(RValue<SByte> rhs)
447         {
448                 storeValue(rhs.value);
449         }
450
451         SByte::SByte(const SByte &rhs)
452         {
453                 Value *value = rhs.loadValue();
454                 storeValue(value);
455         }
456
457         SByte::SByte(const Reference<SByte> &rhs)
458         {
459                 Value *value = rhs.loadValue();
460                 storeValue(value);
461         }
462
463         RValue<SByte> SByte::operator=(RValue<SByte> rhs)
464         {
465                 storeValue(rhs.value);
466
467                 return rhs;
468         }
469
470         RValue<SByte> SByte::operator=(const SByte &rhs)
471         {
472                 Value *value = rhs.loadValue();
473                 storeValue(value);
474
475                 return RValue<SByte>(value);
476         }
477
478         RValue<SByte> SByte::operator=(const Reference<SByte> &rhs)
479         {
480                 Value *value = rhs.loadValue();
481                 storeValue(value);
482
483                 return RValue<SByte>(value);
484         }
485
486         RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs)
487         {
488                 return RValue<SByte>(Nucleus::createAdd(lhs.value, rhs.value));
489         }
490
491         RValue<SByte> operator-(RValue<SByte> lhs, RValue<SByte> rhs)
492         {
493                 return RValue<SByte>(Nucleus::createSub(lhs.value, rhs.value));
494         }
495
496         RValue<SByte> operator*(RValue<SByte> lhs, RValue<SByte> rhs)
497         {
498                 return RValue<SByte>(Nucleus::createMul(lhs.value, rhs.value));
499         }
500
501         RValue<SByte> operator/(RValue<SByte> lhs, RValue<SByte> rhs)
502         {
503                 return RValue<SByte>(Nucleus::createSDiv(lhs.value, rhs.value));
504         }
505
506         RValue<SByte> operator%(RValue<SByte> lhs, RValue<SByte> rhs)
507         {
508                 return RValue<SByte>(Nucleus::createSRem(lhs.value, rhs.value));
509         }
510
511         RValue<SByte> operator&(RValue<SByte> lhs, RValue<SByte> rhs)
512         {
513                 return RValue<SByte>(Nucleus::createAnd(lhs.value, rhs.value));
514         }
515
516         RValue<SByte> operator|(RValue<SByte> lhs, RValue<SByte> rhs)
517         {
518                 return RValue<SByte>(Nucleus::createOr(lhs.value, rhs.value));
519         }
520
521         RValue<SByte> operator^(RValue<SByte> lhs, RValue<SByte> rhs)
522         {
523                 return RValue<SByte>(Nucleus::createXor(lhs.value, rhs.value));
524         }
525
526         RValue<SByte> operator<<(RValue<SByte> lhs, RValue<SByte> rhs)
527         {
528                 return RValue<SByte>(Nucleus::createShl(lhs.value, rhs.value));
529         }
530
531         RValue<SByte> operator>>(RValue<SByte> lhs, RValue<SByte> rhs)
532         {
533                 return RValue<SByte>(Nucleus::createAShr(lhs.value, rhs.value));
534         }
535
536         RValue<SByte> operator+=(SByte &lhs, RValue<SByte> rhs)
537         {
538                 return lhs = lhs + rhs;
539         }
540
541         RValue<SByte> operator-=(SByte &lhs, RValue<SByte> rhs)
542         {
543                 return lhs = lhs - rhs;
544         }
545
546         RValue<SByte> operator*=(SByte &lhs, RValue<SByte> rhs)
547         {
548                 return lhs = lhs * rhs;
549         }
550
551         RValue<SByte> operator/=(SByte &lhs, RValue<SByte> rhs)
552         {
553                 return lhs = lhs / rhs;
554         }
555
556         RValue<SByte> operator%=(SByte &lhs, RValue<SByte> rhs)
557         {
558                 return lhs = lhs % rhs;
559         }
560
561         RValue<SByte> operator&=(SByte &lhs, RValue<SByte> rhs)
562         {
563                 return lhs = lhs & rhs;
564         }
565
566         RValue<SByte> operator|=(SByte &lhs, RValue<SByte> rhs)
567         {
568                 return lhs = lhs | rhs;
569         }
570
571         RValue<SByte> operator^=(SByte &lhs, RValue<SByte> rhs)
572         {
573                 return lhs = lhs ^ rhs;
574         }
575
576         RValue<SByte> operator<<=(SByte &lhs, RValue<SByte> rhs)
577         {
578                 return lhs = lhs << rhs;
579         }
580
581         RValue<SByte> operator>>=(SByte &lhs, RValue<SByte> rhs)
582         {
583                 return lhs = lhs >> rhs;
584         }
585
586         RValue<SByte> operator+(RValue<SByte> val)
587         {
588                 return val;
589         }
590
591         RValue<SByte> operator-(RValue<SByte> val)
592         {
593                 return RValue<SByte>(Nucleus::createNeg(val.value));
594         }
595
596         RValue<SByte> operator~(RValue<SByte> val)
597         {
598                 return RValue<SByte>(Nucleus::createNot(val.value));
599         }
600
601         RValue<SByte> operator++(SByte &val, int)   // Post-increment
602         {
603                 RValue<SByte> res = val;
604
605                 Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantByte((signed char)1));
606                 val.storeValue(inc);
607
608                 return res;
609         }
610
611         const SByte &operator++(SByte &val)   // Pre-increment
612         {
613                 Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantByte((signed char)1));
614                 val.storeValue(inc);
615
616                 return val;
617         }
618
619         RValue<SByte> operator--(SByte &val, int)   // Post-decrement
620         {
621                 RValue<SByte> res = val;
622
623                 Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantByte((signed char)1));
624                 val.storeValue(inc);
625
626                 return res;
627         }
628
629         const SByte &operator--(SByte &val)   // Pre-decrement
630         {
631                 Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantByte((signed char)1));
632                 val.storeValue(inc);
633
634                 return val;
635         }
636
637         RValue<Bool> operator<(RValue<SByte> lhs, RValue<SByte> rhs)
638         {
639                 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
640         }
641
642         RValue<Bool> operator<=(RValue<SByte> lhs, RValue<SByte> rhs)
643         {
644                 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
645         }
646
647         RValue<Bool> operator>(RValue<SByte> lhs, RValue<SByte> rhs)
648         {
649                 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
650         }
651
652         RValue<Bool> operator>=(RValue<SByte> lhs, RValue<SByte> rhs)
653         {
654                 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
655         }
656
657         RValue<Bool> operator!=(RValue<SByte> lhs, RValue<SByte> rhs)
658         {
659                 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
660         }
661
662         RValue<Bool> operator==(RValue<SByte> lhs, RValue<SByte> rhs)
663         {
664                 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
665         }
666
667         Short::Short(Argument<Short> argument)
668         {
669                 storeValue(argument.value);
670         }
671
672         Short::Short(RValue<Int> cast)
673         {
674                 Value *integer = Nucleus::createTrunc(cast.value, Short::getType());
675
676                 storeValue(integer);
677         }
678
679         Short::Short(short x)
680         {
681                 storeValue(Nucleus::createConstantShort(x));
682         }
683
684         Short::Short(RValue<Short> rhs)
685         {
686                 storeValue(rhs.value);
687         }
688
689         Short::Short(const Short &rhs)
690         {
691                 Value *value = rhs.loadValue();
692                 storeValue(value);
693         }
694
695         Short::Short(const Reference<Short> &rhs)
696         {
697                 Value *value = rhs.loadValue();
698                 storeValue(value);
699         }
700
701         RValue<Short> Short::operator=(RValue<Short> rhs)
702         {
703                 storeValue(rhs.value);
704
705                 return rhs;
706         }
707
708         RValue<Short> Short::operator=(const Short &rhs)
709         {
710                 Value *value = rhs.loadValue();
711                 storeValue(value);
712
713                 return RValue<Short>(value);
714         }
715
716         RValue<Short> Short::operator=(const Reference<Short> &rhs)
717         {
718                 Value *value = rhs.loadValue();
719                 storeValue(value);
720
721                 return RValue<Short>(value);
722         }
723
724         RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs)
725         {
726                 return RValue<Short>(Nucleus::createAdd(lhs.value, rhs.value));
727         }
728
729         RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs)
730         {
731                 return RValue<Short>(Nucleus::createSub(lhs.value, rhs.value));
732         }
733
734         RValue<Short> operator*(RValue<Short> lhs, RValue<Short> rhs)
735         {
736                 return RValue<Short>(Nucleus::createMul(lhs.value, rhs.value));
737         }
738
739         RValue<Short> operator/(RValue<Short> lhs, RValue<Short> rhs)
740         {
741                 return RValue<Short>(Nucleus::createSDiv(lhs.value, rhs.value));
742         }
743
744         RValue<Short> operator%(RValue<Short> lhs, RValue<Short> rhs)
745         {
746                 return RValue<Short>(Nucleus::createSRem(lhs.value, rhs.value));
747         }
748
749         RValue<Short> operator&(RValue<Short> lhs, RValue<Short> rhs)
750         {
751                 return RValue<Short>(Nucleus::createAnd(lhs.value, rhs.value));
752         }
753
754         RValue<Short> operator|(RValue<Short> lhs, RValue<Short> rhs)
755         {
756                 return RValue<Short>(Nucleus::createOr(lhs.value, rhs.value));
757         }
758
759         RValue<Short> operator^(RValue<Short> lhs, RValue<Short> rhs)
760         {
761                 return RValue<Short>(Nucleus::createXor(lhs.value, rhs.value));
762         }
763
764         RValue<Short> operator<<(RValue<Short> lhs, RValue<Short> rhs)
765         {
766                 return RValue<Short>(Nucleus::createShl(lhs.value, rhs.value));
767         }
768
769         RValue<Short> operator>>(RValue<Short> lhs, RValue<Short> rhs)
770         {
771                 return RValue<Short>(Nucleus::createAShr(lhs.value, rhs.value));
772         }
773
774         RValue<Short> operator+=(Short &lhs, RValue<Short> rhs)
775         {
776                 return lhs = lhs + rhs;
777         }
778
779         RValue<Short> operator-=(Short &lhs, RValue<Short> rhs)
780         {
781                 return lhs = lhs - rhs;
782         }
783
784         RValue<Short> operator*=(Short &lhs, RValue<Short> rhs)
785         {
786                 return lhs = lhs * rhs;
787         }
788
789         RValue<Short> operator/=(Short &lhs, RValue<Short> rhs)
790         {
791                 return lhs = lhs / rhs;
792         }
793
794         RValue<Short> operator%=(Short &lhs, RValue<Short> rhs)
795         {
796                 return lhs = lhs % rhs;
797         }
798
799         RValue<Short> operator&=(Short &lhs, RValue<Short> rhs)
800         {
801                 return lhs = lhs & rhs;
802         }
803
804         RValue<Short> operator|=(Short &lhs, RValue<Short> rhs)
805         {
806                 return lhs = lhs | rhs;
807         }
808
809         RValue<Short> operator^=(Short &lhs, RValue<Short> rhs)
810         {
811                 return lhs = lhs ^ rhs;
812         }
813
814         RValue<Short> operator<<=(Short &lhs, RValue<Short> rhs)
815         {
816                 return lhs = lhs << rhs;
817         }
818
819         RValue<Short> operator>>=(Short &lhs, RValue<Short> rhs)
820         {
821                 return lhs = lhs >> rhs;
822         }
823
824         RValue<Short> operator+(RValue<Short> val)
825         {
826                 return val;
827         }
828
829         RValue<Short> operator-(RValue<Short> val)
830         {
831                 return RValue<Short>(Nucleus::createNeg(val.value));
832         }
833
834         RValue<Short> operator~(RValue<Short> val)
835         {
836                 return RValue<Short>(Nucleus::createNot(val.value));
837         }
838
839         RValue<Short> operator++(Short &val, int)   // Post-increment
840         {
841                 RValue<Short> res = val;
842
843                 Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantShort((short)1));
844                 val.storeValue(inc);
845
846                 return res;
847         }
848
849         const Short &operator++(Short &val)   // Pre-increment
850         {
851                 Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantShort((short)1));
852                 val.storeValue(inc);
853
854                 return val;
855         }
856
857         RValue<Short> operator--(Short &val, int)   // Post-decrement
858         {
859                 RValue<Short> res = val;
860
861                 Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantShort((short)1));
862                 val.storeValue(inc);
863
864                 return res;
865         }
866
867         const Short &operator--(Short &val)   // Pre-decrement
868         {
869                 Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantShort((short)1));
870                 val.storeValue(inc);
871
872                 return val;
873         }
874
875         RValue<Bool> operator<(RValue<Short> lhs, RValue<Short> rhs)
876         {
877                 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
878         }
879
880         RValue<Bool> operator<=(RValue<Short> lhs, RValue<Short> rhs)
881         {
882                 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
883         }
884
885         RValue<Bool> operator>(RValue<Short> lhs, RValue<Short> rhs)
886         {
887                 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
888         }
889
890         RValue<Bool> operator>=(RValue<Short> lhs, RValue<Short> rhs)
891         {
892                 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
893         }
894
895         RValue<Bool> operator!=(RValue<Short> lhs, RValue<Short> rhs)
896         {
897                 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
898         }
899
900         RValue<Bool> operator==(RValue<Short> lhs, RValue<Short> rhs)
901         {
902                 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
903         }
904
905         UShort::UShort(Argument<UShort> argument)
906         {
907                 storeValue(argument.value);
908         }
909
910         UShort::UShort(RValue<UInt> cast)
911         {
912                 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
913
914                 storeValue(integer);
915         }
916
917         UShort::UShort(RValue<Int> cast)
918         {
919                 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
920
921                 storeValue(integer);
922         }
923
924         UShort::UShort(unsigned short x)
925         {
926                 storeValue(Nucleus::createConstantShort(x));
927         }
928
929         UShort::UShort(RValue<UShort> rhs)
930         {
931                 storeValue(rhs.value);
932         }
933
934         UShort::UShort(const UShort &rhs)
935         {
936                 Value *value = rhs.loadValue();
937                 storeValue(value);
938         }
939
940         UShort::UShort(const Reference<UShort> &rhs)
941         {
942                 Value *value = rhs.loadValue();
943                 storeValue(value);
944         }
945
946         RValue<UShort> UShort::operator=(RValue<UShort> rhs)
947         {
948                 storeValue(rhs.value);
949
950                 return rhs;
951         }
952
953         RValue<UShort> UShort::operator=(const UShort &rhs)
954         {
955                 Value *value = rhs.loadValue();
956                 storeValue(value);
957
958                 return RValue<UShort>(value);
959         }
960
961         RValue<UShort> UShort::operator=(const Reference<UShort> &rhs)
962         {
963                 Value *value = rhs.loadValue();
964                 storeValue(value);
965
966                 return RValue<UShort>(value);
967         }
968
969         RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs)
970         {
971                 return RValue<UShort>(Nucleus::createAdd(lhs.value, rhs.value));
972         }
973
974         RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs)
975         {
976                 return RValue<UShort>(Nucleus::createSub(lhs.value, rhs.value));
977         }
978
979         RValue<UShort> operator*(RValue<UShort> lhs, RValue<UShort> rhs)
980         {
981                 return RValue<UShort>(Nucleus::createMul(lhs.value, rhs.value));
982         }
983
984         RValue<UShort> operator/(RValue<UShort> lhs, RValue<UShort> rhs)
985         {
986                 return RValue<UShort>(Nucleus::createUDiv(lhs.value, rhs.value));
987         }
988
989         RValue<UShort> operator%(RValue<UShort> lhs, RValue<UShort> rhs)
990         {
991                 return RValue<UShort>(Nucleus::createURem(lhs.value, rhs.value));
992         }
993
994         RValue<UShort> operator&(RValue<UShort> lhs, RValue<UShort> rhs)
995         {
996                 return RValue<UShort>(Nucleus::createAnd(lhs.value, rhs.value));
997         }
998
999         RValue<UShort> operator|(RValue<UShort> lhs, RValue<UShort> rhs)
1000         {
1001                 return RValue<UShort>(Nucleus::createOr(lhs.value, rhs.value));
1002         }
1003
1004         RValue<UShort> operator^(RValue<UShort> lhs, RValue<UShort> rhs)
1005         {
1006                 return RValue<UShort>(Nucleus::createXor(lhs.value, rhs.value));
1007         }
1008
1009         RValue<UShort> operator<<(RValue<UShort> lhs, RValue<UShort> rhs)
1010         {
1011                 return RValue<UShort>(Nucleus::createShl(lhs.value, rhs.value));
1012         }
1013
1014         RValue<UShort> operator>>(RValue<UShort> lhs, RValue<UShort> rhs)
1015         {
1016                 return RValue<UShort>(Nucleus::createLShr(lhs.value, rhs.value));
1017         }
1018
1019         RValue<UShort> operator+=(UShort &lhs, RValue<UShort> rhs)
1020         {
1021                 return lhs = lhs + rhs;
1022         }
1023
1024         RValue<UShort> operator-=(UShort &lhs, RValue<UShort> rhs)
1025         {
1026                 return lhs = lhs - rhs;
1027         }
1028
1029         RValue<UShort> operator*=(UShort &lhs, RValue<UShort> rhs)
1030         {
1031                 return lhs = lhs * rhs;
1032         }
1033
1034         RValue<UShort> operator/=(UShort &lhs, RValue<UShort> rhs)
1035         {
1036                 return lhs = lhs / rhs;
1037         }
1038
1039         RValue<UShort> operator%=(UShort &lhs, RValue<UShort> rhs)
1040         {
1041                 return lhs = lhs % rhs;
1042         }
1043
1044         RValue<UShort> operator&=(UShort &lhs, RValue<UShort> rhs)
1045         {
1046                 return lhs = lhs & rhs;
1047         }
1048
1049         RValue<UShort> operator|=(UShort &lhs, RValue<UShort> rhs)
1050         {
1051                 return lhs = lhs | rhs;
1052         }
1053
1054         RValue<UShort> operator^=(UShort &lhs, RValue<UShort> rhs)
1055         {
1056                 return lhs = lhs ^ rhs;
1057         }
1058
1059         RValue<UShort> operator<<=(UShort &lhs, RValue<UShort> rhs)
1060         {
1061                 return lhs = lhs << rhs;
1062         }
1063
1064         RValue<UShort> operator>>=(UShort &lhs, RValue<UShort> rhs)
1065         {
1066                 return lhs = lhs >> rhs;
1067         }
1068
1069         RValue<UShort> operator+(RValue<UShort> val)
1070         {
1071                 return val;
1072         }
1073
1074         RValue<UShort> operator-(RValue<UShort> val)
1075         {
1076                 return RValue<UShort>(Nucleus::createNeg(val.value));
1077         }
1078
1079         RValue<UShort> operator~(RValue<UShort> val)
1080         {
1081                 return RValue<UShort>(Nucleus::createNot(val.value));
1082         }
1083
1084         RValue<UShort> operator++(UShort &val, int)   // Post-increment
1085         {
1086                 RValue<UShort> res = val;
1087
1088                 Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantShort((unsigned short)1));
1089                 val.storeValue(inc);
1090
1091                 return res;
1092         }
1093
1094         const UShort &operator++(UShort &val)   // Pre-increment
1095         {
1096                 Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantShort((unsigned short)1));
1097                 val.storeValue(inc);
1098
1099                 return val;
1100         }
1101
1102         RValue<UShort> operator--(UShort &val, int)   // Post-decrement
1103         {
1104                 RValue<UShort> res = val;
1105
1106                 Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantShort((unsigned short)1));
1107                 val.storeValue(inc);
1108
1109                 return res;
1110         }
1111
1112         const UShort &operator--(UShort &val)   // Pre-decrement
1113         {
1114                 Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantShort((unsigned short)1));
1115                 val.storeValue(inc);
1116
1117                 return val;
1118         }
1119
1120         RValue<Bool> operator<(RValue<UShort> lhs, RValue<UShort> rhs)
1121         {
1122                 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1123         }
1124
1125         RValue<Bool> operator<=(RValue<UShort> lhs, RValue<UShort> rhs)
1126         {
1127                 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1128         }
1129
1130         RValue<Bool> operator>(RValue<UShort> lhs, RValue<UShort> rhs)
1131         {
1132                 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1133         }
1134
1135         RValue<Bool> operator>=(RValue<UShort> lhs, RValue<UShort> rhs)
1136         {
1137                 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1138         }
1139
1140         RValue<Bool> operator!=(RValue<UShort> lhs, RValue<UShort> rhs)
1141         {
1142                 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1143         }
1144
1145         RValue<Bool> operator==(RValue<UShort> lhs, RValue<UShort> rhs)
1146         {
1147                 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1148         }
1149
1150         Byte4::Byte4(RValue<Byte8> cast)
1151         {
1152                 storeValue(Nucleus::createBitCast(cast.value, getType()));
1153         }
1154
1155         Byte4::Byte4(const Reference<Byte4> &rhs)
1156         {
1157                 Value *value = rhs.loadValue();
1158                 storeValue(value);
1159         }
1160
1161         Byte8::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)
1162         {
1163                 int64_t constantVector[8] = {x0, x1, x2, x3, x4, x5, x6, x7};
1164                 storeValue(Nucleus::createConstantVector(constantVector, getType()));
1165         }
1166
1167         Byte8::Byte8(RValue<Byte8> rhs)
1168         {
1169                 storeValue(rhs.value);
1170         }
1171
1172         Byte8::Byte8(const Byte8 &rhs)
1173         {
1174                 Value *value = rhs.loadValue();
1175                 storeValue(value);
1176         }
1177
1178         Byte8::Byte8(const Reference<Byte8> &rhs)
1179         {
1180                 Value *value = rhs.loadValue();
1181                 storeValue(value);
1182         }
1183
1184         RValue<Byte8> Byte8::operator=(RValue<Byte8> rhs)
1185         {
1186                 storeValue(rhs.value);
1187
1188                 return rhs;
1189         }
1190
1191         RValue<Byte8> Byte8::operator=(const Byte8 &rhs)
1192         {
1193                 Value *value = rhs.loadValue();
1194                 storeValue(value);
1195
1196                 return RValue<Byte8>(value);
1197         }
1198
1199         RValue<Byte8> Byte8::operator=(const Reference<Byte8> &rhs)
1200         {
1201                 Value *value = rhs.loadValue();
1202                 storeValue(value);
1203
1204                 return RValue<Byte8>(value);
1205         }
1206
1207         RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs)
1208         {
1209                 return RValue<Byte8>(Nucleus::createAdd(lhs.value, rhs.value));
1210         }
1211
1212         RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs)
1213         {
1214                 return RValue<Byte8>(Nucleus::createSub(lhs.value, rhs.value));
1215         }
1216
1217 //      RValue<Byte8> operator*(RValue<Byte8> lhs, RValue<Byte8> rhs)
1218 //      {
1219 //              return RValue<Byte8>(Nucleus::createMul(lhs.value, rhs.value));
1220 //      }
1221
1222 //      RValue<Byte8> operator/(RValue<Byte8> lhs, RValue<Byte8> rhs)
1223 //      {
1224 //              return RValue<Byte8>(Nucleus::createUDiv(lhs.value, rhs.value));
1225 //      }
1226
1227 //      RValue<Byte8> operator%(RValue<Byte8> lhs, RValue<Byte8> rhs)
1228 //      {
1229 //              return RValue<Byte8>(Nucleus::createURem(lhs.value, rhs.value));
1230 //      }
1231
1232         RValue<Byte8> operator&(RValue<Byte8> lhs, RValue<Byte8> rhs)
1233         {
1234                 return RValue<Byte8>(Nucleus::createAnd(lhs.value, rhs.value));
1235         }
1236
1237         RValue<Byte8> operator|(RValue<Byte8> lhs, RValue<Byte8> rhs)
1238         {
1239                 return RValue<Byte8>(Nucleus::createOr(lhs.value, rhs.value));
1240         }
1241
1242         RValue<Byte8> operator^(RValue<Byte8> lhs, RValue<Byte8> rhs)
1243         {
1244                 return RValue<Byte8>(Nucleus::createXor(lhs.value, rhs.value));
1245         }
1246
1247 //      RValue<Byte8> operator<<(RValue<Byte8> lhs, unsigned char rhs)
1248 //      {
1249 //              return RValue<Byte8>(Nucleus::createShl(lhs.value, rhs.value));
1250 //      }
1251
1252 //      RValue<Byte8> operator>>(RValue<Byte8> lhs, unsigned char rhs)
1253 //      {
1254 //              return RValue<Byte8>(Nucleus::createLShr(lhs.value, rhs.value));
1255 //      }
1256
1257         RValue<Byte8> operator+=(Byte8 &lhs, RValue<Byte8> rhs)
1258         {
1259                 return lhs = lhs + rhs;
1260         }
1261
1262         RValue<Byte8> operator-=(Byte8 &lhs, RValue<Byte8> rhs)
1263         {
1264                 return lhs = lhs - rhs;
1265         }
1266
1267 //      RValue<Byte8> operator*=(Byte8 &lhs, RValue<Byte8> rhs)
1268 //      {
1269 //              return lhs = lhs * rhs;
1270 //      }
1271
1272 //      RValue<Byte8> operator/=(Byte8 &lhs, RValue<Byte8> rhs)
1273 //      {
1274 //              return lhs = lhs / rhs;
1275 //      }
1276
1277 //      RValue<Byte8> operator%=(Byte8 &lhs, RValue<Byte8> rhs)
1278 //      {
1279 //              return lhs = lhs % rhs;
1280 //      }
1281
1282         RValue<Byte8> operator&=(Byte8 &lhs, RValue<Byte8> rhs)
1283         {
1284                 return lhs = lhs & rhs;
1285         }
1286
1287         RValue<Byte8> operator|=(Byte8 &lhs, RValue<Byte8> rhs)
1288         {
1289                 return lhs = lhs | rhs;
1290         }
1291
1292         RValue<Byte8> operator^=(Byte8 &lhs, RValue<Byte8> rhs)
1293         {
1294                 return lhs = lhs ^ rhs;
1295         }
1296
1297 //      RValue<Byte8> operator<<=(Byte8 &lhs, RValue<Byte8> rhs)
1298 //      {
1299 //              return lhs = lhs << rhs;
1300 //      }
1301
1302 //      RValue<Byte8> operator>>=(Byte8 &lhs, RValue<Byte8> rhs)
1303 //      {
1304 //              return lhs = lhs >> rhs;
1305 //      }
1306
1307 //      RValue<Byte8> operator+(RValue<Byte8> val)
1308 //      {
1309 //              return val;
1310 //      }
1311
1312 //      RValue<Byte8> operator-(RValue<Byte8> val)
1313 //      {
1314 //              return RValue<Byte8>(Nucleus::createNeg(val.value));
1315 //      }
1316
1317         RValue<Byte8> operator~(RValue<Byte8> val)
1318         {
1319                 return RValue<Byte8>(Nucleus::createNot(val.value));
1320         }
1321
1322         RValue<Short4> Unpack(RValue<Byte4> x)
1323         {
1324                 int shuffle[16] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7};   // Real type is v16i8
1325                 return As<Short4>(Nucleus::createShuffleVector(x.value, x.value, shuffle));
1326         }
1327
1328         RValue<Short4> Unpack(RValue<Byte4> x, RValue<Byte4> y)
1329         {
1330                 return UnpackLow(As<Byte8>(x), As<Byte8>(y));
1331         }
1332
1333         RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y)
1334         {
1335                 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23};   // Real type is v16i8
1336                 return As<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
1337         }
1338
1339         RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y)
1340         {
1341                 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23};   // Real type is v16i8
1342                 auto lowHigh = RValue<Byte16>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
1343                 return As<Short4>(Swizzle(As<Int4>(lowHigh), 0xEE));
1344         }
1345
1346         SByte8::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)
1347         {
1348                 int64_t constantVector[8] = {x0, x1, x2, x3, x4, x5, x6, x7};
1349                 Value *vector = Nucleus::createConstantVector(constantVector, getType());
1350
1351                 storeValue(Nucleus::createBitCast(vector, getType()));
1352         }
1353
1354         SByte8::SByte8(RValue<SByte8> rhs)
1355         {
1356                 storeValue(rhs.value);
1357         }
1358
1359         SByte8::SByte8(const SByte8 &rhs)
1360         {
1361                 Value *value = rhs.loadValue();
1362                 storeValue(value);
1363         }
1364
1365         SByte8::SByte8(const Reference<SByte8> &rhs)
1366         {
1367                 Value *value = rhs.loadValue();
1368                 storeValue(value);
1369         }
1370
1371         RValue<SByte8> SByte8::operator=(RValue<SByte8> rhs)
1372         {
1373                 storeValue(rhs.value);
1374
1375                 return rhs;
1376         }
1377
1378         RValue<SByte8> SByte8::operator=(const SByte8 &rhs)
1379         {
1380                 Value *value = rhs.loadValue();
1381                 storeValue(value);
1382
1383                 return RValue<SByte8>(value);
1384         }
1385
1386         RValue<SByte8> SByte8::operator=(const Reference<SByte8> &rhs)
1387         {
1388                 Value *value = rhs.loadValue();
1389                 storeValue(value);
1390
1391                 return RValue<SByte8>(value);
1392         }
1393
1394         RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs)
1395         {
1396                 return RValue<SByte8>(Nucleus::createAdd(lhs.value, rhs.value));
1397         }
1398
1399         RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs)
1400         {
1401                 return RValue<SByte8>(Nucleus::createSub(lhs.value, rhs.value));
1402         }
1403
1404 //      RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs)
1405 //      {
1406 //              return RValue<SByte8>(Nucleus::createMul(lhs.value, rhs.value));
1407 //      }
1408
1409 //      RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs)
1410 //      {
1411 //              return RValue<SByte8>(Nucleus::createSDiv(lhs.value, rhs.value));
1412 //      }
1413
1414 //      RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs)
1415 //      {
1416 //              return RValue<SByte8>(Nucleus::createSRem(lhs.value, rhs.value));
1417 //      }
1418
1419         RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs)
1420         {
1421                 return RValue<SByte8>(Nucleus::createAnd(lhs.value, rhs.value));
1422         }
1423
1424         RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs)
1425         {
1426                 return RValue<SByte8>(Nucleus::createOr(lhs.value, rhs.value));
1427         }
1428
1429         RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs)
1430         {
1431                 return RValue<SByte8>(Nucleus::createXor(lhs.value, rhs.value));
1432         }
1433
1434 //      RValue<SByte8> operator<<(RValue<SByte8> lhs, unsigned char rhs)
1435 //      {
1436 //              return RValue<SByte8>(Nucleus::createShl(lhs.value, rhs.value));
1437 //      }
1438
1439 //      RValue<SByte8> operator>>(RValue<SByte8> lhs, unsigned char rhs)
1440 //      {
1441 //              return RValue<SByte8>(Nucleus::createAShr(lhs.value, rhs.value));
1442 //      }
1443
1444         RValue<SByte8> operator+=(SByte8 &lhs, RValue<SByte8> rhs)
1445         {
1446                 return lhs = lhs + rhs;
1447         }
1448
1449         RValue<SByte8> operator-=(SByte8 &lhs, RValue<SByte8> rhs)
1450         {
1451                 return lhs = lhs - rhs;
1452         }
1453
1454 //      RValue<SByte8> operator*=(SByte8 &lhs, RValue<SByte8> rhs)
1455 //      {
1456 //              return lhs = lhs * rhs;
1457 //      }
1458
1459 //      RValue<SByte8> operator/=(SByte8 &lhs, RValue<SByte8> rhs)
1460 //      {
1461 //              return lhs = lhs / rhs;
1462 //      }
1463
1464 //      RValue<SByte8> operator%=(SByte8 &lhs, RValue<SByte8> rhs)
1465 //      {
1466 //              return lhs = lhs % rhs;
1467 //      }
1468
1469         RValue<SByte8> operator&=(SByte8 &lhs, RValue<SByte8> rhs)
1470         {
1471                 return lhs = lhs & rhs;
1472         }
1473
1474         RValue<SByte8> operator|=(SByte8 &lhs, RValue<SByte8> rhs)
1475         {
1476                 return lhs = lhs | rhs;
1477         }
1478
1479         RValue<SByte8> operator^=(SByte8 &lhs, RValue<SByte8> rhs)
1480         {
1481                 return lhs = lhs ^ rhs;
1482         }
1483
1484 //      RValue<SByte8> operator<<=(SByte8 &lhs, RValue<SByte8> rhs)
1485 //      {
1486 //              return lhs = lhs << rhs;
1487 //      }
1488
1489 //      RValue<SByte8> operator>>=(SByte8 &lhs, RValue<SByte8> rhs)
1490 //      {
1491 //              return lhs = lhs >> rhs;
1492 //      }
1493
1494 //      RValue<SByte8> operator+(RValue<SByte8> val)
1495 //      {
1496 //              return val;
1497 //      }
1498
1499 //      RValue<SByte8> operator-(RValue<SByte8> val)
1500 //      {
1501 //              return RValue<SByte8>(Nucleus::createNeg(val.value));
1502 //      }
1503
1504         RValue<SByte8> operator~(RValue<SByte8> val)
1505         {
1506                 return RValue<SByte8>(Nucleus::createNot(val.value));
1507         }
1508
1509         RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y)
1510         {
1511                 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23};   // Real type is v16i8
1512                 return As<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
1513         }
1514
1515         RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y)
1516         {
1517                 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23};   // Real type is v16i8
1518                 auto lowHigh = RValue<Byte16>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
1519                 return As<Short4>(Swizzle(As<Int4>(lowHigh), 0xEE));
1520         }
1521
1522         Byte16::Byte16(RValue<Byte16> rhs)
1523         {
1524                 storeValue(rhs.value);
1525         }
1526
1527         Byte16::Byte16(const Byte16 &rhs)
1528         {
1529                 Value *value = rhs.loadValue();
1530                 storeValue(value);
1531         }
1532
1533         Byte16::Byte16(const Reference<Byte16> &rhs)
1534         {
1535                 Value *value = rhs.loadValue();
1536                 storeValue(value);
1537         }
1538
1539         RValue<Byte16> Byte16::operator=(RValue<Byte16> rhs)
1540         {
1541                 storeValue(rhs.value);
1542
1543                 return rhs;
1544         }
1545
1546         RValue<Byte16> Byte16::operator=(const Byte16 &rhs)
1547         {
1548                 Value *value = rhs.loadValue();
1549                 storeValue(value);
1550
1551                 return RValue<Byte16>(value);
1552         }
1553
1554         RValue<Byte16> Byte16::operator=(const Reference<Byte16> &rhs)
1555         {
1556                 Value *value = rhs.loadValue();
1557                 storeValue(value);
1558
1559                 return RValue<Byte16>(value);
1560         }
1561
1562         Short2::Short2(RValue<Short4> cast)
1563         {
1564                 storeValue(Nucleus::createBitCast(cast.value, getType()));
1565         }
1566
1567         UShort2::UShort2(RValue<UShort4> cast)
1568         {
1569                 storeValue(Nucleus::createBitCast(cast.value, getType()));
1570         }
1571
1572         Short4::Short4(RValue<Int> cast)
1573         {
1574                 Value *vector = loadValue();
1575                 Value *element = Nucleus::createTrunc(cast.value, Short::getType());
1576                 Value *insert = Nucleus::createInsertElement(vector, element, 0);
1577                 Value *swizzle = Swizzle(RValue<Short4>(insert), 0x00).value;
1578
1579                 storeValue(swizzle);
1580         }
1581
1582 //      Short4::Short4(RValue<Float> cast)
1583 //      {
1584 //      }
1585
1586         Short4::Short4(short xyzw)
1587         {
1588                 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
1589                 storeValue(Nucleus::createConstantVector(constantVector, getType()));
1590         }
1591
1592         Short4::Short4(short x, short y, short z, short w)
1593         {
1594                 int64_t constantVector[4] = {x, y, z, w};
1595                 storeValue(Nucleus::createConstantVector(constantVector, getType()));
1596         }
1597
1598         Short4::Short4(RValue<Short4> rhs)
1599         {
1600                 storeValue(rhs.value);
1601         }
1602
1603         Short4::Short4(const Short4 &rhs)
1604         {
1605                 Value *value = rhs.loadValue();
1606                 storeValue(value);
1607         }
1608
1609         Short4::Short4(const Reference<Short4> &rhs)
1610         {
1611                 Value *value = rhs.loadValue();
1612                 storeValue(value);
1613         }
1614
1615         Short4::Short4(RValue<UShort4> rhs)
1616         {
1617                 storeValue(rhs.value);
1618         }
1619
1620         Short4::Short4(const UShort4 &rhs)
1621         {
1622                 storeValue(rhs.loadValue());
1623         }
1624
1625         Short4::Short4(const Reference<UShort4> &rhs)
1626         {
1627                 storeValue(rhs.loadValue());
1628         }
1629
1630         RValue<Short4> Short4::operator=(RValue<Short4> rhs)
1631         {
1632                 storeValue(rhs.value);
1633
1634                 return rhs;
1635         }
1636
1637         RValue<Short4> Short4::operator=(const Short4 &rhs)
1638         {
1639                 Value *value = rhs.loadValue();
1640                 storeValue(value);
1641
1642                 return RValue<Short4>(value);
1643         }
1644
1645         RValue<Short4> Short4::operator=(const Reference<Short4> &rhs)
1646         {
1647                 Value *value = rhs.loadValue();
1648                 storeValue(value);
1649
1650                 return RValue<Short4>(value);
1651         }
1652
1653         RValue<Short4> Short4::operator=(RValue<UShort4> rhs)
1654         {
1655                 storeValue(rhs.value);
1656
1657                 return RValue<Short4>(rhs);
1658         }
1659
1660         RValue<Short4> Short4::operator=(const UShort4 &rhs)
1661         {
1662                 Value *value = rhs.loadValue();
1663                 storeValue(value);
1664
1665                 return RValue<Short4>(value);
1666         }
1667
1668         RValue<Short4> Short4::operator=(const Reference<UShort4> &rhs)
1669         {
1670                 Value *value = rhs.loadValue();
1671                 storeValue(value);
1672
1673                 return RValue<Short4>(value);
1674         }
1675
1676         RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs)
1677         {
1678                 return RValue<Short4>(Nucleus::createAdd(lhs.value, rhs.value));
1679         }
1680
1681         RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs)
1682         {
1683                 return RValue<Short4>(Nucleus::createSub(lhs.value, rhs.value));
1684         }
1685
1686         RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs)
1687         {
1688                 return RValue<Short4>(Nucleus::createMul(lhs.value, rhs.value));
1689         }
1690
1691 //      RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs)
1692 //      {
1693 //              return RValue<Short4>(Nucleus::createSDiv(lhs.value, rhs.value));
1694 //      }
1695
1696 //      RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs)
1697 //      {
1698 //              return RValue<Short4>(Nucleus::createSRem(lhs.value, rhs.value));
1699 //      }
1700
1701         RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs)
1702         {
1703                 return RValue<Short4>(Nucleus::createAnd(lhs.value, rhs.value));
1704         }
1705
1706         RValue<Short4> operator|(RValue<Short4> lhs, RValue<Short4> rhs)
1707         {
1708                 return RValue<Short4>(Nucleus::createOr(lhs.value, rhs.value));
1709         }
1710
1711         RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs)
1712         {
1713                 return RValue<Short4>(Nucleus::createXor(lhs.value, rhs.value));
1714         }
1715
1716         RValue<Short4> operator+=(Short4 &lhs, RValue<Short4> rhs)
1717         {
1718                 return lhs = lhs + rhs;
1719         }
1720
1721         RValue<Short4> operator-=(Short4 &lhs, RValue<Short4> rhs)
1722         {
1723                 return lhs = lhs - rhs;
1724         }
1725
1726         RValue<Short4> operator*=(Short4 &lhs, RValue<Short4> rhs)
1727         {
1728                 return lhs = lhs * rhs;
1729         }
1730
1731 //      RValue<Short4> operator/=(Short4 &lhs, RValue<Short4> rhs)
1732 //      {
1733 //              return lhs = lhs / rhs;
1734 //      }
1735
1736 //      RValue<Short4> operator%=(Short4 &lhs, RValue<Short4> rhs)
1737 //      {
1738 //              return lhs = lhs % rhs;
1739 //      }
1740
1741         RValue<Short4> operator&=(Short4 &lhs, RValue<Short4> rhs)
1742         {
1743                 return lhs = lhs & rhs;
1744         }
1745
1746         RValue<Short4> operator|=(Short4 &lhs, RValue<Short4> rhs)
1747         {
1748                 return lhs = lhs | rhs;
1749         }
1750
1751         RValue<Short4> operator^=(Short4 &lhs, RValue<Short4> rhs)
1752         {
1753                 return lhs = lhs ^ rhs;
1754         }
1755
1756         RValue<Short4> operator<<=(Short4 &lhs, unsigned char rhs)
1757         {
1758                 return lhs = lhs << rhs;
1759         }
1760
1761         RValue<Short4> operator>>=(Short4 &lhs, unsigned char rhs)
1762         {
1763                 return lhs = lhs >> rhs;
1764         }
1765
1766 //      RValue<Short4> operator+(RValue<Short4> val)
1767 //      {
1768 //              return val;
1769 //      }
1770
1771         RValue<Short4> operator-(RValue<Short4> val)
1772         {
1773                 return RValue<Short4>(Nucleus::createNeg(val.value));
1774         }
1775
1776         RValue<Short4> operator~(RValue<Short4> val)
1777         {
1778                 return RValue<Short4>(Nucleus::createNot(val.value));
1779         }
1780
1781         RValue<Short4> RoundShort4(RValue<Float4> cast)
1782         {
1783                 RValue<Int4> int4 = RoundInt(cast);
1784                 return As<Short4>(PackSigned(int4, int4));
1785         }
1786
1787         RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y)
1788         {
1789                 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11};   // Real type is v8i16
1790                 return As<Int2>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
1791         }
1792
1793         RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y)
1794         {
1795                 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11};   // Real type is v8i16
1796                 auto lowHigh = RValue<Short8>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
1797                 return As<Int2>(Swizzle(As<Int4>(lowHigh), 0xEE));
1798         }
1799
1800         RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select)
1801         {
1802                 // Real type is v8i16
1803                 int shuffle[8] =
1804                 {
1805                         (select >> 0) & 0x03,
1806                         (select >> 2) & 0x03,
1807                         (select >> 4) & 0x03,
1808                         (select >> 6) & 0x03,
1809                         (select >> 0) & 0x03,
1810                         (select >> 2) & 0x03,
1811                         (select >> 4) & 0x03,
1812                         (select >> 6) & 0x03,
1813                 };
1814
1815                 return As<Short4>(Nucleus::createShuffleVector(x.value, x.value, shuffle));
1816         }
1817
1818         RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i)
1819         {
1820                 return RValue<Short4>(Nucleus::createInsertElement(val.value, element.value, i));
1821         }
1822
1823         RValue<Short> Extract(RValue<Short4> val, int i)
1824         {
1825                 return RValue<Short>(Nucleus::createExtractElement(val.value, Short::getType(), i));
1826         }
1827
1828         UShort4::UShort4(RValue<Int4> cast)
1829         {
1830                 *this = Short4(cast);
1831         }
1832
1833         UShort4::UShort4(unsigned short xyzw)
1834         {
1835                 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
1836                 storeValue(Nucleus::createConstantVector(constantVector, getType()));
1837         }
1838
1839         UShort4::UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w)
1840         {
1841                 int64_t constantVector[4] = {x, y, z, w};
1842                 storeValue(Nucleus::createConstantVector(constantVector, getType()));
1843         }
1844
1845         UShort4::UShort4(RValue<UShort4> rhs)
1846         {
1847                 storeValue(rhs.value);
1848         }
1849
1850         UShort4::UShort4(const UShort4 &rhs)
1851         {
1852                 Value *value = rhs.loadValue();
1853                 storeValue(value);
1854         }
1855
1856         UShort4::UShort4(const Reference<UShort4> &rhs)
1857         {
1858                 Value *value = rhs.loadValue();
1859                 storeValue(value);
1860         }
1861
1862         UShort4::UShort4(RValue<Short4> rhs)
1863         {
1864                 storeValue(rhs.value);
1865         }
1866
1867         UShort4::UShort4(const Short4 &rhs)
1868         {
1869                 Value *value = rhs.loadValue();
1870                 storeValue(value);
1871         }
1872
1873         UShort4::UShort4(const Reference<Short4> &rhs)
1874         {
1875                 Value *value = rhs.loadValue();
1876                 storeValue(value);
1877         }
1878
1879         RValue<UShort4> UShort4::operator=(RValue<UShort4> rhs)
1880         {
1881                 storeValue(rhs.value);
1882
1883                 return rhs;
1884         }
1885
1886         RValue<UShort4> UShort4::operator=(const UShort4 &rhs)
1887         {
1888                 Value *value = rhs.loadValue();
1889                 storeValue(value);
1890
1891                 return RValue<UShort4>(value);
1892         }
1893
1894         RValue<UShort4> UShort4::operator=(const Reference<UShort4> &rhs)
1895         {
1896                 Value *value = rhs.loadValue();
1897                 storeValue(value);
1898
1899                 return RValue<UShort4>(value);
1900         }
1901
1902         RValue<UShort4> UShort4::operator=(RValue<Short4> rhs)
1903         {
1904                 storeValue(rhs.value);
1905
1906                 return RValue<UShort4>(rhs);
1907         }
1908
1909         RValue<UShort4> UShort4::operator=(const Short4 &rhs)
1910         {
1911                 Value *value = rhs.loadValue();
1912                 storeValue(value);
1913
1914                 return RValue<UShort4>(value);
1915         }
1916
1917         RValue<UShort4> UShort4::operator=(const Reference<Short4> &rhs)
1918         {
1919                 Value *value = rhs.loadValue();
1920                 storeValue(value);
1921
1922                 return RValue<UShort4>(value);
1923         }
1924
1925         RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs)
1926         {
1927                 return RValue<UShort4>(Nucleus::createAdd(lhs.value, rhs.value));
1928         }
1929
1930         RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs)
1931         {
1932                 return RValue<UShort4>(Nucleus::createSub(lhs.value, rhs.value));
1933         }
1934
1935         RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs)
1936         {
1937                 return RValue<UShort4>(Nucleus::createMul(lhs.value, rhs.value));
1938         }
1939
1940         RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs)
1941         {
1942                 return RValue<UShort4>(Nucleus::createAnd(lhs.value, rhs.value));
1943         }
1944
1945         RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs)
1946         {
1947                 return RValue<UShort4>(Nucleus::createOr(lhs.value, rhs.value));
1948         }
1949
1950         RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs)
1951         {
1952                 return RValue<UShort4>(Nucleus::createXor(lhs.value, rhs.value));
1953         }
1954
1955         RValue<UShort4> operator<<=(UShort4 &lhs, unsigned char rhs)
1956         {
1957                 return lhs = lhs << rhs;
1958         }
1959
1960         RValue<UShort4> operator>>=(UShort4 &lhs, unsigned char rhs)
1961         {
1962                 return lhs = lhs >> rhs;
1963         }
1964
1965         RValue<UShort4> operator~(RValue<UShort4> val)
1966         {
1967                 return RValue<UShort4>(Nucleus::createNot(val.value));
1968         }
1969
1970         Short8::Short8(short c)
1971         {
1972                 int64_t constantVector[8] = {c, c, c, c, c, c, c, c};
1973                 storeValue(Nucleus::createConstantVector(constantVector, getType()));
1974         }
1975
1976         Short8::Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7)
1977         {
1978                 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
1979                 storeValue(Nucleus::createConstantVector(constantVector, getType()));
1980         }
1981
1982         Short8::Short8(RValue<Short8> rhs)
1983         {
1984                 storeValue(rhs.value);
1985         }
1986
1987         Short8::Short8(const Reference<Short8> &rhs)
1988         {
1989                 Value *value = rhs.loadValue();
1990                 storeValue(value);
1991         }
1992
1993         Short8::Short8(RValue<Short4> lo, RValue<Short4> hi)
1994         {
1995                 int shuffle[8] = {0, 1, 2, 3, 8, 9, 10, 11};   // Real type is v8i16
1996                 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
1997
1998                 storeValue(packed);
1999         }
2000
2001         RValue<Short8> Short8::operator=(RValue<Short8> rhs)
2002         {
2003                 storeValue(rhs.value);
2004
2005                 return rhs;
2006         }
2007
2008         RValue<Short8> Short8::operator=(const Short8 &rhs)
2009         {
2010                 Value *value = rhs.loadValue();
2011                 storeValue(value);
2012
2013                 return RValue<Short8>(value);
2014         }
2015
2016         RValue<Short8> Short8::operator=(const Reference<Short8> &rhs)
2017         {
2018                 Value *value = rhs.loadValue();
2019                 storeValue(value);
2020
2021                 return RValue<Short8>(value);
2022         }
2023
2024         RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs)
2025         {
2026                 return RValue<Short8>(Nucleus::createAdd(lhs.value, rhs.value));
2027         }
2028
2029         RValue<Short8> operator&(RValue<Short8> lhs, RValue<Short8> rhs)
2030         {
2031                 return RValue<Short8>(Nucleus::createAnd(lhs.value, rhs.value));
2032         }
2033
2034         RValue<Int4> Abs(RValue<Int4> x)
2035         {
2036                 // TODO: Optimize.
2037                 auto negative = x >> 31;
2038                 return (x ^ negative) - negative;
2039         }
2040
2041         UShort8::UShort8(unsigned short c)
2042         {
2043                 int64_t constantVector[8] = {c, c, c, c, c, c, c, c};
2044                 storeValue(Nucleus::createConstantVector(constantVector, getType()));
2045         }
2046
2047         UShort8::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)
2048         {
2049                 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
2050                 storeValue(Nucleus::createConstantVector(constantVector, getType()));
2051         }
2052
2053         UShort8::UShort8(RValue<UShort8> rhs)
2054         {
2055                 storeValue(rhs.value);
2056         }
2057
2058         UShort8::UShort8(const Reference<UShort8> &rhs)
2059         {
2060                 Value *value = rhs.loadValue();
2061                 storeValue(value);
2062         }
2063
2064         UShort8::UShort8(RValue<UShort4> lo, RValue<UShort4> hi)
2065         {
2066                 int shuffle[8] = {0, 1, 2, 3, 8, 9, 10, 11};   // Real type is v8i16
2067                 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
2068
2069                 storeValue(packed);
2070         }
2071
2072         RValue<UShort8> UShort8::operator=(RValue<UShort8> rhs)
2073         {
2074                 storeValue(rhs.value);
2075
2076                 return rhs;
2077         }
2078
2079         RValue<UShort8> UShort8::operator=(const UShort8 &rhs)
2080         {
2081                 Value *value = rhs.loadValue();
2082                 storeValue(value);
2083
2084                 return RValue<UShort8>(value);
2085         }
2086
2087         RValue<UShort8> UShort8::operator=(const Reference<UShort8> &rhs)
2088         {
2089                 Value *value = rhs.loadValue();
2090                 storeValue(value);
2091
2092                 return RValue<UShort8>(value);
2093         }
2094
2095         RValue<UShort8> operator&(RValue<UShort8> lhs, RValue<UShort8> rhs)
2096         {
2097                 return RValue<UShort8>(Nucleus::createAnd(lhs.value, rhs.value));
2098         }
2099
2100         RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs)
2101         {
2102                 return RValue<UShort8>(Nucleus::createAdd(lhs.value, rhs.value));
2103         }
2104
2105         RValue<UShort8> operator*(RValue<UShort8> lhs, RValue<UShort8> rhs)
2106         {
2107                 return RValue<UShort8>(Nucleus::createMul(lhs.value, rhs.value));
2108         }
2109
2110         RValue<UShort8> operator+=(UShort8 &lhs, RValue<UShort8> rhs)
2111         {
2112                 return lhs = lhs + rhs;
2113         }
2114
2115         RValue<UShort8> operator~(RValue<UShort8> val)
2116         {
2117                 return RValue<UShort8>(Nucleus::createNot(val.value));
2118         }
2119
2120         Int::Int(Argument<Int> argument)
2121         {
2122                 storeValue(argument.value);
2123         }
2124
2125         Int::Int(RValue<Byte> cast)
2126         {
2127                 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
2128
2129                 storeValue(integer);
2130         }
2131
2132         Int::Int(RValue<SByte> cast)
2133         {
2134                 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
2135
2136                 storeValue(integer);
2137         }
2138
2139         Int::Int(RValue<Short> cast)
2140         {
2141                 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
2142
2143                 storeValue(integer);
2144         }
2145
2146         Int::Int(RValue<UShort> cast)
2147         {
2148                 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
2149
2150                 storeValue(integer);
2151         }
2152
2153         Int::Int(RValue<Int2> cast)
2154         {
2155                 *this = Extract(cast, 0);
2156         }
2157
2158         Int::Int(RValue<Long> cast)
2159         {
2160                 Value *integer = Nucleus::createTrunc(cast.value, Int::getType());
2161
2162                 storeValue(integer);
2163         }
2164
2165         Int::Int(RValue<Float> cast)
2166         {
2167                 Value *integer = Nucleus::createFPToSI(cast.value, Int::getType());
2168
2169                 storeValue(integer);
2170         }
2171
2172         Int::Int(int x)
2173         {
2174                 storeValue(Nucleus::createConstantInt(x));
2175         }
2176
2177         Int::Int(RValue<Int> rhs)
2178         {
2179                 storeValue(rhs.value);
2180         }
2181
2182         Int::Int(RValue<UInt> rhs)
2183         {
2184                 storeValue(rhs.value);
2185         }
2186
2187         Int::Int(const Int &rhs)
2188         {
2189                 Value *value = rhs.loadValue();
2190                 storeValue(value);
2191         }
2192
2193         Int::Int(const Reference<Int> &rhs)
2194         {
2195                 Value *value = rhs.loadValue();
2196                 storeValue(value);
2197         }
2198
2199         Int::Int(const UInt &rhs)
2200         {
2201                 Value *value = rhs.loadValue();
2202                 storeValue(value);
2203         }
2204
2205         Int::Int(const Reference<UInt> &rhs)
2206         {
2207                 Value *value = rhs.loadValue();
2208                 storeValue(value);
2209         }
2210
2211         RValue<Int> Int::operator=(int rhs)
2212         {
2213                 return RValue<Int>(storeValue(Nucleus::createConstantInt(rhs)));
2214         }
2215
2216         RValue<Int> Int::operator=(RValue<Int> rhs)
2217         {
2218                 storeValue(rhs.value);
2219
2220                 return rhs;
2221         }
2222
2223         RValue<Int> Int::operator=(RValue<UInt> rhs)
2224         {
2225                 storeValue(rhs.value);
2226
2227                 return RValue<Int>(rhs);
2228         }
2229
2230         RValue<Int> Int::operator=(const Int &rhs)
2231         {
2232                 Value *value = rhs.loadValue();
2233                 storeValue(value);
2234
2235                 return RValue<Int>(value);
2236         }
2237
2238         RValue<Int> Int::operator=(const Reference<Int> &rhs)
2239         {
2240                 Value *value = rhs.loadValue();
2241                 storeValue(value);
2242
2243                 return RValue<Int>(value);
2244         }
2245
2246         RValue<Int> Int::operator=(const UInt &rhs)
2247         {
2248                 Value *value = rhs.loadValue();
2249                 storeValue(value);
2250
2251                 return RValue<Int>(value);
2252         }
2253
2254         RValue<Int> Int::operator=(const Reference<UInt> &rhs)
2255         {
2256                 Value *value = rhs.loadValue();
2257                 storeValue(value);
2258
2259                 return RValue<Int>(value);
2260         }
2261
2262         RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs)
2263         {
2264                 return RValue<Int>(Nucleus::createAdd(lhs.value, rhs.value));
2265         }
2266
2267         RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs)
2268         {
2269                 return RValue<Int>(Nucleus::createSub(lhs.value, rhs.value));
2270         }
2271
2272         RValue<Int> operator*(RValue<Int> lhs, RValue<Int> rhs)
2273         {
2274                 return RValue<Int>(Nucleus::createMul(lhs.value, rhs.value));
2275         }
2276
2277         RValue<Int> operator/(RValue<Int> lhs, RValue<Int> rhs)
2278         {
2279                 return RValue<Int>(Nucleus::createSDiv(lhs.value, rhs.value));
2280         }
2281
2282         RValue<Int> operator%(RValue<Int> lhs, RValue<Int> rhs)
2283         {
2284                 return RValue<Int>(Nucleus::createSRem(lhs.value, rhs.value));
2285         }
2286
2287         RValue<Int> operator&(RValue<Int> lhs, RValue<Int> rhs)
2288         {
2289                 return RValue<Int>(Nucleus::createAnd(lhs.value, rhs.value));
2290         }
2291
2292         RValue<Int> operator|(RValue<Int> lhs, RValue<Int> rhs)
2293         {
2294                 return RValue<Int>(Nucleus::createOr(lhs.value, rhs.value));
2295         }
2296
2297         RValue<Int> operator^(RValue<Int> lhs, RValue<Int> rhs)
2298         {
2299                 return RValue<Int>(Nucleus::createXor(lhs.value, rhs.value));
2300         }
2301
2302         RValue<Int> operator<<(RValue<Int> lhs, RValue<Int> rhs)
2303         {
2304                 return RValue<Int>(Nucleus::createShl(lhs.value, rhs.value));
2305         }
2306
2307         RValue<Int> operator>>(RValue<Int> lhs, RValue<Int> rhs)
2308         {
2309                 return RValue<Int>(Nucleus::createAShr(lhs.value, rhs.value));
2310         }
2311
2312         RValue<Int> operator+=(Int &lhs, RValue<Int> rhs)
2313         {
2314                 return lhs = lhs + rhs;
2315         }
2316
2317         RValue<Int> operator-=(Int &lhs, RValue<Int> rhs)
2318         {
2319                 return lhs = lhs - rhs;
2320         }
2321
2322         RValue<Int> operator*=(Int &lhs, RValue<Int> rhs)
2323         {
2324                 return lhs = lhs * rhs;
2325         }
2326
2327         RValue<Int> operator/=(Int &lhs, RValue<Int> rhs)
2328         {
2329                 return lhs = lhs / rhs;
2330         }
2331
2332         RValue<Int> operator%=(Int &lhs, RValue<Int> rhs)
2333         {
2334                 return lhs = lhs % rhs;
2335         }
2336
2337         RValue<Int> operator&=(Int &lhs, RValue<Int> rhs)
2338         {
2339                 return lhs = lhs & rhs;
2340         }
2341
2342         RValue<Int> operator|=(Int &lhs, RValue<Int> rhs)
2343         {
2344                 return lhs = lhs | rhs;
2345         }
2346
2347         RValue<Int> operator^=(Int &lhs, RValue<Int> rhs)
2348         {
2349                 return lhs = lhs ^ rhs;
2350         }
2351
2352         RValue<Int> operator<<=(Int &lhs, RValue<Int> rhs)
2353         {
2354                 return lhs = lhs << rhs;
2355         }
2356
2357         RValue<Int> operator>>=(Int &lhs, RValue<Int> rhs)
2358         {
2359                 return lhs = lhs >> rhs;
2360         }
2361
2362         RValue<Int> operator+(RValue<Int> val)
2363         {
2364                 return val;
2365         }
2366
2367         RValue<Int> operator-(RValue<Int> val)
2368         {
2369                 return RValue<Int>(Nucleus::createNeg(val.value));
2370         }
2371
2372         RValue<Int> operator~(RValue<Int> val)
2373         {
2374                 return RValue<Int>(Nucleus::createNot(val.value));
2375         }
2376
2377         RValue<Bool> operator<(RValue<Int> lhs, RValue<Int> rhs)
2378         {
2379                 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
2380         }
2381
2382         RValue<Bool> operator<=(RValue<Int> lhs, RValue<Int> rhs)
2383         {
2384                 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
2385         }
2386
2387         RValue<Bool> operator>(RValue<Int> lhs, RValue<Int> rhs)
2388         {
2389                 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
2390         }
2391
2392         RValue<Bool> operator>=(RValue<Int> lhs, RValue<Int> rhs)
2393         {
2394                 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
2395         }
2396
2397         RValue<Bool> operator!=(RValue<Int> lhs, RValue<Int> rhs)
2398         {
2399                 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
2400         }
2401
2402         RValue<Bool> operator==(RValue<Int> lhs, RValue<Int> rhs)
2403         {
2404                 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
2405         }
2406
2407         RValue<Int> Max(RValue<Int> x, RValue<Int> y)
2408         {
2409                 return IfThenElse(x > y, x, y);
2410         }
2411
2412         RValue<Int> Min(RValue<Int> x, RValue<Int> y)
2413         {
2414                 return IfThenElse(x < y, x, y);
2415         }
2416
2417         RValue<Int> Clamp(RValue<Int> x, RValue<Int> min, RValue<Int> max)
2418         {
2419                 return Min(Max(x, min), max);
2420         }
2421
2422         Long::Long(RValue<Int> cast)
2423         {
2424                 Value *integer = Nucleus::createSExt(cast.value, Long::getType());
2425
2426                 storeValue(integer);
2427         }
2428
2429         Long::Long(RValue<UInt> cast)
2430         {
2431                 Value *integer = Nucleus::createZExt(cast.value, Long::getType());
2432
2433                 storeValue(integer);
2434         }
2435
2436         Long::Long(RValue<Long> rhs)
2437         {
2438                 storeValue(rhs.value);
2439         }
2440
2441         RValue<Long> Long::operator=(int64_t rhs)
2442         {
2443                 return RValue<Long>(storeValue(Nucleus::createConstantLong(rhs)));
2444         }
2445
2446         RValue<Long> Long::operator=(RValue<Long> rhs)
2447         {
2448                 storeValue(rhs.value);
2449
2450                 return rhs;
2451         }
2452
2453         RValue<Long> Long::operator=(const Long &rhs)
2454         {
2455                 Value *value = rhs.loadValue();
2456                 storeValue(value);
2457
2458                 return RValue<Long>(value);
2459         }
2460
2461         RValue<Long> Long::operator=(const Reference<Long> &rhs)
2462         {
2463                 Value *value = rhs.loadValue();
2464                 storeValue(value);
2465
2466                 return RValue<Long>(value);
2467         }
2468
2469         RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs)
2470         {
2471                 return RValue<Long>(Nucleus::createAdd(lhs.value, rhs.value));
2472         }
2473
2474         RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs)
2475         {
2476                 return RValue<Long>(Nucleus::createSub(lhs.value, rhs.value));
2477         }
2478
2479         RValue<Long> operator*(RValue<Long> lhs, RValue<Long> rhs)
2480         {
2481                 return RValue<Long>(Nucleus::createMul(lhs.value, rhs.value));
2482         }
2483
2484         RValue<Long> operator>>(RValue<Long> lhs, RValue<Long> rhs)
2485         {
2486                 return RValue<Long>(Nucleus::createAShr(lhs.value, rhs.value));
2487         }
2488
2489         RValue<Long> operator+=(Long &lhs, RValue<Long> rhs)
2490         {
2491                 return lhs = lhs + rhs;
2492         }
2493
2494         RValue<Long> operator-=(Long &lhs, RValue<Long> rhs)
2495         {
2496                 return lhs = lhs - rhs;
2497         }
2498
2499         RValue<Long> AddAtomic(RValue<Pointer<Long> > x, RValue<Long> y)
2500         {
2501                 return RValue<Long>(Nucleus::createAtomicAdd(x.value, y.value));
2502         }
2503
2504         UInt::UInt(Argument<UInt> argument)
2505         {
2506                 storeValue(argument.value);
2507         }
2508
2509         UInt::UInt(RValue<UShort> cast)
2510         {
2511                 Value *integer = Nucleus::createZExt(cast.value, UInt::getType());
2512
2513                 storeValue(integer);
2514         }
2515
2516         UInt::UInt(RValue<Long> cast)
2517         {
2518                 Value *integer = Nucleus::createTrunc(cast.value, UInt::getType());
2519
2520                 storeValue(integer);
2521         }
2522
2523         UInt::UInt(int x)
2524         {
2525                 storeValue(Nucleus::createConstantInt(x));
2526         }
2527
2528         UInt::UInt(unsigned int x)
2529         {
2530                 storeValue(Nucleus::createConstantInt(x));
2531         }
2532
2533         UInt::UInt(RValue<UInt> rhs)
2534         {
2535                 storeValue(rhs.value);
2536         }
2537
2538         UInt::UInt(RValue<Int> rhs)
2539         {
2540                 storeValue(rhs.value);
2541         }
2542
2543         UInt::UInt(const UInt &rhs)
2544         {
2545                 Value *value = rhs.loadValue();
2546                 storeValue(value);
2547         }
2548
2549         UInt::UInt(const Reference<UInt> &rhs)
2550         {
2551                 Value *value = rhs.loadValue();
2552                 storeValue(value);
2553         }
2554
2555         UInt::UInt(const Int &rhs)
2556         {
2557                 Value *value = rhs.loadValue();
2558                 storeValue(value);
2559         }
2560
2561         UInt::UInt(const Reference<Int> &rhs)
2562         {
2563                 Value *value = rhs.loadValue();
2564                 storeValue(value);
2565         }
2566
2567         RValue<UInt> UInt::operator=(unsigned int rhs)
2568         {
2569                 return RValue<UInt>(storeValue(Nucleus::createConstantInt(rhs)));
2570         }
2571
2572         RValue<UInt> UInt::operator=(RValue<UInt> rhs)
2573         {
2574                 storeValue(rhs.value);
2575
2576                 return rhs;
2577         }
2578
2579         RValue<UInt> UInt::operator=(RValue<Int> rhs)
2580         {
2581                 storeValue(rhs.value);
2582
2583                 return RValue<UInt>(rhs);
2584         }
2585
2586         RValue<UInt> UInt::operator=(const UInt &rhs)
2587         {
2588                 Value *value = rhs.loadValue();
2589                 storeValue(value);
2590
2591                 return RValue<UInt>(value);
2592         }
2593
2594         RValue<UInt> UInt::operator=(const Reference<UInt> &rhs)
2595         {
2596                 Value *value = rhs.loadValue();
2597                 storeValue(value);
2598
2599                 return RValue<UInt>(value);
2600         }
2601
2602         RValue<UInt> UInt::operator=(const Int &rhs)
2603         {
2604                 Value *value = rhs.loadValue();
2605                 storeValue(value);
2606
2607                 return RValue<UInt>(value);
2608         }
2609
2610         RValue<UInt> UInt::operator=(const Reference<Int> &rhs)
2611         {
2612                 Value *value = rhs.loadValue();
2613                 storeValue(value);
2614
2615                 return RValue<UInt>(value);
2616         }
2617
2618         RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs)
2619         {
2620                 return RValue<UInt>(Nucleus::createAdd(lhs.value, rhs.value));
2621         }
2622
2623         RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs)
2624         {
2625                 return RValue<UInt>(Nucleus::createSub(lhs.value, rhs.value));
2626         }
2627
2628         RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs)
2629         {
2630                 return RValue<UInt>(Nucleus::createMul(lhs.value, rhs.value));
2631         }
2632
2633         RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs)
2634         {
2635                 return RValue<UInt>(Nucleus::createUDiv(lhs.value, rhs.value));
2636         }
2637
2638         RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs)
2639         {
2640                 return RValue<UInt>(Nucleus::createURem(lhs.value, rhs.value));
2641         }
2642
2643         RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs)
2644         {
2645                 return RValue<UInt>(Nucleus::createAnd(lhs.value, rhs.value));
2646         }
2647
2648         RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs)
2649         {
2650                 return RValue<UInt>(Nucleus::createOr(lhs.value, rhs.value));
2651         }
2652
2653         RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs)
2654         {
2655                 return RValue<UInt>(Nucleus::createXor(lhs.value, rhs.value));
2656         }
2657
2658         RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs)
2659         {
2660                 return RValue<UInt>(Nucleus::createShl(lhs.value, rhs.value));
2661         }
2662
2663         RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs)
2664         {
2665                 return RValue<UInt>(Nucleus::createLShr(lhs.value, rhs.value));
2666         }
2667
2668         RValue<UInt> operator+=(UInt &lhs, RValue<UInt> rhs)
2669         {
2670                 return lhs = lhs + rhs;
2671         }
2672
2673         RValue<UInt> operator-=(UInt &lhs, RValue<UInt> rhs)
2674         {
2675                 return lhs = lhs - rhs;
2676         }
2677
2678         RValue<UInt> operator*=(UInt &lhs, RValue<UInt> rhs)
2679         {
2680                 return lhs = lhs * rhs;
2681         }
2682
2683         RValue<UInt> operator/=(UInt &lhs, RValue<UInt> rhs)
2684         {
2685                 return lhs = lhs / rhs;
2686         }
2687
2688         RValue<UInt> operator%=(UInt &lhs, RValue<UInt> rhs)
2689         {
2690                 return lhs = lhs % rhs;
2691         }
2692
2693         RValue<UInt> operator&=(UInt &lhs, RValue<UInt> rhs)
2694         {
2695                 return lhs = lhs & rhs;
2696         }
2697
2698         RValue<UInt> operator|=(UInt &lhs, RValue<UInt> rhs)
2699         {
2700                 return lhs = lhs | rhs;
2701         }
2702
2703         RValue<UInt> operator^=(UInt &lhs, RValue<UInt> rhs)
2704         {
2705                 return lhs = lhs ^ rhs;
2706         }
2707
2708         RValue<UInt> operator<<=(UInt &lhs, RValue<UInt> rhs)
2709         {
2710                 return lhs = lhs << rhs;
2711         }
2712
2713         RValue<UInt> operator>>=(UInt &lhs, RValue<UInt> rhs)
2714         {
2715                 return lhs = lhs >> rhs;
2716         }
2717
2718         RValue<UInt> operator+(RValue<UInt> val)
2719         {
2720                 return val;
2721         }
2722
2723         RValue<UInt> operator-(RValue<UInt> val)
2724         {
2725                 return RValue<UInt>(Nucleus::createNeg(val.value));
2726         }
2727
2728         RValue<UInt> operator~(RValue<UInt> val)
2729         {
2730                 return RValue<UInt>(Nucleus::createNot(val.value));
2731         }
2732
2733         RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y)
2734         {
2735                 return IfThenElse(x > y, x, y);
2736         }
2737
2738         RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y)
2739         {
2740                 return IfThenElse(x < y, x, y);
2741         }
2742
2743         RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max)
2744         {
2745                 return Min(Max(x, min), max);
2746         }
2747
2748         RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs)
2749         {
2750                 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
2751         }
2752
2753         RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs)
2754         {
2755                 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
2756         }
2757
2758         RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs)
2759         {
2760                 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
2761         }
2762
2763         RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs)
2764         {
2765                 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
2766         }
2767
2768         RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs)
2769         {
2770                 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
2771         }
2772
2773         RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs)
2774         {
2775                 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
2776         }
2777
2778         Int2::Int2(RValue<Int4> cast)
2779         {
2780                 storeValue(Nucleus::createBitCast(cast.value, getType()));
2781         }
2782
2783         Int2::Int2(int x, int y)
2784         {
2785                 int64_t constantVector[2] = {x, y};
2786                 storeValue(Nucleus::createConstantVector(constantVector, getType()));
2787         }
2788
2789         Int2::Int2(RValue<Int2> rhs)
2790         {
2791                 storeValue(rhs.value);
2792         }
2793
2794         Int2::Int2(const Int2 &rhs)
2795         {
2796                 Value *value = rhs.loadValue();
2797                 storeValue(value);
2798         }
2799
2800         Int2::Int2(const Reference<Int2> &rhs)
2801         {
2802                 Value *value = rhs.loadValue();
2803                 storeValue(value);
2804         }
2805
2806         Int2::Int2(RValue<Int> lo, RValue<Int> hi)
2807         {
2808                 int shuffle[4] = {0, 4, 1, 5};
2809                 Value *packed = Nucleus::createShuffleVector(Int4(lo).loadValue(), Int4(hi).loadValue(), shuffle);
2810
2811                 storeValue(Nucleus::createBitCast(packed, Int2::getType()));
2812         }
2813
2814         RValue<Int2> Int2::operator=(RValue<Int2> rhs)
2815         {
2816                 storeValue(rhs.value);
2817
2818                 return rhs;
2819         }
2820
2821         RValue<Int2> Int2::operator=(const Int2 &rhs)
2822         {
2823                 Value *value = rhs.loadValue();
2824                 storeValue(value);
2825
2826                 return RValue<Int2>(value);
2827         }
2828
2829         RValue<Int2> Int2::operator=(const Reference<Int2> &rhs)
2830         {
2831                 Value *value = rhs.loadValue();
2832                 storeValue(value);
2833
2834                 return RValue<Int2>(value);
2835         }
2836
2837         RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs)
2838         {
2839                 return RValue<Int2>(Nucleus::createAdd(lhs.value, rhs.value));
2840         }
2841
2842         RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs)
2843         {
2844                 return RValue<Int2>(Nucleus::createSub(lhs.value, rhs.value));
2845         }
2846
2847 //      RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs)
2848 //      {
2849 //              return RValue<Int2>(Nucleus::createMul(lhs.value, rhs.value));
2850 //      }
2851
2852 //      RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs)
2853 //      {
2854 //              return RValue<Int2>(Nucleus::createSDiv(lhs.value, rhs.value));
2855 //      }
2856
2857 //      RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs)
2858 //      {
2859 //              return RValue<Int2>(Nucleus::createSRem(lhs.value, rhs.value));
2860 //      }
2861
2862         RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs)
2863         {
2864                 return RValue<Int2>(Nucleus::createAnd(lhs.value, rhs.value));
2865         }
2866
2867         RValue<Int2> operator|(RValue<Int2> lhs, RValue<Int2> rhs)
2868         {
2869                 return RValue<Int2>(Nucleus::createOr(lhs.value, rhs.value));
2870         }
2871
2872         RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs)
2873         {
2874                 return RValue<Int2>(Nucleus::createXor(lhs.value, rhs.value));
2875         }
2876
2877         RValue<Int2> operator+=(Int2 &lhs, RValue<Int2> rhs)
2878         {
2879                 return lhs = lhs + rhs;
2880         }
2881
2882         RValue<Int2> operator-=(Int2 &lhs, RValue<Int2> rhs)
2883         {
2884                 return lhs = lhs - rhs;
2885         }
2886
2887 //      RValue<Int2> operator*=(Int2 &lhs, RValue<Int2> rhs)
2888 //      {
2889 //              return lhs = lhs * rhs;
2890 //      }
2891
2892 //      RValue<Int2> operator/=(Int2 &lhs, RValue<Int2> rhs)
2893 //      {
2894 //              return lhs = lhs / rhs;
2895 //      }
2896
2897 //      RValue<Int2> operator%=(Int2 &lhs, RValue<Int2> rhs)
2898 //      {
2899 //              return lhs = lhs % rhs;
2900 //      }
2901
2902         RValue<Int2> operator&=(Int2 &lhs, RValue<Int2> rhs)
2903         {
2904                 return lhs = lhs & rhs;
2905         }
2906
2907         RValue<Int2> operator|=(Int2 &lhs, RValue<Int2> rhs)
2908         {
2909                 return lhs = lhs | rhs;
2910         }
2911
2912         RValue<Int2> operator^=(Int2 &lhs, RValue<Int2> rhs)
2913         {
2914                 return lhs = lhs ^ rhs;
2915         }
2916
2917         RValue<Int2> operator<<=(Int2 &lhs, unsigned char rhs)
2918         {
2919                 return lhs = lhs << rhs;
2920         }
2921
2922         RValue<Int2> operator>>=(Int2 &lhs, unsigned char rhs)
2923         {
2924                 return lhs = lhs >> rhs;
2925         }
2926
2927 //      RValue<Int2> operator+(RValue<Int2> val)
2928 //      {
2929 //              return val;
2930 //      }
2931
2932 //      RValue<Int2> operator-(RValue<Int2> val)
2933 //      {
2934 //              return RValue<Int2>(Nucleus::createNeg(val.value));
2935 //      }
2936
2937         RValue<Int2> operator~(RValue<Int2> val)
2938         {
2939                 return RValue<Int2>(Nucleus::createNot(val.value));
2940         }
2941
2942         RValue<Short4> UnpackLow(RValue<Int2> x, RValue<Int2> y)
2943         {
2944                 int shuffle[4] = {0, 4, 1, 5};   // Real type is v4i32
2945                 return As<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
2946         }
2947
2948         RValue<Short4> UnpackHigh(RValue<Int2> x, RValue<Int2> y)
2949         {
2950                 int shuffle[4] = {0, 4, 1, 5};   // Real type is v4i32
2951                 auto lowHigh = RValue<Int4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
2952                 return As<Short4>(Swizzle(lowHigh, 0xEE));
2953         }
2954
2955         RValue<Int> Extract(RValue<Int2> val, int i)
2956         {
2957                 return RValue<Int>(Nucleus::createExtractElement(val.value, Int::getType(), i));
2958         }
2959
2960         RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i)
2961         {
2962                 return RValue<Int2>(Nucleus::createInsertElement(val.value, element.value, i));
2963         }
2964
2965         UInt2::UInt2(unsigned int x, unsigned int y)
2966         {
2967                 int64_t constantVector[2] = {x, y};
2968                 storeValue(Nucleus::createConstantVector(constantVector, getType()));
2969         }
2970
2971         UInt2::UInt2(RValue<UInt2> rhs)
2972         {
2973                 storeValue(rhs.value);
2974         }
2975
2976         UInt2::UInt2(const UInt2 &rhs)
2977         {
2978                 Value *value = rhs.loadValue();
2979                 storeValue(value);
2980         }
2981
2982         UInt2::UInt2(const Reference<UInt2> &rhs)
2983         {
2984                 Value *value = rhs.loadValue();
2985                 storeValue(value);
2986         }
2987
2988         RValue<UInt2> UInt2::operator=(RValue<UInt2> rhs)
2989         {
2990                 storeValue(rhs.value);
2991
2992                 return rhs;
2993         }
2994
2995         RValue<UInt2> UInt2::operator=(const UInt2 &rhs)
2996         {
2997                 Value *value = rhs.loadValue();
2998                 storeValue(value);
2999
3000                 return RValue<UInt2>(value);
3001         }
3002
3003         RValue<UInt2> UInt2::operator=(const Reference<UInt2> &rhs)
3004         {
3005                 Value *value = rhs.loadValue();
3006                 storeValue(value);
3007
3008                 return RValue<UInt2>(value);
3009         }
3010
3011         RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs)
3012         {
3013                 return RValue<UInt2>(Nucleus::createAdd(lhs.value, rhs.value));
3014         }
3015
3016         RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs)
3017         {
3018                 return RValue<UInt2>(Nucleus::createSub(lhs.value, rhs.value));
3019         }
3020
3021 //      RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs)
3022 //      {
3023 //              return RValue<UInt2>(Nucleus::createMul(lhs.value, rhs.value));
3024 //      }
3025
3026 //      RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs)
3027 //      {
3028 //              return RValue<UInt2>(Nucleus::createUDiv(lhs.value, rhs.value));
3029 //      }
3030
3031 //      RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs)
3032 //      {
3033 //              return RValue<UInt2>(Nucleus::createURem(lhs.value, rhs.value));
3034 //      }
3035
3036         RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs)
3037         {
3038                 return RValue<UInt2>(Nucleus::createAnd(lhs.value, rhs.value));
3039         }
3040
3041         RValue<UInt2> operator|(RValue<UInt2> lhs, RValue<UInt2> rhs)
3042         {
3043                 return RValue<UInt2>(Nucleus::createOr(lhs.value, rhs.value));
3044         }
3045
3046         RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs)
3047         {
3048                 return RValue<UInt2>(Nucleus::createXor(lhs.value, rhs.value));
3049         }
3050
3051         RValue<UInt2> operator+=(UInt2 &lhs, RValue<UInt2> rhs)
3052         {
3053                 return lhs = lhs + rhs;
3054         }
3055
3056         RValue<UInt2> operator-=(UInt2 &lhs, RValue<UInt2> rhs)
3057         {
3058                 return lhs = lhs - rhs;
3059         }
3060
3061 //      RValue<UInt2> operator*=(UInt2 &lhs, RValue<UInt2> rhs)
3062 //      {
3063 //              return lhs = lhs * rhs;
3064 //      }
3065
3066 //      RValue<UInt2> operator/=(UInt2 &lhs, RValue<UInt2> rhs)
3067 //      {
3068 //              return lhs = lhs / rhs;
3069 //      }
3070
3071 //      RValue<UInt2> operator%=(UInt2 &lhs, RValue<UInt2> rhs)
3072 //      {
3073 //              return lhs = lhs % rhs;
3074 //      }
3075
3076         RValue<UInt2> operator&=(UInt2 &lhs, RValue<UInt2> rhs)
3077         {
3078                 return lhs = lhs & rhs;
3079         }
3080
3081         RValue<UInt2> operator|=(UInt2 &lhs, RValue<UInt2> rhs)
3082         {
3083                 return lhs = lhs | rhs;
3084         }
3085
3086         RValue<UInt2> operator^=(UInt2 &lhs, RValue<UInt2> rhs)
3087         {
3088                 return lhs = lhs ^ rhs;
3089         }
3090
3091         RValue<UInt2> operator<<=(UInt2 &lhs, unsigned char rhs)
3092         {
3093                 return lhs = lhs << rhs;
3094         }
3095
3096         RValue<UInt2> operator>>=(UInt2 &lhs, unsigned char rhs)
3097         {
3098                 return lhs = lhs >> rhs;
3099         }
3100
3101 //      RValue<UInt2> operator+(RValue<UInt2> val)
3102 //      {
3103 //              return val;
3104 //      }
3105
3106 //      RValue<UInt2> operator-(RValue<UInt2> val)
3107 //      {
3108 //              return RValue<UInt2>(Nucleus::createNeg(val.value));
3109 //      }
3110
3111         RValue<UInt2> operator~(RValue<UInt2> val)
3112         {
3113                 return RValue<UInt2>(Nucleus::createNot(val.value));
3114         }
3115
3116         Int4::Int4() : XYZW(this)
3117         {
3118         }
3119
3120         Int4::Int4(RValue<Float4> cast) : XYZW(this)
3121         {
3122                 Value *xyzw = Nucleus::createFPToSI(cast.value, Int4::getType());
3123
3124                 storeValue(xyzw);
3125         }
3126
3127         Int4::Int4(int xyzw) : XYZW(this)
3128         {
3129                 constant(xyzw, xyzw, xyzw, xyzw);
3130         }
3131
3132         Int4::Int4(int x, int yzw) : XYZW(this)
3133         {
3134                 constant(x, yzw, yzw, yzw);
3135         }
3136
3137         Int4::Int4(int x, int y, int zw) : XYZW(this)
3138         {
3139                 constant(x, y, zw, zw);
3140         }
3141
3142         Int4::Int4(int x, int y, int z, int w) : XYZW(this)
3143         {
3144                 constant(x, y, z, w);
3145         }
3146
3147         void Int4::constant(int x, int y, int z, int w)
3148         {
3149                 int64_t constantVector[4] = {x, y, z, w};
3150                 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3151         }
3152
3153         Int4::Int4(RValue<Int4> rhs) : XYZW(this)
3154         {
3155                 storeValue(rhs.value);
3156         }
3157
3158         Int4::Int4(const Int4 &rhs) : XYZW(this)
3159         {
3160                 Value *value = rhs.loadValue();
3161                 storeValue(value);
3162         }
3163
3164         Int4::Int4(const Reference<Int4> &rhs) : XYZW(this)
3165         {
3166                 Value *value = rhs.loadValue();
3167                 storeValue(value);
3168         }
3169
3170         Int4::Int4(RValue<UInt4> rhs) : XYZW(this)
3171         {
3172                 storeValue(rhs.value);
3173         }
3174
3175         Int4::Int4(const UInt4 &rhs) : XYZW(this)
3176         {
3177                 Value *value = rhs.loadValue();
3178                 storeValue(value);
3179         }
3180
3181         Int4::Int4(const Reference<UInt4> &rhs) : XYZW(this)
3182         {
3183                 Value *value = rhs.loadValue();
3184                 storeValue(value);
3185         }
3186
3187         Int4::Int4(RValue<Int2> lo, RValue<Int2> hi) : XYZW(this)
3188         {
3189                 int shuffle[4] = {0, 1, 4, 5};   // Real type is v4i32
3190                 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
3191
3192                 storeValue(packed);
3193         }
3194
3195         Int4::Int4(const Int &rhs) : XYZW(this)
3196         {
3197                 *this = RValue<Int>(rhs.loadValue());
3198         }
3199
3200         Int4::Int4(const Reference<Int> &rhs) : XYZW(this)
3201         {
3202                 *this = RValue<Int>(rhs.loadValue());
3203         }
3204
3205         RValue<Int4> Int4::operator=(RValue<Int4> rhs)
3206         {
3207                 storeValue(rhs.value);
3208
3209                 return rhs;
3210         }
3211
3212         RValue<Int4> Int4::operator=(const Int4 &rhs)
3213         {
3214                 Value *value = rhs.loadValue();
3215                 storeValue(value);
3216
3217                 return RValue<Int4>(value);
3218         }
3219
3220         RValue<Int4> Int4::operator=(const Reference<Int4> &rhs)
3221         {
3222                 Value *value = rhs.loadValue();
3223                 storeValue(value);
3224
3225                 return RValue<Int4>(value);
3226         }
3227
3228         RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs)
3229         {
3230                 return RValue<Int4>(Nucleus::createAdd(lhs.value, rhs.value));
3231         }
3232
3233         RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs)
3234         {
3235                 return RValue<Int4>(Nucleus::createSub(lhs.value, rhs.value));
3236         }
3237
3238         RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs)
3239         {
3240                 return RValue<Int4>(Nucleus::createMul(lhs.value, rhs.value));
3241         }
3242
3243         RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs)
3244         {
3245                 return RValue<Int4>(Nucleus::createSDiv(lhs.value, rhs.value));
3246         }
3247
3248         RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs)
3249         {
3250                 return RValue<Int4>(Nucleus::createSRem(lhs.value, rhs.value));
3251         }
3252
3253         RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs)
3254         {
3255                 return RValue<Int4>(Nucleus::createAnd(lhs.value, rhs.value));
3256         }
3257
3258         RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs)
3259         {
3260                 return RValue<Int4>(Nucleus::createOr(lhs.value, rhs.value));
3261         }
3262
3263         RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs)
3264         {
3265                 return RValue<Int4>(Nucleus::createXor(lhs.value, rhs.value));
3266         }
3267
3268         RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs)
3269         {
3270                 return RValue<Int4>(Nucleus::createShl(lhs.value, rhs.value));
3271         }
3272
3273         RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs)
3274         {
3275                 return RValue<Int4>(Nucleus::createAShr(lhs.value, rhs.value));
3276         }
3277
3278         RValue<Int4> operator+=(Int4 &lhs, RValue<Int4> rhs)
3279         {
3280                 return lhs = lhs + rhs;
3281         }
3282
3283         RValue<Int4> operator-=(Int4 &lhs, RValue<Int4> rhs)
3284         {
3285                 return lhs = lhs - rhs;
3286         }
3287
3288         RValue<Int4> operator*=(Int4 &lhs, RValue<Int4> rhs)
3289         {
3290                 return lhs = lhs * rhs;
3291         }
3292
3293 //      RValue<Int4> operator/=(Int4 &lhs, RValue<Int4> rhs)
3294 //      {
3295 //              return lhs = lhs / rhs;
3296 //      }
3297
3298 //      RValue<Int4> operator%=(Int4 &lhs, RValue<Int4> rhs)
3299 //      {
3300 //              return lhs = lhs % rhs;
3301 //      }
3302
3303         RValue<Int4> operator&=(Int4 &lhs, RValue<Int4> rhs)
3304         {
3305                 return lhs = lhs & rhs;
3306         }
3307
3308         RValue<Int4> operator|=(Int4 &lhs, RValue<Int4> rhs)
3309         {
3310                 return lhs = lhs | rhs;
3311         }
3312
3313         RValue<Int4> operator^=(Int4 &lhs, RValue<Int4> rhs)
3314         {
3315                 return lhs = lhs ^ rhs;
3316         }
3317
3318         RValue<Int4> operator<<=(Int4 &lhs, unsigned char rhs)
3319         {
3320                 return lhs = lhs << rhs;
3321         }
3322
3323         RValue<Int4> operator>>=(Int4 &lhs, unsigned char rhs)
3324         {
3325                 return lhs = lhs >> rhs;
3326         }
3327
3328         RValue<Int4> operator+(RValue<Int4> val)
3329         {
3330                 return val;
3331         }
3332
3333         RValue<Int4> operator-(RValue<Int4> val)
3334         {
3335                 return RValue<Int4>(Nucleus::createNeg(val.value));
3336         }
3337
3338         RValue<Int4> operator~(RValue<Int4> val)
3339         {
3340                 return RValue<Int4>(Nucleus::createNot(val.value));
3341         }
3342
3343         RValue<Int> Extract(RValue<Int4> x, int i)
3344         {
3345                 return RValue<Int>(Nucleus::createExtractElement(x.value, Int::getType(), i));
3346         }
3347
3348         RValue<Int4> Insert(RValue<Int4> x, RValue<Int> element, int i)
3349         {
3350                 return RValue<Int4>(Nucleus::createInsertElement(x.value, element.value, i));
3351         }
3352
3353         RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select)
3354         {
3355                 return RValue<Int4>(createSwizzle4(x.value, select));
3356         }
3357
3358         UInt4::UInt4() : XYZW(this)
3359         {
3360         }
3361
3362         UInt4::UInt4(int xyzw) : XYZW(this)
3363         {
3364                 constant(xyzw, xyzw, xyzw, xyzw);
3365         }
3366
3367         UInt4::UInt4(int x, int yzw) : XYZW(this)
3368         {
3369                 constant(x, yzw, yzw, yzw);
3370         }
3371
3372         UInt4::UInt4(int x, int y, int zw) : XYZW(this)
3373         {
3374                 constant(x, y, zw, zw);
3375         }
3376
3377         UInt4::UInt4(int x, int y, int z, int w) : XYZW(this)
3378         {
3379                 constant(x, y, z, w);
3380         }
3381
3382         void UInt4::constant(int x, int y, int z, int w)
3383         {
3384                 int64_t constantVector[4] = {x, y, z, w};
3385                 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3386         }
3387
3388         UInt4::UInt4(RValue<UInt4> rhs) : XYZW(this)
3389         {
3390                 storeValue(rhs.value);
3391         }
3392
3393         UInt4::UInt4(const UInt4 &rhs) : XYZW(this)
3394         {
3395                 Value *value = rhs.loadValue();
3396                 storeValue(value);
3397         }
3398
3399         UInt4::UInt4(const Reference<UInt4> &rhs) : XYZW(this)
3400         {
3401                 Value *value = rhs.loadValue();
3402                 storeValue(value);
3403         }
3404
3405         UInt4::UInt4(RValue<Int4> rhs) : XYZW(this)
3406         {
3407                 storeValue(rhs.value);
3408         }
3409
3410         UInt4::UInt4(const Int4 &rhs) : XYZW(this)
3411         {
3412                 Value *value = rhs.loadValue();
3413                 storeValue(value);
3414         }
3415
3416         UInt4::UInt4(const Reference<Int4> &rhs) : XYZW(this)
3417         {
3418                 Value *value = rhs.loadValue();
3419                 storeValue(value);
3420         }
3421
3422         UInt4::UInt4(RValue<UInt2> lo, RValue<UInt2> hi) : XYZW(this)
3423         {
3424                 int shuffle[4] = {0, 1, 4, 5};   // Real type is v4i32
3425                 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
3426
3427                 storeValue(packed);
3428         }
3429
3430         RValue<UInt4> UInt4::operator=(RValue<UInt4> rhs)
3431         {
3432                 storeValue(rhs.value);
3433
3434                 return rhs;
3435         }
3436
3437         RValue<UInt4> UInt4::operator=(const UInt4 &rhs)
3438         {
3439                 Value *value = rhs.loadValue();
3440                 storeValue(value);
3441
3442                 return RValue<UInt4>(value);
3443         }
3444
3445         RValue<UInt4> UInt4::operator=(const Reference<UInt4> &rhs)
3446         {
3447                 Value *value = rhs.loadValue();
3448                 storeValue(value);
3449
3450                 return RValue<UInt4>(value);
3451         }
3452
3453         RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs)
3454         {
3455                 return RValue<UInt4>(Nucleus::createAdd(lhs.value, rhs.value));
3456         }
3457
3458         RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs)
3459         {
3460                 return RValue<UInt4>(Nucleus::createSub(lhs.value, rhs.value));
3461         }
3462
3463         RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs)
3464         {
3465                 return RValue<UInt4>(Nucleus::createMul(lhs.value, rhs.value));
3466         }
3467
3468         RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs)
3469         {
3470                 return RValue<UInt4>(Nucleus::createUDiv(lhs.value, rhs.value));
3471         }
3472
3473         RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs)
3474         {
3475                 return RValue<UInt4>(Nucleus::createURem(lhs.value, rhs.value));
3476         }
3477
3478         RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs)
3479         {
3480                 return RValue<UInt4>(Nucleus::createAnd(lhs.value, rhs.value));
3481         }
3482
3483         RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs)
3484         {
3485                 return RValue<UInt4>(Nucleus::createOr(lhs.value, rhs.value));
3486         }
3487
3488         RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs)
3489         {
3490                 return RValue<UInt4>(Nucleus::createXor(lhs.value, rhs.value));
3491         }
3492
3493         RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs)
3494         {
3495                 return RValue<UInt4>(Nucleus::createShl(lhs.value, rhs.value));
3496         }
3497
3498         RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs)
3499         {
3500                 return RValue<UInt4>(Nucleus::createLShr(lhs.value, rhs.value));
3501         }
3502
3503         RValue<UInt4> operator+=(UInt4 &lhs, RValue<UInt4> rhs)
3504         {
3505                 return lhs = lhs + rhs;
3506         }
3507
3508         RValue<UInt4> operator-=(UInt4 &lhs, RValue<UInt4> rhs)
3509         {
3510                 return lhs = lhs - rhs;
3511         }
3512
3513         RValue<UInt4> operator*=(UInt4 &lhs, RValue<UInt4> rhs)
3514         {
3515                 return lhs = lhs * rhs;
3516         }
3517
3518 //      RValue<UInt4> operator/=(UInt4 &lhs, RValue<UInt4> rhs)
3519 //      {
3520 //              return lhs = lhs / rhs;
3521 //      }
3522
3523 //      RValue<UInt4> operator%=(UInt4 &lhs, RValue<UInt4> rhs)
3524 //      {
3525 //              return lhs = lhs % rhs;
3526 //      }
3527
3528         RValue<UInt4> operator&=(UInt4 &lhs, RValue<UInt4> rhs)
3529         {
3530                 return lhs = lhs & rhs;
3531         }
3532
3533         RValue<UInt4> operator|=(UInt4 &lhs, RValue<UInt4> rhs)
3534         {
3535                 return lhs = lhs | rhs;
3536         }
3537
3538         RValue<UInt4> operator^=(UInt4 &lhs, RValue<UInt4> rhs)
3539         {
3540                 return lhs = lhs ^ rhs;
3541         }
3542
3543         RValue<UInt4> operator<<=(UInt4 &lhs, unsigned char rhs)
3544         {
3545                 return lhs = lhs << rhs;
3546         }
3547
3548         RValue<UInt4> operator>>=(UInt4 &lhs, unsigned char rhs)
3549         {
3550                 return lhs = lhs >> rhs;
3551         }
3552
3553         RValue<UInt4> operator+(RValue<UInt4> val)
3554         {
3555                 return val;
3556         }
3557
3558         RValue<UInt4> operator-(RValue<UInt4> val)
3559         {
3560                 return RValue<UInt4>(Nucleus::createNeg(val.value));
3561         }
3562
3563         RValue<UInt4> operator~(RValue<UInt4> val)
3564         {
3565                 return RValue<UInt4>(Nucleus::createNot(val.value));
3566         }
3567
3568         Half::Half(RValue<Float> cast)
3569         {
3570                 UInt fp32i = As<UInt>(cast);
3571                 UInt abs = fp32i & 0x7FFFFFFF;
3572                 UShort fp16i((fp32i & 0x80000000) >> 16); // sign
3573
3574                 If(abs > 0x47FFEFFF) // Infinity
3575                 {
3576                         fp16i |= UShort(0x7FFF);
3577                 }
3578                 Else
3579                 {
3580                         If(abs < 0x38800000) // Denormal
3581                         {
3582                                 Int mantissa = (abs & 0x007FFFFF) | 0x00800000;
3583                                 Int e = 113 - (abs >> 23);
3584                                 abs = IfThenElse(e < 24, mantissa >> e, Int(0));
3585                                 fp16i |= UShort((abs + 0x00000FFF + ((abs >> 13) & 1)) >> 13);
3586                         }
3587                         Else
3588                         {
3589                                 fp16i |= UShort((abs + 0xC8000000 + 0x00000FFF + ((abs >> 13) & 1)) >> 13);
3590                         }
3591                 }
3592
3593                 storeValue(fp16i.loadValue());
3594         }
3595
3596         Float::Float(RValue<Int> cast)
3597         {
3598                 Value *integer = Nucleus::createSIToFP(cast.value, Float::getType());
3599
3600                 storeValue(integer);
3601         }
3602
3603         Float::Float(RValue<UInt> cast)
3604         {
3605                 RValue<Float> result = Float(Int(cast & UInt(0x7FFFFFFF))) +
3606                                        As<Float>((As<Int>(cast) >> 31) & As<Int>(Float(0x80000000u)));
3607
3608                 storeValue(result.value);
3609         }
3610
3611         Float::Float(RValue<Half> cast)
3612         {
3613                 Int fp16i(As<UShort>(cast));
3614
3615                 Int s = (fp16i >> 15) & 0x00000001;
3616                 Int e = (fp16i >> 10) & 0x0000001F;
3617                 Int m = fp16i & 0x000003FF;
3618
3619                 UInt fp32i(s << 31);
3620                 If(e == 0)
3621                 {
3622                         If(m != 0)
3623                         {
3624                                 While((m & 0x00000400) == 0)
3625                                 {
3626                                         m <<= 1;
3627                                         e -= 1;
3628                                 }
3629
3630                                 fp32i |= As<UInt>(((e + (127 - 15) + 1) << 23) | ((m & ~0x00000400) << 13));
3631                         }
3632                 }
3633                 Else
3634                 {
3635                         fp32i |= As<UInt>(((e + (127 - 15)) << 23) | (m << 13));
3636                 }
3637
3638                 storeValue(As<Float>(fp32i).value);
3639         }
3640
3641         Float::Float(float x)
3642         {
3643                 storeValue(Nucleus::createConstantFloat(x));
3644         }
3645
3646         Float::Float(RValue<Float> rhs)
3647         {
3648                 storeValue(rhs.value);
3649         }
3650
3651         Float::Float(const Float &rhs)
3652         {
3653                 Value *value = rhs.loadValue();
3654                 storeValue(value);
3655         }
3656
3657         Float::Float(const Reference<Float> &rhs)
3658         {
3659                 Value *value = rhs.loadValue();
3660                 storeValue(value);
3661         }
3662
3663         Float::Float(Argument<Float> argument)
3664         {
3665                 storeValue(argument.value);
3666         }
3667
3668         RValue<Float> Float::operator=(RValue<Float> rhs)
3669         {
3670                 storeValue(rhs.value);
3671
3672                 return rhs;
3673         }
3674
3675         RValue<Float> Float::operator=(const Float &rhs)
3676         {
3677                 Value *value = rhs.loadValue();
3678                 storeValue(value);
3679
3680                 return RValue<Float>(value);
3681         }
3682
3683         RValue<Float> Float::operator=(const Reference<Float> &rhs)
3684         {
3685                 Value *value = rhs.loadValue();
3686                 storeValue(value);
3687
3688                 return RValue<Float>(value);
3689         }
3690
3691         RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs)
3692         {
3693                 return RValue<Float>(Nucleus::createFAdd(lhs.value, rhs.value));
3694         }
3695
3696         RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs)
3697         {
3698                 return RValue<Float>(Nucleus::createFSub(lhs.value, rhs.value));
3699         }
3700
3701         RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs)
3702         {
3703                 return RValue<Float>(Nucleus::createFMul(lhs.value, rhs.value));
3704         }
3705
3706         RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs)
3707         {
3708                 return RValue<Float>(Nucleus::createFDiv(lhs.value, rhs.value));
3709         }
3710
3711         RValue<Float> operator+=(Float &lhs, RValue<Float> rhs)
3712         {
3713                 return lhs = lhs + rhs;
3714         }
3715
3716         RValue<Float> operator-=(Float &lhs, RValue<Float> rhs)
3717         {
3718                 return lhs = lhs - rhs;
3719         }
3720
3721         RValue<Float> operator*=(Float &lhs, RValue<Float> rhs)
3722         {
3723                 return lhs = lhs * rhs;
3724         }
3725
3726         RValue<Float> operator/=(Float &lhs, RValue<Float> rhs)
3727         {
3728                 return lhs = lhs / rhs;
3729         }
3730
3731         RValue<Float> operator+(RValue<Float> val)
3732         {
3733                 return val;
3734         }
3735
3736         RValue<Float> operator-(RValue<Float> val)
3737         {
3738                 return RValue<Float>(Nucleus::createFNeg(val.value));
3739         }
3740
3741         RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs)
3742         {
3743                 return RValue<Bool>(Nucleus::createFCmpOLT(lhs.value, rhs.value));
3744         }
3745
3746         RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs)
3747         {
3748                 return RValue<Bool>(Nucleus::createFCmpOLE(lhs.value, rhs.value));
3749         }
3750
3751         RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs)
3752         {
3753                 return RValue<Bool>(Nucleus::createFCmpOGT(lhs.value, rhs.value));
3754         }
3755
3756         RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs)
3757         {
3758                 return RValue<Bool>(Nucleus::createFCmpOGE(lhs.value, rhs.value));
3759         }
3760
3761         RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs)
3762         {
3763                 return RValue<Bool>(Nucleus::createFCmpONE(lhs.value, rhs.value));
3764         }
3765
3766         RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs)
3767         {
3768                 return RValue<Bool>(Nucleus::createFCmpOEQ(lhs.value, rhs.value));
3769         }
3770
3771         RValue<Float> Abs(RValue<Float> x)
3772         {
3773                 return IfThenElse(x > 0.0f, x, -x);
3774         }
3775
3776         RValue<Float> Max(RValue<Float> x, RValue<Float> y)
3777         {
3778                 return IfThenElse(x > y, x, y);
3779         }
3780
3781         RValue<Float> Min(RValue<Float> x, RValue<Float> y)
3782         {
3783                 return IfThenElse(x < y, x, y);
3784         }
3785
3786         Float2::Float2(RValue<Float4> cast)
3787         {
3788                 storeValue(Nucleus::createBitCast(cast.value, getType()));
3789         }
3790
3791         Float4::Float4(RValue<Byte4> cast) : XYZW(this)
3792         {
3793                 Value *a = Int4(cast).loadValue();
3794                 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
3795
3796                 storeValue(xyzw);
3797         }
3798
3799         Float4::Float4(RValue<SByte4> cast) : XYZW(this)
3800         {
3801                 Value *a = Int4(cast).loadValue();
3802                 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
3803
3804                 storeValue(xyzw);
3805         }
3806
3807         Float4::Float4(RValue<Short4> cast) : XYZW(this)
3808         {
3809                 Int4 c(cast);
3810                 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
3811         }
3812
3813         Float4::Float4(RValue<UShort4> cast) : XYZW(this)
3814         {
3815                 Int4 c(cast);
3816                 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
3817         }
3818
3819         Float4::Float4(RValue<Int4> cast) : XYZW(this)
3820         {
3821                 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType());
3822
3823                 storeValue(xyzw);
3824         }
3825
3826         Float4::Float4(RValue<UInt4> cast) : XYZW(this)
3827         {
3828                 RValue<Float4> result = Float4(Int4(cast & UInt4(0x7FFFFFFF))) +
3829                                         As<Float4>((As<Int4>(cast) >> 31) & As<Int4>(Float4(0x80000000u)));
3830
3831                 storeValue(result.value);
3832         }
3833
3834         Float4::Float4() : XYZW(this)
3835         {
3836         }
3837
3838         Float4::Float4(float xyzw) : XYZW(this)
3839         {
3840                 constant(xyzw, xyzw, xyzw, xyzw);
3841         }
3842
3843         Float4::Float4(float x, float yzw) : XYZW(this)
3844         {
3845                 constant(x, yzw, yzw, yzw);
3846         }
3847
3848         Float4::Float4(float x, float y, float zw) : XYZW(this)
3849         {
3850                 constant(x, y, zw, zw);
3851         }
3852
3853         Float4::Float4(float x, float y, float z, float w) : XYZW(this)
3854         {
3855                 constant(x, y, z, w);
3856         }
3857
3858         void Float4::constant(float x, float y, float z, float w)
3859         {
3860                 double constantVector[4] = {x, y, z, w};
3861                 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3862         }
3863
3864         Float4::Float4(RValue<Float4> rhs) : XYZW(this)
3865         {
3866                 storeValue(rhs.value);
3867         }
3868
3869         Float4::Float4(const Float4 &rhs) : XYZW(this)
3870         {
3871                 Value *value = rhs.loadValue();
3872                 storeValue(value);
3873         }
3874
3875         Float4::Float4(const Reference<Float4> &rhs) : XYZW(this)
3876         {
3877                 Value *value = rhs.loadValue();
3878                 storeValue(value);
3879         }
3880
3881         Float4::Float4(const Float &rhs) : XYZW(this)
3882         {
3883                 *this = RValue<Float>(rhs.loadValue());
3884         }
3885
3886         Float4::Float4(const Reference<Float> &rhs) : XYZW(this)
3887         {
3888                 *this = RValue<Float>(rhs.loadValue());
3889         }
3890
3891         RValue<Float4> Float4::operator=(float x)
3892         {
3893                 return *this = Float4(x, x, x, x);
3894         }
3895
3896         RValue<Float4> Float4::operator=(RValue<Float4> rhs)
3897         {
3898                 storeValue(rhs.value);
3899
3900                 return rhs;
3901         }
3902
3903         RValue<Float4> Float4::operator=(const Float4 &rhs)
3904         {
3905                 Value *value = rhs.loadValue();
3906                 storeValue(value);
3907
3908                 return RValue<Float4>(value);
3909         }
3910
3911         RValue<Float4> Float4::operator=(const Reference<Float4> &rhs)
3912         {
3913                 Value *value = rhs.loadValue();
3914                 storeValue(value);
3915
3916                 return RValue<Float4>(value);
3917         }
3918
3919         RValue<Float4> Float4::operator=(RValue<Float> rhs)
3920         {
3921                 return *this = Float4(rhs);
3922         }
3923
3924         RValue<Float4> Float4::operator=(const Float &rhs)
3925         {
3926                 return *this = Float4(rhs);
3927         }
3928
3929         RValue<Float4> Float4::operator=(const Reference<Float> &rhs)
3930         {
3931                 return *this = Float4(rhs);
3932         }
3933
3934         RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs)
3935         {
3936                 return RValue<Float4>(Nucleus::createFAdd(lhs.value, rhs.value));
3937         }
3938
3939         RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs)
3940         {
3941                 return RValue<Float4>(Nucleus::createFSub(lhs.value, rhs.value));
3942         }
3943
3944         RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs)
3945         {
3946                 return RValue<Float4>(Nucleus::createFMul(lhs.value, rhs.value));
3947         }
3948
3949         RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs)
3950         {
3951                 return RValue<Float4>(Nucleus::createFDiv(lhs.value, rhs.value));
3952         }
3953
3954         RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs)
3955         {
3956                 return RValue<Float4>(Nucleus::createFRem(lhs.value, rhs.value));
3957         }
3958
3959         RValue<Float4> operator+=(Float4 &lhs, RValue<Float4> rhs)
3960         {
3961                 return lhs = lhs + rhs;
3962         }
3963
3964         RValue<Float4> operator-=(Float4 &lhs, RValue<Float4> rhs)
3965         {
3966                 return lhs = lhs - rhs;
3967         }
3968
3969         RValue<Float4> operator*=(Float4 &lhs, RValue<Float4> rhs)
3970         {
3971                 return lhs = lhs * rhs;
3972         }
3973
3974         RValue<Float4> operator/=(Float4 &lhs, RValue<Float4> rhs)
3975         {
3976                 return lhs = lhs / rhs;
3977         }
3978
3979         RValue<Float4> operator%=(Float4 &lhs, RValue<Float4> rhs)
3980         {
3981                 return lhs = lhs % rhs;
3982         }
3983
3984         RValue<Float4> operator+(RValue<Float4> val)
3985         {
3986                 return val;
3987         }
3988
3989         RValue<Float4> operator-(RValue<Float4> val)
3990         {
3991                 return RValue<Float4>(Nucleus::createFNeg(val.value));
3992         }
3993
3994         RValue<Float4> Abs(RValue<Float4> x)
3995         {
3996                 // TODO: Optimize.
3997                 Value *vector = Nucleus::createBitCast(x.value, Int4::getType());
3998                 int64_t constantVector[4] = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF};
3999                 Value *result = Nucleus::createAnd(vector, Nucleus::createConstantVector(constantVector, Int4::getType()));
4000
4001                 return As<Float4>(result);
4002         }
4003
4004         RValue<Float4> Insert(RValue<Float4> x, RValue<Float> element, int i)
4005         {
4006                 return RValue<Float4>(Nucleus::createInsertElement(x.value, element.value, i));
4007         }
4008
4009         RValue<Float> Extract(RValue<Float4> x, int i)
4010         {
4011                 return RValue<Float>(Nucleus::createExtractElement(x.value, Float::getType(), i));
4012         }
4013
4014         RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select)
4015         {
4016                 return RValue<Float4>(createSwizzle4(x.value, select));
4017         }
4018
4019         RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
4020         {
4021                 int shuffle[4] =
4022                 {
4023                         ((imm >> 0) & 0x03) + 0,
4024                         ((imm >> 2) & 0x03) + 0,
4025                         ((imm >> 4) & 0x03) + 4,
4026                         ((imm >> 6) & 0x03) + 4,
4027                 };
4028
4029                 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
4030         }
4031
4032         RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y)
4033         {
4034                 int shuffle[4] = {0, 4, 1, 5};
4035                 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
4036         }
4037
4038         RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y)
4039         {
4040                 int shuffle[4] = {2, 6, 3, 7};
4041                 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
4042         }
4043
4044         RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select)
4045         {
4046                 Value *vector = lhs.loadValue();
4047                 Value *result = createMask4(vector, rhs.value, select);
4048                 lhs.storeValue(result);
4049
4050                 return RValue<Float4>(result);
4051         }
4052
4053         RValue<Int4> IsInf(RValue<Float4> x)
4054         {
4055                 return CmpEQ(As<Int4>(x) & Int4(0x7FFFFFFF), Int4(0x7F800000));
4056         }
4057
4058         RValue<Int4> IsNan(RValue<Float4> x)
4059         {
4060                 return ~CmpEQ(x, x);
4061         }
4062
4063         RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset)
4064         {
4065                 return lhs + RValue<Int>(Nucleus::createConstantInt(offset));
4066         }
4067
4068         RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
4069         {
4070                 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value, false));
4071         }
4072
4073         RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
4074         {
4075                 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value, true));
4076         }
4077
4078         RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, int offset)
4079         {
4080                 return lhs = lhs + offset;
4081         }
4082
4083         RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<Int> offset)
4084         {
4085                 return lhs = lhs + offset;
4086         }
4087
4088         RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<UInt> offset)
4089         {
4090                 return lhs = lhs + offset;
4091         }
4092
4093         RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset)
4094         {
4095                 return lhs + -offset;
4096         }
4097
4098         RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
4099         {
4100                 return lhs + -offset;
4101         }
4102
4103         RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
4104         {
4105                 return lhs + -offset;
4106         }
4107
4108         RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, int offset)
4109         {
4110                 return lhs = lhs - offset;
4111         }
4112
4113         RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<Int> offset)
4114         {
4115                 return lhs = lhs - offset;
4116         }
4117
4118         RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<UInt> offset)
4119         {
4120                 return lhs = lhs - offset;
4121         }
4122
4123         void Return()
4124         {
4125                 Nucleus::createRetVoid();
4126                 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
4127                 Nucleus::createUnreachable();
4128         }
4129
4130         void Return(RValue<Int> ret)
4131         {
4132                 Nucleus::createRet(ret.value);
4133                 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
4134                 Nucleus::createUnreachable();
4135         }
4136
4137         void branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB)
4138         {
4139                 Nucleus::createCondBr(cmp.value, bodyBB, endBB);
4140                 Nucleus::setInsertBlock(bodyBB);
4141         }
4142 }