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