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