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