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