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