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