• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 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 "Optimizer.hpp"
18 #include "ExecutableMemory.hpp"
19 
20 #include "src/IceTypes.h"
21 #include "src/IceCfg.h"
22 #include "src/IceELFStreamer.h"
23 #include "src/IceGlobalContext.h"
24 #include "src/IceCfgNode.h"
25 #include "src/IceELFObjectWriter.h"
26 #include "src/IceGlobalInits.h"
27 
28 #include "llvm/Support/FileSystem.h"
29 #include "llvm/Support/raw_os_ostream.h"
30 #include "llvm/Support/Compiler.h"
31 
32 #if __has_feature(memory_sanitizer)
33 #include <sanitizer/msan_interface.h>
34 #endif
35 
36 #if defined(_WIN32)
37 #ifndef WIN32_LEAN_AND_MEAN
38 #define WIN32_LEAN_AND_MEAN
39 #endif // !WIN32_LEAN_AND_MEAN
40 #ifndef NOMINMAX
41 #define NOMINMAX
42 #endif // !NOMINMAX
43 #include <Windows.h>
44 #else
45 #include <sys/mman.h>
46 #if !defined(MAP_ANONYMOUS)
47 #define MAP_ANONYMOUS MAP_ANON
48 #endif
49 #endif
50 
51 #include <mutex>
52 #include <limits>
53 #include <iostream>
54 #include <cassert>
55 
56 namespace
57 {
58 	Ice::GlobalContext *context = nullptr;
59 	Ice::Cfg *function = nullptr;
60 	Ice::CfgNode *basicBlock = nullptr;
61 	Ice::CfgLocalAllocatorScope *allocator = nullptr;
62 	rr::Routine *routine = nullptr;
63 
64 	std::mutex codegenMutex;
65 
66 	Ice::ELFFileStreamer *elfFile = nullptr;
67 	Ice::Fdstream *out = nullptr;
68 }
69 
70 namespace
71 {
72 	#if !defined(__i386__) && defined(_M_IX86)
73 		#define __i386__ 1
74 	#endif
75 
76 	#if !defined(__x86_64__) && (defined(_M_AMD64) || defined (_M_X64))
77 		#define __x86_64__ 1
78 	#endif
79 
80 	class CPUID
81 	{
82 	public:
83 		const static bool ARM;
84 		const static bool SSE4_1;
85 
86 	private:
cpuid(int registers[4],int info)87 		static void cpuid(int registers[4], int info)
88 		{
89 			#if defined(__i386__) || defined(__x86_64__)
90 				#if defined(_WIN32)
91 					__cpuid(registers, info);
92 				#else
93 					__asm volatile("cpuid": "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]): "a" (info));
94 				#endif
95 			#else
96 				registers[0] = 0;
97 				registers[1] = 0;
98 				registers[2] = 0;
99 				registers[3] = 0;
100 			#endif
101 		}
102 
detectARM()103 		static bool detectARM()
104 		{
105 			#if defined(__arm__) || defined(__aarch64__)
106 				return true;
107 			#elif defined(__i386__) || defined(__x86_64__)
108 				return false;
109 			#elif defined(__mips__)
110 				return false;
111 			#else
112 				#error "Unknown architecture"
113 			#endif
114 		}
115 
detectSSE4_1()116 		static bool detectSSE4_1()
117 		{
118 			#if defined(__i386__) || defined(__x86_64__)
119 				int registers[4];
120 				cpuid(registers, 1);
121 				return (registers[2] & 0x00080000) != 0;
122 			#else
123 				return false;
124 			#endif
125 		}
126 	};
127 
128 	const bool CPUID::ARM = CPUID::detectARM();
129 	const bool CPUID::SSE4_1 = CPUID::detectSSE4_1();
130 	const bool emulateIntrinsics = false;
131 	const bool emulateMismatchedBitCast = CPUID::ARM;
132 }
133 
134 namespace rr
135 {
136 	enum EmulatedType
137 	{
138 		EmulatedShift = 16,
139 		EmulatedV2 = 2 << EmulatedShift,
140 		EmulatedV4 = 4 << EmulatedShift,
141 		EmulatedV8 = 8 << EmulatedShift,
142 		EmulatedBits = EmulatedV2 | EmulatedV4 | EmulatedV8,
143 
144 		Type_v2i32 = Ice::IceType_v4i32 | EmulatedV2,
145 		Type_v4i16 = Ice::IceType_v8i16 | EmulatedV4,
146 		Type_v2i16 = Ice::IceType_v8i16 | EmulatedV2,
147 		Type_v8i8 =  Ice::IceType_v16i8 | EmulatedV8,
148 		Type_v4i8 =  Ice::IceType_v16i8 | EmulatedV4,
149 		Type_v2f32 = Ice::IceType_v4f32 | EmulatedV2,
150 	};
151 
152 	class Value : public Ice::Operand {};
153 	class SwitchCases : public Ice::InstSwitch {};
154 	class BasicBlock : public Ice::CfgNode {};
155 
T(Type * t)156 	Ice::Type T(Type *t)
157 	{
158 		static_assert(static_cast<unsigned int>(Ice::IceType_NUM) < static_cast<unsigned int>(EmulatedBits), "Ice::Type overlaps with our emulated types!");
159 		return (Ice::Type)(reinterpret_cast<std::intptr_t>(t) & ~EmulatedBits);
160 	}
161 
T(Ice::Type t)162 	Type *T(Ice::Type t)
163 	{
164 		return reinterpret_cast<Type*>(t);
165 	}
166 
T(EmulatedType t)167 	Type *T(EmulatedType t)
168 	{
169 		return reinterpret_cast<Type*>(t);
170 	}
171 
V(Ice::Operand * v)172 	Value *V(Ice::Operand *v)
173 	{
174 		return reinterpret_cast<Value*>(v);
175 	}
176 
B(Ice::CfgNode * b)177 	BasicBlock *B(Ice::CfgNode *b)
178 	{
179 		return reinterpret_cast<BasicBlock*>(b);
180 	}
181 
typeSize(Type * type)182 	static size_t typeSize(Type *type)
183 	{
184 		if(reinterpret_cast<std::intptr_t>(type) & EmulatedBits)
185 		{
186 			switch(reinterpret_cast<std::intptr_t>(type))
187 			{
188 			case Type_v2i32: return 8;
189 			case Type_v4i16: return 8;
190 			case Type_v2i16: return 4;
191 			case Type_v8i8:  return 8;
192 			case Type_v4i8:  return 4;
193 			case Type_v2f32: return 8;
194 			default: assert(false);
195 			}
196 		}
197 
198 		return Ice::typeWidthInBytes(T(type));
199 	}
200 
201 	Optimization optimization[10] = {InstructionCombining, Disabled};
202 
203 	using ElfHeader = std::conditional<sizeof(void*) == 8, Elf64_Ehdr, Elf32_Ehdr>::type;
204 	using SectionHeader = std::conditional<sizeof(void*) == 8, Elf64_Shdr, Elf32_Shdr>::type;
205 
sectionHeader(const ElfHeader * elfHeader)206 	inline const SectionHeader *sectionHeader(const ElfHeader *elfHeader)
207 	{
208 		return reinterpret_cast<const SectionHeader*>((intptr_t)elfHeader + elfHeader->e_shoff);
209 	}
210 
elfSection(const ElfHeader * elfHeader,int index)211 	inline const SectionHeader *elfSection(const ElfHeader *elfHeader, int index)
212 	{
213 		return &sectionHeader(elfHeader)[index];
214 	}
215 
relocateSymbol(const ElfHeader * elfHeader,const Elf32_Rel & relocation,const SectionHeader & relocationTable)216 	static void *relocateSymbol(const ElfHeader *elfHeader, const Elf32_Rel &relocation, const SectionHeader &relocationTable)
217 	{
218 		const SectionHeader *target = elfSection(elfHeader, relocationTable.sh_info);
219 
220 		uint32_t index = relocation.getSymbol();
221 		int table = relocationTable.sh_link;
222 		void *symbolValue = nullptr;
223 
224 		if(index != SHN_UNDEF)
225 		{
226 			if(table == SHN_UNDEF) return nullptr;
227 			const SectionHeader *symbolTable = elfSection(elfHeader, table);
228 
229 			uint32_t symtab_entries = symbolTable->sh_size / symbolTable->sh_entsize;
230 			if(index >= symtab_entries)
231 			{
232 				assert(index < symtab_entries && "Symbol Index out of range");
233 				return nullptr;
234 			}
235 
236 			intptr_t symbolAddress = (intptr_t)elfHeader + symbolTable->sh_offset;
237 			Elf32_Sym &symbol = ((Elf32_Sym*)symbolAddress)[index];
238 			uint16_t section = symbol.st_shndx;
239 
240 			if(section != SHN_UNDEF && section < SHN_LORESERVE)
241 			{
242 				const SectionHeader *target = elfSection(elfHeader, symbol.st_shndx);
243 				symbolValue = reinterpret_cast<void*>((intptr_t)elfHeader + symbol.st_value + target->sh_offset);
244 			}
245 			else
246 			{
247 				return nullptr;
248 			}
249 		}
250 
251 		intptr_t address = (intptr_t)elfHeader + target->sh_offset;
252 		unaligned_ptr<int32_t> patchSite = (int32_t*)(address + relocation.r_offset);
253 
254 		if(CPUID::ARM)
255 		{
256 			switch(relocation.getType())
257 			{
258 			case R_ARM_NONE:
259 				// No relocation
260 				break;
261 			case R_ARM_MOVW_ABS_NC:
262 				{
263 					uint32_t thumb = 0;   // Calls to Thumb code not supported.
264 					uint32_t lo = (uint32_t)(intptr_t)symbolValue | thumb;
265 					*patchSite = (*patchSite & 0xFFF0F000) | ((lo & 0xF000) << 4) | (lo & 0x0FFF);
266 				}
267 				break;
268 			case R_ARM_MOVT_ABS:
269 				{
270 					uint32_t hi = (uint32_t)(intptr_t)(symbolValue) >> 16;
271 					*patchSite = (*patchSite & 0xFFF0F000) | ((hi & 0xF000) << 4) | (hi & 0x0FFF);
272 				}
273 				break;
274 			default:
275 				assert(false && "Unsupported relocation type");
276 				return nullptr;
277 			}
278 		}
279 		else
280 		{
281 			switch(relocation.getType())
282 			{
283 			case R_386_NONE:
284 				// No relocation
285 				break;
286 			case R_386_32:
287 				*patchSite = (int32_t)((intptr_t)symbolValue + *patchSite);
288 				break;
289 		//	case R_386_PC32:
290 		//		*patchSite = (int32_t)((intptr_t)symbolValue + *patchSite - (intptr_t)patchSite);
291 		//		break;
292 			default:
293 				assert(false && "Unsupported relocation type");
294 				return nullptr;
295 			}
296 		}
297 
298 		return symbolValue;
299 	}
300 
relocateSymbol(const ElfHeader * elfHeader,const Elf64_Rela & relocation,const SectionHeader & relocationTable)301 	static void *relocateSymbol(const ElfHeader *elfHeader, const Elf64_Rela &relocation, const SectionHeader &relocationTable)
302 	{
303 		const SectionHeader *target = elfSection(elfHeader, relocationTable.sh_info);
304 
305 		uint32_t index = relocation.getSymbol();
306 		int table = relocationTable.sh_link;
307 		void *symbolValue = nullptr;
308 
309 		if(index != SHN_UNDEF)
310 		{
311 			if(table == SHN_UNDEF) return nullptr;
312 			const SectionHeader *symbolTable = elfSection(elfHeader, table);
313 
314 			uint32_t symtab_entries = symbolTable->sh_size / symbolTable->sh_entsize;
315 			if(index >= symtab_entries)
316 			{
317 				assert(index < symtab_entries && "Symbol Index out of range");
318 				return nullptr;
319 			}
320 
321 			intptr_t symbolAddress = (intptr_t)elfHeader + symbolTable->sh_offset;
322 			Elf64_Sym &symbol = ((Elf64_Sym*)symbolAddress)[index];
323 			uint16_t section = symbol.st_shndx;
324 
325 			if(section != SHN_UNDEF && section < SHN_LORESERVE)
326 			{
327 				const SectionHeader *target = elfSection(elfHeader, symbol.st_shndx);
328 				symbolValue = reinterpret_cast<void*>((intptr_t)elfHeader + symbol.st_value + target->sh_offset);
329 			}
330 			else
331 			{
332 				return nullptr;
333 			}
334 		}
335 
336 		intptr_t address = (intptr_t)elfHeader + target->sh_offset;
337 		unaligned_ptr<int32_t> patchSite32 = (int32_t*)(address + relocation.r_offset);
338 		unaligned_ptr<int64_t> patchSite64 = (int64_t*)(address + relocation.r_offset);
339 
340 		switch(relocation.getType())
341 		{
342 		case R_X86_64_NONE:
343 			// No relocation
344 			break;
345 		case R_X86_64_64:
346 			*patchSite64 = (int64_t)((intptr_t)symbolValue + *patchSite64 + relocation.r_addend);
347 			break;
348 		case R_X86_64_PC32:
349 			*patchSite32 = (int32_t)((intptr_t)symbolValue + *patchSite32 - (intptr_t)patchSite32 + relocation.r_addend);
350 			break;
351 		case R_X86_64_32S:
352 			*patchSite32 = (int32_t)((intptr_t)symbolValue + *patchSite32 + relocation.r_addend);
353 			break;
354 		default:
355 			assert(false && "Unsupported relocation type");
356 			return nullptr;
357 		}
358 
359 		return symbolValue;
360 	}
361 
loadImage(uint8_t * const elfImage,size_t & codeSize)362 	void *loadImage(uint8_t *const elfImage, size_t &codeSize)
363 	{
364 		ElfHeader *elfHeader = (ElfHeader*)elfImage;
365 
366 		if(!elfHeader->checkMagic())
367 		{
368 			return nullptr;
369 		}
370 
371 		// Expect ELF bitness to match platform
372 		assert(sizeof(void*) == 8 ? elfHeader->getFileClass() == ELFCLASS64 : elfHeader->getFileClass() == ELFCLASS32);
373 		#if defined(__i386__)
374 			assert(sizeof(void*) == 4 && elfHeader->e_machine == EM_386);
375 		#elif defined(__x86_64__)
376 			assert(sizeof(void*) == 8 && elfHeader->e_machine == EM_X86_64);
377 		#elif defined(__arm__)
378 			assert(sizeof(void*) == 4 && elfHeader->e_machine == EM_ARM);
379 		#elif defined(__aarch64__)
380 			assert(sizeof(void*) == 8 && elfHeader->e_machine == EM_AARCH64);
381 		#elif defined(__mips__)
382 			assert(sizeof(void*) == 4 && elfHeader->e_machine == EM_MIPS);
383 		#else
384 			#error "Unsupported platform"
385 		#endif
386 
387 		SectionHeader *sectionHeader = (SectionHeader*)(elfImage + elfHeader->e_shoff);
388 		void *entry = nullptr;
389 
390 		for(int i = 0; i < elfHeader->e_shnum; i++)
391 		{
392 			if(sectionHeader[i].sh_type == SHT_PROGBITS)
393 			{
394 				if(sectionHeader[i].sh_flags & SHF_EXECINSTR)
395 				{
396 					entry = elfImage + sectionHeader[i].sh_offset;
397 					codeSize = sectionHeader[i].sh_size;
398 				}
399 			}
400 			else if(sectionHeader[i].sh_type == SHT_REL)
401 			{
402 				assert(sizeof(void*) == 4 && "UNIMPLEMENTED");   // Only expected/implemented for 32-bit code
403 
404 				for(Elf32_Word index = 0; index < sectionHeader[i].sh_size / sectionHeader[i].sh_entsize; index++)
405 				{
406 					const Elf32_Rel &relocation = ((const Elf32_Rel*)(elfImage + sectionHeader[i].sh_offset))[index];
407 					relocateSymbol(elfHeader, relocation, sectionHeader[i]);
408 				}
409 			}
410 			else if(sectionHeader[i].sh_type == SHT_RELA)
411 			{
412 				assert(sizeof(void*) == 8 && "UNIMPLEMENTED");   // Only expected/implemented for 64-bit code
413 
414 				for(Elf32_Word index = 0; index < sectionHeader[i].sh_size / sectionHeader[i].sh_entsize; index++)
415 				{
416 					const Elf64_Rela &relocation = ((const Elf64_Rela*)(elfImage + sectionHeader[i].sh_offset))[index];
417 					relocateSymbol(elfHeader, relocation, sectionHeader[i]);
418 				}
419 			}
420 		}
421 
422 		return entry;
423 	}
424 
425 	template<typename T>
426 	struct ExecutableAllocator
427 	{
ExecutableAllocatorrr::ExecutableAllocator428 		ExecutableAllocator() {};
ExecutableAllocatorrr::ExecutableAllocator429 		template<class U> ExecutableAllocator(const ExecutableAllocator<U> &other) {};
430 
431 		using value_type = T;
432 		using size_type = std::size_t;
433 
allocaterr::ExecutableAllocator434 		T *allocate(size_type n)
435 		{
436 			return (T*)allocateExecutable(sizeof(T) * n);
437 		}
438 
deallocaterr::ExecutableAllocator439 		void deallocate(T *p, size_type n)
440 		{
441 			deallocateExecutable(p, sizeof(T) * n);
442 		}
443 	};
444 
445 	class ELFMemoryStreamer : public Ice::ELFStreamer, public Routine
446 	{
447 		ELFMemoryStreamer(const ELFMemoryStreamer &) = delete;
448 		ELFMemoryStreamer &operator=(const ELFMemoryStreamer &) = delete;
449 
450 	public:
ELFMemoryStreamer()451 		ELFMemoryStreamer() : Routine(), entry(nullptr)
452 		{
453 			position = 0;
454 			buffer.reserve(0x1000);
455 		}
456 
~ELFMemoryStreamer()457 		~ELFMemoryStreamer() override
458 		{
459 			#if defined(_WIN32)
460 				if(buffer.size() != 0)
461 				{
462 					DWORD exeProtection;
463 					VirtualProtect(&buffer[0], buffer.size(), oldProtection, &exeProtection);
464 				}
465 			#endif
466 		}
467 
write8(uint8_t Value)468 		void write8(uint8_t Value) override
469 		{
470 			if(position == (uint64_t)buffer.size())
471 			{
472 				buffer.push_back(Value);
473 				position++;
474 			}
475 			else if(position < (uint64_t)buffer.size())
476 			{
477 				buffer[position] = Value;
478 				position++;
479 			}
480 			else assert(false && "UNIMPLEMENTED");
481 		}
482 
writeBytes(llvm::StringRef Bytes)483 		void writeBytes(llvm::StringRef Bytes) override
484 		{
485 			std::size_t oldSize = buffer.size();
486 			buffer.resize(oldSize + Bytes.size());
487 			memcpy(&buffer[oldSize], Bytes.begin(), Bytes.size());
488 			position += Bytes.size();
489 		}
490 
tell() const491 		uint64_t tell() const override { return position; }
492 
seek(uint64_t Off)493 		void seek(uint64_t Off) override { position = Off; }
494 
getEntry()495 		const void *getEntry() override
496 		{
497 			if(!entry)
498 			{
499 				position = std::numeric_limits<std::size_t>::max();   // Can't stream more data after this
500 
501 				size_t codeSize = 0;
502 				entry = loadImage(&buffer[0], codeSize);
503 
504 				#if defined(_WIN32)
505 					VirtualProtect(&buffer[0], buffer.size(), PAGE_EXECUTE_READ, &oldProtection);
506 					FlushInstructionCache(GetCurrentProcess(), NULL, 0);
507 				#else
508 					mprotect(&buffer[0], buffer.size(), PROT_READ | PROT_EXEC);
509 					__builtin___clear_cache((char*)entry, (char*)entry + codeSize);
510 				#endif
511 			}
512 
513 			return entry;
514 		}
515 
516 	private:
517 		void *entry;
518 		std::vector<uint8_t, ExecutableAllocator<uint8_t>> buffer;
519 		std::size_t position;
520 
521 		#if defined(_WIN32)
522 		DWORD oldProtection;
523 		#endif
524 	};
525 
Nucleus()526 	Nucleus::Nucleus()
527 	{
528 		::codegenMutex.lock();   // Reactor is currently not thread safe
529 
530 		Ice::ClFlags &Flags = Ice::ClFlags::Flags;
531 		Ice::ClFlags::getParsedClFlags(Flags);
532 
533 		#if defined(__arm__)
534 			Flags.setTargetArch(Ice::Target_ARM32);
535 			Flags.setTargetInstructionSet(Ice::ARM32InstructionSet_HWDivArm);
536 		#elif defined(__mips__)
537 			Flags.setTargetArch(Ice::Target_MIPS32);
538 			Flags.setTargetInstructionSet(Ice::BaseInstructionSet);
539 		#else   // x86
540 			Flags.setTargetArch(sizeof(void*) == 8 ? Ice::Target_X8664 : Ice::Target_X8632);
541 			Flags.setTargetInstructionSet(CPUID::SSE4_1 ? Ice::X86InstructionSet_SSE4_1 : Ice::X86InstructionSet_SSE2);
542 		#endif
543 		Flags.setOutFileType(Ice::FT_Elf);
544 		Flags.setOptLevel(Ice::Opt_2);
545 		Flags.setApplicationBinaryInterface(Ice::ABI_Platform);
546 		Flags.setVerbose(false ? Ice::IceV_Most : Ice::IceV_None);
547 		Flags.setDisableHybridAssembly(true);
548 
549 		static llvm::raw_os_ostream cout(std::cout);
550 		static llvm::raw_os_ostream cerr(std::cerr);
551 
552 		if(false)   // Write out to a file
553 		{
554 			std::error_code errorCode;
555 			::out = new Ice::Fdstream("out.o", errorCode, llvm::sys::fs::F_None);
556 			::elfFile = new Ice::ELFFileStreamer(*out);
557 			::context = new Ice::GlobalContext(&cout, &cout, &cerr, elfFile);
558 		}
559 		else
560 		{
561 			ELFMemoryStreamer *elfMemory = new ELFMemoryStreamer();
562 			::context = new Ice::GlobalContext(&cout, &cout, &cerr, elfMemory);
563 			::routine = elfMemory;
564 		}
565 	}
566 
~Nucleus()567 	Nucleus::~Nucleus()
568 	{
569 		delete ::routine;
570 
571 		delete ::allocator;
572 		delete ::function;
573 		delete ::context;
574 
575 		delete ::elfFile;
576 		delete ::out;
577 
578 		::codegenMutex.unlock();
579 	}
580 
acquireRoutine(const char * name,bool runOptimizations)581 	Routine *Nucleus::acquireRoutine(const char *name, bool runOptimizations)
582 	{
583 		if(basicBlock->getInsts().empty() || basicBlock->getInsts().back().getKind() != Ice::Inst::Ret)
584 		{
585 			createRetVoid();
586 		}
587 
588 		::function->setFunctionName(Ice::GlobalString::createWithString(::context, name));
589 
590 		optimize();
591 
592 		::function->translate();
593 		assert(!::function->hasError());
594 
595 		auto globals = ::function->getGlobalInits();
596 
597 		if(globals && !globals->empty())
598 		{
599 			::context->getGlobals()->merge(globals.get());
600 		}
601 
602 		::context->emitFileHeader();
603 		::function->emitIAS();
604 		auto assembler = ::function->releaseAssembler();
605 		auto objectWriter = ::context->getObjectWriter();
606 		assembler->alignFunction();
607 		objectWriter->writeFunctionCode(::function->getFunctionName(), false, assembler.get());
608 		::context->lowerGlobals("last");
609 		::context->lowerConstants();
610 		::context->lowerJumpTables();
611 		objectWriter->setUndefinedSyms(::context->getConstantExternSyms());
612 		objectWriter->writeNonUserSections();
613 
614 		Routine *handoffRoutine = ::routine;
615 		::routine = nullptr;
616 
617 		return handoffRoutine;
618 	}
619 
optimize()620 	void Nucleus::optimize()
621 	{
622 		rr::optimize(::function);
623 	}
624 
allocateStackVariable(Type * t,int arraySize)625 	Value *Nucleus::allocateStackVariable(Type *t, int arraySize)
626 	{
627 		Ice::Type type = T(t);
628 		int typeSize = Ice::typeWidthInBytes(type);
629 		int totalSize = typeSize * (arraySize ? arraySize : 1);
630 
631 		auto bytes = Ice::ConstantInteger32::create(::context, type, totalSize);
632 		auto address = ::function->makeVariable(T(getPointerType(t)));
633 		auto alloca = Ice::InstAlloca::create(::function, address, bytes, typeSize);
634 		::function->getEntryNode()->getInsts().push_front(alloca);
635 
636 		return V(address);
637 	}
638 
createBasicBlock()639 	BasicBlock *Nucleus::createBasicBlock()
640 	{
641 		return B(::function->makeNode());
642 	}
643 
getInsertBlock()644 	BasicBlock *Nucleus::getInsertBlock()
645 	{
646 		return B(::basicBlock);
647 	}
648 
setInsertBlock(BasicBlock * basicBlock)649 	void Nucleus::setInsertBlock(BasicBlock *basicBlock)
650 	{
651 	//	assert(::basicBlock->getInsts().back().getTerminatorEdges().size() >= 0 && "Previous basic block must have a terminator");
652 		::basicBlock = basicBlock;
653 	}
654 
createFunction(Type * ReturnType,std::vector<Type * > & Params)655 	void Nucleus::createFunction(Type *ReturnType, std::vector<Type*> &Params)
656 	{
657 		uint32_t sequenceNumber = 0;
658 		::function = Ice::Cfg::create(::context, sequenceNumber).release();
659 		::allocator = new Ice::CfgLocalAllocatorScope(::function);
660 
661 		for(Type *type : Params)
662 		{
663 			Ice::Variable *arg = ::function->makeVariable(T(type));
664 			::function->addArg(arg);
665 		}
666 
667 		Ice::CfgNode *node = ::function->makeNode();
668 		::function->setEntryNode(node);
669 		::basicBlock = node;
670 	}
671 
getArgument(unsigned int index)672 	Value *Nucleus::getArgument(unsigned int index)
673 	{
674 		return V(::function->getArgs()[index]);
675 	}
676 
createRetVoid()677 	void Nucleus::createRetVoid()
678 	{
679 		Ice::InstRet *ret = Ice::InstRet::create(::function);
680 		::basicBlock->appendInst(ret);
681 	}
682 
createRet(Value * v)683 	void Nucleus::createRet(Value *v)
684 	{
685 		Ice::InstRet *ret = Ice::InstRet::create(::function, v);
686 		::basicBlock->appendInst(ret);
687 	}
688 
createBr(BasicBlock * dest)689 	void Nucleus::createBr(BasicBlock *dest)
690 	{
691 		auto br = Ice::InstBr::create(::function, dest);
692 		::basicBlock->appendInst(br);
693 	}
694 
createCondBr(Value * cond,BasicBlock * ifTrue,BasicBlock * ifFalse)695 	void Nucleus::createCondBr(Value *cond, BasicBlock *ifTrue, BasicBlock *ifFalse)
696 	{
697 		auto br = Ice::InstBr::create(::function, cond, ifTrue, ifFalse);
698 		::basicBlock->appendInst(br);
699 	}
700 
isCommutative(Ice::InstArithmetic::OpKind op)701 	static bool isCommutative(Ice::InstArithmetic::OpKind op)
702 	{
703 		switch(op)
704 		{
705 		case Ice::InstArithmetic::Add:
706 		case Ice::InstArithmetic::Fadd:
707 		case Ice::InstArithmetic::Mul:
708 		case Ice::InstArithmetic::Fmul:
709 		case Ice::InstArithmetic::And:
710 		case Ice::InstArithmetic::Or:
711 		case Ice::InstArithmetic::Xor:
712 			return true;
713 		default:
714 			return false;
715 		}
716 	}
717 
createArithmetic(Ice::InstArithmetic::OpKind op,Value * lhs,Value * rhs)718 	static Value *createArithmetic(Ice::InstArithmetic::OpKind op, Value *lhs, Value *rhs)
719 	{
720 		assert(lhs->getType() == rhs->getType() || llvm::isa<Ice::Constant>(rhs));
721 
722 		bool swapOperands = llvm::isa<Ice::Constant>(lhs) && isCommutative(op);
723 
724 		Ice::Variable *result = ::function->makeVariable(lhs->getType());
725 		Ice::InstArithmetic *arithmetic = Ice::InstArithmetic::create(::function, op, result, swapOperands ? rhs : lhs, swapOperands ? lhs : rhs);
726 		::basicBlock->appendInst(arithmetic);
727 
728 		return V(result);
729 	}
730 
createAdd(Value * lhs,Value * rhs)731 	Value *Nucleus::createAdd(Value *lhs, Value *rhs)
732 	{
733 		return createArithmetic(Ice::InstArithmetic::Add, lhs, rhs);
734 	}
735 
createSub(Value * lhs,Value * rhs)736 	Value *Nucleus::createSub(Value *lhs, Value *rhs)
737 	{
738 		return createArithmetic(Ice::InstArithmetic::Sub, lhs, rhs);
739 	}
740 
createMul(Value * lhs,Value * rhs)741 	Value *Nucleus::createMul(Value *lhs, Value *rhs)
742 	{
743 		return createArithmetic(Ice::InstArithmetic::Mul, lhs, rhs);
744 	}
745 
createUDiv(Value * lhs,Value * rhs)746 	Value *Nucleus::createUDiv(Value *lhs, Value *rhs)
747 	{
748 		return createArithmetic(Ice::InstArithmetic::Udiv, lhs, rhs);
749 	}
750 
createSDiv(Value * lhs,Value * rhs)751 	Value *Nucleus::createSDiv(Value *lhs, Value *rhs)
752 	{
753 		return createArithmetic(Ice::InstArithmetic::Sdiv, lhs, rhs);
754 	}
755 
createFAdd(Value * lhs,Value * rhs)756 	Value *Nucleus::createFAdd(Value *lhs, Value *rhs)
757 	{
758 		return createArithmetic(Ice::InstArithmetic::Fadd, lhs, rhs);
759 	}
760 
createFSub(Value * lhs,Value * rhs)761 	Value *Nucleus::createFSub(Value *lhs, Value *rhs)
762 	{
763 		return createArithmetic(Ice::InstArithmetic::Fsub, lhs, rhs);
764 	}
765 
createFMul(Value * lhs,Value * rhs)766 	Value *Nucleus::createFMul(Value *lhs, Value *rhs)
767 	{
768 		return createArithmetic(Ice::InstArithmetic::Fmul, lhs, rhs);
769 	}
770 
createFDiv(Value * lhs,Value * rhs)771 	Value *Nucleus::createFDiv(Value *lhs, Value *rhs)
772 	{
773 		return createArithmetic(Ice::InstArithmetic::Fdiv, lhs, rhs);
774 	}
775 
createURem(Value * lhs,Value * rhs)776 	Value *Nucleus::createURem(Value *lhs, Value *rhs)
777 	{
778 		return createArithmetic(Ice::InstArithmetic::Urem, lhs, rhs);
779 	}
780 
createSRem(Value * lhs,Value * rhs)781 	Value *Nucleus::createSRem(Value *lhs, Value *rhs)
782 	{
783 		return createArithmetic(Ice::InstArithmetic::Srem, lhs, rhs);
784 	}
785 
createFRem(Value * lhs,Value * rhs)786 	Value *Nucleus::createFRem(Value *lhs, Value *rhs)
787 	{
788 		return createArithmetic(Ice::InstArithmetic::Frem, lhs, rhs);
789 	}
790 
createShl(Value * lhs,Value * rhs)791 	Value *Nucleus::createShl(Value *lhs, Value *rhs)
792 	{
793 		return createArithmetic(Ice::InstArithmetic::Shl, lhs, rhs);
794 	}
795 
createLShr(Value * lhs,Value * rhs)796 	Value *Nucleus::createLShr(Value *lhs, Value *rhs)
797 	{
798 		return createArithmetic(Ice::InstArithmetic::Lshr, lhs, rhs);
799 	}
800 
createAShr(Value * lhs,Value * rhs)801 	Value *Nucleus::createAShr(Value *lhs, Value *rhs)
802 	{
803 		return createArithmetic(Ice::InstArithmetic::Ashr, lhs, rhs);
804 	}
805 
createAnd(Value * lhs,Value * rhs)806 	Value *Nucleus::createAnd(Value *lhs, Value *rhs)
807 	{
808 		return createArithmetic(Ice::InstArithmetic::And, lhs, rhs);
809 	}
810 
createOr(Value * lhs,Value * rhs)811 	Value *Nucleus::createOr(Value *lhs, Value *rhs)
812 	{
813 		return createArithmetic(Ice::InstArithmetic::Or, lhs, rhs);
814 	}
815 
createXor(Value * lhs,Value * rhs)816 	Value *Nucleus::createXor(Value *lhs, Value *rhs)
817 	{
818 		return createArithmetic(Ice::InstArithmetic::Xor, lhs, rhs);
819 	}
820 
createNeg(Value * v)821 	Value *Nucleus::createNeg(Value *v)
822 	{
823 		return createSub(createNullValue(T(v->getType())), v);
824 	}
825 
createFNeg(Value * v)826 	Value *Nucleus::createFNeg(Value *v)
827 	{
828 		double c[4] = {-0.0, -0.0, -0.0, -0.0};
829 		Value *negativeZero = Ice::isVectorType(v->getType()) ?
830 		                      createConstantVector(c, T(v->getType())) :
831 		                      V(::context->getConstantFloat(-0.0f));
832 
833 		return createFSub(negativeZero, v);
834 	}
835 
createNot(Value * v)836 	Value *Nucleus::createNot(Value *v)
837 	{
838 		if(Ice::isScalarIntegerType(v->getType()))
839 		{
840 			return createXor(v, V(::context->getConstantInt(v->getType(), -1)));
841 		}
842 		else   // Vector
843 		{
844 			int64_t c[16] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
845 			return createXor(v, createConstantVector(c, T(v->getType())));
846 		}
847 	}
848 
createLoad(Value * ptr,Type * type,bool isVolatile,unsigned int align)849 	Value *Nucleus::createLoad(Value *ptr, Type *type, bool isVolatile, unsigned int align)
850 	{
851 		int valueType = (int)reinterpret_cast<intptr_t>(type);
852 		Ice::Variable *result = ::function->makeVariable(T(type));
853 
854 		if((valueType & EmulatedBits) && (align != 0))   // Narrow vector not stored on stack.
855 		{
856 			if(emulateIntrinsics)
857 			{
858 				if(typeSize(type) == 4)
859 				{
860 					auto pointer = RValue<Pointer<Byte>>(ptr);
861 					Int x = *Pointer<Int>(pointer);
862 
863 					Int4 vector;
864 					vector = Insert(vector, x, 0);
865 
866 					auto bitcast = Ice::InstCast::create(::function, Ice::InstCast::Bitcast, result, vector.loadValue());
867 					::basicBlock->appendInst(bitcast);
868 				}
869 				else if(typeSize(type) == 8)
870 				{
871 					auto pointer = RValue<Pointer<Byte>>(ptr);
872 					Int x = *Pointer<Int>(pointer);
873 					Int y = *Pointer<Int>(pointer + 4);
874 
875 					Int4 vector;
876 					vector = Insert(vector, x, 0);
877 					vector = Insert(vector, y, 1);
878 
879 					auto bitcast = Ice::InstCast::create(::function, Ice::InstCast::Bitcast, result, vector.loadValue());
880 					::basicBlock->appendInst(bitcast);
881 				}
882 				else assert(false);
883 			}
884 			else
885 			{
886 				const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::LoadSubVector, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
887 				auto target = ::context->getConstantUndef(Ice::IceType_i32);
888 				auto load = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
889 				load->addArg(ptr);
890 				load->addArg(::context->getConstantInt32(typeSize(type)));
891 				::basicBlock->appendInst(load);
892 			}
893 		}
894 		else
895 		{
896 			auto load = Ice::InstLoad::create(::function, result, ptr, align);
897 			::basicBlock->appendInst(load);
898 		}
899 
900 		return V(result);
901 	}
902 
createStore(Value * value,Value * ptr,Type * type,bool isVolatile,unsigned int align)903 	Value *Nucleus::createStore(Value *value, Value *ptr, Type *type, bool isVolatile, unsigned int align)
904 	{
905 		#if __has_feature(memory_sanitizer)
906 			// Mark all (non-stack) memory writes as initialized by calling __msan_unpoison
907 			if(align != 0)
908 			{
909 				auto call = Ice::InstCall::create(::function, 2, nullptr, ::context->getConstantInt64(reinterpret_cast<intptr_t>(__msan_unpoison)), false);
910 				call->addArg(ptr);
911 				call->addArg(::context->getConstantInt64(typeSize(type)));
912 				::basicBlock->appendInst(call);
913 			}
914 		#endif
915 
916 		int valueType = (int)reinterpret_cast<intptr_t>(type);
917 
918 		if((valueType & EmulatedBits) && (align != 0))   // Narrow vector not stored on stack.
919 		{
920 			if(emulateIntrinsics)
921 			{
922 				if(typeSize(type) == 4)
923 				{
924 					Ice::Variable *vector = ::function->makeVariable(Ice::IceType_v4i32);
925 					auto bitcast = Ice::InstCast::create(::function, Ice::InstCast::Bitcast, vector, value);
926 					::basicBlock->appendInst(bitcast);
927 
928 					RValue<Int4> v(V(vector));
929 
930 					auto pointer = RValue<Pointer<Byte>>(ptr);
931 					Int x = Extract(v, 0);
932 					*Pointer<Int>(pointer) = x;
933 				}
934 				else if(typeSize(type) == 8)
935 				{
936 					Ice::Variable *vector = ::function->makeVariable(Ice::IceType_v4i32);
937 					auto bitcast = Ice::InstCast::create(::function, Ice::InstCast::Bitcast, vector, value);
938 					::basicBlock->appendInst(bitcast);
939 
940 					RValue<Int4> v(V(vector));
941 
942 					auto pointer = RValue<Pointer<Byte>>(ptr);
943 					Int x = Extract(v, 0);
944 					*Pointer<Int>(pointer) = x;
945 					Int y = Extract(v, 1);
946 					*Pointer<Int>(pointer + 4) = y;
947 				}
948 				else assert(false);
949 			}
950 			else
951 			{
952 				const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::StoreSubVector, Ice::Intrinsics::SideEffects_T, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_T};
953 				auto target = ::context->getConstantUndef(Ice::IceType_i32);
954 				auto store = Ice::InstIntrinsicCall::create(::function, 3, nullptr, target, intrinsic);
955 				store->addArg(value);
956 				store->addArg(ptr);
957 				store->addArg(::context->getConstantInt32(typeSize(type)));
958 				::basicBlock->appendInst(store);
959 			}
960 		}
961 		else
962 		{
963 			assert(value->getType() == T(type));
964 
965 			auto store = Ice::InstStore::create(::function, value, ptr, align);
966 			::basicBlock->appendInst(store);
967 		}
968 
969 		return value;
970 	}
971 
createGEP(Value * ptr,Type * type,Value * index,bool unsignedIndex)972 	Value *Nucleus::createGEP(Value *ptr, Type *type, Value *index, bool unsignedIndex)
973 	{
974 		assert(index->getType() == Ice::IceType_i32);
975 
976 		if(auto *constant = llvm::dyn_cast<Ice::ConstantInteger32>(index))
977 		{
978 			int32_t offset = constant->getValue() * (int)typeSize(type);
979 
980 			if(offset == 0)
981 			{
982 				return ptr;
983 			}
984 
985 			return createAdd(ptr, createConstantInt(offset));
986 		}
987 
988 		if(!Ice::isByteSizedType(T(type)))
989 		{
990 			index = createMul(index, createConstantInt((int)typeSize(type)));
991 		}
992 
993 		if(sizeof(void*) == 8)
994 		{
995 			if(unsignedIndex)
996 			{
997 				index = createZExt(index, T(Ice::IceType_i64));
998 			}
999 			else
1000 			{
1001 				index = createSExt(index, T(Ice::IceType_i64));
1002 			}
1003 		}
1004 
1005 		return createAdd(ptr, index);
1006 	}
1007 
createAtomicAdd(Value * ptr,Value * value)1008 	Value *Nucleus::createAtomicAdd(Value *ptr, Value *value)
1009 	{
1010 		assert(false && "UNIMPLEMENTED"); return nullptr;
1011 	}
1012 
createCast(Ice::InstCast::OpKind op,Value * v,Type * destType)1013 	static Value *createCast(Ice::InstCast::OpKind op, Value *v, Type *destType)
1014 	{
1015 		if(v->getType() == T(destType))
1016 		{
1017 			return v;
1018 		}
1019 
1020 		Ice::Variable *result = ::function->makeVariable(T(destType));
1021 		Ice::InstCast *cast = Ice::InstCast::create(::function, op, result, v);
1022 		::basicBlock->appendInst(cast);
1023 
1024 		return V(result);
1025 	}
1026 
createTrunc(Value * v,Type * destType)1027 	Value *Nucleus::createTrunc(Value *v, Type *destType)
1028 	{
1029 		return createCast(Ice::InstCast::Trunc, v, destType);
1030 	}
1031 
createZExt(Value * v,Type * destType)1032 	Value *Nucleus::createZExt(Value *v, Type *destType)
1033 	{
1034 		return createCast(Ice::InstCast::Zext, v, destType);
1035 	}
1036 
createSExt(Value * v,Type * destType)1037 	Value *Nucleus::createSExt(Value *v, Type *destType)
1038 	{
1039 		return createCast(Ice::InstCast::Sext, v, destType);
1040 	}
1041 
createFPToSI(Value * v,Type * destType)1042 	Value *Nucleus::createFPToSI(Value *v, Type *destType)
1043 	{
1044 		return createCast(Ice::InstCast::Fptosi, v, destType);
1045 	}
1046 
createSIToFP(Value * v,Type * destType)1047 	Value *Nucleus::createSIToFP(Value *v, Type *destType)
1048 	{
1049 		return createCast(Ice::InstCast::Sitofp, v, destType);
1050 	}
1051 
createFPTrunc(Value * v,Type * destType)1052 	Value *Nucleus::createFPTrunc(Value *v, Type *destType)
1053 	{
1054 		return createCast(Ice::InstCast::Fptrunc, v, destType);
1055 	}
1056 
createFPExt(Value * v,Type * destType)1057 	Value *Nucleus::createFPExt(Value *v, Type *destType)
1058 	{
1059 		return createCast(Ice::InstCast::Fpext, v, destType);
1060 	}
1061 
createBitCast(Value * v,Type * destType)1062 	Value *Nucleus::createBitCast(Value *v, Type *destType)
1063 	{
1064 		// Bitcasts must be between types of the same logical size. But with emulated narrow vectors we need
1065 		// support for casting between scalars and wide vectors. For platforms where this is not supported,
1066 		// emulate them by writing to the stack and reading back as the destination type.
1067 		if(emulateMismatchedBitCast)
1068 		{
1069 			if(!Ice::isVectorType(v->getType()) && Ice::isVectorType(T(destType)))
1070 			{
1071 				Value *address = allocateStackVariable(destType);
1072 				createStore(v, address, T(v->getType()));
1073 				return createLoad(address, destType);
1074 			}
1075 			else if(Ice::isVectorType(v->getType()) && !Ice::isVectorType(T(destType)))
1076 			{
1077 				Value *address = allocateStackVariable(T(v->getType()));
1078 				createStore(v, address, T(v->getType()));
1079 				return createLoad(address, destType);
1080 			}
1081 		}
1082 
1083 		return createCast(Ice::InstCast::Bitcast, v, destType);
1084 	}
1085 
createIntCompare(Ice::InstIcmp::ICond condition,Value * lhs,Value * rhs)1086 	static Value *createIntCompare(Ice::InstIcmp::ICond condition, Value *lhs, Value *rhs)
1087 	{
1088 		assert(lhs->getType() == rhs->getType());
1089 
1090 		auto result = ::function->makeVariable(Ice::isScalarIntegerType(lhs->getType()) ? Ice::IceType_i1 : lhs->getType());
1091 		auto cmp = Ice::InstIcmp::create(::function, condition, result, lhs, rhs);
1092 		::basicBlock->appendInst(cmp);
1093 
1094 		return V(result);
1095 	}
1096 
createICmpEQ(Value * lhs,Value * rhs)1097 	Value *Nucleus::createICmpEQ(Value *lhs, Value *rhs)
1098 	{
1099 		return createIntCompare(Ice::InstIcmp::Eq, lhs, rhs);
1100 	}
1101 
createICmpNE(Value * lhs,Value * rhs)1102 	Value *Nucleus::createICmpNE(Value *lhs, Value *rhs)
1103 	{
1104 		return createIntCompare(Ice::InstIcmp::Ne, lhs, rhs);
1105 	}
1106 
createICmpUGT(Value * lhs,Value * rhs)1107 	Value *Nucleus::createICmpUGT(Value *lhs, Value *rhs)
1108 	{
1109 		return createIntCompare(Ice::InstIcmp::Ugt, lhs, rhs);
1110 	}
1111 
createICmpUGE(Value * lhs,Value * rhs)1112 	Value *Nucleus::createICmpUGE(Value *lhs, Value *rhs)
1113 	{
1114 		return createIntCompare(Ice::InstIcmp::Uge, lhs, rhs);
1115 	}
1116 
createICmpULT(Value * lhs,Value * rhs)1117 	Value *Nucleus::createICmpULT(Value *lhs, Value *rhs)
1118 	{
1119 		return createIntCompare(Ice::InstIcmp::Ult, lhs, rhs);
1120 	}
1121 
createICmpULE(Value * lhs,Value * rhs)1122 	Value *Nucleus::createICmpULE(Value *lhs, Value *rhs)
1123 	{
1124 		return createIntCompare(Ice::InstIcmp::Ule, lhs, rhs);
1125 	}
1126 
createICmpSGT(Value * lhs,Value * rhs)1127 	Value *Nucleus::createICmpSGT(Value *lhs, Value *rhs)
1128 	{
1129 		return createIntCompare(Ice::InstIcmp::Sgt, lhs, rhs);
1130 	}
1131 
createICmpSGE(Value * lhs,Value * rhs)1132 	Value *Nucleus::createICmpSGE(Value *lhs, Value *rhs)
1133 	{
1134 		return createIntCompare(Ice::InstIcmp::Sge, lhs, rhs);
1135 	}
1136 
createICmpSLT(Value * lhs,Value * rhs)1137 	Value *Nucleus::createICmpSLT(Value *lhs, Value *rhs)
1138 	{
1139 		return createIntCompare(Ice::InstIcmp::Slt, lhs, rhs);
1140 	}
1141 
createICmpSLE(Value * lhs,Value * rhs)1142 	Value *Nucleus::createICmpSLE(Value *lhs, Value *rhs)
1143 	{
1144 		return createIntCompare(Ice::InstIcmp::Sle, lhs, rhs);
1145 	}
1146 
createFloatCompare(Ice::InstFcmp::FCond condition,Value * lhs,Value * rhs)1147 	static Value *createFloatCompare(Ice::InstFcmp::FCond condition, Value *lhs, Value *rhs)
1148 	{
1149 		assert(lhs->getType() == rhs->getType());
1150 		assert(Ice::isScalarFloatingType(lhs->getType()) || lhs->getType() == Ice::IceType_v4f32);
1151 
1152 		auto result = ::function->makeVariable(Ice::isScalarFloatingType(lhs->getType()) ? Ice::IceType_i1 : Ice::IceType_v4i32);
1153 		auto cmp = Ice::InstFcmp::create(::function, condition, result, lhs, rhs);
1154 		::basicBlock->appendInst(cmp);
1155 
1156 		return V(result);
1157 	}
1158 
createFCmpOEQ(Value * lhs,Value * rhs)1159 	Value *Nucleus::createFCmpOEQ(Value *lhs, Value *rhs)
1160 	{
1161 		return createFloatCompare(Ice::InstFcmp::Oeq, lhs, rhs);
1162 	}
1163 
createFCmpOGT(Value * lhs,Value * rhs)1164 	Value *Nucleus::createFCmpOGT(Value *lhs, Value *rhs)
1165 	{
1166 		return createFloatCompare(Ice::InstFcmp::Ogt, lhs, rhs);
1167 	}
1168 
createFCmpOGE(Value * lhs,Value * rhs)1169 	Value *Nucleus::createFCmpOGE(Value *lhs, Value *rhs)
1170 	{
1171 		return createFloatCompare(Ice::InstFcmp::Oge, lhs, rhs);
1172 	}
1173 
createFCmpOLT(Value * lhs,Value * rhs)1174 	Value *Nucleus::createFCmpOLT(Value *lhs, Value *rhs)
1175 	{
1176 		return createFloatCompare(Ice::InstFcmp::Olt, lhs, rhs);
1177 	}
1178 
createFCmpOLE(Value * lhs,Value * rhs)1179 	Value *Nucleus::createFCmpOLE(Value *lhs, Value *rhs)
1180 	{
1181 		return createFloatCompare(Ice::InstFcmp::Ole, lhs, rhs);
1182 	}
1183 
createFCmpONE(Value * lhs,Value * rhs)1184 	Value *Nucleus::createFCmpONE(Value *lhs, Value *rhs)
1185 	{
1186 		return createFloatCompare(Ice::InstFcmp::One, lhs, rhs);
1187 	}
1188 
createFCmpORD(Value * lhs,Value * rhs)1189 	Value *Nucleus::createFCmpORD(Value *lhs, Value *rhs)
1190 	{
1191 		return createFloatCompare(Ice::InstFcmp::Ord, lhs, rhs);
1192 	}
1193 
createFCmpUNO(Value * lhs,Value * rhs)1194 	Value *Nucleus::createFCmpUNO(Value *lhs, Value *rhs)
1195 	{
1196 		return createFloatCompare(Ice::InstFcmp::Uno, lhs, rhs);
1197 	}
1198 
createFCmpUEQ(Value * lhs,Value * rhs)1199 	Value *Nucleus::createFCmpUEQ(Value *lhs, Value *rhs)
1200 	{
1201 		return createFloatCompare(Ice::InstFcmp::Ueq, lhs, rhs);
1202 	}
1203 
createFCmpUGT(Value * lhs,Value * rhs)1204 	Value *Nucleus::createFCmpUGT(Value *lhs, Value *rhs)
1205 	{
1206 		return createFloatCompare(Ice::InstFcmp::Ugt, lhs, rhs);
1207 	}
1208 
createFCmpUGE(Value * lhs,Value * rhs)1209 	Value *Nucleus::createFCmpUGE(Value *lhs, Value *rhs)
1210 	{
1211 		return createFloatCompare(Ice::InstFcmp::Uge, lhs, rhs);
1212 	}
1213 
createFCmpULT(Value * lhs,Value * rhs)1214 	Value *Nucleus::createFCmpULT(Value *lhs, Value *rhs)
1215 	{
1216 		return createFloatCompare(Ice::InstFcmp::Ult, lhs, rhs);
1217 	}
1218 
createFCmpULE(Value * lhs,Value * rhs)1219 	Value *Nucleus::createFCmpULE(Value *lhs, Value *rhs)
1220 	{
1221 		return createFloatCompare(Ice::InstFcmp::Ule, lhs, rhs);
1222 	}
1223 
createFCmpUNE(Value * lhs,Value * rhs)1224 	Value *Nucleus::createFCmpUNE(Value *lhs, Value *rhs)
1225 	{
1226 		return createFloatCompare(Ice::InstFcmp::Une, lhs, rhs);
1227 	}
1228 
createExtractElement(Value * vector,Type * type,int index)1229 	Value *Nucleus::createExtractElement(Value *vector, Type *type, int index)
1230 	{
1231 		auto result = ::function->makeVariable(T(type));
1232 		auto extract = Ice::InstExtractElement::create(::function, result, vector, ::context->getConstantInt32(index));
1233 		::basicBlock->appendInst(extract);
1234 
1235 		return V(result);
1236 	}
1237 
createInsertElement(Value * vector,Value * element,int index)1238 	Value *Nucleus::createInsertElement(Value *vector, Value *element, int index)
1239 	{
1240 		auto result = ::function->makeVariable(vector->getType());
1241 		auto insert = Ice::InstInsertElement::create(::function, result, vector, element, ::context->getConstantInt32(index));
1242 		::basicBlock->appendInst(insert);
1243 
1244 		return V(result);
1245 	}
1246 
createShuffleVector(Value * V1,Value * V2,const int * select)1247 	Value *Nucleus::createShuffleVector(Value *V1, Value *V2, const int *select)
1248 	{
1249 		assert(V1->getType() == V2->getType());
1250 
1251 		int size = Ice::typeNumElements(V1->getType());
1252 		auto result = ::function->makeVariable(V1->getType());
1253 		auto shuffle = Ice::InstShuffleVector::create(::function, result, V1, V2);
1254 
1255 		for(int i = 0; i < size; i++)
1256 		{
1257 			shuffle->addIndex(llvm::cast<Ice::ConstantInteger32>(::context->getConstantInt32(select[i])));
1258 		}
1259 
1260 		::basicBlock->appendInst(shuffle);
1261 
1262 		return V(result);
1263 	}
1264 
createSelect(Value * C,Value * ifTrue,Value * ifFalse)1265 	Value *Nucleus::createSelect(Value *C, Value *ifTrue, Value *ifFalse)
1266 	{
1267 		assert(ifTrue->getType() == ifFalse->getType());
1268 
1269 		auto result = ::function->makeVariable(ifTrue->getType());
1270 		auto *select = Ice::InstSelect::create(::function, result, C, ifTrue, ifFalse);
1271 		::basicBlock->appendInst(select);
1272 
1273 		return V(result);
1274 	}
1275 
createSwitch(Value * control,BasicBlock * defaultBranch,unsigned numCases)1276 	SwitchCases *Nucleus::createSwitch(Value *control, BasicBlock *defaultBranch, unsigned numCases)
1277 	{
1278 		auto switchInst = Ice::InstSwitch::create(::function, numCases, control, defaultBranch);
1279 		::basicBlock->appendInst(switchInst);
1280 
1281 		return reinterpret_cast<SwitchCases*>(switchInst);
1282 	}
1283 
addSwitchCase(SwitchCases * switchCases,int label,BasicBlock * branch)1284 	void Nucleus::addSwitchCase(SwitchCases *switchCases, int label, BasicBlock *branch)
1285 	{
1286 		switchCases->addBranch(label, label, branch);
1287 	}
1288 
createUnreachable()1289 	void Nucleus::createUnreachable()
1290 	{
1291 		Ice::InstUnreachable *unreachable = Ice::InstUnreachable::create(::function);
1292 		::basicBlock->appendInst(unreachable);
1293 	}
1294 
createSwizzle4(Value * val,unsigned char select)1295 	static Value *createSwizzle4(Value *val, unsigned char select)
1296 	{
1297 		int swizzle[4] =
1298 		{
1299 			(select >> 0) & 0x03,
1300 			(select >> 2) & 0x03,
1301 			(select >> 4) & 0x03,
1302 			(select >> 6) & 0x03,
1303 		};
1304 
1305 		return Nucleus::createShuffleVector(val, val, swizzle);
1306 	}
1307 
createMask4(Value * lhs,Value * rhs,unsigned char select)1308 	static Value *createMask4(Value *lhs, Value *rhs, unsigned char select)
1309 	{
1310 		int64_t mask[4] = {0, 0, 0, 0};
1311 
1312 		mask[(select >> 0) & 0x03] = -1;
1313 		mask[(select >> 2) & 0x03] = -1;
1314 		mask[(select >> 4) & 0x03] = -1;
1315 		mask[(select >> 6) & 0x03] = -1;
1316 
1317 		Value *condition = Nucleus::createConstantVector(mask, T(Ice::IceType_v4i1));
1318 		Value *result = Nucleus::createSelect(condition, rhs, lhs);
1319 
1320 		return result;
1321 	}
1322 
getPointerType(Type * ElementType)1323 	Type *Nucleus::getPointerType(Type *ElementType)
1324 	{
1325 		if(sizeof(void*) == 8)
1326 		{
1327 			return T(Ice::IceType_i64);
1328 		}
1329 		else
1330 		{
1331 			return T(Ice::IceType_i32);
1332 		}
1333 	}
1334 
createNullValue(Type * Ty)1335 	Value *Nucleus::createNullValue(Type *Ty)
1336 	{
1337 		if(Ice::isVectorType(T(Ty)))
1338 		{
1339 			assert(Ice::typeNumElements(T(Ty)) <= 16);
1340 			int64_t c[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1341 			return createConstantVector(c, Ty);
1342 		}
1343 		else
1344 		{
1345 			return V(::context->getConstantZero(T(Ty)));
1346 		}
1347 	}
1348 
createConstantLong(int64_t i)1349 	Value *Nucleus::createConstantLong(int64_t i)
1350 	{
1351 		return V(::context->getConstantInt64(i));
1352 	}
1353 
createConstantInt(int i)1354 	Value *Nucleus::createConstantInt(int i)
1355 	{
1356 		return V(::context->getConstantInt32(i));
1357 	}
1358 
createConstantInt(unsigned int i)1359 	Value *Nucleus::createConstantInt(unsigned int i)
1360 	{
1361 		return V(::context->getConstantInt32(i));
1362 	}
1363 
createConstantBool(bool b)1364 	Value *Nucleus::createConstantBool(bool b)
1365 	{
1366 		return V(::context->getConstantInt1(b));
1367 	}
1368 
createConstantByte(signed char i)1369 	Value *Nucleus::createConstantByte(signed char i)
1370 	{
1371 		return V(::context->getConstantInt8(i));
1372 	}
1373 
createConstantByte(unsigned char i)1374 	Value *Nucleus::createConstantByte(unsigned char i)
1375 	{
1376 		return V(::context->getConstantInt8(i));
1377 	}
1378 
createConstantShort(short i)1379 	Value *Nucleus::createConstantShort(short i)
1380 	{
1381 		return V(::context->getConstantInt16(i));
1382 	}
1383 
createConstantShort(unsigned short i)1384 	Value *Nucleus::createConstantShort(unsigned short i)
1385 	{
1386 		return V(::context->getConstantInt16(i));
1387 	}
1388 
createConstantFloat(float x)1389 	Value *Nucleus::createConstantFloat(float x)
1390 	{
1391 		return V(::context->getConstantFloat(x));
1392 	}
1393 
createNullPointer(Type * Ty)1394 	Value *Nucleus::createNullPointer(Type *Ty)
1395 	{
1396 		return createNullValue(T(sizeof(void*) == 8 ? Ice::IceType_i64 : Ice::IceType_i32));
1397 	}
1398 
createConstantVector(const int64_t * constants,Type * type)1399 	Value *Nucleus::createConstantVector(const int64_t *constants, Type *type)
1400 	{
1401 		const int vectorSize = 16;
1402 		assert(Ice::typeWidthInBytes(T(type)) == vectorSize);
1403 		const int alignment = vectorSize;
1404 		auto globalPool = ::function->getGlobalPool();
1405 
1406 		const int64_t *i = constants;
1407 		const double *f = reinterpret_cast<const double*>(constants);
1408 		Ice::VariableDeclaration::DataInitializer *dataInitializer = nullptr;
1409 
1410 		switch((int)reinterpret_cast<intptr_t>(type))
1411 		{
1412 		case Ice::IceType_v4i32:
1413 		case Ice::IceType_v4i1:
1414 			{
1415 				const int initializer[4] = {(int)i[0], (int)i[1], (int)i[2], (int)i[3]};
1416 				static_assert(sizeof(initializer) == vectorSize, "!");
1417 				dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1418 			}
1419 			break;
1420 		case Ice::IceType_v4f32:
1421 			{
1422 				const float initializer[4] = {(float)f[0], (float)f[1], (float)f[2], (float)f[3]};
1423 				static_assert(sizeof(initializer) == vectorSize, "!");
1424 				dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1425 			}
1426 			break;
1427 		case Ice::IceType_v8i16:
1428 		case Ice::IceType_v8i1:
1429 			{
1430 				const short initializer[8] = {(short)i[0], (short)i[1], (short)i[2], (short)i[3], (short)i[4], (short)i[5], (short)i[6], (short)i[7]};
1431 				static_assert(sizeof(initializer) == vectorSize, "!");
1432 				dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1433 			}
1434 			break;
1435 		case Ice::IceType_v16i8:
1436 		case Ice::IceType_v16i1:
1437 			{
1438 				const char initializer[16] = {(char)i[0], (char)i[1], (char)i[2], (char)i[3], (char)i[4], (char)i[5], (char)i[6], (char)i[7], (char)i[8], (char)i[9], (char)i[10], (char)i[11], (char)i[12], (char)i[13], (char)i[14], (char)i[15]};
1439 				static_assert(sizeof(initializer) == vectorSize, "!");
1440 				dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1441 			}
1442 			break;
1443 		case Type_v2i32:
1444 			{
1445 				const int initializer[4] = {(int)i[0], (int)i[1], (int)i[0], (int)i[1]};
1446 				static_assert(sizeof(initializer) == vectorSize, "!");
1447 				dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1448 			}
1449 			break;
1450 		case Type_v2f32:
1451 			{
1452 				const float initializer[4] = {(float)f[0], (float)f[1], (float)f[0], (float)f[1]};
1453 				static_assert(sizeof(initializer) == vectorSize, "!");
1454 				dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1455 			}
1456 			break;
1457 		case Type_v4i16:
1458 			{
1459 				const short initializer[8] = {(short)i[0], (short)i[1], (short)i[2], (short)i[3], (short)i[0], (short)i[1], (short)i[2], (short)i[3]};
1460 				static_assert(sizeof(initializer) == vectorSize, "!");
1461 				dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1462 			}
1463 			break;
1464 		case Type_v8i8:
1465 			{
1466 				const char initializer[16] = {(char)i[0], (char)i[1], (char)i[2], (char)i[3], (char)i[4], (char)i[5], (char)i[6], (char)i[7], (char)i[0], (char)i[1], (char)i[2], (char)i[3], (char)i[4], (char)i[5], (char)i[6], (char)i[7]};
1467 				static_assert(sizeof(initializer) == vectorSize, "!");
1468 				dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1469 			}
1470 			break;
1471 		case Type_v4i8:
1472 			{
1473 				const char initializer[16] = {(char)i[0], (char)i[1], (char)i[2], (char)i[3], (char)i[0], (char)i[1], (char)i[2], (char)i[3], (char)i[0], (char)i[1], (char)i[2], (char)i[3], (char)i[0], (char)i[1], (char)i[2], (char)i[3]};
1474 				static_assert(sizeof(initializer) == vectorSize, "!");
1475 				dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1476 			}
1477 			break;
1478 		default:
1479 			assert(false && "Unknown constant vector type" && type);
1480 		}
1481 
1482 		auto name = Ice::GlobalString::createWithoutString(::context);
1483 		auto *variableDeclaration = Ice::VariableDeclaration::create(globalPool);
1484 		variableDeclaration->setName(name);
1485 		variableDeclaration->setAlignment(alignment);
1486 		variableDeclaration->setIsConstant(true);
1487 		variableDeclaration->addInitializer(dataInitializer);
1488 
1489 		::function->addGlobal(variableDeclaration);
1490 
1491 		constexpr int32_t offset = 0;
1492 		Ice::Operand *ptr = ::context->getConstantSym(offset, name);
1493 
1494 		Ice::Variable *result = ::function->makeVariable(T(type));
1495 		auto load = Ice::InstLoad::create(::function, result, ptr, alignment);
1496 		::basicBlock->appendInst(load);
1497 
1498 		return V(result);
1499 	}
1500 
createConstantVector(const double * constants,Type * type)1501 	Value *Nucleus::createConstantVector(const double *constants, Type *type)
1502 	{
1503 		return createConstantVector((const int64_t*)constants, type);
1504 	}
1505 
getType()1506 	Type *Void::getType()
1507 	{
1508 		return T(Ice::IceType_void);
1509 	}
1510 
Bool(Argument<Bool> argument)1511 	Bool::Bool(Argument<Bool> argument)
1512 	{
1513 		storeValue(argument.value);
1514 	}
1515 
Bool(bool x)1516 	Bool::Bool(bool x)
1517 	{
1518 		storeValue(Nucleus::createConstantBool(x));
1519 	}
1520 
Bool(RValue<Bool> rhs)1521 	Bool::Bool(RValue<Bool> rhs)
1522 	{
1523 		storeValue(rhs.value);
1524 	}
1525 
Bool(const Bool & rhs)1526 	Bool::Bool(const Bool &rhs)
1527 	{
1528 		Value *value = rhs.loadValue();
1529 		storeValue(value);
1530 	}
1531 
Bool(const Reference<Bool> & rhs)1532 	Bool::Bool(const Reference<Bool> &rhs)
1533 	{
1534 		Value *value = rhs.loadValue();
1535 		storeValue(value);
1536 	}
1537 
operator =(RValue<Bool> rhs)1538 	RValue<Bool> Bool::operator=(RValue<Bool> rhs)
1539 	{
1540 		storeValue(rhs.value);
1541 
1542 		return rhs;
1543 	}
1544 
operator =(const Bool & rhs)1545 	RValue<Bool> Bool::operator=(const Bool &rhs)
1546 	{
1547 		Value *value = rhs.loadValue();
1548 		storeValue(value);
1549 
1550 		return RValue<Bool>(value);
1551 	}
1552 
operator =(const Reference<Bool> & rhs)1553 	RValue<Bool> Bool::operator=(const Reference<Bool> &rhs)
1554 	{
1555 		Value *value = rhs.loadValue();
1556 		storeValue(value);
1557 
1558 		return RValue<Bool>(value);
1559 	}
1560 
operator !(RValue<Bool> val)1561 	RValue<Bool> operator!(RValue<Bool> val)
1562 	{
1563 		return RValue<Bool>(Nucleus::createNot(val.value));
1564 	}
1565 
operator &&(RValue<Bool> lhs,RValue<Bool> rhs)1566 	RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs)
1567 	{
1568 		return RValue<Bool>(Nucleus::createAnd(lhs.value, rhs.value));
1569 	}
1570 
operator ||(RValue<Bool> lhs,RValue<Bool> rhs)1571 	RValue<Bool> operator||(RValue<Bool> lhs, RValue<Bool> rhs)
1572 	{
1573 		return RValue<Bool>(Nucleus::createOr(lhs.value, rhs.value));
1574 	}
1575 
getType()1576 	Type *Bool::getType()
1577 	{
1578 		return T(Ice::IceType_i1);
1579 	}
1580 
Byte(Argument<Byte> argument)1581 	Byte::Byte(Argument<Byte> argument)
1582 	{
1583 		storeValue(argument.value);
1584 	}
1585 
Byte(RValue<Int> cast)1586 	Byte::Byte(RValue<Int> cast)
1587 	{
1588 		Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
1589 
1590 		storeValue(integer);
1591 	}
1592 
Byte(RValue<UInt> cast)1593 	Byte::Byte(RValue<UInt> cast)
1594 	{
1595 		Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
1596 
1597 		storeValue(integer);
1598 	}
1599 
Byte(RValue<UShort> cast)1600 	Byte::Byte(RValue<UShort> cast)
1601 	{
1602 		Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
1603 
1604 		storeValue(integer);
1605 	}
1606 
Byte(int x)1607 	Byte::Byte(int x)
1608 	{
1609 		storeValue(Nucleus::createConstantByte((unsigned char)x));
1610 	}
1611 
Byte(unsigned char x)1612 	Byte::Byte(unsigned char x)
1613 	{
1614 		storeValue(Nucleus::createConstantByte(x));
1615 	}
1616 
Byte(RValue<Byte> rhs)1617 	Byte::Byte(RValue<Byte> rhs)
1618 	{
1619 		storeValue(rhs.value);
1620 	}
1621 
Byte(const Byte & rhs)1622 	Byte::Byte(const Byte &rhs)
1623 	{
1624 		Value *value = rhs.loadValue();
1625 		storeValue(value);
1626 	}
1627 
Byte(const Reference<Byte> & rhs)1628 	Byte::Byte(const Reference<Byte> &rhs)
1629 	{
1630 		Value *value = rhs.loadValue();
1631 		storeValue(value);
1632 	}
1633 
operator =(RValue<Byte> rhs)1634 	RValue<Byte> Byte::operator=(RValue<Byte> rhs)
1635 	{
1636 		storeValue(rhs.value);
1637 
1638 		return rhs;
1639 	}
1640 
operator =(const Byte & rhs)1641 	RValue<Byte> Byte::operator=(const Byte &rhs)
1642 	{
1643 		Value *value = rhs.loadValue();
1644 		storeValue(value);
1645 
1646 		return RValue<Byte>(value);
1647 	}
1648 
operator =(const Reference<Byte> & rhs)1649 	RValue<Byte> Byte::operator=(const Reference<Byte> &rhs)
1650 	{
1651 		Value *value = rhs.loadValue();
1652 		storeValue(value);
1653 
1654 		return RValue<Byte>(value);
1655 	}
1656 
operator +(RValue<Byte> lhs,RValue<Byte> rhs)1657 	RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs)
1658 	{
1659 		return RValue<Byte>(Nucleus::createAdd(lhs.value, rhs.value));
1660 	}
1661 
operator -(RValue<Byte> lhs,RValue<Byte> rhs)1662 	RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs)
1663 	{
1664 		return RValue<Byte>(Nucleus::createSub(lhs.value, rhs.value));
1665 	}
1666 
operator *(RValue<Byte> lhs,RValue<Byte> rhs)1667 	RValue<Byte> operator*(RValue<Byte> lhs, RValue<Byte> rhs)
1668 	{
1669 		return RValue<Byte>(Nucleus::createMul(lhs.value, rhs.value));
1670 	}
1671 
operator /(RValue<Byte> lhs,RValue<Byte> rhs)1672 	RValue<Byte> operator/(RValue<Byte> lhs, RValue<Byte> rhs)
1673 	{
1674 		return RValue<Byte>(Nucleus::createUDiv(lhs.value, rhs.value));
1675 	}
1676 
operator %(RValue<Byte> lhs,RValue<Byte> rhs)1677 	RValue<Byte> operator%(RValue<Byte> lhs, RValue<Byte> rhs)
1678 	{
1679 		return RValue<Byte>(Nucleus::createURem(lhs.value, rhs.value));
1680 	}
1681 
operator &(RValue<Byte> lhs,RValue<Byte> rhs)1682 	RValue<Byte> operator&(RValue<Byte> lhs, RValue<Byte> rhs)
1683 	{
1684 		return RValue<Byte>(Nucleus::createAnd(lhs.value, rhs.value));
1685 	}
1686 
operator |(RValue<Byte> lhs,RValue<Byte> rhs)1687 	RValue<Byte> operator|(RValue<Byte> lhs, RValue<Byte> rhs)
1688 	{
1689 		return RValue<Byte>(Nucleus::createOr(lhs.value, rhs.value));
1690 	}
1691 
operator ^(RValue<Byte> lhs,RValue<Byte> rhs)1692 	RValue<Byte> operator^(RValue<Byte> lhs, RValue<Byte> rhs)
1693 	{
1694 		return RValue<Byte>(Nucleus::createXor(lhs.value, rhs.value));
1695 	}
1696 
operator <<(RValue<Byte> lhs,RValue<Byte> rhs)1697 	RValue<Byte> operator<<(RValue<Byte> lhs, RValue<Byte> rhs)
1698 	{
1699 		return RValue<Byte>(Nucleus::createShl(lhs.value, rhs.value));
1700 	}
1701 
operator >>(RValue<Byte> lhs,RValue<Byte> rhs)1702 	RValue<Byte> operator>>(RValue<Byte> lhs, RValue<Byte> rhs)
1703 	{
1704 		return RValue<Byte>(Nucleus::createLShr(lhs.value, rhs.value));
1705 	}
1706 
operator +=(Byte & lhs,RValue<Byte> rhs)1707 	RValue<Byte> operator+=(Byte &lhs, RValue<Byte> rhs)
1708 	{
1709 		return lhs = lhs + rhs;
1710 	}
1711 
operator -=(Byte & lhs,RValue<Byte> rhs)1712 	RValue<Byte> operator-=(Byte &lhs, RValue<Byte> rhs)
1713 	{
1714 		return lhs = lhs - rhs;
1715 	}
1716 
operator *=(Byte & lhs,RValue<Byte> rhs)1717 	RValue<Byte> operator*=(Byte &lhs, RValue<Byte> rhs)
1718 	{
1719 		return lhs = lhs * rhs;
1720 	}
1721 
operator /=(Byte & lhs,RValue<Byte> rhs)1722 	RValue<Byte> operator/=(Byte &lhs, RValue<Byte> rhs)
1723 	{
1724 		return lhs = lhs / rhs;
1725 	}
1726 
operator %=(Byte & lhs,RValue<Byte> rhs)1727 	RValue<Byte> operator%=(Byte &lhs, RValue<Byte> rhs)
1728 	{
1729 		return lhs = lhs % rhs;
1730 	}
1731 
operator &=(Byte & lhs,RValue<Byte> rhs)1732 	RValue<Byte> operator&=(Byte &lhs, RValue<Byte> rhs)
1733 	{
1734 		return lhs = lhs & rhs;
1735 	}
1736 
operator |=(Byte & lhs,RValue<Byte> rhs)1737 	RValue<Byte> operator|=(Byte &lhs, RValue<Byte> rhs)
1738 	{
1739 		return lhs = lhs | rhs;
1740 	}
1741 
operator ^=(Byte & lhs,RValue<Byte> rhs)1742 	RValue<Byte> operator^=(Byte &lhs, RValue<Byte> rhs)
1743 	{
1744 		return lhs = lhs ^ rhs;
1745 	}
1746 
operator <<=(Byte & lhs,RValue<Byte> rhs)1747 	RValue<Byte> operator<<=(Byte &lhs, RValue<Byte> rhs)
1748 	{
1749 		return lhs = lhs << rhs;
1750 	}
1751 
operator >>=(Byte & lhs,RValue<Byte> rhs)1752 	RValue<Byte> operator>>=(Byte &lhs, RValue<Byte> rhs)
1753 	{
1754 		return lhs = lhs >> rhs;
1755 	}
1756 
operator +(RValue<Byte> val)1757 	RValue<Byte> operator+(RValue<Byte> val)
1758 	{
1759 		return val;
1760 	}
1761 
operator -(RValue<Byte> val)1762 	RValue<Byte> operator-(RValue<Byte> val)
1763 	{
1764 		return RValue<Byte>(Nucleus::createNeg(val.value));
1765 	}
1766 
operator ~(RValue<Byte> val)1767 	RValue<Byte> operator~(RValue<Byte> val)
1768 	{
1769 		return RValue<Byte>(Nucleus::createNot(val.value));
1770 	}
1771 
operator ++(Byte & val,int)1772 	RValue<Byte> operator++(Byte &val, int)   // Post-increment
1773 	{
1774 		RValue<Byte> res = val;
1775 		val += Byte(1);
1776 		return res;
1777 	}
1778 
operator ++(Byte & val)1779 	const Byte &operator++(Byte &val)   // Pre-increment
1780 	{
1781 		val += Byte(1);
1782 		return val;
1783 	}
1784 
operator --(Byte & val,int)1785 	RValue<Byte> operator--(Byte &val, int)   // Post-decrement
1786 	{
1787 		RValue<Byte> res = val;
1788 		val -= Byte(1);
1789 		return res;
1790 	}
1791 
operator --(Byte & val)1792 	const Byte &operator--(Byte &val)   // Pre-decrement
1793 	{
1794 		val -= Byte(1);
1795 		return val;
1796 	}
1797 
operator <(RValue<Byte> lhs,RValue<Byte> rhs)1798 	RValue<Bool> operator<(RValue<Byte> lhs, RValue<Byte> rhs)
1799 	{
1800 		return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1801 	}
1802 
operator <=(RValue<Byte> lhs,RValue<Byte> rhs)1803 	RValue<Bool> operator<=(RValue<Byte> lhs, RValue<Byte> rhs)
1804 	{
1805 		return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1806 	}
1807 
operator >(RValue<Byte> lhs,RValue<Byte> rhs)1808 	RValue<Bool> operator>(RValue<Byte> lhs, RValue<Byte> rhs)
1809 	{
1810 		return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1811 	}
1812 
operator >=(RValue<Byte> lhs,RValue<Byte> rhs)1813 	RValue<Bool> operator>=(RValue<Byte> lhs, RValue<Byte> rhs)
1814 	{
1815 		return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1816 	}
1817 
operator !=(RValue<Byte> lhs,RValue<Byte> rhs)1818 	RValue<Bool> operator!=(RValue<Byte> lhs, RValue<Byte> rhs)
1819 	{
1820 		return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1821 	}
1822 
operator ==(RValue<Byte> lhs,RValue<Byte> rhs)1823 	RValue<Bool> operator==(RValue<Byte> lhs, RValue<Byte> rhs)
1824 	{
1825 		return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1826 	}
1827 
getType()1828 	Type *Byte::getType()
1829 	{
1830 		return T(Ice::IceType_i8);
1831 	}
1832 
SByte(Argument<SByte> argument)1833 	SByte::SByte(Argument<SByte> argument)
1834 	{
1835 		storeValue(argument.value);
1836 	}
1837 
SByte(RValue<Int> cast)1838 	SByte::SByte(RValue<Int> cast)
1839 	{
1840 		Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1841 
1842 		storeValue(integer);
1843 	}
1844 
SByte(RValue<Short> cast)1845 	SByte::SByte(RValue<Short> cast)
1846 	{
1847 		Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1848 
1849 		storeValue(integer);
1850 	}
1851 
SByte(signed char x)1852 	SByte::SByte(signed char x)
1853 	{
1854 		storeValue(Nucleus::createConstantByte(x));
1855 	}
1856 
SByte(RValue<SByte> rhs)1857 	SByte::SByte(RValue<SByte> rhs)
1858 	{
1859 		storeValue(rhs.value);
1860 	}
1861 
SByte(const SByte & rhs)1862 	SByte::SByte(const SByte &rhs)
1863 	{
1864 		Value *value = rhs.loadValue();
1865 		storeValue(value);
1866 	}
1867 
SByte(const Reference<SByte> & rhs)1868 	SByte::SByte(const Reference<SByte> &rhs)
1869 	{
1870 		Value *value = rhs.loadValue();
1871 		storeValue(value);
1872 	}
1873 
operator =(RValue<SByte> rhs)1874 	RValue<SByte> SByte::operator=(RValue<SByte> rhs)
1875 	{
1876 		storeValue(rhs.value);
1877 
1878 		return rhs;
1879 	}
1880 
operator =(const SByte & rhs)1881 	RValue<SByte> SByte::operator=(const SByte &rhs)
1882 	{
1883 		Value *value = rhs.loadValue();
1884 		storeValue(value);
1885 
1886 		return RValue<SByte>(value);
1887 	}
1888 
operator =(const Reference<SByte> & rhs)1889 	RValue<SByte> SByte::operator=(const Reference<SByte> &rhs)
1890 	{
1891 		Value *value = rhs.loadValue();
1892 		storeValue(value);
1893 
1894 		return RValue<SByte>(value);
1895 	}
1896 
operator +(RValue<SByte> lhs,RValue<SByte> rhs)1897 	RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs)
1898 	{
1899 		return RValue<SByte>(Nucleus::createAdd(lhs.value, rhs.value));
1900 	}
1901 
operator -(RValue<SByte> lhs,RValue<SByte> rhs)1902 	RValue<SByte> operator-(RValue<SByte> lhs, RValue<SByte> rhs)
1903 	{
1904 		return RValue<SByte>(Nucleus::createSub(lhs.value, rhs.value));
1905 	}
1906 
operator *(RValue<SByte> lhs,RValue<SByte> rhs)1907 	RValue<SByte> operator*(RValue<SByte> lhs, RValue<SByte> rhs)
1908 	{
1909 		return RValue<SByte>(Nucleus::createMul(lhs.value, rhs.value));
1910 	}
1911 
operator /(RValue<SByte> lhs,RValue<SByte> rhs)1912 	RValue<SByte> operator/(RValue<SByte> lhs, RValue<SByte> rhs)
1913 	{
1914 		return RValue<SByte>(Nucleus::createSDiv(lhs.value, rhs.value));
1915 	}
1916 
operator %(RValue<SByte> lhs,RValue<SByte> rhs)1917 	RValue<SByte> operator%(RValue<SByte> lhs, RValue<SByte> rhs)
1918 	{
1919 		return RValue<SByte>(Nucleus::createSRem(lhs.value, rhs.value));
1920 	}
1921 
operator &(RValue<SByte> lhs,RValue<SByte> rhs)1922 	RValue<SByte> operator&(RValue<SByte> lhs, RValue<SByte> rhs)
1923 	{
1924 		return RValue<SByte>(Nucleus::createAnd(lhs.value, rhs.value));
1925 	}
1926 
operator |(RValue<SByte> lhs,RValue<SByte> rhs)1927 	RValue<SByte> operator|(RValue<SByte> lhs, RValue<SByte> rhs)
1928 	{
1929 		return RValue<SByte>(Nucleus::createOr(lhs.value, rhs.value));
1930 	}
1931 
operator ^(RValue<SByte> lhs,RValue<SByte> rhs)1932 	RValue<SByte> operator^(RValue<SByte> lhs, RValue<SByte> rhs)
1933 	{
1934 		return RValue<SByte>(Nucleus::createXor(lhs.value, rhs.value));
1935 	}
1936 
operator <<(RValue<SByte> lhs,RValue<SByte> rhs)1937 	RValue<SByte> operator<<(RValue<SByte> lhs, RValue<SByte> rhs)
1938 	{
1939 		return RValue<SByte>(Nucleus::createShl(lhs.value, rhs.value));
1940 	}
1941 
operator >>(RValue<SByte> lhs,RValue<SByte> rhs)1942 	RValue<SByte> operator>>(RValue<SByte> lhs, RValue<SByte> rhs)
1943 	{
1944 		return RValue<SByte>(Nucleus::createAShr(lhs.value, rhs.value));
1945 	}
1946 
operator +=(SByte & lhs,RValue<SByte> rhs)1947 	RValue<SByte> operator+=(SByte &lhs, RValue<SByte> rhs)
1948 	{
1949 		return lhs = lhs + rhs;
1950 	}
1951 
operator -=(SByte & lhs,RValue<SByte> rhs)1952 	RValue<SByte> operator-=(SByte &lhs, RValue<SByte> rhs)
1953 	{
1954 		return lhs = lhs - rhs;
1955 	}
1956 
operator *=(SByte & lhs,RValue<SByte> rhs)1957 	RValue<SByte> operator*=(SByte &lhs, RValue<SByte> rhs)
1958 	{
1959 		return lhs = lhs * rhs;
1960 	}
1961 
operator /=(SByte & lhs,RValue<SByte> rhs)1962 	RValue<SByte> operator/=(SByte &lhs, RValue<SByte> rhs)
1963 	{
1964 		return lhs = lhs / rhs;
1965 	}
1966 
operator %=(SByte & lhs,RValue<SByte> rhs)1967 	RValue<SByte> operator%=(SByte &lhs, RValue<SByte> rhs)
1968 	{
1969 		return lhs = lhs % rhs;
1970 	}
1971 
operator &=(SByte & lhs,RValue<SByte> rhs)1972 	RValue<SByte> operator&=(SByte &lhs, RValue<SByte> rhs)
1973 	{
1974 		return lhs = lhs & rhs;
1975 	}
1976 
operator |=(SByte & lhs,RValue<SByte> rhs)1977 	RValue<SByte> operator|=(SByte &lhs, RValue<SByte> rhs)
1978 	{
1979 		return lhs = lhs | rhs;
1980 	}
1981 
operator ^=(SByte & lhs,RValue<SByte> rhs)1982 	RValue<SByte> operator^=(SByte &lhs, RValue<SByte> rhs)
1983 	{
1984 		return lhs = lhs ^ rhs;
1985 	}
1986 
operator <<=(SByte & lhs,RValue<SByte> rhs)1987 	RValue<SByte> operator<<=(SByte &lhs, RValue<SByte> rhs)
1988 	{
1989 		return lhs = lhs << rhs;
1990 	}
1991 
operator >>=(SByte & lhs,RValue<SByte> rhs)1992 	RValue<SByte> operator>>=(SByte &lhs, RValue<SByte> rhs)
1993 	{
1994 		return lhs = lhs >> rhs;
1995 	}
1996 
operator +(RValue<SByte> val)1997 	RValue<SByte> operator+(RValue<SByte> val)
1998 	{
1999 		return val;
2000 	}
2001 
operator -(RValue<SByte> val)2002 	RValue<SByte> operator-(RValue<SByte> val)
2003 	{
2004 		return RValue<SByte>(Nucleus::createNeg(val.value));
2005 	}
2006 
operator ~(RValue<SByte> val)2007 	RValue<SByte> operator~(RValue<SByte> val)
2008 	{
2009 		return RValue<SByte>(Nucleus::createNot(val.value));
2010 	}
2011 
operator ++(SByte & val,int)2012 	RValue<SByte> operator++(SByte &val, int)   // Post-increment
2013 	{
2014 		RValue<SByte> res = val;
2015 		val += SByte(1);
2016 		return res;
2017 	}
2018 
operator ++(SByte & val)2019 	const SByte &operator++(SByte &val)   // Pre-increment
2020 	{
2021 		val += SByte(1);
2022 		return val;
2023 	}
2024 
operator --(SByte & val,int)2025 	RValue<SByte> operator--(SByte &val, int)   // Post-decrement
2026 	{
2027 		RValue<SByte> res = val;
2028 		val -= SByte(1);
2029 		return res;
2030 	}
2031 
operator --(SByte & val)2032 	const SByte &operator--(SByte &val)   // Pre-decrement
2033 	{
2034 		val -= SByte(1);
2035 		return val;
2036 	}
2037 
operator <(RValue<SByte> lhs,RValue<SByte> rhs)2038 	RValue<Bool> operator<(RValue<SByte> lhs, RValue<SByte> rhs)
2039 	{
2040 		return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
2041 	}
2042 
operator <=(RValue<SByte> lhs,RValue<SByte> rhs)2043 	RValue<Bool> operator<=(RValue<SByte> lhs, RValue<SByte> rhs)
2044 	{
2045 		return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
2046 	}
2047 
operator >(RValue<SByte> lhs,RValue<SByte> rhs)2048 	RValue<Bool> operator>(RValue<SByte> lhs, RValue<SByte> rhs)
2049 	{
2050 		return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
2051 	}
2052 
operator >=(RValue<SByte> lhs,RValue<SByte> rhs)2053 	RValue<Bool> operator>=(RValue<SByte> lhs, RValue<SByte> rhs)
2054 	{
2055 		return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
2056 	}
2057 
operator !=(RValue<SByte> lhs,RValue<SByte> rhs)2058 	RValue<Bool> operator!=(RValue<SByte> lhs, RValue<SByte> rhs)
2059 	{
2060 		return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
2061 	}
2062 
operator ==(RValue<SByte> lhs,RValue<SByte> rhs)2063 	RValue<Bool> operator==(RValue<SByte> lhs, RValue<SByte> rhs)
2064 	{
2065 		return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
2066 	}
2067 
getType()2068 	Type *SByte::getType()
2069 	{
2070 		return T(Ice::IceType_i8);
2071 	}
2072 
Short(Argument<Short> argument)2073 	Short::Short(Argument<Short> argument)
2074 	{
2075 		storeValue(argument.value);
2076 	}
2077 
Short(RValue<Int> cast)2078 	Short::Short(RValue<Int> cast)
2079 	{
2080 		Value *integer = Nucleus::createTrunc(cast.value, Short::getType());
2081 
2082 		storeValue(integer);
2083 	}
2084 
Short(short x)2085 	Short::Short(short x)
2086 	{
2087 		storeValue(Nucleus::createConstantShort(x));
2088 	}
2089 
Short(RValue<Short> rhs)2090 	Short::Short(RValue<Short> rhs)
2091 	{
2092 		storeValue(rhs.value);
2093 	}
2094 
Short(const Short & rhs)2095 	Short::Short(const Short &rhs)
2096 	{
2097 		Value *value = rhs.loadValue();
2098 		storeValue(value);
2099 	}
2100 
Short(const Reference<Short> & rhs)2101 	Short::Short(const Reference<Short> &rhs)
2102 	{
2103 		Value *value = rhs.loadValue();
2104 		storeValue(value);
2105 	}
2106 
operator =(RValue<Short> rhs)2107 	RValue<Short> Short::operator=(RValue<Short> rhs)
2108 	{
2109 		storeValue(rhs.value);
2110 
2111 		return rhs;
2112 	}
2113 
operator =(const Short & rhs)2114 	RValue<Short> Short::operator=(const Short &rhs)
2115 	{
2116 		Value *value = rhs.loadValue();
2117 		storeValue(value);
2118 
2119 		return RValue<Short>(value);
2120 	}
2121 
operator =(const Reference<Short> & rhs)2122 	RValue<Short> Short::operator=(const Reference<Short> &rhs)
2123 	{
2124 		Value *value = rhs.loadValue();
2125 		storeValue(value);
2126 
2127 		return RValue<Short>(value);
2128 	}
2129 
operator +(RValue<Short> lhs,RValue<Short> rhs)2130 	RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs)
2131 	{
2132 		return RValue<Short>(Nucleus::createAdd(lhs.value, rhs.value));
2133 	}
2134 
operator -(RValue<Short> lhs,RValue<Short> rhs)2135 	RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs)
2136 	{
2137 		return RValue<Short>(Nucleus::createSub(lhs.value, rhs.value));
2138 	}
2139 
operator *(RValue<Short> lhs,RValue<Short> rhs)2140 	RValue<Short> operator*(RValue<Short> lhs, RValue<Short> rhs)
2141 	{
2142 		return RValue<Short>(Nucleus::createMul(lhs.value, rhs.value));
2143 	}
2144 
operator /(RValue<Short> lhs,RValue<Short> rhs)2145 	RValue<Short> operator/(RValue<Short> lhs, RValue<Short> rhs)
2146 	{
2147 		return RValue<Short>(Nucleus::createSDiv(lhs.value, rhs.value));
2148 	}
2149 
operator %(RValue<Short> lhs,RValue<Short> rhs)2150 	RValue<Short> operator%(RValue<Short> lhs, RValue<Short> rhs)
2151 	{
2152 		return RValue<Short>(Nucleus::createSRem(lhs.value, rhs.value));
2153 	}
2154 
operator &(RValue<Short> lhs,RValue<Short> rhs)2155 	RValue<Short> operator&(RValue<Short> lhs, RValue<Short> rhs)
2156 	{
2157 		return RValue<Short>(Nucleus::createAnd(lhs.value, rhs.value));
2158 	}
2159 
operator |(RValue<Short> lhs,RValue<Short> rhs)2160 	RValue<Short> operator|(RValue<Short> lhs, RValue<Short> rhs)
2161 	{
2162 		return RValue<Short>(Nucleus::createOr(lhs.value, rhs.value));
2163 	}
2164 
operator ^(RValue<Short> lhs,RValue<Short> rhs)2165 	RValue<Short> operator^(RValue<Short> lhs, RValue<Short> rhs)
2166 	{
2167 		return RValue<Short>(Nucleus::createXor(lhs.value, rhs.value));
2168 	}
2169 
operator <<(RValue<Short> lhs,RValue<Short> rhs)2170 	RValue<Short> operator<<(RValue<Short> lhs, RValue<Short> rhs)
2171 	{
2172 		return RValue<Short>(Nucleus::createShl(lhs.value, rhs.value));
2173 	}
2174 
operator >>(RValue<Short> lhs,RValue<Short> rhs)2175 	RValue<Short> operator>>(RValue<Short> lhs, RValue<Short> rhs)
2176 	{
2177 		return RValue<Short>(Nucleus::createAShr(lhs.value, rhs.value));
2178 	}
2179 
operator +=(Short & lhs,RValue<Short> rhs)2180 	RValue<Short> operator+=(Short &lhs, RValue<Short> rhs)
2181 	{
2182 		return lhs = lhs + rhs;
2183 	}
2184 
operator -=(Short & lhs,RValue<Short> rhs)2185 	RValue<Short> operator-=(Short &lhs, RValue<Short> rhs)
2186 	{
2187 		return lhs = lhs - rhs;
2188 	}
2189 
operator *=(Short & lhs,RValue<Short> rhs)2190 	RValue<Short> operator*=(Short &lhs, RValue<Short> rhs)
2191 	{
2192 		return lhs = lhs * rhs;
2193 	}
2194 
operator /=(Short & lhs,RValue<Short> rhs)2195 	RValue<Short> operator/=(Short &lhs, RValue<Short> rhs)
2196 	{
2197 		return lhs = lhs / rhs;
2198 	}
2199 
operator %=(Short & lhs,RValue<Short> rhs)2200 	RValue<Short> operator%=(Short &lhs, RValue<Short> rhs)
2201 	{
2202 		return lhs = lhs % rhs;
2203 	}
2204 
operator &=(Short & lhs,RValue<Short> rhs)2205 	RValue<Short> operator&=(Short &lhs, RValue<Short> rhs)
2206 	{
2207 		return lhs = lhs & rhs;
2208 	}
2209 
operator |=(Short & lhs,RValue<Short> rhs)2210 	RValue<Short> operator|=(Short &lhs, RValue<Short> rhs)
2211 	{
2212 		return lhs = lhs | rhs;
2213 	}
2214 
operator ^=(Short & lhs,RValue<Short> rhs)2215 	RValue<Short> operator^=(Short &lhs, RValue<Short> rhs)
2216 	{
2217 		return lhs = lhs ^ rhs;
2218 	}
2219 
operator <<=(Short & lhs,RValue<Short> rhs)2220 	RValue<Short> operator<<=(Short &lhs, RValue<Short> rhs)
2221 	{
2222 		return lhs = lhs << rhs;
2223 	}
2224 
operator >>=(Short & lhs,RValue<Short> rhs)2225 	RValue<Short> operator>>=(Short &lhs, RValue<Short> rhs)
2226 	{
2227 		return lhs = lhs >> rhs;
2228 	}
2229 
operator +(RValue<Short> val)2230 	RValue<Short> operator+(RValue<Short> val)
2231 	{
2232 		return val;
2233 	}
2234 
operator -(RValue<Short> val)2235 	RValue<Short> operator-(RValue<Short> val)
2236 	{
2237 		return RValue<Short>(Nucleus::createNeg(val.value));
2238 	}
2239 
operator ~(RValue<Short> val)2240 	RValue<Short> operator~(RValue<Short> val)
2241 	{
2242 		return RValue<Short>(Nucleus::createNot(val.value));
2243 	}
2244 
operator ++(Short & val,int)2245 	RValue<Short> operator++(Short &val, int)   // Post-increment
2246 	{
2247 		RValue<Short> res = val;
2248 		val += Short(1);
2249 		return res;
2250 	}
2251 
operator ++(Short & val)2252 	const Short &operator++(Short &val)   // Pre-increment
2253 	{
2254 		val += Short(1);
2255 		return val;
2256 	}
2257 
operator --(Short & val,int)2258 	RValue<Short> operator--(Short &val, int)   // Post-decrement
2259 	{
2260 		RValue<Short> res = val;
2261 		val -= Short(1);
2262 		return res;
2263 	}
2264 
operator --(Short & val)2265 	const Short &operator--(Short &val)   // Pre-decrement
2266 	{
2267 		val -= Short(1);
2268 		return val;
2269 	}
2270 
operator <(RValue<Short> lhs,RValue<Short> rhs)2271 	RValue<Bool> operator<(RValue<Short> lhs, RValue<Short> rhs)
2272 	{
2273 		return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
2274 	}
2275 
operator <=(RValue<Short> lhs,RValue<Short> rhs)2276 	RValue<Bool> operator<=(RValue<Short> lhs, RValue<Short> rhs)
2277 	{
2278 		return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
2279 	}
2280 
operator >(RValue<Short> lhs,RValue<Short> rhs)2281 	RValue<Bool> operator>(RValue<Short> lhs, RValue<Short> rhs)
2282 	{
2283 		return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
2284 	}
2285 
operator >=(RValue<Short> lhs,RValue<Short> rhs)2286 	RValue<Bool> operator>=(RValue<Short> lhs, RValue<Short> rhs)
2287 	{
2288 		return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
2289 	}
2290 
operator !=(RValue<Short> lhs,RValue<Short> rhs)2291 	RValue<Bool> operator!=(RValue<Short> lhs, RValue<Short> rhs)
2292 	{
2293 		return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
2294 	}
2295 
operator ==(RValue<Short> lhs,RValue<Short> rhs)2296 	RValue<Bool> operator==(RValue<Short> lhs, RValue<Short> rhs)
2297 	{
2298 		return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
2299 	}
2300 
getType()2301 	Type *Short::getType()
2302 	{
2303 		return T(Ice::IceType_i16);
2304 	}
2305 
UShort(Argument<UShort> argument)2306 	UShort::UShort(Argument<UShort> argument)
2307 	{
2308 		storeValue(argument.value);
2309 	}
2310 
UShort(RValue<UInt> cast)2311 	UShort::UShort(RValue<UInt> cast)
2312 	{
2313 		Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
2314 
2315 		storeValue(integer);
2316 	}
2317 
UShort(RValue<Int> cast)2318 	UShort::UShort(RValue<Int> cast)
2319 	{
2320 		Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
2321 
2322 		storeValue(integer);
2323 	}
2324 
UShort(unsigned short x)2325 	UShort::UShort(unsigned short x)
2326 	{
2327 		storeValue(Nucleus::createConstantShort(x));
2328 	}
2329 
UShort(RValue<UShort> rhs)2330 	UShort::UShort(RValue<UShort> rhs)
2331 	{
2332 		storeValue(rhs.value);
2333 	}
2334 
UShort(const UShort & rhs)2335 	UShort::UShort(const UShort &rhs)
2336 	{
2337 		Value *value = rhs.loadValue();
2338 		storeValue(value);
2339 	}
2340 
UShort(const Reference<UShort> & rhs)2341 	UShort::UShort(const Reference<UShort> &rhs)
2342 	{
2343 		Value *value = rhs.loadValue();
2344 		storeValue(value);
2345 	}
2346 
operator =(RValue<UShort> rhs)2347 	RValue<UShort> UShort::operator=(RValue<UShort> rhs)
2348 	{
2349 		storeValue(rhs.value);
2350 
2351 		return rhs;
2352 	}
2353 
operator =(const UShort & rhs)2354 	RValue<UShort> UShort::operator=(const UShort &rhs)
2355 	{
2356 		Value *value = rhs.loadValue();
2357 		storeValue(value);
2358 
2359 		return RValue<UShort>(value);
2360 	}
2361 
operator =(const Reference<UShort> & rhs)2362 	RValue<UShort> UShort::operator=(const Reference<UShort> &rhs)
2363 	{
2364 		Value *value = rhs.loadValue();
2365 		storeValue(value);
2366 
2367 		return RValue<UShort>(value);
2368 	}
2369 
operator +(RValue<UShort> lhs,RValue<UShort> rhs)2370 	RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs)
2371 	{
2372 		return RValue<UShort>(Nucleus::createAdd(lhs.value, rhs.value));
2373 	}
2374 
operator -(RValue<UShort> lhs,RValue<UShort> rhs)2375 	RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs)
2376 	{
2377 		return RValue<UShort>(Nucleus::createSub(lhs.value, rhs.value));
2378 	}
2379 
operator *(RValue<UShort> lhs,RValue<UShort> rhs)2380 	RValue<UShort> operator*(RValue<UShort> lhs, RValue<UShort> rhs)
2381 	{
2382 		return RValue<UShort>(Nucleus::createMul(lhs.value, rhs.value));
2383 	}
2384 
operator /(RValue<UShort> lhs,RValue<UShort> rhs)2385 	RValue<UShort> operator/(RValue<UShort> lhs, RValue<UShort> rhs)
2386 	{
2387 		return RValue<UShort>(Nucleus::createUDiv(lhs.value, rhs.value));
2388 	}
2389 
operator %(RValue<UShort> lhs,RValue<UShort> rhs)2390 	RValue<UShort> operator%(RValue<UShort> lhs, RValue<UShort> rhs)
2391 	{
2392 		return RValue<UShort>(Nucleus::createURem(lhs.value, rhs.value));
2393 	}
2394 
operator &(RValue<UShort> lhs,RValue<UShort> rhs)2395 	RValue<UShort> operator&(RValue<UShort> lhs, RValue<UShort> rhs)
2396 	{
2397 		return RValue<UShort>(Nucleus::createAnd(lhs.value, rhs.value));
2398 	}
2399 
operator |(RValue<UShort> lhs,RValue<UShort> rhs)2400 	RValue<UShort> operator|(RValue<UShort> lhs, RValue<UShort> rhs)
2401 	{
2402 		return RValue<UShort>(Nucleus::createOr(lhs.value, rhs.value));
2403 	}
2404 
operator ^(RValue<UShort> lhs,RValue<UShort> rhs)2405 	RValue<UShort> operator^(RValue<UShort> lhs, RValue<UShort> rhs)
2406 	{
2407 		return RValue<UShort>(Nucleus::createXor(lhs.value, rhs.value));
2408 	}
2409 
operator <<(RValue<UShort> lhs,RValue<UShort> rhs)2410 	RValue<UShort> operator<<(RValue<UShort> lhs, RValue<UShort> rhs)
2411 	{
2412 		return RValue<UShort>(Nucleus::createShl(lhs.value, rhs.value));
2413 	}
2414 
operator >>(RValue<UShort> lhs,RValue<UShort> rhs)2415 	RValue<UShort> operator>>(RValue<UShort> lhs, RValue<UShort> rhs)
2416 	{
2417 		return RValue<UShort>(Nucleus::createLShr(lhs.value, rhs.value));
2418 	}
2419 
operator +=(UShort & lhs,RValue<UShort> rhs)2420 	RValue<UShort> operator+=(UShort &lhs, RValue<UShort> rhs)
2421 	{
2422 		return lhs = lhs + rhs;
2423 	}
2424 
operator -=(UShort & lhs,RValue<UShort> rhs)2425 	RValue<UShort> operator-=(UShort &lhs, RValue<UShort> rhs)
2426 	{
2427 		return lhs = lhs - rhs;
2428 	}
2429 
operator *=(UShort & lhs,RValue<UShort> rhs)2430 	RValue<UShort> operator*=(UShort &lhs, RValue<UShort> rhs)
2431 	{
2432 		return lhs = lhs * rhs;
2433 	}
2434 
operator /=(UShort & lhs,RValue<UShort> rhs)2435 	RValue<UShort> operator/=(UShort &lhs, RValue<UShort> rhs)
2436 	{
2437 		return lhs = lhs / rhs;
2438 	}
2439 
operator %=(UShort & lhs,RValue<UShort> rhs)2440 	RValue<UShort> operator%=(UShort &lhs, RValue<UShort> rhs)
2441 	{
2442 		return lhs = lhs % rhs;
2443 	}
2444 
operator &=(UShort & lhs,RValue<UShort> rhs)2445 	RValue<UShort> operator&=(UShort &lhs, RValue<UShort> rhs)
2446 	{
2447 		return lhs = lhs & rhs;
2448 	}
2449 
operator |=(UShort & lhs,RValue<UShort> rhs)2450 	RValue<UShort> operator|=(UShort &lhs, RValue<UShort> rhs)
2451 	{
2452 		return lhs = lhs | rhs;
2453 	}
2454 
operator ^=(UShort & lhs,RValue<UShort> rhs)2455 	RValue<UShort> operator^=(UShort &lhs, RValue<UShort> rhs)
2456 	{
2457 		return lhs = lhs ^ rhs;
2458 	}
2459 
operator <<=(UShort & lhs,RValue<UShort> rhs)2460 	RValue<UShort> operator<<=(UShort &lhs, RValue<UShort> rhs)
2461 	{
2462 		return lhs = lhs << rhs;
2463 	}
2464 
operator >>=(UShort & lhs,RValue<UShort> rhs)2465 	RValue<UShort> operator>>=(UShort &lhs, RValue<UShort> rhs)
2466 	{
2467 		return lhs = lhs >> rhs;
2468 	}
2469 
operator +(RValue<UShort> val)2470 	RValue<UShort> operator+(RValue<UShort> val)
2471 	{
2472 		return val;
2473 	}
2474 
operator -(RValue<UShort> val)2475 	RValue<UShort> operator-(RValue<UShort> val)
2476 	{
2477 		return RValue<UShort>(Nucleus::createNeg(val.value));
2478 	}
2479 
operator ~(RValue<UShort> val)2480 	RValue<UShort> operator~(RValue<UShort> val)
2481 	{
2482 		return RValue<UShort>(Nucleus::createNot(val.value));
2483 	}
2484 
operator ++(UShort & val,int)2485 	RValue<UShort> operator++(UShort &val, int)   // Post-increment
2486 	{
2487 		RValue<UShort> res = val;
2488 		val += UShort(1);
2489 		return res;
2490 	}
2491 
operator ++(UShort & val)2492 	const UShort &operator++(UShort &val)   // Pre-increment
2493 	{
2494 		val += UShort(1);
2495 		return val;
2496 	}
2497 
operator --(UShort & val,int)2498 	RValue<UShort> operator--(UShort &val, int)   // Post-decrement
2499 	{
2500 		RValue<UShort> res = val;
2501 		val -= UShort(1);
2502 		return res;
2503 	}
2504 
operator --(UShort & val)2505 	const UShort &operator--(UShort &val)   // Pre-decrement
2506 	{
2507 		val -= UShort(1);
2508 		return val;
2509 	}
2510 
operator <(RValue<UShort> lhs,RValue<UShort> rhs)2511 	RValue<Bool> operator<(RValue<UShort> lhs, RValue<UShort> rhs)
2512 	{
2513 		return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
2514 	}
2515 
operator <=(RValue<UShort> lhs,RValue<UShort> rhs)2516 	RValue<Bool> operator<=(RValue<UShort> lhs, RValue<UShort> rhs)
2517 	{
2518 		return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
2519 	}
2520 
operator >(RValue<UShort> lhs,RValue<UShort> rhs)2521 	RValue<Bool> operator>(RValue<UShort> lhs, RValue<UShort> rhs)
2522 	{
2523 		return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
2524 	}
2525 
operator >=(RValue<UShort> lhs,RValue<UShort> rhs)2526 	RValue<Bool> operator>=(RValue<UShort> lhs, RValue<UShort> rhs)
2527 	{
2528 		return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
2529 	}
2530 
operator !=(RValue<UShort> lhs,RValue<UShort> rhs)2531 	RValue<Bool> operator!=(RValue<UShort> lhs, RValue<UShort> rhs)
2532 	{
2533 		return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
2534 	}
2535 
operator ==(RValue<UShort> lhs,RValue<UShort> rhs)2536 	RValue<Bool> operator==(RValue<UShort> lhs, RValue<UShort> rhs)
2537 	{
2538 		return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
2539 	}
2540 
getType()2541 	Type *UShort::getType()
2542 	{
2543 		return T(Ice::IceType_i16);
2544 	}
2545 
Byte4(RValue<Byte8> cast)2546 	Byte4::Byte4(RValue<Byte8> cast)
2547 	{
2548 		storeValue(Nucleus::createBitCast(cast.value, getType()));
2549 	}
2550 
Byte4(const Reference<Byte4> & rhs)2551 	Byte4::Byte4(const Reference<Byte4> &rhs)
2552 	{
2553 		Value *value = rhs.loadValue();
2554 		storeValue(value);
2555 	}
2556 
getType()2557 	Type *Byte4::getType()
2558 	{
2559 		return T(Type_v4i8);
2560 	}
2561 
getType()2562 	Type *SByte4::getType()
2563 	{
2564 		return T(Type_v4i8);
2565 	}
2566 
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)2567 	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)
2568 	{
2569 		int64_t constantVector[8] = {x0, x1, x2, x3, x4, x5, x6, x7};
2570 		storeValue(Nucleus::createConstantVector(constantVector, getType()));
2571 	}
2572 
Byte8(RValue<Byte8> rhs)2573 	Byte8::Byte8(RValue<Byte8> rhs)
2574 	{
2575 		storeValue(rhs.value);
2576 	}
2577 
Byte8(const Byte8 & rhs)2578 	Byte8::Byte8(const Byte8 &rhs)
2579 	{
2580 		Value *value = rhs.loadValue();
2581 		storeValue(value);
2582 	}
2583 
Byte8(const Reference<Byte8> & rhs)2584 	Byte8::Byte8(const Reference<Byte8> &rhs)
2585 	{
2586 		Value *value = rhs.loadValue();
2587 		storeValue(value);
2588 	}
2589 
operator =(RValue<Byte8> rhs)2590 	RValue<Byte8> Byte8::operator=(RValue<Byte8> rhs)
2591 	{
2592 		storeValue(rhs.value);
2593 
2594 		return rhs;
2595 	}
2596 
operator =(const Byte8 & rhs)2597 	RValue<Byte8> Byte8::operator=(const Byte8 &rhs)
2598 	{
2599 		Value *value = rhs.loadValue();
2600 		storeValue(value);
2601 
2602 		return RValue<Byte8>(value);
2603 	}
2604 
operator =(const Reference<Byte8> & rhs)2605 	RValue<Byte8> Byte8::operator=(const Reference<Byte8> &rhs)
2606 	{
2607 		Value *value = rhs.loadValue();
2608 		storeValue(value);
2609 
2610 		return RValue<Byte8>(value);
2611 	}
2612 
operator +(RValue<Byte8> lhs,RValue<Byte8> rhs)2613 	RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs)
2614 	{
2615 		return RValue<Byte8>(Nucleus::createAdd(lhs.value, rhs.value));
2616 	}
2617 
operator -(RValue<Byte8> lhs,RValue<Byte8> rhs)2618 	RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs)
2619 	{
2620 		return RValue<Byte8>(Nucleus::createSub(lhs.value, rhs.value));
2621 	}
2622 
2623 //	RValue<Byte8> operator*(RValue<Byte8> lhs, RValue<Byte8> rhs)
2624 //	{
2625 //		return RValue<Byte8>(Nucleus::createMul(lhs.value, rhs.value));
2626 //	}
2627 
2628 //	RValue<Byte8> operator/(RValue<Byte8> lhs, RValue<Byte8> rhs)
2629 //	{
2630 //		return RValue<Byte8>(Nucleus::createUDiv(lhs.value, rhs.value));
2631 //	}
2632 
2633 //	RValue<Byte8> operator%(RValue<Byte8> lhs, RValue<Byte8> rhs)
2634 //	{
2635 //		return RValue<Byte8>(Nucleus::createURem(lhs.value, rhs.value));
2636 //	}
2637 
operator &(RValue<Byte8> lhs,RValue<Byte8> rhs)2638 	RValue<Byte8> operator&(RValue<Byte8> lhs, RValue<Byte8> rhs)
2639 	{
2640 		return RValue<Byte8>(Nucleus::createAnd(lhs.value, rhs.value));
2641 	}
2642 
operator |(RValue<Byte8> lhs,RValue<Byte8> rhs)2643 	RValue<Byte8> operator|(RValue<Byte8> lhs, RValue<Byte8> rhs)
2644 	{
2645 		return RValue<Byte8>(Nucleus::createOr(lhs.value, rhs.value));
2646 	}
2647 
operator ^(RValue<Byte8> lhs,RValue<Byte8> rhs)2648 	RValue<Byte8> operator^(RValue<Byte8> lhs, RValue<Byte8> rhs)
2649 	{
2650 		return RValue<Byte8>(Nucleus::createXor(lhs.value, rhs.value));
2651 	}
2652 
2653 //	RValue<Byte8> operator<<(RValue<Byte8> lhs, unsigned char rhs)
2654 //	{
2655 //		return RValue<Byte8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
2656 //	}
2657 
2658 //	RValue<Byte8> operator>>(RValue<Byte8> lhs, unsigned char rhs)
2659 //	{
2660 //		return RValue<Byte8>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
2661 //	}
2662 
operator +=(Byte8 & lhs,RValue<Byte8> rhs)2663 	RValue<Byte8> operator+=(Byte8 &lhs, RValue<Byte8> rhs)
2664 	{
2665 		return lhs = lhs + rhs;
2666 	}
2667 
operator -=(Byte8 & lhs,RValue<Byte8> rhs)2668 	RValue<Byte8> operator-=(Byte8 &lhs, RValue<Byte8> rhs)
2669 	{
2670 		return lhs = lhs - rhs;
2671 	}
2672 
2673 //	RValue<Byte8> operator*=(Byte8 &lhs, RValue<Byte8> rhs)
2674 //	{
2675 //		return lhs = lhs * rhs;
2676 //	}
2677 
2678 //	RValue<Byte8> operator/=(Byte8 &lhs, RValue<Byte8> rhs)
2679 //	{
2680 //		return lhs = lhs / rhs;
2681 //	}
2682 
2683 //	RValue<Byte8> operator%=(Byte8 &lhs, RValue<Byte8> rhs)
2684 //	{
2685 //		return lhs = lhs % rhs;
2686 //	}
2687 
operator &=(Byte8 & lhs,RValue<Byte8> rhs)2688 	RValue<Byte8> operator&=(Byte8 &lhs, RValue<Byte8> rhs)
2689 	{
2690 		return lhs = lhs & rhs;
2691 	}
2692 
operator |=(Byte8 & lhs,RValue<Byte8> rhs)2693 	RValue<Byte8> operator|=(Byte8 &lhs, RValue<Byte8> rhs)
2694 	{
2695 		return lhs = lhs | rhs;
2696 	}
2697 
operator ^=(Byte8 & lhs,RValue<Byte8> rhs)2698 	RValue<Byte8> operator^=(Byte8 &lhs, RValue<Byte8> rhs)
2699 	{
2700 		return lhs = lhs ^ rhs;
2701 	}
2702 
2703 //	RValue<Byte8> operator<<=(Byte8 &lhs, RValue<Byte8> rhs)
2704 //	{
2705 //		return lhs = lhs << rhs;
2706 //	}
2707 
2708 //	RValue<Byte8> operator>>=(Byte8 &lhs, RValue<Byte8> rhs)
2709 //	{
2710 //		return lhs = lhs >> rhs;
2711 //	}
2712 
2713 //	RValue<Byte8> operator+(RValue<Byte8> val)
2714 //	{
2715 //		return val;
2716 //	}
2717 
2718 //	RValue<Byte8> operator-(RValue<Byte8> val)
2719 //	{
2720 //		return RValue<Byte8>(Nucleus::createNeg(val.value));
2721 //	}
2722 
operator ~(RValue<Byte8> val)2723 	RValue<Byte8> operator~(RValue<Byte8> val)
2724 	{
2725 		return RValue<Byte8>(Nucleus::createNot(val.value));
2726 	}
2727 
Extract(RValue<Byte8> val,int i)2728 	RValue<Byte> Extract(RValue<Byte8> val, int i)
2729 	{
2730 		return RValue<Byte>(Nucleus::createExtractElement(val.value, Byte::getType(), i));
2731 	}
2732 
Insert(RValue<Byte8> val,RValue<Byte> element,int i)2733 	RValue<Byte8> Insert(RValue<Byte8> val, RValue<Byte> element, int i)
2734 	{
2735 		return RValue<Byte8>(Nucleus::createInsertElement(val.value, element.value, i));
2736 	}
2737 
SaturateUnsigned(RValue<Short> x)2738 	RValue<Byte> SaturateUnsigned(RValue<Short> x)
2739 	{
2740 		return Byte(IfThenElse(Int(x) > 0xFF, Int(0xFF), IfThenElse(Int(x) < 0, Int(0), Int(x))));
2741 	}
2742 
AddSat(RValue<Byte8> x,RValue<Byte8> y)2743 	RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y)
2744 	{
2745 		if(emulateIntrinsics)
2746 		{
2747 			Byte8 result;
2748 			result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 0)) + Int(Extract(y, 0)))), 0);
2749 			result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 1)) + Int(Extract(y, 1)))), 1);
2750 			result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 2)) + Int(Extract(y, 2)))), 2);
2751 			result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 3)) + Int(Extract(y, 3)))), 3);
2752 			result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 4)) + Int(Extract(y, 4)))), 4);
2753 			result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 5)) + Int(Extract(y, 5)))), 5);
2754 			result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 6)) + Int(Extract(y, 6)))), 6);
2755 			result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 7)) + Int(Extract(y, 7)))), 7);
2756 
2757 			return result;
2758 		}
2759 		else
2760 		{
2761 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
2762 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2763 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
2764 			auto paddusb = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
2765 			paddusb->addArg(x.value);
2766 			paddusb->addArg(y.value);
2767 			::basicBlock->appendInst(paddusb);
2768 
2769 			return RValue<Byte8>(V(result));
2770 		}
2771 	}
2772 
SubSat(RValue<Byte8> x,RValue<Byte8> y)2773 	RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y)
2774 	{
2775 		if(emulateIntrinsics)
2776 		{
2777 			Byte8 result;
2778 			result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 0)) - Int(Extract(y, 0)))), 0);
2779 			result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 1)) - Int(Extract(y, 1)))), 1);
2780 			result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 2)) - Int(Extract(y, 2)))), 2);
2781 			result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 3)) - Int(Extract(y, 3)))), 3);
2782 			result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 4)) - Int(Extract(y, 4)))), 4);
2783 			result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 5)) - Int(Extract(y, 5)))), 5);
2784 			result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 6)) - Int(Extract(y, 6)))), 6);
2785 			result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 7)) - Int(Extract(y, 7)))), 7);
2786 
2787 			return result;
2788 		}
2789 		else
2790 		{
2791 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
2792 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2793 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
2794 			auto psubusw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
2795 			psubusw->addArg(x.value);
2796 			psubusw->addArg(y.value);
2797 			::basicBlock->appendInst(psubusw);
2798 
2799 			return RValue<Byte8>(V(result));
2800 		}
2801 	}
2802 
Unpack(RValue<Byte4> x)2803 	RValue<Short4> Unpack(RValue<Byte4> x)
2804 	{
2805 		int shuffle[16] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7};   // Real type is v16i8
2806 		return As<Short4>(Nucleus::createShuffleVector(x.value, x.value, shuffle));
2807 	}
2808 
Unpack(RValue<Byte4> x,RValue<Byte4> y)2809 	RValue<Short4> Unpack(RValue<Byte4> x, RValue<Byte4> y)
2810 	{
2811 		return UnpackLow(As<Byte8>(x), As<Byte8>(y));
2812 	}
2813 
UnpackLow(RValue<Byte8> x,RValue<Byte8> y)2814 	RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y)
2815 	{
2816 		int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23};   // Real type is v16i8
2817 		return As<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
2818 	}
2819 
UnpackHigh(RValue<Byte8> x,RValue<Byte8> y)2820 	RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y)
2821 	{
2822 		int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23};   // Real type is v16i8
2823 		auto lowHigh = RValue<Byte16>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
2824 		return As<Short4>(Swizzle(As<Int4>(lowHigh), 0xEE));
2825 	}
2826 
Extract(RValue<SByte8> val,int i)2827 	RValue<SByte> Extract(RValue<SByte8> val, int i)
2828 	{
2829 		return RValue<SByte>(Nucleus::createExtractElement(val.value, SByte::getType(), i));
2830 	}
2831 
Insert(RValue<SByte8> val,RValue<SByte> element,int i)2832 	RValue<SByte8> Insert(RValue<SByte8> val, RValue<SByte> element, int i)
2833 	{
2834 		return RValue<SByte8>(Nucleus::createInsertElement(val.value, element.value, i));
2835 	}
2836 
operator >>(RValue<SByte8> lhs,unsigned char rhs)2837 	RValue<SByte8> operator>>(RValue<SByte8> lhs, unsigned char rhs)
2838 	{
2839 		if(emulateIntrinsics)
2840 		{
2841 			SByte8 result;
2842 			result = Insert(result, Extract(lhs, 0) >> SByte(rhs), 0);
2843 			result = Insert(result, Extract(lhs, 1) >> SByte(rhs), 1);
2844 			result = Insert(result, Extract(lhs, 2) >> SByte(rhs), 2);
2845 			result = Insert(result, Extract(lhs, 3) >> SByte(rhs), 3);
2846 			result = Insert(result, Extract(lhs, 4) >> SByte(rhs), 4);
2847 			result = Insert(result, Extract(lhs, 5) >> SByte(rhs), 5);
2848 			result = Insert(result, Extract(lhs, 6) >> SByte(rhs), 6);
2849 			result = Insert(result, Extract(lhs, 7) >> SByte(rhs), 7);
2850 
2851 			return result;
2852 		}
2853 		else
2854 		{
2855 			#if defined(__i386__) || defined(__x86_64__)
2856 				// SSE2 doesn't support byte vector shifts, so shift as shorts and recombine.
2857 				RValue<Short4> hi = (As<Short4>(lhs) >> rhs) & Short4(0xFF00u);
2858 				RValue<Short4> lo = As<Short4>(As<UShort4>((As<Short4>(lhs) << 8) >> rhs) >> 8);
2859 
2860 				return As<SByte8>(hi | lo);
2861 			#else
2862 				return RValue<SByte8>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
2863 			#endif
2864 		}
2865 	}
2866 
SignMask(RValue<Byte8> x)2867 	RValue<Int> SignMask(RValue<Byte8> x)
2868 	{
2869 		if(emulateIntrinsics || CPUID::ARM)
2870 		{
2871 			Byte8 xx = As<Byte8>(As<SByte8>(x) >> 7) & Byte8(0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80);
2872 			return Int(Extract(xx, 0)) | Int(Extract(xx, 1)) | Int(Extract(xx, 2)) | Int(Extract(xx, 3)) | Int(Extract(xx, 4)) | Int(Extract(xx, 5)) | Int(Extract(xx, 6)) | Int(Extract(xx, 7));
2873 		}
2874 		else
2875 		{
2876 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
2877 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2878 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
2879 			auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
2880 			movmsk->addArg(x.value);
2881 			::basicBlock->appendInst(movmsk);
2882 
2883 			return RValue<Int>(V(result)) & 0xFF;
2884 		}
2885 	}
2886 
2887 //	RValue<Byte8> CmpGT(RValue<Byte8> x, RValue<Byte8> y)
2888 //	{
2889 //		return RValue<Byte8>(createIntCompare(Ice::InstIcmp::Ugt, x.value, y.value));
2890 //	}
2891 
CmpEQ(RValue<Byte8> x,RValue<Byte8> y)2892 	RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y)
2893 	{
2894 		return RValue<Byte8>(Nucleus::createICmpEQ(x.value, y.value));
2895 	}
2896 
getType()2897 	Type *Byte8::getType()
2898 	{
2899 		return T(Type_v8i8);
2900 	}
2901 
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)2902 	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)
2903 	{
2904 		int64_t constantVector[8] = { x0, x1, x2, x3, x4, x5, x6, x7 };
2905 		Value *vector = V(Nucleus::createConstantVector(constantVector, getType()));
2906 
2907 		storeValue(Nucleus::createBitCast(vector, getType()));
2908 	}
2909 
SByte8(RValue<SByte8> rhs)2910 	SByte8::SByte8(RValue<SByte8> rhs)
2911 	{
2912 		storeValue(rhs.value);
2913 	}
2914 
SByte8(const SByte8 & rhs)2915 	SByte8::SByte8(const SByte8 &rhs)
2916 	{
2917 		Value *value = rhs.loadValue();
2918 		storeValue(value);
2919 	}
2920 
SByte8(const Reference<SByte8> & rhs)2921 	SByte8::SByte8(const Reference<SByte8> &rhs)
2922 	{
2923 		Value *value = rhs.loadValue();
2924 		storeValue(value);
2925 	}
2926 
operator =(RValue<SByte8> rhs)2927 	RValue<SByte8> SByte8::operator=(RValue<SByte8> rhs)
2928 	{
2929 		storeValue(rhs.value);
2930 
2931 		return rhs;
2932 	}
2933 
operator =(const SByte8 & rhs)2934 	RValue<SByte8> SByte8::operator=(const SByte8 &rhs)
2935 	{
2936 		Value *value = rhs.loadValue();
2937 		storeValue(value);
2938 
2939 		return RValue<SByte8>(value);
2940 	}
2941 
operator =(const Reference<SByte8> & rhs)2942 	RValue<SByte8> SByte8::operator=(const Reference<SByte8> &rhs)
2943 	{
2944 		Value *value = rhs.loadValue();
2945 		storeValue(value);
2946 
2947 		return RValue<SByte8>(value);
2948 	}
2949 
operator +(RValue<SByte8> lhs,RValue<SByte8> rhs)2950 	RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs)
2951 	{
2952 		return RValue<SByte8>(Nucleus::createAdd(lhs.value, rhs.value));
2953 	}
2954 
operator -(RValue<SByte8> lhs,RValue<SByte8> rhs)2955 	RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs)
2956 	{
2957 		return RValue<SByte8>(Nucleus::createSub(lhs.value, rhs.value));
2958 	}
2959 
2960 //	RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs)
2961 //	{
2962 //		return RValue<SByte8>(Nucleus::createMul(lhs.value, rhs.value));
2963 //	}
2964 
2965 //	RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs)
2966 //	{
2967 //		return RValue<SByte8>(Nucleus::createSDiv(lhs.value, rhs.value));
2968 //	}
2969 
2970 //	RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs)
2971 //	{
2972 //		return RValue<SByte8>(Nucleus::createSRem(lhs.value, rhs.value));
2973 //	}
2974 
operator &(RValue<SByte8> lhs,RValue<SByte8> rhs)2975 	RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs)
2976 	{
2977 		return RValue<SByte8>(Nucleus::createAnd(lhs.value, rhs.value));
2978 	}
2979 
operator |(RValue<SByte8> lhs,RValue<SByte8> rhs)2980 	RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs)
2981 	{
2982 		return RValue<SByte8>(Nucleus::createOr(lhs.value, rhs.value));
2983 	}
2984 
operator ^(RValue<SByte8> lhs,RValue<SByte8> rhs)2985 	RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs)
2986 	{
2987 		return RValue<SByte8>(Nucleus::createXor(lhs.value, rhs.value));
2988 	}
2989 
2990 //	RValue<SByte8> operator<<(RValue<SByte8> lhs, unsigned char rhs)
2991 //	{
2992 //		return RValue<SByte8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
2993 //	}
2994 
2995 //	RValue<SByte8> operator>>(RValue<SByte8> lhs, unsigned char rhs)
2996 //	{
2997 //		return RValue<SByte8>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
2998 //	}
2999 
operator +=(SByte8 & lhs,RValue<SByte8> rhs)3000 	RValue<SByte8> operator+=(SByte8 &lhs, RValue<SByte8> rhs)
3001 	{
3002 		return lhs = lhs + rhs;
3003 	}
3004 
operator -=(SByte8 & lhs,RValue<SByte8> rhs)3005 	RValue<SByte8> operator-=(SByte8 &lhs, RValue<SByte8> rhs)
3006 	{
3007 		return lhs = lhs - rhs;
3008 	}
3009 
3010 //	RValue<SByte8> operator*=(SByte8 &lhs, RValue<SByte8> rhs)
3011 //	{
3012 //		return lhs = lhs * rhs;
3013 //	}
3014 
3015 //	RValue<SByte8> operator/=(SByte8 &lhs, RValue<SByte8> rhs)
3016 //	{
3017 //		return lhs = lhs / rhs;
3018 //	}
3019 
3020 //	RValue<SByte8> operator%=(SByte8 &lhs, RValue<SByte8> rhs)
3021 //	{
3022 //		return lhs = lhs % rhs;
3023 //	}
3024 
operator &=(SByte8 & lhs,RValue<SByte8> rhs)3025 	RValue<SByte8> operator&=(SByte8 &lhs, RValue<SByte8> rhs)
3026 	{
3027 		return lhs = lhs & rhs;
3028 	}
3029 
operator |=(SByte8 & lhs,RValue<SByte8> rhs)3030 	RValue<SByte8> operator|=(SByte8 &lhs, RValue<SByte8> rhs)
3031 	{
3032 		return lhs = lhs | rhs;
3033 	}
3034 
operator ^=(SByte8 & lhs,RValue<SByte8> rhs)3035 	RValue<SByte8> operator^=(SByte8 &lhs, RValue<SByte8> rhs)
3036 	{
3037 		return lhs = lhs ^ rhs;
3038 	}
3039 
3040 //	RValue<SByte8> operator<<=(SByte8 &lhs, RValue<SByte8> rhs)
3041 //	{
3042 //		return lhs = lhs << rhs;
3043 //	}
3044 
3045 //	RValue<SByte8> operator>>=(SByte8 &lhs, RValue<SByte8> rhs)
3046 //	{
3047 //		return lhs = lhs >> rhs;
3048 //	}
3049 
3050 //	RValue<SByte8> operator+(RValue<SByte8> val)
3051 //	{
3052 //		return val;
3053 //	}
3054 
3055 //	RValue<SByte8> operator-(RValue<SByte8> val)
3056 //	{
3057 //		return RValue<SByte8>(Nucleus::createNeg(val.value));
3058 //	}
3059 
operator ~(RValue<SByte8> val)3060 	RValue<SByte8> operator~(RValue<SByte8> val)
3061 	{
3062 		return RValue<SByte8>(Nucleus::createNot(val.value));
3063 	}
3064 
SaturateSigned(RValue<Short> x)3065 	RValue<SByte> SaturateSigned(RValue<Short> x)
3066 	{
3067 		return SByte(IfThenElse(Int(x) > 0x7F, Int(0x7F), IfThenElse(Int(x) < -0x80, Int(0x80), Int(x))));
3068 	}
3069 
AddSat(RValue<SByte8> x,RValue<SByte8> y)3070 	RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y)
3071 	{
3072 		if(emulateIntrinsics)
3073 		{
3074 			SByte8 result;
3075 			result = Insert(result, SaturateSigned(Short(Int(Extract(x, 0)) + Int(Extract(y, 0)))), 0);
3076 			result = Insert(result, SaturateSigned(Short(Int(Extract(x, 1)) + Int(Extract(y, 1)))), 1);
3077 			result = Insert(result, SaturateSigned(Short(Int(Extract(x, 2)) + Int(Extract(y, 2)))), 2);
3078 			result = Insert(result, SaturateSigned(Short(Int(Extract(x, 3)) + Int(Extract(y, 3)))), 3);
3079 			result = Insert(result, SaturateSigned(Short(Int(Extract(x, 4)) + Int(Extract(y, 4)))), 4);
3080 			result = Insert(result, SaturateSigned(Short(Int(Extract(x, 5)) + Int(Extract(y, 5)))), 5);
3081 			result = Insert(result, SaturateSigned(Short(Int(Extract(x, 6)) + Int(Extract(y, 6)))), 6);
3082 			result = Insert(result, SaturateSigned(Short(Int(Extract(x, 7)) + Int(Extract(y, 7)))), 7);
3083 
3084 			return result;
3085 		}
3086 		else
3087 		{
3088 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
3089 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3090 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
3091 			auto paddsb = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3092 			paddsb->addArg(x.value);
3093 			paddsb->addArg(y.value);
3094 			::basicBlock->appendInst(paddsb);
3095 
3096 			return RValue<SByte8>(V(result));
3097 		}
3098 	}
3099 
SubSat(RValue<SByte8> x,RValue<SByte8> y)3100 	RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y)
3101 	{
3102 		if(emulateIntrinsics)
3103 		{
3104 			SByte8 result;
3105 			result = Insert(result, SaturateSigned(Short(Int(Extract(x, 0)) - Int(Extract(y, 0)))), 0);
3106 			result = Insert(result, SaturateSigned(Short(Int(Extract(x, 1)) - Int(Extract(y, 1)))), 1);
3107 			result = Insert(result, SaturateSigned(Short(Int(Extract(x, 2)) - Int(Extract(y, 2)))), 2);
3108 			result = Insert(result, SaturateSigned(Short(Int(Extract(x, 3)) - Int(Extract(y, 3)))), 3);
3109 			result = Insert(result, SaturateSigned(Short(Int(Extract(x, 4)) - Int(Extract(y, 4)))), 4);
3110 			result = Insert(result, SaturateSigned(Short(Int(Extract(x, 5)) - Int(Extract(y, 5)))), 5);
3111 			result = Insert(result, SaturateSigned(Short(Int(Extract(x, 6)) - Int(Extract(y, 6)))), 6);
3112 			result = Insert(result, SaturateSigned(Short(Int(Extract(x, 7)) - Int(Extract(y, 7)))), 7);
3113 
3114 			return result;
3115 		}
3116 		else
3117 		{
3118 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
3119 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3120 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
3121 			auto psubsb = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3122 			psubsb->addArg(x.value);
3123 			psubsb->addArg(y.value);
3124 			::basicBlock->appendInst(psubsb);
3125 
3126 			return RValue<SByte8>(V(result));
3127 		}
3128 	}
3129 
UnpackLow(RValue<SByte8> x,RValue<SByte8> y)3130 	RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y)
3131 	{
3132 		int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23};   // Real type is v16i8
3133 		return As<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
3134 	}
3135 
UnpackHigh(RValue<SByte8> x,RValue<SByte8> y)3136 	RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y)
3137 	{
3138 		int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23};   // Real type is v16i8
3139 		auto lowHigh = RValue<Byte16>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
3140 		return As<Short4>(Swizzle(As<Int4>(lowHigh), 0xEE));
3141 	}
3142 
SignMask(RValue<SByte8> x)3143 	RValue<Int> SignMask(RValue<SByte8> x)
3144 	{
3145 		if(emulateIntrinsics || CPUID::ARM)
3146 		{
3147 			SByte8 xx = (x >> 7) & SByte8(0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80);
3148 			return Int(Extract(xx, 0)) | Int(Extract(xx, 1)) | Int(Extract(xx, 2)) | Int(Extract(xx, 3)) | Int(Extract(xx, 4)) | Int(Extract(xx, 5)) | Int(Extract(xx, 6)) | Int(Extract(xx, 7));
3149 		}
3150 		else
3151 		{
3152 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
3153 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3154 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
3155 			auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
3156 			movmsk->addArg(x.value);
3157 			::basicBlock->appendInst(movmsk);
3158 
3159 			return RValue<Int>(V(result)) & 0xFF;
3160 		}
3161 	}
3162 
CmpGT(RValue<SByte8> x,RValue<SByte8> y)3163 	RValue<Byte8> CmpGT(RValue<SByte8> x, RValue<SByte8> y)
3164 	{
3165 		return RValue<Byte8>(createIntCompare(Ice::InstIcmp::Sgt, x.value, y.value));
3166 	}
3167 
CmpEQ(RValue<SByte8> x,RValue<SByte8> y)3168 	RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y)
3169 	{
3170 		return RValue<Byte8>(Nucleus::createICmpEQ(x.value, y.value));
3171 	}
3172 
getType()3173 	Type *SByte8::getType()
3174 	{
3175 		return T(Type_v8i8);
3176 	}
3177 
Byte16(RValue<Byte16> rhs)3178 	Byte16::Byte16(RValue<Byte16> rhs)
3179 	{
3180 		storeValue(rhs.value);
3181 	}
3182 
Byte16(const Byte16 & rhs)3183 	Byte16::Byte16(const Byte16 &rhs)
3184 	{
3185 		Value *value = rhs.loadValue();
3186 		storeValue(value);
3187 	}
3188 
Byte16(const Reference<Byte16> & rhs)3189 	Byte16::Byte16(const Reference<Byte16> &rhs)
3190 	{
3191 		Value *value = rhs.loadValue();
3192 		storeValue(value);
3193 	}
3194 
operator =(RValue<Byte16> rhs)3195 	RValue<Byte16> Byte16::operator=(RValue<Byte16> rhs)
3196 	{
3197 		storeValue(rhs.value);
3198 
3199 		return rhs;
3200 	}
3201 
operator =(const Byte16 & rhs)3202 	RValue<Byte16> Byte16::operator=(const Byte16 &rhs)
3203 	{
3204 		Value *value = rhs.loadValue();
3205 		storeValue(value);
3206 
3207 		return RValue<Byte16>(value);
3208 	}
3209 
operator =(const Reference<Byte16> & rhs)3210 	RValue<Byte16> Byte16::operator=(const Reference<Byte16> &rhs)
3211 	{
3212 		Value *value = rhs.loadValue();
3213 		storeValue(value);
3214 
3215 		return RValue<Byte16>(value);
3216 	}
3217 
getType()3218 	Type *Byte16::getType()
3219 	{
3220 		return T(Ice::IceType_v16i8);
3221 	}
3222 
getType()3223 	Type *SByte16::getType()
3224 	{
3225 		return T(Ice::IceType_v16i8);
3226 	}
3227 
Short2(RValue<Short4> cast)3228 	Short2::Short2(RValue<Short4> cast)
3229 	{
3230 		storeValue(Nucleus::createBitCast(cast.value, getType()));
3231 	}
3232 
getType()3233 	Type *Short2::getType()
3234 	{
3235 		return T(Type_v2i16);
3236 	}
3237 
UShort2(RValue<UShort4> cast)3238 	UShort2::UShort2(RValue<UShort4> cast)
3239 	{
3240 		storeValue(Nucleus::createBitCast(cast.value, getType()));
3241 	}
3242 
getType()3243 	Type *UShort2::getType()
3244 	{
3245 		return T(Type_v2i16);
3246 	}
3247 
Short4(RValue<Int> cast)3248 	Short4::Short4(RValue<Int> cast)
3249 	{
3250 		Value *vector = loadValue();
3251 		Value *element = Nucleus::createTrunc(cast.value, Short::getType());
3252 		Value *insert = Nucleus::createInsertElement(vector, element, 0);
3253 		Value *swizzle = Swizzle(RValue<Short4>(insert), 0x00).value;
3254 
3255 		storeValue(swizzle);
3256 	}
3257 
Short4(RValue<Int4> cast)3258 	Short4::Short4(RValue<Int4> cast)
3259 	{
3260 		int select[8] = {0, 2, 4, 6, 0, 2, 4, 6};
3261 		Value *short8 = Nucleus::createBitCast(cast.value, Short8::getType());
3262 		Value *packed = Nucleus::createShuffleVector(short8, short8, select);
3263 
3264 		Value *int2 = RValue<Int2>(Int2(As<Int4>(packed))).value;
3265 		Value *short4 = Nucleus::createBitCast(int2, Short4::getType());
3266 
3267 		storeValue(short4);
3268 	}
3269 
3270 //	Short4::Short4(RValue<Float> cast)
3271 //	{
3272 //	}
3273 
Short4(RValue<Float4> cast)3274 	Short4::Short4(RValue<Float4> cast)
3275 	{
3276 		assert(false && "UNIMPLEMENTED");
3277 	}
3278 
Short4(short xyzw)3279 	Short4::Short4(short xyzw)
3280 	{
3281 		int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
3282 		storeValue(Nucleus::createConstantVector(constantVector, getType()));
3283 	}
3284 
Short4(short x,short y,short z,short w)3285 	Short4::Short4(short x, short y, short z, short w)
3286 	{
3287 		int64_t constantVector[4] = {x, y, z, w};
3288 		storeValue(Nucleus::createConstantVector(constantVector, getType()));
3289 	}
3290 
Short4(RValue<Short4> rhs)3291 	Short4::Short4(RValue<Short4> rhs)
3292 	{
3293 		storeValue(rhs.value);
3294 	}
3295 
Short4(const Short4 & rhs)3296 	Short4::Short4(const Short4 &rhs)
3297 	{
3298 		Value *value = rhs.loadValue();
3299 		storeValue(value);
3300 	}
3301 
Short4(const Reference<Short4> & rhs)3302 	Short4::Short4(const Reference<Short4> &rhs)
3303 	{
3304 		Value *value = rhs.loadValue();
3305 		storeValue(value);
3306 	}
3307 
Short4(RValue<UShort4> rhs)3308 	Short4::Short4(RValue<UShort4> rhs)
3309 	{
3310 		storeValue(rhs.value);
3311 	}
3312 
Short4(const UShort4 & rhs)3313 	Short4::Short4(const UShort4 &rhs)
3314 	{
3315 		storeValue(rhs.loadValue());
3316 	}
3317 
Short4(const Reference<UShort4> & rhs)3318 	Short4::Short4(const Reference<UShort4> &rhs)
3319 	{
3320 		storeValue(rhs.loadValue());
3321 	}
3322 
operator =(RValue<Short4> rhs)3323 	RValue<Short4> Short4::operator=(RValue<Short4> rhs)
3324 	{
3325 		storeValue(rhs.value);
3326 
3327 		return rhs;
3328 	}
3329 
operator =(const Short4 & rhs)3330 	RValue<Short4> Short4::operator=(const Short4 &rhs)
3331 	{
3332 		Value *value = rhs.loadValue();
3333 		storeValue(value);
3334 
3335 		return RValue<Short4>(value);
3336 	}
3337 
operator =(const Reference<Short4> & rhs)3338 	RValue<Short4> Short4::operator=(const Reference<Short4> &rhs)
3339 	{
3340 		Value *value = rhs.loadValue();
3341 		storeValue(value);
3342 
3343 		return RValue<Short4>(value);
3344 	}
3345 
operator =(RValue<UShort4> rhs)3346 	RValue<Short4> Short4::operator=(RValue<UShort4> rhs)
3347 	{
3348 		storeValue(rhs.value);
3349 
3350 		return RValue<Short4>(rhs);
3351 	}
3352 
operator =(const UShort4 & rhs)3353 	RValue<Short4> Short4::operator=(const UShort4 &rhs)
3354 	{
3355 		Value *value = rhs.loadValue();
3356 		storeValue(value);
3357 
3358 		return RValue<Short4>(value);
3359 	}
3360 
operator =(const Reference<UShort4> & rhs)3361 	RValue<Short4> Short4::operator=(const Reference<UShort4> &rhs)
3362 	{
3363 		Value *value = rhs.loadValue();
3364 		storeValue(value);
3365 
3366 		return RValue<Short4>(value);
3367 	}
3368 
operator +(RValue<Short4> lhs,RValue<Short4> rhs)3369 	RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs)
3370 	{
3371 		return RValue<Short4>(Nucleus::createAdd(lhs.value, rhs.value));
3372 	}
3373 
operator -(RValue<Short4> lhs,RValue<Short4> rhs)3374 	RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs)
3375 	{
3376 		return RValue<Short4>(Nucleus::createSub(lhs.value, rhs.value));
3377 	}
3378 
operator *(RValue<Short4> lhs,RValue<Short4> rhs)3379 	RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs)
3380 	{
3381 		return RValue<Short4>(Nucleus::createMul(lhs.value, rhs.value));
3382 	}
3383 
3384 //	RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs)
3385 //	{
3386 //		return RValue<Short4>(Nucleus::createSDiv(lhs.value, rhs.value));
3387 //	}
3388 
3389 //	RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs)
3390 //	{
3391 //		return RValue<Short4>(Nucleus::createSRem(lhs.value, rhs.value));
3392 //	}
3393 
operator &(RValue<Short4> lhs,RValue<Short4> rhs)3394 	RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs)
3395 	{
3396 		return RValue<Short4>(Nucleus::createAnd(lhs.value, rhs.value));
3397 	}
3398 
operator |(RValue<Short4> lhs,RValue<Short4> rhs)3399 	RValue<Short4> operator|(RValue<Short4> lhs, RValue<Short4> rhs)
3400 	{
3401 		return RValue<Short4>(Nucleus::createOr(lhs.value, rhs.value));
3402 	}
3403 
operator ^(RValue<Short4> lhs,RValue<Short4> rhs)3404 	RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs)
3405 	{
3406 		return RValue<Short4>(Nucleus::createXor(lhs.value, rhs.value));
3407 	}
3408 
operator <<(RValue<Short4> lhs,unsigned char rhs)3409 	RValue<Short4> operator<<(RValue<Short4> lhs, unsigned char rhs)
3410 	{
3411 		if(emulateIntrinsics)
3412 		{
3413 			Short4 result;
3414 			result = Insert(result, Extract(lhs, 0) << Short(rhs), 0);
3415 			result = Insert(result, Extract(lhs, 1) << Short(rhs), 1);
3416 			result = Insert(result, Extract(lhs, 2) << Short(rhs), 2);
3417 			result = Insert(result, Extract(lhs, 3) << Short(rhs), 3);
3418 
3419 			return result;
3420 		}
3421 		else
3422 		{
3423 			return RValue<Short4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
3424 		}
3425 	}
3426 
operator >>(RValue<Short4> lhs,unsigned char rhs)3427 	RValue<Short4> operator>>(RValue<Short4> lhs, unsigned char rhs)
3428 	{
3429 		if(emulateIntrinsics)
3430 		{
3431 			Short4 result;
3432 			result = Insert(result, Extract(lhs, 0) >> Short(rhs), 0);
3433 			result = Insert(result, Extract(lhs, 1) >> Short(rhs), 1);
3434 			result = Insert(result, Extract(lhs, 2) >> Short(rhs), 2);
3435 			result = Insert(result, Extract(lhs, 3) >> Short(rhs), 3);
3436 
3437 			return result;
3438 		}
3439 		else
3440 		{
3441 			return RValue<Short4>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
3442 		}
3443 	}
3444 
operator +=(Short4 & lhs,RValue<Short4> rhs)3445 	RValue<Short4> operator+=(Short4 &lhs, RValue<Short4> rhs)
3446 	{
3447 		return lhs = lhs + rhs;
3448 	}
3449 
operator -=(Short4 & lhs,RValue<Short4> rhs)3450 	RValue<Short4> operator-=(Short4 &lhs, RValue<Short4> rhs)
3451 	{
3452 		return lhs = lhs - rhs;
3453 	}
3454 
operator *=(Short4 & lhs,RValue<Short4> rhs)3455 	RValue<Short4> operator*=(Short4 &lhs, RValue<Short4> rhs)
3456 	{
3457 		return lhs = lhs * rhs;
3458 	}
3459 
3460 //	RValue<Short4> operator/=(Short4 &lhs, RValue<Short4> rhs)
3461 //	{
3462 //		return lhs = lhs / rhs;
3463 //	}
3464 
3465 //	RValue<Short4> operator%=(Short4 &lhs, RValue<Short4> rhs)
3466 //	{
3467 //		return lhs = lhs % rhs;
3468 //	}
3469 
operator &=(Short4 & lhs,RValue<Short4> rhs)3470 	RValue<Short4> operator&=(Short4 &lhs, RValue<Short4> rhs)
3471 	{
3472 		return lhs = lhs & rhs;
3473 	}
3474 
operator |=(Short4 & lhs,RValue<Short4> rhs)3475 	RValue<Short4> operator|=(Short4 &lhs, RValue<Short4> rhs)
3476 	{
3477 		return lhs = lhs | rhs;
3478 	}
3479 
operator ^=(Short4 & lhs,RValue<Short4> rhs)3480 	RValue<Short4> operator^=(Short4 &lhs, RValue<Short4> rhs)
3481 	{
3482 		return lhs = lhs ^ rhs;
3483 	}
3484 
operator <<=(Short4 & lhs,unsigned char rhs)3485 	RValue<Short4> operator<<=(Short4 &lhs, unsigned char rhs)
3486 	{
3487 		return lhs = lhs << rhs;
3488 	}
3489 
operator >>=(Short4 & lhs,unsigned char rhs)3490 	RValue<Short4> operator>>=(Short4 &lhs, unsigned char rhs)
3491 	{
3492 		return lhs = lhs >> rhs;
3493 	}
3494 
3495 //	RValue<Short4> operator+(RValue<Short4> val)
3496 //	{
3497 //		return val;
3498 //	}
3499 
operator -(RValue<Short4> val)3500 	RValue<Short4> operator-(RValue<Short4> val)
3501 	{
3502 		return RValue<Short4>(Nucleus::createNeg(val.value));
3503 	}
3504 
operator ~(RValue<Short4> val)3505 	RValue<Short4> operator~(RValue<Short4> val)
3506 	{
3507 		return RValue<Short4>(Nucleus::createNot(val.value));
3508 	}
3509 
RoundShort4(RValue<Float4> cast)3510 	RValue<Short4> RoundShort4(RValue<Float4> cast)
3511 	{
3512 		RValue<Int4> int4 = RoundInt(cast);
3513 		return As<Short4>(PackSigned(int4, int4));
3514 	}
3515 
Max(RValue<Short4> x,RValue<Short4> y)3516 	RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y)
3517 	{
3518 		Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3519 		auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sle, condition, x.value, y.value);
3520 		::basicBlock->appendInst(cmp);
3521 
3522 		Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3523 		auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3524 		::basicBlock->appendInst(select);
3525 
3526 		return RValue<Short4>(V(result));
3527 	}
3528 
Min(RValue<Short4> x,RValue<Short4> y)3529 	RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y)
3530 	{
3531 		Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3532 		auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sgt, condition, x.value, y.value);
3533 		::basicBlock->appendInst(cmp);
3534 
3535 		Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3536 		auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3537 		::basicBlock->appendInst(select);
3538 
3539 		return RValue<Short4>(V(result));
3540 	}
3541 
SaturateSigned(RValue<Int> x)3542 	RValue<Short> SaturateSigned(RValue<Int> x)
3543 	{
3544 		return Short(IfThenElse(x > 0x7FFF, Int(0x7FFF), IfThenElse(x < -0x8000, Int(0x8000), x)));
3545 	}
3546 
AddSat(RValue<Short4> x,RValue<Short4> y)3547 	RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y)
3548 	{
3549 		if(emulateIntrinsics)
3550 		{
3551 			Short4 result;
3552 			result = Insert(result, SaturateSigned(Int(Extract(x, 0)) + Int(Extract(y, 0))), 0);
3553 			result = Insert(result, SaturateSigned(Int(Extract(x, 1)) + Int(Extract(y, 1))), 1);
3554 			result = Insert(result, SaturateSigned(Int(Extract(x, 2)) + Int(Extract(y, 2))), 2);
3555 			result = Insert(result, SaturateSigned(Int(Extract(x, 3)) + Int(Extract(y, 3))), 3);
3556 
3557 			return result;
3558 		}
3559 		else
3560 		{
3561 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3562 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3563 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
3564 			auto paddsw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3565 			paddsw->addArg(x.value);
3566 			paddsw->addArg(y.value);
3567 			::basicBlock->appendInst(paddsw);
3568 
3569 			return RValue<Short4>(V(result));
3570 		}
3571 	}
3572 
SubSat(RValue<Short4> x,RValue<Short4> y)3573 	RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y)
3574 	{
3575 		if(emulateIntrinsics)
3576 		{
3577 			Short4 result;
3578 			result = Insert(result, SaturateSigned(Int(Extract(x, 0)) - Int(Extract(y, 0))), 0);
3579 			result = Insert(result, SaturateSigned(Int(Extract(x, 1)) - Int(Extract(y, 1))), 1);
3580 			result = Insert(result, SaturateSigned(Int(Extract(x, 2)) - Int(Extract(y, 2))), 2);
3581 			result = Insert(result, SaturateSigned(Int(Extract(x, 3)) - Int(Extract(y, 3))), 3);
3582 
3583 			return result;
3584 		}
3585 		else
3586 		{
3587 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3588 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3589 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
3590 			auto psubsw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3591 			psubsw->addArg(x.value);
3592 			psubsw->addArg(y.value);
3593 			::basicBlock->appendInst(psubsw);
3594 
3595 			return RValue<Short4>(V(result));
3596 		}
3597 	}
3598 
MulHigh(RValue<Short4> x,RValue<Short4> y)3599 	RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y)
3600 	{
3601 		if(emulateIntrinsics)
3602 		{
3603 			Short4 result;
3604 			result = Insert(result, Short((Int(Extract(x, 0)) * Int(Extract(y, 0))) >> 16), 0);
3605 			result = Insert(result, Short((Int(Extract(x, 1)) * Int(Extract(y, 1))) >> 16), 1);
3606 			result = Insert(result, Short((Int(Extract(x, 2)) * Int(Extract(y, 2))) >> 16), 2);
3607 			result = Insert(result, Short((Int(Extract(x, 3)) * Int(Extract(y, 3))) >> 16), 3);
3608 
3609 			return result;
3610 		}
3611 		else
3612 		{
3613 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3614 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::MultiplyHighSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3615 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
3616 			auto pmulhw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3617 			pmulhw->addArg(x.value);
3618 			pmulhw->addArg(y.value);
3619 			::basicBlock->appendInst(pmulhw);
3620 
3621 			return RValue<Short4>(V(result));
3622 		}
3623 	}
3624 
MulAdd(RValue<Short4> x,RValue<Short4> y)3625 	RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y)
3626 	{
3627 		if(emulateIntrinsics)
3628 		{
3629 			Int2 result;
3630 			result = Insert(result, Int(Extract(x, 0)) * Int(Extract(y, 0)) + Int(Extract(x, 1)) * Int(Extract(y, 1)), 0);
3631 			result = Insert(result, Int(Extract(x, 2)) * Int(Extract(y, 2)) + Int(Extract(x, 3)) * Int(Extract(y, 3)), 1);
3632 
3633 			return result;
3634 		}
3635 		else
3636 		{
3637 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3638 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::MultiplyAddPairs, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3639 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
3640 			auto pmaddwd = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3641 			pmaddwd->addArg(x.value);
3642 			pmaddwd->addArg(y.value);
3643 			::basicBlock->appendInst(pmaddwd);
3644 
3645 			return As<Int2>(V(result));
3646 		}
3647 	}
3648 
PackSigned(RValue<Short4> x,RValue<Short4> y)3649 	RValue<SByte8> PackSigned(RValue<Short4> x, RValue<Short4> y)
3650 	{
3651 		if(emulateIntrinsics)
3652 		{
3653 			SByte8 result;
3654 			result = Insert(result, SaturateSigned(Extract(x, 0)), 0);
3655 			result = Insert(result, SaturateSigned(Extract(x, 1)), 1);
3656 			result = Insert(result, SaturateSigned(Extract(x, 2)), 2);
3657 			result = Insert(result, SaturateSigned(Extract(x, 3)), 3);
3658 			result = Insert(result, SaturateSigned(Extract(y, 0)), 4);
3659 			result = Insert(result, SaturateSigned(Extract(y, 1)), 5);
3660 			result = Insert(result, SaturateSigned(Extract(y, 2)), 6);
3661 			result = Insert(result, SaturateSigned(Extract(y, 3)), 7);
3662 
3663 			return result;
3664 		}
3665 		else
3666 		{
3667 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
3668 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3669 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
3670 			auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3671 			pack->addArg(x.value);
3672 			pack->addArg(y.value);
3673 			::basicBlock->appendInst(pack);
3674 
3675 			return As<SByte8>(Swizzle(As<Int4>(V(result)), 0x88));
3676 		}
3677 	}
3678 
PackUnsigned(RValue<Short4> x,RValue<Short4> y)3679 	RValue<Byte8> PackUnsigned(RValue<Short4> x, RValue<Short4> y)
3680 	{
3681 		if(emulateIntrinsics)
3682 		{
3683 			Byte8 result;
3684 			result = Insert(result, SaturateUnsigned(Extract(x, 0)), 0);
3685 			result = Insert(result, SaturateUnsigned(Extract(x, 1)), 1);
3686 			result = Insert(result, SaturateUnsigned(Extract(x, 2)), 2);
3687 			result = Insert(result, SaturateUnsigned(Extract(x, 3)), 3);
3688 			result = Insert(result, SaturateUnsigned(Extract(y, 0)), 4);
3689 			result = Insert(result, SaturateUnsigned(Extract(y, 1)), 5);
3690 			result = Insert(result, SaturateUnsigned(Extract(y, 2)), 6);
3691 			result = Insert(result, SaturateUnsigned(Extract(y, 3)), 7);
3692 
3693 			return result;
3694 		}
3695 		else
3696 		{
3697 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
3698 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3699 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
3700 			auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3701 			pack->addArg(x.value);
3702 			pack->addArg(y.value);
3703 			::basicBlock->appendInst(pack);
3704 
3705 			return As<Byte8>(Swizzle(As<Int4>(V(result)), 0x88));
3706 		}
3707 	}
3708 
UnpackLow(RValue<Short4> x,RValue<Short4> y)3709 	RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y)
3710 	{
3711 		int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11};   // Real type is v8i16
3712 		return As<Int2>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
3713 	}
3714 
UnpackHigh(RValue<Short4> x,RValue<Short4> y)3715 	RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y)
3716 	{
3717 		int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11};   // Real type is v8i16
3718 		auto lowHigh = RValue<Short8>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
3719 		return As<Int2>(Swizzle(As<Int4>(lowHigh), 0xEE));
3720 	}
3721 
Swizzle(RValue<Short4> x,unsigned char select)3722 	RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select)
3723 	{
3724 		// Real type is v8i16
3725 		int shuffle[8] =
3726 		{
3727 			(select >> 0) & 0x03,
3728 			(select >> 2) & 0x03,
3729 			(select >> 4) & 0x03,
3730 			(select >> 6) & 0x03,
3731 			(select >> 0) & 0x03,
3732 			(select >> 2) & 0x03,
3733 			(select >> 4) & 0x03,
3734 			(select >> 6) & 0x03,
3735 		};
3736 
3737 		return RValue<Short4>(Nucleus::createShuffleVector(x.value, x.value, shuffle));
3738 	}
3739 
Insert(RValue<Short4> val,RValue<Short> element,int i)3740 	RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i)
3741 	{
3742 		return RValue<Short4>(Nucleus::createInsertElement(val.value, element.value, i));
3743 	}
3744 
Extract(RValue<Short4> val,int i)3745 	RValue<Short> Extract(RValue<Short4> val, int i)
3746 	{
3747 		return RValue<Short>(Nucleus::createExtractElement(val.value, Short::getType(), i));
3748 	}
3749 
CmpGT(RValue<Short4> x,RValue<Short4> y)3750 	RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y)
3751 	{
3752 		return RValue<Short4>(createIntCompare(Ice::InstIcmp::Sgt, x.value, y.value));
3753 	}
3754 
CmpEQ(RValue<Short4> x,RValue<Short4> y)3755 	RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y)
3756 	{
3757 		return RValue<Short4>(Nucleus::createICmpEQ(x.value, y.value));
3758 	}
3759 
getType()3760 	Type *Short4::getType()
3761 	{
3762 		return T(Type_v4i16);
3763 	}
3764 
UShort4(RValue<Int4> cast)3765 	UShort4::UShort4(RValue<Int4> cast)
3766 	{
3767 		*this = Short4(cast);
3768 	}
3769 
UShort4(RValue<Float4> cast,bool saturate)3770 	UShort4::UShort4(RValue<Float4> cast, bool saturate)
3771 	{
3772 		if(saturate)
3773 		{
3774 			if(CPUID::SSE4_1)
3775 			{
3776 				// x86 produces 0x80000000 on 32-bit integer overflow/underflow.
3777 				// PackUnsigned takes care of 0x0000 saturation.
3778 				Int4 int4(Min(cast, Float4(0xFFFF)));
3779 				*this = As<UShort4>(PackUnsigned(int4, int4));
3780 			}
3781 			else if(CPUID::ARM)
3782 			{
3783 				// ARM saturates the 32-bit integer result on overflow/undeflow.
3784 				Int4 int4(cast);
3785 				*this = As<UShort4>(PackUnsigned(int4, int4));
3786 			}
3787 			else
3788 			{
3789 				*this = Short4(Int4(Max(Min(cast, Float4(0xFFFF)), Float4(0x0000))));
3790 			}
3791 		}
3792 		else
3793 		{
3794 			*this = Short4(Int4(cast));
3795 		}
3796 	}
3797 
UShort4(unsigned short xyzw)3798 	UShort4::UShort4(unsigned short xyzw)
3799 	{
3800 		int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
3801 		storeValue(Nucleus::createConstantVector(constantVector, getType()));
3802 	}
3803 
UShort4(unsigned short x,unsigned short y,unsigned short z,unsigned short w)3804 	UShort4::UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w)
3805 	{
3806 		int64_t constantVector[4] = {x, y, z, w};
3807 		storeValue(Nucleus::createConstantVector(constantVector, getType()));
3808 	}
3809 
UShort4(RValue<UShort4> rhs)3810 	UShort4::UShort4(RValue<UShort4> rhs)
3811 	{
3812 		storeValue(rhs.value);
3813 	}
3814 
UShort4(const UShort4 & rhs)3815 	UShort4::UShort4(const UShort4 &rhs)
3816 	{
3817 		Value *value = rhs.loadValue();
3818 		storeValue(value);
3819 	}
3820 
UShort4(const Reference<UShort4> & rhs)3821 	UShort4::UShort4(const Reference<UShort4> &rhs)
3822 	{
3823 		Value *value = rhs.loadValue();
3824 		storeValue(value);
3825 	}
3826 
UShort4(RValue<Short4> rhs)3827 	UShort4::UShort4(RValue<Short4> rhs)
3828 	{
3829 		storeValue(rhs.value);
3830 	}
3831 
UShort4(const Short4 & rhs)3832 	UShort4::UShort4(const Short4 &rhs)
3833 	{
3834 		Value *value = rhs.loadValue();
3835 		storeValue(value);
3836 	}
3837 
UShort4(const Reference<Short4> & rhs)3838 	UShort4::UShort4(const Reference<Short4> &rhs)
3839 	{
3840 		Value *value = rhs.loadValue();
3841 		storeValue(value);
3842 	}
3843 
operator =(RValue<UShort4> rhs)3844 	RValue<UShort4> UShort4::operator=(RValue<UShort4> rhs)
3845 	{
3846 		storeValue(rhs.value);
3847 
3848 		return rhs;
3849 	}
3850 
operator =(const UShort4 & rhs)3851 	RValue<UShort4> UShort4::operator=(const UShort4 &rhs)
3852 	{
3853 		Value *value = rhs.loadValue();
3854 		storeValue(value);
3855 
3856 		return RValue<UShort4>(value);
3857 	}
3858 
operator =(const Reference<UShort4> & rhs)3859 	RValue<UShort4> UShort4::operator=(const Reference<UShort4> &rhs)
3860 	{
3861 		Value *value = rhs.loadValue();
3862 		storeValue(value);
3863 
3864 		return RValue<UShort4>(value);
3865 	}
3866 
operator =(RValue<Short4> rhs)3867 	RValue<UShort4> UShort4::operator=(RValue<Short4> rhs)
3868 	{
3869 		storeValue(rhs.value);
3870 
3871 		return RValue<UShort4>(rhs);
3872 	}
3873 
operator =(const Short4 & rhs)3874 	RValue<UShort4> UShort4::operator=(const Short4 &rhs)
3875 	{
3876 		Value *value = rhs.loadValue();
3877 		storeValue(value);
3878 
3879 		return RValue<UShort4>(value);
3880 	}
3881 
operator =(const Reference<Short4> & rhs)3882 	RValue<UShort4> UShort4::operator=(const Reference<Short4> &rhs)
3883 	{
3884 		Value *value = rhs.loadValue();
3885 		storeValue(value);
3886 
3887 		return RValue<UShort4>(value);
3888 	}
3889 
operator +(RValue<UShort4> lhs,RValue<UShort4> rhs)3890 	RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs)
3891 	{
3892 		return RValue<UShort4>(Nucleus::createAdd(lhs.value, rhs.value));
3893 	}
3894 
operator -(RValue<UShort4> lhs,RValue<UShort4> rhs)3895 	RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs)
3896 	{
3897 		return RValue<UShort4>(Nucleus::createSub(lhs.value, rhs.value));
3898 	}
3899 
operator *(RValue<UShort4> lhs,RValue<UShort4> rhs)3900 	RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs)
3901 	{
3902 		return RValue<UShort4>(Nucleus::createMul(lhs.value, rhs.value));
3903 	}
3904 
operator &(RValue<UShort4> lhs,RValue<UShort4> rhs)3905 	RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs)
3906 	{
3907 		return RValue<UShort4>(Nucleus::createAnd(lhs.value, rhs.value));
3908 	}
3909 
operator |(RValue<UShort4> lhs,RValue<UShort4> rhs)3910 	RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs)
3911 	{
3912 		return RValue<UShort4>(Nucleus::createOr(lhs.value, rhs.value));
3913 	}
3914 
operator ^(RValue<UShort4> lhs,RValue<UShort4> rhs)3915 	RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs)
3916 	{
3917 		return RValue<UShort4>(Nucleus::createXor(lhs.value, rhs.value));
3918 	}
3919 
Extract(RValue<UShort4> val,int i)3920 	RValue<UShort> Extract(RValue<UShort4> val, int i)
3921 	{
3922 		return RValue<UShort>(Nucleus::createExtractElement(val.value, UShort::getType(), i));
3923 	}
3924 
Insert(RValue<UShort4> val,RValue<UShort> element,int i)3925 	RValue<UShort4> Insert(RValue<UShort4> val, RValue<UShort> element, int i)
3926 	{
3927 		return RValue<UShort4>(Nucleus::createInsertElement(val.value, element.value, i));
3928 	}
3929 
operator <<(RValue<UShort4> lhs,unsigned char rhs)3930 	RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs)
3931 	{
3932 		if(emulateIntrinsics)
3933 		{
3934 			UShort4 result;
3935 			result = Insert(result, Extract(lhs, 0) << UShort(rhs), 0);
3936 			result = Insert(result, Extract(lhs, 1) << UShort(rhs), 1);
3937 			result = Insert(result, Extract(lhs, 2) << UShort(rhs), 2);
3938 			result = Insert(result, Extract(lhs, 3) << UShort(rhs), 3);
3939 
3940 			return result;
3941 		}
3942 		else
3943 		{
3944 			return RValue<UShort4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
3945 		}
3946 	}
3947 
operator >>(RValue<UShort4> lhs,unsigned char rhs)3948 	RValue<UShort4> operator>>(RValue<UShort4> lhs, unsigned char rhs)
3949 	{
3950 		if(emulateIntrinsics)
3951 		{
3952 			UShort4 result;
3953 			result = Insert(result, Extract(lhs, 0) >> UShort(rhs), 0);
3954 			result = Insert(result, Extract(lhs, 1) >> UShort(rhs), 1);
3955 			result = Insert(result, Extract(lhs, 2) >> UShort(rhs), 2);
3956 			result = Insert(result, Extract(lhs, 3) >> UShort(rhs), 3);
3957 
3958 			return result;
3959 		}
3960 		else
3961 		{
3962 			return RValue<UShort4>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
3963 		}
3964 	}
3965 
operator <<=(UShort4 & lhs,unsigned char rhs)3966 	RValue<UShort4> operator<<=(UShort4 &lhs, unsigned char rhs)
3967 	{
3968 		return lhs = lhs << rhs;
3969 	}
3970 
operator >>=(UShort4 & lhs,unsigned char rhs)3971 	RValue<UShort4> operator>>=(UShort4 &lhs, unsigned char rhs)
3972 	{
3973 		return lhs = lhs >> rhs;
3974 	}
3975 
operator ~(RValue<UShort4> val)3976 	RValue<UShort4> operator~(RValue<UShort4> val)
3977 	{
3978 		return RValue<UShort4>(Nucleus::createNot(val.value));
3979 	}
3980 
Max(RValue<UShort4> x,RValue<UShort4> y)3981 	RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y)
3982 	{
3983 		Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3984 		auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ule, condition, x.value, y.value);
3985 		::basicBlock->appendInst(cmp);
3986 
3987 		Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3988 		auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3989 		::basicBlock->appendInst(select);
3990 
3991 		return RValue<UShort4>(V(result));
3992 	}
3993 
Min(RValue<UShort4> x,RValue<UShort4> y)3994 	RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y)
3995 	{
3996 		Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3997 		auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ugt, condition, x.value, y.value);
3998 		::basicBlock->appendInst(cmp);
3999 
4000 		Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
4001 		auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
4002 		::basicBlock->appendInst(select);
4003 
4004 		return RValue<UShort4>(V(result));
4005 	}
4006 
SaturateUnsigned(RValue<Int> x)4007 	RValue<UShort> SaturateUnsigned(RValue<Int> x)
4008 	{
4009 		return UShort(IfThenElse(x > 0xFFFF, Int(0xFFFF), IfThenElse(x < 0, Int(0), x)));
4010 	}
4011 
AddSat(RValue<UShort4> x,RValue<UShort4> y)4012 	RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y)
4013 	{
4014 		if(emulateIntrinsics)
4015 		{
4016 			UShort4 result;
4017 			result = Insert(result, SaturateUnsigned(Int(Extract(x, 0)) + Int(Extract(y, 0))), 0);
4018 			result = Insert(result, SaturateUnsigned(Int(Extract(x, 1)) + Int(Extract(y, 1))), 1);
4019 			result = Insert(result, SaturateUnsigned(Int(Extract(x, 2)) + Int(Extract(y, 2))), 2);
4020 			result = Insert(result, SaturateUnsigned(Int(Extract(x, 3)) + Int(Extract(y, 3))), 3);
4021 
4022 			return result;
4023 		}
4024 		else
4025 		{
4026 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
4027 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
4028 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
4029 			auto paddusw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
4030 			paddusw->addArg(x.value);
4031 			paddusw->addArg(y.value);
4032 			::basicBlock->appendInst(paddusw);
4033 
4034 			return RValue<UShort4>(V(result));
4035 		}
4036 	}
4037 
SubSat(RValue<UShort4> x,RValue<UShort4> y)4038 	RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y)
4039 	{
4040 		if(emulateIntrinsics)
4041 		{
4042 			UShort4 result;
4043 			result = Insert(result, SaturateUnsigned(Int(Extract(x, 0)) - Int(Extract(y, 0))), 0);
4044 			result = Insert(result, SaturateUnsigned(Int(Extract(x, 1)) - Int(Extract(y, 1))), 1);
4045 			result = Insert(result, SaturateUnsigned(Int(Extract(x, 2)) - Int(Extract(y, 2))), 2);
4046 			result = Insert(result, SaturateUnsigned(Int(Extract(x, 3)) - Int(Extract(y, 3))), 3);
4047 
4048 			return result;
4049 		}
4050 		else
4051 		{
4052 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
4053 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
4054 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
4055 			auto psubusw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
4056 			psubusw->addArg(x.value);
4057 			psubusw->addArg(y.value);
4058 			::basicBlock->appendInst(psubusw);
4059 
4060 			return RValue<UShort4>(V(result));
4061 		}
4062 	}
4063 
MulHigh(RValue<UShort4> x,RValue<UShort4> y)4064 	RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y)
4065 	{
4066 		if(emulateIntrinsics)
4067 		{
4068 			UShort4 result;
4069 			result = Insert(result, UShort((UInt(Extract(x, 0)) * UInt(Extract(y, 0))) >> 16), 0);
4070 			result = Insert(result, UShort((UInt(Extract(x, 1)) * UInt(Extract(y, 1))) >> 16), 1);
4071 			result = Insert(result, UShort((UInt(Extract(x, 2)) * UInt(Extract(y, 2))) >> 16), 2);
4072 			result = Insert(result, UShort((UInt(Extract(x, 3)) * UInt(Extract(y, 3))) >> 16), 3);
4073 
4074 			return result;
4075 		}
4076 		else
4077 		{
4078 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
4079 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::MultiplyHighUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
4080 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
4081 			auto pmulhuw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
4082 			pmulhuw->addArg(x.value);
4083 			pmulhuw->addArg(y.value);
4084 			::basicBlock->appendInst(pmulhuw);
4085 
4086 			return RValue<UShort4>(V(result));
4087 		}
4088 	}
4089 
Average(RValue<UShort4> x,RValue<UShort4> y)4090 	RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y)
4091 	{
4092 		assert(false && "UNIMPLEMENTED"); return RValue<UShort4>(V(nullptr));
4093 	}
4094 
getType()4095 	Type *UShort4::getType()
4096 	{
4097 		return T(Type_v4i16);
4098 	}
4099 
Short8(short c)4100 	Short8::Short8(short c)
4101 	{
4102 		int64_t constantVector[8] = {c, c, c, c, c, c, c, c};
4103 		storeValue(Nucleus::createConstantVector(constantVector, getType()));
4104 	}
4105 
Short8(short c0,short c1,short c2,short c3,short c4,short c5,short c6,short c7)4106 	Short8::Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7)
4107 	{
4108 		int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
4109 		storeValue(Nucleus::createConstantVector(constantVector, getType()));
4110 	}
4111 
Short8(RValue<Short8> rhs)4112 	Short8::Short8(RValue<Short8> rhs)
4113 	{
4114 		storeValue(rhs.value);
4115 	}
4116 
Short8(const Reference<Short8> & rhs)4117 	Short8::Short8(const Reference<Short8> &rhs)
4118 	{
4119 		Value *value = rhs.loadValue();
4120 		storeValue(value);
4121 	}
4122 
Short8(RValue<Short4> lo,RValue<Short4> hi)4123 	Short8::Short8(RValue<Short4> lo, RValue<Short4> hi)
4124 	{
4125 		int shuffle[8] = {0, 1, 2, 3, 8, 9, 10, 11};   // Real type is v8i16
4126 		Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
4127 
4128 		storeValue(packed);
4129 	}
4130 
operator +(RValue<Short8> lhs,RValue<Short8> rhs)4131 	RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs)
4132 	{
4133 		return RValue<Short8>(Nucleus::createAdd(lhs.value, rhs.value));
4134 	}
4135 
operator &(RValue<Short8> lhs,RValue<Short8> rhs)4136 	RValue<Short8> operator&(RValue<Short8> lhs, RValue<Short8> rhs)
4137 	{
4138 		return RValue<Short8>(Nucleus::createAnd(lhs.value, rhs.value));
4139 	}
4140 
Extract(RValue<Short8> val,int i)4141 	RValue<Short> Extract(RValue<Short8> val, int i)
4142 	{
4143 		return RValue<Short>(Nucleus::createExtractElement(val.value, Short::getType(), i));
4144 	}
4145 
Insert(RValue<Short8> val,RValue<Short> element,int i)4146 	RValue<Short8> Insert(RValue<Short8> val, RValue<Short> element, int i)
4147 	{
4148 		return RValue<Short8>(Nucleus::createInsertElement(val.value, element.value, i));
4149 	}
4150 
operator <<(RValue<Short8> lhs,unsigned char rhs)4151 	RValue<Short8> operator<<(RValue<Short8> lhs, unsigned char rhs)
4152 	{
4153 		if(emulateIntrinsics)
4154 		{
4155 			Short8 result;
4156 			result = Insert(result, Extract(lhs, 0) << Short(rhs), 0);
4157 			result = Insert(result, Extract(lhs, 1) << Short(rhs), 1);
4158 			result = Insert(result, Extract(lhs, 2) << Short(rhs), 2);
4159 			result = Insert(result, Extract(lhs, 3) << Short(rhs), 3);
4160 			result = Insert(result, Extract(lhs, 4) << Short(rhs), 4);
4161 			result = Insert(result, Extract(lhs, 5) << Short(rhs), 5);
4162 			result = Insert(result, Extract(lhs, 6) << Short(rhs), 6);
4163 			result = Insert(result, Extract(lhs, 7) << Short(rhs), 7);
4164 
4165 			return result;
4166 		}
4167 		else
4168 		{
4169 			return RValue<Short8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
4170 		}
4171 	}
4172 
operator >>(RValue<Short8> lhs,unsigned char rhs)4173 	RValue<Short8> operator>>(RValue<Short8> lhs, unsigned char rhs)
4174 	{
4175 		if(emulateIntrinsics)
4176 		{
4177 			Short8 result;
4178 			result = Insert(result, Extract(lhs, 0) >> Short(rhs), 0);
4179 			result = Insert(result, Extract(lhs, 1) >> Short(rhs), 1);
4180 			result = Insert(result, Extract(lhs, 2) >> Short(rhs), 2);
4181 			result = Insert(result, Extract(lhs, 3) >> Short(rhs), 3);
4182 			result = Insert(result, Extract(lhs, 4) >> Short(rhs), 4);
4183 			result = Insert(result, Extract(lhs, 5) >> Short(rhs), 5);
4184 			result = Insert(result, Extract(lhs, 6) >> Short(rhs), 6);
4185 			result = Insert(result, Extract(lhs, 7) >> Short(rhs), 7);
4186 
4187 			return result;
4188 		}
4189 		else
4190 		{
4191 			return RValue<Short8>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
4192 		}
4193 	}
4194 
MulAdd(RValue<Short8> x,RValue<Short8> y)4195 	RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y)
4196 	{
4197 		assert(false && "UNIMPLEMENTED"); return RValue<Int4>(V(nullptr));
4198 	}
4199 
Abs(RValue<Int4> x)4200 	RValue<Int4> Abs(RValue<Int4> x)
4201 	{
4202 		auto negative = x >> 31;
4203 		return (x ^ negative) - negative;
4204 	}
4205 
MulHigh(RValue<Short8> x,RValue<Short8> y)4206 	RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y)
4207 	{
4208 		assert(false && "UNIMPLEMENTED"); return RValue<Short8>(V(nullptr));
4209 	}
4210 
getType()4211 	Type *Short8::getType()
4212 	{
4213 		return T(Ice::IceType_v8i16);
4214 	}
4215 
UShort8(unsigned short c)4216 	UShort8::UShort8(unsigned short c)
4217 	{
4218 		int64_t constantVector[8] = {c, c, c, c, c, c, c, c};
4219 		storeValue(Nucleus::createConstantVector(constantVector, getType()));
4220 	}
4221 
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)4222 	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)
4223 	{
4224 		int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
4225 		storeValue(Nucleus::createConstantVector(constantVector, getType()));
4226 	}
4227 
UShort8(RValue<UShort8> rhs)4228 	UShort8::UShort8(RValue<UShort8> rhs)
4229 	{
4230 		storeValue(rhs.value);
4231 	}
4232 
UShort8(const Reference<UShort8> & rhs)4233 	UShort8::UShort8(const Reference<UShort8> &rhs)
4234 	{
4235 		Value *value = rhs.loadValue();
4236 		storeValue(value);
4237 	}
4238 
UShort8(RValue<UShort4> lo,RValue<UShort4> hi)4239 	UShort8::UShort8(RValue<UShort4> lo, RValue<UShort4> hi)
4240 	{
4241 		int shuffle[8] = {0, 1, 2, 3, 8, 9, 10, 11};   // Real type is v8i16
4242 		Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
4243 
4244 		storeValue(packed);
4245 	}
4246 
operator =(RValue<UShort8> rhs)4247 	RValue<UShort8> UShort8::operator=(RValue<UShort8> rhs)
4248 	{
4249 		storeValue(rhs.value);
4250 
4251 		return rhs;
4252 	}
4253 
operator =(const UShort8 & rhs)4254 	RValue<UShort8> UShort8::operator=(const UShort8 &rhs)
4255 	{
4256 		Value *value = rhs.loadValue();
4257 		storeValue(value);
4258 
4259 		return RValue<UShort8>(value);
4260 	}
4261 
operator =(const Reference<UShort8> & rhs)4262 	RValue<UShort8> UShort8::operator=(const Reference<UShort8> &rhs)
4263 	{
4264 		Value *value = rhs.loadValue();
4265 		storeValue(value);
4266 
4267 		return RValue<UShort8>(value);
4268 	}
4269 
operator &(RValue<UShort8> lhs,RValue<UShort8> rhs)4270 	RValue<UShort8> operator&(RValue<UShort8> lhs, RValue<UShort8> rhs)
4271 	{
4272 		return RValue<UShort8>(Nucleus::createAnd(lhs.value, rhs.value));
4273 	}
4274 
Extract(RValue<UShort8> val,int i)4275 	RValue<UShort> Extract(RValue<UShort8> val, int i)
4276 	{
4277 		return RValue<UShort>(Nucleus::createExtractElement(val.value, UShort::getType(), i));
4278 	}
4279 
Insert(RValue<UShort8> val,RValue<UShort> element,int i)4280 	RValue<UShort8> Insert(RValue<UShort8> val, RValue<UShort> element, int i)
4281 	{
4282 		return RValue<UShort8>(Nucleus::createInsertElement(val.value, element.value, i));
4283 	}
4284 
operator <<(RValue<UShort8> lhs,unsigned char rhs)4285 	RValue<UShort8> operator<<(RValue<UShort8> lhs, unsigned char rhs)
4286 	{
4287 		if(emulateIntrinsics)
4288 		{
4289 			UShort8 result;
4290 			result = Insert(result, Extract(lhs, 0) << UShort(rhs), 0);
4291 			result = Insert(result, Extract(lhs, 1) << UShort(rhs), 1);
4292 			result = Insert(result, Extract(lhs, 2) << UShort(rhs), 2);
4293 			result = Insert(result, Extract(lhs, 3) << UShort(rhs), 3);
4294 			result = Insert(result, Extract(lhs, 4) << UShort(rhs), 4);
4295 			result = Insert(result, Extract(lhs, 5) << UShort(rhs), 5);
4296 			result = Insert(result, Extract(lhs, 6) << UShort(rhs), 6);
4297 			result = Insert(result, Extract(lhs, 7) << UShort(rhs), 7);
4298 
4299 			return result;
4300 		}
4301 		else
4302 		{
4303 			return RValue<UShort8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
4304 		}
4305 	}
4306 
operator >>(RValue<UShort8> lhs,unsigned char rhs)4307 	RValue<UShort8> operator>>(RValue<UShort8> lhs, unsigned char rhs)
4308 	{
4309 		if(emulateIntrinsics)
4310 		{
4311 			UShort8 result;
4312 			result = Insert(result, Extract(lhs, 0) >> UShort(rhs), 0);
4313 			result = Insert(result, Extract(lhs, 1) >> UShort(rhs), 1);
4314 			result = Insert(result, Extract(lhs, 2) >> UShort(rhs), 2);
4315 			result = Insert(result, Extract(lhs, 3) >> UShort(rhs), 3);
4316 			result = Insert(result, Extract(lhs, 4) >> UShort(rhs), 4);
4317 			result = Insert(result, Extract(lhs, 5) >> UShort(rhs), 5);
4318 			result = Insert(result, Extract(lhs, 6) >> UShort(rhs), 6);
4319 			result = Insert(result, Extract(lhs, 7) >> UShort(rhs), 7);
4320 
4321 			return result;
4322 		}
4323 		else
4324 		{
4325 			return RValue<UShort8>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
4326 		}
4327 	}
4328 
operator +(RValue<UShort8> lhs,RValue<UShort8> rhs)4329 	RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs)
4330 	{
4331 		return RValue<UShort8>(Nucleus::createAdd(lhs.value, rhs.value));
4332 	}
4333 
operator *(RValue<UShort8> lhs,RValue<UShort8> rhs)4334 	RValue<UShort8> operator*(RValue<UShort8> lhs, RValue<UShort8> rhs)
4335 	{
4336 		return RValue<UShort8>(Nucleus::createMul(lhs.value, rhs.value));
4337 	}
4338 
operator +=(UShort8 & lhs,RValue<UShort8> rhs)4339 	RValue<UShort8> operator+=(UShort8 &lhs, RValue<UShort8> rhs)
4340 	{
4341 		return lhs = lhs + rhs;
4342 	}
4343 
operator ~(RValue<UShort8> val)4344 	RValue<UShort8> operator~(RValue<UShort8> val)
4345 	{
4346 		return RValue<UShort8>(Nucleus::createNot(val.value));
4347 	}
4348 
Swizzle(RValue<UShort8> x,char select0,char select1,char select2,char select3,char select4,char select5,char select6,char select7)4349 	RValue<UShort8> Swizzle(RValue<UShort8> x, char select0, char select1, char select2, char select3, char select4, char select5, char select6, char select7)
4350 	{
4351 		assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
4352 	}
4353 
MulHigh(RValue<UShort8> x,RValue<UShort8> y)4354 	RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y)
4355 	{
4356 		assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
4357 	}
4358 
4359 	// FIXME: Implement as Shuffle(x, y, Select(i0, ..., i16)) and Shuffle(x, y, SELECT_PACK_REPEAT(element))
4360 //	RValue<UShort8> PackRepeat(RValue<Byte16> x, RValue<Byte16> y, int element)
4361 //	{
4362 //		assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
4363 //	}
4364 
getType()4365 	Type *UShort8::getType()
4366 	{
4367 		return T(Ice::IceType_v8i16);
4368 	}
4369 
Int(Argument<Int> argument)4370 	Int::Int(Argument<Int> argument)
4371 	{
4372 		storeValue(argument.value);
4373 	}
4374 
Int(RValue<Byte> cast)4375 	Int::Int(RValue<Byte> cast)
4376 	{
4377 		Value *integer = Nucleus::createZExt(cast.value, Int::getType());
4378 
4379 		storeValue(integer);
4380 	}
4381 
Int(RValue<SByte> cast)4382 	Int::Int(RValue<SByte> cast)
4383 	{
4384 		Value *integer = Nucleus::createSExt(cast.value, Int::getType());
4385 
4386 		storeValue(integer);
4387 	}
4388 
Int(RValue<Short> cast)4389 	Int::Int(RValue<Short> cast)
4390 	{
4391 		Value *integer = Nucleus::createSExt(cast.value, Int::getType());
4392 
4393 		storeValue(integer);
4394 	}
4395 
Int(RValue<UShort> cast)4396 	Int::Int(RValue<UShort> cast)
4397 	{
4398 		Value *integer = Nucleus::createZExt(cast.value, Int::getType());
4399 
4400 		storeValue(integer);
4401 	}
4402 
Int(RValue<Int2> cast)4403 	Int::Int(RValue<Int2> cast)
4404 	{
4405 		*this = Extract(cast, 0);
4406 	}
4407 
Int(RValue<Long> cast)4408 	Int::Int(RValue<Long> cast)
4409 	{
4410 		Value *integer = Nucleus::createTrunc(cast.value, Int::getType());
4411 
4412 		storeValue(integer);
4413 	}
4414 
Int(RValue<Float> cast)4415 	Int::Int(RValue<Float> cast)
4416 	{
4417 		Value *integer = Nucleus::createFPToSI(cast.value, Int::getType());
4418 
4419 		storeValue(integer);
4420 	}
4421 
Int(int x)4422 	Int::Int(int x)
4423 	{
4424 		storeValue(Nucleus::createConstantInt(x));
4425 	}
4426 
Int(RValue<Int> rhs)4427 	Int::Int(RValue<Int> rhs)
4428 	{
4429 		storeValue(rhs.value);
4430 	}
4431 
Int(RValue<UInt> rhs)4432 	Int::Int(RValue<UInt> rhs)
4433 	{
4434 		storeValue(rhs.value);
4435 	}
4436 
Int(const Int & rhs)4437 	Int::Int(const Int &rhs)
4438 	{
4439 		Value *value = rhs.loadValue();
4440 		storeValue(value);
4441 	}
4442 
Int(const Reference<Int> & rhs)4443 	Int::Int(const Reference<Int> &rhs)
4444 	{
4445 		Value *value = rhs.loadValue();
4446 		storeValue(value);
4447 	}
4448 
Int(const UInt & rhs)4449 	Int::Int(const UInt &rhs)
4450 	{
4451 		Value *value = rhs.loadValue();
4452 		storeValue(value);
4453 	}
4454 
Int(const Reference<UInt> & rhs)4455 	Int::Int(const Reference<UInt> &rhs)
4456 	{
4457 		Value *value = rhs.loadValue();
4458 		storeValue(value);
4459 	}
4460 
operator =(int rhs)4461 	RValue<Int> Int::operator=(int rhs)
4462 	{
4463 		return RValue<Int>(storeValue(Nucleus::createConstantInt(rhs)));
4464 	}
4465 
operator =(RValue<Int> rhs)4466 	RValue<Int> Int::operator=(RValue<Int> rhs)
4467 	{
4468 		storeValue(rhs.value);
4469 
4470 		return rhs;
4471 	}
4472 
operator =(RValue<UInt> rhs)4473 	RValue<Int> Int::operator=(RValue<UInt> rhs)
4474 	{
4475 		storeValue(rhs.value);
4476 
4477 		return RValue<Int>(rhs);
4478 	}
4479 
operator =(const Int & rhs)4480 	RValue<Int> Int::operator=(const Int &rhs)
4481 	{
4482 		Value *value = rhs.loadValue();
4483 		storeValue(value);
4484 
4485 		return RValue<Int>(value);
4486 	}
4487 
operator =(const Reference<Int> & rhs)4488 	RValue<Int> Int::operator=(const Reference<Int> &rhs)
4489 	{
4490 		Value *value = rhs.loadValue();
4491 		storeValue(value);
4492 
4493 		return RValue<Int>(value);
4494 	}
4495 
operator =(const UInt & rhs)4496 	RValue<Int> Int::operator=(const UInt &rhs)
4497 	{
4498 		Value *value = rhs.loadValue();
4499 		storeValue(value);
4500 
4501 		return RValue<Int>(value);
4502 	}
4503 
operator =(const Reference<UInt> & rhs)4504 	RValue<Int> Int::operator=(const Reference<UInt> &rhs)
4505 	{
4506 		Value *value = rhs.loadValue();
4507 		storeValue(value);
4508 
4509 		return RValue<Int>(value);
4510 	}
4511 
operator +(RValue<Int> lhs,RValue<Int> rhs)4512 	RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs)
4513 	{
4514 		return RValue<Int>(Nucleus::createAdd(lhs.value, rhs.value));
4515 	}
4516 
operator -(RValue<Int> lhs,RValue<Int> rhs)4517 	RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs)
4518 	{
4519 		return RValue<Int>(Nucleus::createSub(lhs.value, rhs.value));
4520 	}
4521 
operator *(RValue<Int> lhs,RValue<Int> rhs)4522 	RValue<Int> operator*(RValue<Int> lhs, RValue<Int> rhs)
4523 	{
4524 		return RValue<Int>(Nucleus::createMul(lhs.value, rhs.value));
4525 	}
4526 
operator /(RValue<Int> lhs,RValue<Int> rhs)4527 	RValue<Int> operator/(RValue<Int> lhs, RValue<Int> rhs)
4528 	{
4529 		return RValue<Int>(Nucleus::createSDiv(lhs.value, rhs.value));
4530 	}
4531 
operator %(RValue<Int> lhs,RValue<Int> rhs)4532 	RValue<Int> operator%(RValue<Int> lhs, RValue<Int> rhs)
4533 	{
4534 		return RValue<Int>(Nucleus::createSRem(lhs.value, rhs.value));
4535 	}
4536 
operator &(RValue<Int> lhs,RValue<Int> rhs)4537 	RValue<Int> operator&(RValue<Int> lhs, RValue<Int> rhs)
4538 	{
4539 		return RValue<Int>(Nucleus::createAnd(lhs.value, rhs.value));
4540 	}
4541 
operator |(RValue<Int> lhs,RValue<Int> rhs)4542 	RValue<Int> operator|(RValue<Int> lhs, RValue<Int> rhs)
4543 	{
4544 		return RValue<Int>(Nucleus::createOr(lhs.value, rhs.value));
4545 	}
4546 
operator ^(RValue<Int> lhs,RValue<Int> rhs)4547 	RValue<Int> operator^(RValue<Int> lhs, RValue<Int> rhs)
4548 	{
4549 		return RValue<Int>(Nucleus::createXor(lhs.value, rhs.value));
4550 	}
4551 
operator <<(RValue<Int> lhs,RValue<Int> rhs)4552 	RValue<Int> operator<<(RValue<Int> lhs, RValue<Int> rhs)
4553 	{
4554 		return RValue<Int>(Nucleus::createShl(lhs.value, rhs.value));
4555 	}
4556 
operator >>(RValue<Int> lhs,RValue<Int> rhs)4557 	RValue<Int> operator>>(RValue<Int> lhs, RValue<Int> rhs)
4558 	{
4559 		return RValue<Int>(Nucleus::createAShr(lhs.value, rhs.value));
4560 	}
4561 
operator +=(Int & lhs,RValue<Int> rhs)4562 	RValue<Int> operator+=(Int &lhs, RValue<Int> rhs)
4563 	{
4564 		return lhs = lhs + rhs;
4565 	}
4566 
operator -=(Int & lhs,RValue<Int> rhs)4567 	RValue<Int> operator-=(Int &lhs, RValue<Int> rhs)
4568 	{
4569 		return lhs = lhs - rhs;
4570 	}
4571 
operator *=(Int & lhs,RValue<Int> rhs)4572 	RValue<Int> operator*=(Int &lhs, RValue<Int> rhs)
4573 	{
4574 		return lhs = lhs * rhs;
4575 	}
4576 
operator /=(Int & lhs,RValue<Int> rhs)4577 	RValue<Int> operator/=(Int &lhs, RValue<Int> rhs)
4578 	{
4579 		return lhs = lhs / rhs;
4580 	}
4581 
operator %=(Int & lhs,RValue<Int> rhs)4582 	RValue<Int> operator%=(Int &lhs, RValue<Int> rhs)
4583 	{
4584 		return lhs = lhs % rhs;
4585 	}
4586 
operator &=(Int & lhs,RValue<Int> rhs)4587 	RValue<Int> operator&=(Int &lhs, RValue<Int> rhs)
4588 	{
4589 		return lhs = lhs & rhs;
4590 	}
4591 
operator |=(Int & lhs,RValue<Int> rhs)4592 	RValue<Int> operator|=(Int &lhs, RValue<Int> rhs)
4593 	{
4594 		return lhs = lhs | rhs;
4595 	}
4596 
operator ^=(Int & lhs,RValue<Int> rhs)4597 	RValue<Int> operator^=(Int &lhs, RValue<Int> rhs)
4598 	{
4599 		return lhs = lhs ^ rhs;
4600 	}
4601 
operator <<=(Int & lhs,RValue<Int> rhs)4602 	RValue<Int> operator<<=(Int &lhs, RValue<Int> rhs)
4603 	{
4604 		return lhs = lhs << rhs;
4605 	}
4606 
operator >>=(Int & lhs,RValue<Int> rhs)4607 	RValue<Int> operator>>=(Int &lhs, RValue<Int> rhs)
4608 	{
4609 		return lhs = lhs >> rhs;
4610 	}
4611 
operator +(RValue<Int> val)4612 	RValue<Int> operator+(RValue<Int> val)
4613 	{
4614 		return val;
4615 	}
4616 
operator -(RValue<Int> val)4617 	RValue<Int> operator-(RValue<Int> val)
4618 	{
4619 		return RValue<Int>(Nucleus::createNeg(val.value));
4620 	}
4621 
operator ~(RValue<Int> val)4622 	RValue<Int> operator~(RValue<Int> val)
4623 	{
4624 		return RValue<Int>(Nucleus::createNot(val.value));
4625 	}
4626 
operator ++(Int & val,int)4627 	RValue<Int> operator++(Int &val, int)   // Post-increment
4628 	{
4629 		RValue<Int> res = val;
4630 		val += 1;
4631 		return res;
4632 	}
4633 
operator ++(Int & val)4634 	const Int &operator++(Int &val)   // Pre-increment
4635 	{
4636 		val += 1;
4637 		return val;
4638 	}
4639 
operator --(Int & val,int)4640 	RValue<Int> operator--(Int &val, int)   // Post-decrement
4641 	{
4642 		RValue<Int> res = val;
4643 		val -= 1;
4644 		return res;
4645 	}
4646 
operator --(Int & val)4647 	const Int &operator--(Int &val)   // Pre-decrement
4648 	{
4649 		val -= 1;
4650 		return val;
4651 	}
4652 
operator <(RValue<Int> lhs,RValue<Int> rhs)4653 	RValue<Bool> operator<(RValue<Int> lhs, RValue<Int> rhs)
4654 	{
4655 		return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
4656 	}
4657 
operator <=(RValue<Int> lhs,RValue<Int> rhs)4658 	RValue<Bool> operator<=(RValue<Int> lhs, RValue<Int> rhs)
4659 	{
4660 		return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
4661 	}
4662 
operator >(RValue<Int> lhs,RValue<Int> rhs)4663 	RValue<Bool> operator>(RValue<Int> lhs, RValue<Int> rhs)
4664 	{
4665 		return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
4666 	}
4667 
operator >=(RValue<Int> lhs,RValue<Int> rhs)4668 	RValue<Bool> operator>=(RValue<Int> lhs, RValue<Int> rhs)
4669 	{
4670 		return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
4671 	}
4672 
operator !=(RValue<Int> lhs,RValue<Int> rhs)4673 	RValue<Bool> operator!=(RValue<Int> lhs, RValue<Int> rhs)
4674 	{
4675 		return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
4676 	}
4677 
operator ==(RValue<Int> lhs,RValue<Int> rhs)4678 	RValue<Bool> operator==(RValue<Int> lhs, RValue<Int> rhs)
4679 	{
4680 		return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
4681 	}
4682 
Max(RValue<Int> x,RValue<Int> y)4683 	RValue<Int> Max(RValue<Int> x, RValue<Int> y)
4684 	{
4685 		return IfThenElse(x > y, x, y);
4686 	}
4687 
Min(RValue<Int> x,RValue<Int> y)4688 	RValue<Int> Min(RValue<Int> x, RValue<Int> y)
4689 	{
4690 		return IfThenElse(x < y, x, y);
4691 	}
4692 
Clamp(RValue<Int> x,RValue<Int> min,RValue<Int> max)4693 	RValue<Int> Clamp(RValue<Int> x, RValue<Int> min, RValue<Int> max)
4694 	{
4695 		return Min(Max(x, min), max);
4696 	}
4697 
RoundInt(RValue<Float> cast)4698 	RValue<Int> RoundInt(RValue<Float> cast)
4699 	{
4700 		if(emulateIntrinsics || CPUID::ARM)
4701 		{
4702 			// Push the fractional part off the mantissa. Accurate up to +/-2^22.
4703 			return Int((cast + Float(0x00C00000)) - Float(0x00C00000));
4704 		}
4705 		else
4706 		{
4707 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
4708 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Nearbyint, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
4709 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
4710 			auto nearbyint = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
4711 			nearbyint->addArg(cast.value);
4712 			::basicBlock->appendInst(nearbyint);
4713 
4714 			return RValue<Int>(V(result));
4715 		}
4716 	}
4717 
getType()4718 	Type *Int::getType()
4719 	{
4720 		return T(Ice::IceType_i32);
4721 	}
4722 
Long(RValue<Int> cast)4723 	Long::Long(RValue<Int> cast)
4724 	{
4725 		Value *integer = Nucleus::createSExt(cast.value, Long::getType());
4726 
4727 		storeValue(integer);
4728 	}
4729 
Long(RValue<UInt> cast)4730 	Long::Long(RValue<UInt> cast)
4731 	{
4732 		Value *integer = Nucleus::createZExt(cast.value, Long::getType());
4733 
4734 		storeValue(integer);
4735 	}
4736 
Long(RValue<Long> rhs)4737 	Long::Long(RValue<Long> rhs)
4738 	{
4739 		storeValue(rhs.value);
4740 	}
4741 
operator =(int64_t rhs)4742 	RValue<Long> Long::operator=(int64_t rhs)
4743 	{
4744 		return RValue<Long>(storeValue(Nucleus::createConstantLong(rhs)));
4745 	}
4746 
operator =(RValue<Long> rhs)4747 	RValue<Long> Long::operator=(RValue<Long> rhs)
4748 	{
4749 		storeValue(rhs.value);
4750 
4751 		return rhs;
4752 	}
4753 
operator =(const Long & rhs)4754 	RValue<Long> Long::operator=(const Long &rhs)
4755 	{
4756 		Value *value = rhs.loadValue();
4757 		storeValue(value);
4758 
4759 		return RValue<Long>(value);
4760 	}
4761 
operator =(const Reference<Long> & rhs)4762 	RValue<Long> Long::operator=(const Reference<Long> &rhs)
4763 	{
4764 		Value *value = rhs.loadValue();
4765 		storeValue(value);
4766 
4767 		return RValue<Long>(value);
4768 	}
4769 
operator +(RValue<Long> lhs,RValue<Long> rhs)4770 	RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs)
4771 	{
4772 		return RValue<Long>(Nucleus::createAdd(lhs.value, rhs.value));
4773 	}
4774 
operator -(RValue<Long> lhs,RValue<Long> rhs)4775 	RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs)
4776 	{
4777 		return RValue<Long>(Nucleus::createSub(lhs.value, rhs.value));
4778 	}
4779 
operator +=(Long & lhs,RValue<Long> rhs)4780 	RValue<Long> operator+=(Long &lhs, RValue<Long> rhs)
4781 	{
4782 		return lhs = lhs + rhs;
4783 	}
4784 
operator -=(Long & lhs,RValue<Long> rhs)4785 	RValue<Long> operator-=(Long &lhs, RValue<Long> rhs)
4786 	{
4787 		return lhs = lhs - rhs;
4788 	}
4789 
AddAtomic(RValue<Pointer<Long>> x,RValue<Long> y)4790 	RValue<Long> AddAtomic(RValue<Pointer<Long> > x, RValue<Long> y)
4791 	{
4792 		return RValue<Long>(Nucleus::createAtomicAdd(x.value, y.value));
4793 	}
4794 
getType()4795 	Type *Long::getType()
4796 	{
4797 		return T(Ice::IceType_i64);
4798 	}
4799 
UInt(Argument<UInt> argument)4800 	UInt::UInt(Argument<UInt> argument)
4801 	{
4802 		storeValue(argument.value);
4803 	}
4804 
UInt(RValue<UShort> cast)4805 	UInt::UInt(RValue<UShort> cast)
4806 	{
4807 		Value *integer = Nucleus::createZExt(cast.value, UInt::getType());
4808 
4809 		storeValue(integer);
4810 	}
4811 
UInt(RValue<Long> cast)4812 	UInt::UInt(RValue<Long> cast)
4813 	{
4814 		Value *integer = Nucleus::createTrunc(cast.value, UInt::getType());
4815 
4816 		storeValue(integer);
4817 	}
4818 
UInt(RValue<Float> cast)4819 	UInt::UInt(RValue<Float> cast)
4820 	{
4821 		// Smallest positive value representable in UInt, but not in Int
4822 		const unsigned int ustart = 0x80000000u;
4823 		const float ustartf = float(ustart);
4824 
4825 		// If the value is negative, store 0, otherwise store the result of the conversion
4826 		storeValue((~(As<Int>(cast) >> 31) &
4827 		// Check if the value can be represented as an Int
4828 			IfThenElse(cast >= ustartf,
4829 		// If the value is too large, subtract ustart and re-add it after conversion.
4830 				As<Int>(As<UInt>(Int(cast - Float(ustartf))) + UInt(ustart)),
4831 		// Otherwise, just convert normally
4832 				Int(cast))).value);
4833 	}
4834 
UInt(int x)4835 	UInt::UInt(int x)
4836 	{
4837 		storeValue(Nucleus::createConstantInt(x));
4838 	}
4839 
UInt(unsigned int x)4840 	UInt::UInt(unsigned int x)
4841 	{
4842 		storeValue(Nucleus::createConstantInt(x));
4843 	}
4844 
UInt(RValue<UInt> rhs)4845 	UInt::UInt(RValue<UInt> rhs)
4846 	{
4847 		storeValue(rhs.value);
4848 	}
4849 
UInt(RValue<Int> rhs)4850 	UInt::UInt(RValue<Int> rhs)
4851 	{
4852 		storeValue(rhs.value);
4853 	}
4854 
UInt(const UInt & rhs)4855 	UInt::UInt(const UInt &rhs)
4856 	{
4857 		Value *value = rhs.loadValue();
4858 		storeValue(value);
4859 	}
4860 
UInt(const Reference<UInt> & rhs)4861 	UInt::UInt(const Reference<UInt> &rhs)
4862 	{
4863 		Value *value = rhs.loadValue();
4864 		storeValue(value);
4865 	}
4866 
UInt(const Int & rhs)4867 	UInt::UInt(const Int &rhs)
4868 	{
4869 		Value *value = rhs.loadValue();
4870 		storeValue(value);
4871 	}
4872 
UInt(const Reference<Int> & rhs)4873 	UInt::UInt(const Reference<Int> &rhs)
4874 	{
4875 		Value *value = rhs.loadValue();
4876 		storeValue(value);
4877 	}
4878 
operator =(unsigned int rhs)4879 	RValue<UInt> UInt::operator=(unsigned int rhs)
4880 	{
4881 		return RValue<UInt>(storeValue(Nucleus::createConstantInt(rhs)));
4882 	}
4883 
operator =(RValue<UInt> rhs)4884 	RValue<UInt> UInt::operator=(RValue<UInt> rhs)
4885 	{
4886 		storeValue(rhs.value);
4887 
4888 		return rhs;
4889 	}
4890 
operator =(RValue<Int> rhs)4891 	RValue<UInt> UInt::operator=(RValue<Int> rhs)
4892 	{
4893 		storeValue(rhs.value);
4894 
4895 		return RValue<UInt>(rhs);
4896 	}
4897 
operator =(const UInt & rhs)4898 	RValue<UInt> UInt::operator=(const UInt &rhs)
4899 	{
4900 		Value *value = rhs.loadValue();
4901 		storeValue(value);
4902 
4903 		return RValue<UInt>(value);
4904 	}
4905 
operator =(const Reference<UInt> & rhs)4906 	RValue<UInt> UInt::operator=(const Reference<UInt> &rhs)
4907 	{
4908 		Value *value = rhs.loadValue();
4909 		storeValue(value);
4910 
4911 		return RValue<UInt>(value);
4912 	}
4913 
operator =(const Int & rhs)4914 	RValue<UInt> UInt::operator=(const Int &rhs)
4915 	{
4916 		Value *value = rhs.loadValue();
4917 		storeValue(value);
4918 
4919 		return RValue<UInt>(value);
4920 	}
4921 
operator =(const Reference<Int> & rhs)4922 	RValue<UInt> UInt::operator=(const Reference<Int> &rhs)
4923 	{
4924 		Value *value = rhs.loadValue();
4925 		storeValue(value);
4926 
4927 		return RValue<UInt>(value);
4928 	}
4929 
operator +(RValue<UInt> lhs,RValue<UInt> rhs)4930 	RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs)
4931 	{
4932 		return RValue<UInt>(Nucleus::createAdd(lhs.value, rhs.value));
4933 	}
4934 
operator -(RValue<UInt> lhs,RValue<UInt> rhs)4935 	RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs)
4936 	{
4937 		return RValue<UInt>(Nucleus::createSub(lhs.value, rhs.value));
4938 	}
4939 
operator *(RValue<UInt> lhs,RValue<UInt> rhs)4940 	RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs)
4941 	{
4942 		return RValue<UInt>(Nucleus::createMul(lhs.value, rhs.value));
4943 	}
4944 
operator /(RValue<UInt> lhs,RValue<UInt> rhs)4945 	RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs)
4946 	{
4947 		return RValue<UInt>(Nucleus::createUDiv(lhs.value, rhs.value));
4948 	}
4949 
operator %(RValue<UInt> lhs,RValue<UInt> rhs)4950 	RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs)
4951 	{
4952 		return RValue<UInt>(Nucleus::createURem(lhs.value, rhs.value));
4953 	}
4954 
operator &(RValue<UInt> lhs,RValue<UInt> rhs)4955 	RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs)
4956 	{
4957 		return RValue<UInt>(Nucleus::createAnd(lhs.value, rhs.value));
4958 	}
4959 
operator |(RValue<UInt> lhs,RValue<UInt> rhs)4960 	RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs)
4961 	{
4962 		return RValue<UInt>(Nucleus::createOr(lhs.value, rhs.value));
4963 	}
4964 
operator ^(RValue<UInt> lhs,RValue<UInt> rhs)4965 	RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs)
4966 	{
4967 		return RValue<UInt>(Nucleus::createXor(lhs.value, rhs.value));
4968 	}
4969 
operator <<(RValue<UInt> lhs,RValue<UInt> rhs)4970 	RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs)
4971 	{
4972 		return RValue<UInt>(Nucleus::createShl(lhs.value, rhs.value));
4973 	}
4974 
operator >>(RValue<UInt> lhs,RValue<UInt> rhs)4975 	RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs)
4976 	{
4977 		return RValue<UInt>(Nucleus::createLShr(lhs.value, rhs.value));
4978 	}
4979 
operator +=(UInt & lhs,RValue<UInt> rhs)4980 	RValue<UInt> operator+=(UInt &lhs, RValue<UInt> rhs)
4981 	{
4982 		return lhs = lhs + rhs;
4983 	}
4984 
operator -=(UInt & lhs,RValue<UInt> rhs)4985 	RValue<UInt> operator-=(UInt &lhs, RValue<UInt> rhs)
4986 	{
4987 		return lhs = lhs - rhs;
4988 	}
4989 
operator *=(UInt & lhs,RValue<UInt> rhs)4990 	RValue<UInt> operator*=(UInt &lhs, RValue<UInt> rhs)
4991 	{
4992 		return lhs = lhs * rhs;
4993 	}
4994 
operator /=(UInt & lhs,RValue<UInt> rhs)4995 	RValue<UInt> operator/=(UInt &lhs, RValue<UInt> rhs)
4996 	{
4997 		return lhs = lhs / rhs;
4998 	}
4999 
operator %=(UInt & lhs,RValue<UInt> rhs)5000 	RValue<UInt> operator%=(UInt &lhs, RValue<UInt> rhs)
5001 	{
5002 		return lhs = lhs % rhs;
5003 	}
5004 
operator &=(UInt & lhs,RValue<UInt> rhs)5005 	RValue<UInt> operator&=(UInt &lhs, RValue<UInt> rhs)
5006 	{
5007 		return lhs = lhs & rhs;
5008 	}
5009 
operator |=(UInt & lhs,RValue<UInt> rhs)5010 	RValue<UInt> operator|=(UInt &lhs, RValue<UInt> rhs)
5011 	{
5012 		return lhs = lhs | rhs;
5013 	}
5014 
operator ^=(UInt & lhs,RValue<UInt> rhs)5015 	RValue<UInt> operator^=(UInt &lhs, RValue<UInt> rhs)
5016 	{
5017 		return lhs = lhs ^ rhs;
5018 	}
5019 
operator <<=(UInt & lhs,RValue<UInt> rhs)5020 	RValue<UInt> operator<<=(UInt &lhs, RValue<UInt> rhs)
5021 	{
5022 		return lhs = lhs << rhs;
5023 	}
5024 
operator >>=(UInt & lhs,RValue<UInt> rhs)5025 	RValue<UInt> operator>>=(UInt &lhs, RValue<UInt> rhs)
5026 	{
5027 		return lhs = lhs >> rhs;
5028 	}
5029 
operator +(RValue<UInt> val)5030 	RValue<UInt> operator+(RValue<UInt> val)
5031 	{
5032 		return val;
5033 	}
5034 
operator -(RValue<UInt> val)5035 	RValue<UInt> operator-(RValue<UInt> val)
5036 	{
5037 		return RValue<UInt>(Nucleus::createNeg(val.value));
5038 	}
5039 
operator ~(RValue<UInt> val)5040 	RValue<UInt> operator~(RValue<UInt> val)
5041 	{
5042 		return RValue<UInt>(Nucleus::createNot(val.value));
5043 	}
5044 
operator ++(UInt & val,int)5045 	RValue<UInt> operator++(UInt &val, int)   // Post-increment
5046 	{
5047 		RValue<UInt> res = val;
5048 		val += 1;
5049 		return res;
5050 	}
5051 
operator ++(UInt & val)5052 	const UInt &operator++(UInt &val)   // Pre-increment
5053 	{
5054 		val += 1;
5055 		return val;
5056 	}
5057 
operator --(UInt & val,int)5058 	RValue<UInt> operator--(UInt &val, int)   // Post-decrement
5059 	{
5060 		RValue<UInt> res = val;
5061 		val -= 1;
5062 		return res;
5063 	}
5064 
operator --(UInt & val)5065 	const UInt &operator--(UInt &val)   // Pre-decrement
5066 	{
5067 		val -= 1;
5068 		return val;
5069 	}
5070 
Max(RValue<UInt> x,RValue<UInt> y)5071 	RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y)
5072 	{
5073 		return IfThenElse(x > y, x, y);
5074 	}
5075 
Min(RValue<UInt> x,RValue<UInt> y)5076 	RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y)
5077 	{
5078 		return IfThenElse(x < y, x, y);
5079 	}
5080 
Clamp(RValue<UInt> x,RValue<UInt> min,RValue<UInt> max)5081 	RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max)
5082 	{
5083 		return Min(Max(x, min), max);
5084 	}
5085 
operator <(RValue<UInt> lhs,RValue<UInt> rhs)5086 	RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs)
5087 	{
5088 		return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
5089 	}
5090 
operator <=(RValue<UInt> lhs,RValue<UInt> rhs)5091 	RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs)
5092 	{
5093 		return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
5094 	}
5095 
operator >(RValue<UInt> lhs,RValue<UInt> rhs)5096 	RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs)
5097 	{
5098 		return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
5099 	}
5100 
operator >=(RValue<UInt> lhs,RValue<UInt> rhs)5101 	RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs)
5102 	{
5103 		return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
5104 	}
5105 
operator !=(RValue<UInt> lhs,RValue<UInt> rhs)5106 	RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs)
5107 	{
5108 		return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
5109 	}
5110 
operator ==(RValue<UInt> lhs,RValue<UInt> rhs)5111 	RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs)
5112 	{
5113 		return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
5114 	}
5115 
5116 //	RValue<UInt> RoundUInt(RValue<Float> cast)
5117 //	{
5118 //		assert(false && "UNIMPLEMENTED"); return RValue<UInt>(V(nullptr));
5119 //	}
5120 
getType()5121 	Type *UInt::getType()
5122 	{
5123 		return T(Ice::IceType_i32);
5124 	}
5125 
5126 //	Int2::Int2(RValue<Int> cast)
5127 //	{
5128 //		Value *extend = Nucleus::createZExt(cast.value, Long::getType());
5129 //		Value *vector = Nucleus::createBitCast(extend, Int2::getType());
5130 //
5131 //		Constant *shuffle[2];
5132 //		shuffle[0] = Nucleus::createConstantInt(0);
5133 //		shuffle[1] = Nucleus::createConstantInt(0);
5134 //
5135 //		Value *replicate = Nucleus::createShuffleVector(vector, UndefValue::get(Int2::getType()), Nucleus::createConstantVector(shuffle, 2));
5136 //
5137 //		storeValue(replicate);
5138 //	}
5139 
Int2(RValue<Int4> cast)5140 	Int2::Int2(RValue<Int4> cast)
5141 	{
5142 		storeValue(Nucleus::createBitCast(cast.value, getType()));
5143 	}
5144 
Int2(int x,int y)5145 	Int2::Int2(int x, int y)
5146 	{
5147 		int64_t constantVector[2] = {x, y};
5148 		storeValue(Nucleus::createConstantVector(constantVector, getType()));
5149 	}
5150 
Int2(RValue<Int2> rhs)5151 	Int2::Int2(RValue<Int2> rhs)
5152 	{
5153 		storeValue(rhs.value);
5154 	}
5155 
Int2(const Int2 & rhs)5156 	Int2::Int2(const Int2 &rhs)
5157 	{
5158 		Value *value = rhs.loadValue();
5159 		storeValue(value);
5160 	}
5161 
Int2(const Reference<Int2> & rhs)5162 	Int2::Int2(const Reference<Int2> &rhs)
5163 	{
5164 		Value *value = rhs.loadValue();
5165 		storeValue(value);
5166 	}
5167 
Int2(RValue<Int> lo,RValue<Int> hi)5168 	Int2::Int2(RValue<Int> lo, RValue<Int> hi)
5169 	{
5170 		int shuffle[4] = {0, 4, 1, 5};
5171 		Value *packed = Nucleus::createShuffleVector(Int4(lo).loadValue(), Int4(hi).loadValue(), shuffle);
5172 
5173 		storeValue(Nucleus::createBitCast(packed, Int2::getType()));
5174 	}
5175 
operator =(RValue<Int2> rhs)5176 	RValue<Int2> Int2::operator=(RValue<Int2> rhs)
5177 	{
5178 		storeValue(rhs.value);
5179 
5180 		return rhs;
5181 	}
5182 
operator =(const Int2 & rhs)5183 	RValue<Int2> Int2::operator=(const Int2 &rhs)
5184 	{
5185 		Value *value = rhs.loadValue();
5186 		storeValue(value);
5187 
5188 		return RValue<Int2>(value);
5189 	}
5190 
operator =(const Reference<Int2> & rhs)5191 	RValue<Int2> Int2::operator=(const Reference<Int2> &rhs)
5192 	{
5193 		Value *value = rhs.loadValue();
5194 		storeValue(value);
5195 
5196 		return RValue<Int2>(value);
5197 	}
5198 
operator +(RValue<Int2> lhs,RValue<Int2> rhs)5199 	RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs)
5200 	{
5201 		return RValue<Int2>(Nucleus::createAdd(lhs.value, rhs.value));
5202 	}
5203 
operator -(RValue<Int2> lhs,RValue<Int2> rhs)5204 	RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs)
5205 	{
5206 		return RValue<Int2>(Nucleus::createSub(lhs.value, rhs.value));
5207 	}
5208 
5209 //	RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs)
5210 //	{
5211 //		return RValue<Int2>(Nucleus::createMul(lhs.value, rhs.value));
5212 //	}
5213 
5214 //	RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs)
5215 //	{
5216 //		return RValue<Int2>(Nucleus::createSDiv(lhs.value, rhs.value));
5217 //	}
5218 
5219 //	RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs)
5220 //	{
5221 //		return RValue<Int2>(Nucleus::createSRem(lhs.value, rhs.value));
5222 //	}
5223 
operator &(RValue<Int2> lhs,RValue<Int2> rhs)5224 	RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs)
5225 	{
5226 		return RValue<Int2>(Nucleus::createAnd(lhs.value, rhs.value));
5227 	}
5228 
operator |(RValue<Int2> lhs,RValue<Int2> rhs)5229 	RValue<Int2> operator|(RValue<Int2> lhs, RValue<Int2> rhs)
5230 	{
5231 		return RValue<Int2>(Nucleus::createOr(lhs.value, rhs.value));
5232 	}
5233 
operator ^(RValue<Int2> lhs,RValue<Int2> rhs)5234 	RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs)
5235 	{
5236 		return RValue<Int2>(Nucleus::createXor(lhs.value, rhs.value));
5237 	}
5238 
operator <<(RValue<Int2> lhs,unsigned char rhs)5239 	RValue<Int2> operator<<(RValue<Int2> lhs, unsigned char rhs)
5240 	{
5241 		if(emulateIntrinsics)
5242 		{
5243 			Int2 result;
5244 			result = Insert(result, Extract(lhs, 0) << Int(rhs), 0);
5245 			result = Insert(result, Extract(lhs, 1) << Int(rhs), 1);
5246 
5247 			return result;
5248 		}
5249 		else
5250 		{
5251 			return RValue<Int2>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
5252 		}
5253 	}
5254 
operator >>(RValue<Int2> lhs,unsigned char rhs)5255 	RValue<Int2> operator>>(RValue<Int2> lhs, unsigned char rhs)
5256 	{
5257 		if(emulateIntrinsics)
5258 		{
5259 			Int2 result;
5260 			result = Insert(result, Extract(lhs, 0) >> Int(rhs), 0);
5261 			result = Insert(result, Extract(lhs, 1) >> Int(rhs), 1);
5262 
5263 			return result;
5264 		}
5265 		else
5266 		{
5267 			return RValue<Int2>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
5268 		}
5269 	}
5270 
operator +=(Int2 & lhs,RValue<Int2> rhs)5271 	RValue<Int2> operator+=(Int2 &lhs, RValue<Int2> rhs)
5272 	{
5273 		return lhs = lhs + rhs;
5274 	}
5275 
operator -=(Int2 & lhs,RValue<Int2> rhs)5276 	RValue<Int2> operator-=(Int2 &lhs, RValue<Int2> rhs)
5277 	{
5278 		return lhs = lhs - rhs;
5279 	}
5280 
5281 //	RValue<Int2> operator*=(Int2 &lhs, RValue<Int2> rhs)
5282 //	{
5283 //		return lhs = lhs * rhs;
5284 //	}
5285 
5286 //	RValue<Int2> operator/=(Int2 &lhs, RValue<Int2> rhs)
5287 //	{
5288 //		return lhs = lhs / rhs;
5289 //	}
5290 
5291 //	RValue<Int2> operator%=(Int2 &lhs, RValue<Int2> rhs)
5292 //	{
5293 //		return lhs = lhs % rhs;
5294 //	}
5295 
operator &=(Int2 & lhs,RValue<Int2> rhs)5296 	RValue<Int2> operator&=(Int2 &lhs, RValue<Int2> rhs)
5297 	{
5298 		return lhs = lhs & rhs;
5299 	}
5300 
operator |=(Int2 & lhs,RValue<Int2> rhs)5301 	RValue<Int2> operator|=(Int2 &lhs, RValue<Int2> rhs)
5302 	{
5303 		return lhs = lhs | rhs;
5304 	}
5305 
operator ^=(Int2 & lhs,RValue<Int2> rhs)5306 	RValue<Int2> operator^=(Int2 &lhs, RValue<Int2> rhs)
5307 	{
5308 		return lhs = lhs ^ rhs;
5309 	}
5310 
operator <<=(Int2 & lhs,unsigned char rhs)5311 	RValue<Int2> operator<<=(Int2 &lhs, unsigned char rhs)
5312 	{
5313 		return lhs = lhs << rhs;
5314 	}
5315 
operator >>=(Int2 & lhs,unsigned char rhs)5316 	RValue<Int2> operator>>=(Int2 &lhs, unsigned char rhs)
5317 	{
5318 		return lhs = lhs >> rhs;
5319 	}
5320 
5321 //	RValue<Int2> operator+(RValue<Int2> val)
5322 //	{
5323 //		return val;
5324 //	}
5325 
5326 //	RValue<Int2> operator-(RValue<Int2> val)
5327 //	{
5328 //		return RValue<Int2>(Nucleus::createNeg(val.value));
5329 //	}
5330 
operator ~(RValue<Int2> val)5331 	RValue<Int2> operator~(RValue<Int2> val)
5332 	{
5333 		return RValue<Int2>(Nucleus::createNot(val.value));
5334 	}
5335 
UnpackLow(RValue<Int2> x,RValue<Int2> y)5336 	RValue<Short4> UnpackLow(RValue<Int2> x, RValue<Int2> y)
5337 	{
5338 		int shuffle[4] = {0, 4, 1, 5};   // Real type is v4i32
5339 		return As<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
5340 	}
5341 
UnpackHigh(RValue<Int2> x,RValue<Int2> y)5342 	RValue<Short4> UnpackHigh(RValue<Int2> x, RValue<Int2> y)
5343 	{
5344 		int shuffle[4] = {0, 4, 1, 5};   // Real type is v4i32
5345 		auto lowHigh = RValue<Int4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
5346 		return As<Short4>(Swizzle(lowHigh, 0xEE));
5347 	}
5348 
Extract(RValue<Int2> val,int i)5349 	RValue<Int> Extract(RValue<Int2> val, int i)
5350 	{
5351 		return RValue<Int>(Nucleus::createExtractElement(val.value, Int::getType(), i));
5352 	}
5353 
Insert(RValue<Int2> val,RValue<Int> element,int i)5354 	RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i)
5355 	{
5356 		return RValue<Int2>(Nucleus::createInsertElement(val.value, element.value, i));
5357 	}
5358 
getType()5359 	Type *Int2::getType()
5360 	{
5361 		return T(Type_v2i32);
5362 	}
5363 
UInt2(unsigned int x,unsigned int y)5364 	UInt2::UInt2(unsigned int x, unsigned int y)
5365 	{
5366 		int64_t constantVector[2] = {x, y};
5367 		storeValue(Nucleus::createConstantVector(constantVector, getType()));
5368 	}
5369 
UInt2(RValue<UInt2> rhs)5370 	UInt2::UInt2(RValue<UInt2> rhs)
5371 	{
5372 		storeValue(rhs.value);
5373 	}
5374 
UInt2(const UInt2 & rhs)5375 	UInt2::UInt2(const UInt2 &rhs)
5376 	{
5377 		Value *value = rhs.loadValue();
5378 		storeValue(value);
5379 	}
5380 
UInt2(const Reference<UInt2> & rhs)5381 	UInt2::UInt2(const Reference<UInt2> &rhs)
5382 	{
5383 		Value *value = rhs.loadValue();
5384 		storeValue(value);
5385 	}
5386 
operator =(RValue<UInt2> rhs)5387 	RValue<UInt2> UInt2::operator=(RValue<UInt2> rhs)
5388 	{
5389 		storeValue(rhs.value);
5390 
5391 		return rhs;
5392 	}
5393 
operator =(const UInt2 & rhs)5394 	RValue<UInt2> UInt2::operator=(const UInt2 &rhs)
5395 	{
5396 		Value *value = rhs.loadValue();
5397 		storeValue(value);
5398 
5399 		return RValue<UInt2>(value);
5400 	}
5401 
operator =(const Reference<UInt2> & rhs)5402 	RValue<UInt2> UInt2::operator=(const Reference<UInt2> &rhs)
5403 	{
5404 		Value *value = rhs.loadValue();
5405 		storeValue(value);
5406 
5407 		return RValue<UInt2>(value);
5408 	}
5409 
operator +(RValue<UInt2> lhs,RValue<UInt2> rhs)5410 	RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs)
5411 	{
5412 		return RValue<UInt2>(Nucleus::createAdd(lhs.value, rhs.value));
5413 	}
5414 
operator -(RValue<UInt2> lhs,RValue<UInt2> rhs)5415 	RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs)
5416 	{
5417 		return RValue<UInt2>(Nucleus::createSub(lhs.value, rhs.value));
5418 	}
5419 
5420 //	RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs)
5421 //	{
5422 //		return RValue<UInt2>(Nucleus::createMul(lhs.value, rhs.value));
5423 //	}
5424 
5425 //	RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs)
5426 //	{
5427 //		return RValue<UInt2>(Nucleus::createUDiv(lhs.value, rhs.value));
5428 //	}
5429 
5430 //	RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs)
5431 //	{
5432 //		return RValue<UInt2>(Nucleus::createURem(lhs.value, rhs.value));
5433 //	}
5434 
operator &(RValue<UInt2> lhs,RValue<UInt2> rhs)5435 	RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs)
5436 	{
5437 		return RValue<UInt2>(Nucleus::createAnd(lhs.value, rhs.value));
5438 	}
5439 
operator |(RValue<UInt2> lhs,RValue<UInt2> rhs)5440 	RValue<UInt2> operator|(RValue<UInt2> lhs, RValue<UInt2> rhs)
5441 	{
5442 		return RValue<UInt2>(Nucleus::createOr(lhs.value, rhs.value));
5443 	}
5444 
operator ^(RValue<UInt2> lhs,RValue<UInt2> rhs)5445 	RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs)
5446 	{
5447 		return RValue<UInt2>(Nucleus::createXor(lhs.value, rhs.value));
5448 	}
5449 
Extract(RValue<UInt2> val,int i)5450 	RValue<UInt> Extract(RValue<UInt2> val, int i)
5451 	{
5452 		return RValue<UInt>(Nucleus::createExtractElement(val.value, UInt::getType(), i));
5453 	}
5454 
Insert(RValue<UInt2> val,RValue<UInt> element,int i)5455 	RValue<UInt2> Insert(RValue<UInt2> val, RValue<UInt> element, int i)
5456 	{
5457 		return RValue<UInt2>(Nucleus::createInsertElement(val.value, element.value, i));
5458 	}
5459 
operator <<(RValue<UInt2> lhs,unsigned char rhs)5460 	RValue<UInt2> operator<<(RValue<UInt2> lhs, unsigned char rhs)
5461 	{
5462 		if(emulateIntrinsics)
5463 		{
5464 			UInt2 result;
5465 			result = Insert(result, Extract(lhs, 0) << UInt(rhs), 0);
5466 			result = Insert(result, Extract(lhs, 1) << UInt(rhs), 1);
5467 
5468 			return result;
5469 		}
5470 		else
5471 		{
5472 			return RValue<UInt2>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
5473 		}
5474 	}
5475 
operator >>(RValue<UInt2> lhs,unsigned char rhs)5476 	RValue<UInt2> operator>>(RValue<UInt2> lhs, unsigned char rhs)
5477 	{
5478 		if(emulateIntrinsics)
5479 		{
5480 			UInt2 result;
5481 			result = Insert(result, Extract(lhs, 0) >> UInt(rhs), 0);
5482 			result = Insert(result, Extract(lhs, 1) >> UInt(rhs), 1);
5483 
5484 			return result;
5485 		}
5486 		else
5487 		{
5488 			return RValue<UInt2>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
5489 		}
5490 	}
5491 
operator +=(UInt2 & lhs,RValue<UInt2> rhs)5492 	RValue<UInt2> operator+=(UInt2 &lhs, RValue<UInt2> rhs)
5493 	{
5494 		return lhs = lhs + rhs;
5495 	}
5496 
operator -=(UInt2 & lhs,RValue<UInt2> rhs)5497 	RValue<UInt2> operator-=(UInt2 &lhs, RValue<UInt2> rhs)
5498 	{
5499 		return lhs = lhs - rhs;
5500 	}
5501 
5502 //	RValue<UInt2> operator*=(UInt2 &lhs, RValue<UInt2> rhs)
5503 //	{
5504 //		return lhs = lhs * rhs;
5505 //	}
5506 
5507 //	RValue<UInt2> operator/=(UInt2 &lhs, RValue<UInt2> rhs)
5508 //	{
5509 //		return lhs = lhs / rhs;
5510 //	}
5511 
5512 //	RValue<UInt2> operator%=(UInt2 &lhs, RValue<UInt2> rhs)
5513 //	{
5514 //		return lhs = lhs % rhs;
5515 //	}
5516 
operator &=(UInt2 & lhs,RValue<UInt2> rhs)5517 	RValue<UInt2> operator&=(UInt2 &lhs, RValue<UInt2> rhs)
5518 	{
5519 		return lhs = lhs & rhs;
5520 	}
5521 
operator |=(UInt2 & lhs,RValue<UInt2> rhs)5522 	RValue<UInt2> operator|=(UInt2 &lhs, RValue<UInt2> rhs)
5523 	{
5524 		return lhs = lhs | rhs;
5525 	}
5526 
operator ^=(UInt2 & lhs,RValue<UInt2> rhs)5527 	RValue<UInt2> operator^=(UInt2 &lhs, RValue<UInt2> rhs)
5528 	{
5529 		return lhs = lhs ^ rhs;
5530 	}
5531 
operator <<=(UInt2 & lhs,unsigned char rhs)5532 	RValue<UInt2> operator<<=(UInt2 &lhs, unsigned char rhs)
5533 	{
5534 		return lhs = lhs << rhs;
5535 	}
5536 
operator >>=(UInt2 & lhs,unsigned char rhs)5537 	RValue<UInt2> operator>>=(UInt2 &lhs, unsigned char rhs)
5538 	{
5539 		return lhs = lhs >> rhs;
5540 	}
5541 
5542 //	RValue<UInt2> operator+(RValue<UInt2> val)
5543 //	{
5544 //		return val;
5545 //	}
5546 
5547 //	RValue<UInt2> operator-(RValue<UInt2> val)
5548 //	{
5549 //		return RValue<UInt2>(Nucleus::createNeg(val.value));
5550 //	}
5551 
operator ~(RValue<UInt2> val)5552 	RValue<UInt2> operator~(RValue<UInt2> val)
5553 	{
5554 		return RValue<UInt2>(Nucleus::createNot(val.value));
5555 	}
5556 
getType()5557 	Type *UInt2::getType()
5558 	{
5559 		return T(Type_v2i32);
5560 	}
5561 
Int4()5562 	Int4::Int4() : XYZW(this)
5563 	{
5564 	}
5565 
Int4(RValue<Byte4> cast)5566 	Int4::Int4(RValue<Byte4> cast) : XYZW(this)
5567 	{
5568 		Value *x = Nucleus::createBitCast(cast.value, Int::getType());
5569 		Value *a = Nucleus::createInsertElement(loadValue(), x, 0);
5570 
5571 		Value *e;
5572 		int swizzle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23};
5573 		Value *b = Nucleus::createBitCast(a, Byte16::getType());
5574 		Value *c = Nucleus::createShuffleVector(b, V(Nucleus::createNullValue(Byte16::getType())), swizzle);
5575 
5576 		int swizzle2[8] = {0, 8, 1, 9, 2, 10, 3, 11};
5577 		Value *d = Nucleus::createBitCast(c, Short8::getType());
5578 		e = Nucleus::createShuffleVector(d, V(Nucleus::createNullValue(Short8::getType())), swizzle2);
5579 
5580 		Value *f = Nucleus::createBitCast(e, Int4::getType());
5581 		storeValue(f);
5582 	}
5583 
Int4(RValue<SByte4> cast)5584 	Int4::Int4(RValue<SByte4> cast) : XYZW(this)
5585 	{
5586 		Value *x = Nucleus::createBitCast(cast.value, Int::getType());
5587 		Value *a = Nucleus::createInsertElement(loadValue(), x, 0);
5588 
5589 		int swizzle[16] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7};
5590 		Value *b = Nucleus::createBitCast(a, Byte16::getType());
5591 		Value *c = Nucleus::createShuffleVector(b, b, swizzle);
5592 
5593 		int swizzle2[8] = {0, 0, 1, 1, 2, 2, 3, 3};
5594 		Value *d = Nucleus::createBitCast(c, Short8::getType());
5595 		Value *e = Nucleus::createShuffleVector(d, d, swizzle2);
5596 
5597 		*this = As<Int4>(e) >> 24;
5598 	}
5599 
Int4(RValue<Float4> cast)5600 	Int4::Int4(RValue<Float4> cast) : XYZW(this)
5601 	{
5602 		Value *xyzw = Nucleus::createFPToSI(cast.value, Int4::getType());
5603 
5604 		storeValue(xyzw);
5605 	}
5606 
Int4(RValue<Short4> cast)5607 	Int4::Int4(RValue<Short4> cast) : XYZW(this)
5608 	{
5609 		int swizzle[8] = {0, 0, 1, 1, 2, 2, 3, 3};
5610 		Value *c = Nucleus::createShuffleVector(cast.value, cast.value, swizzle);
5611 
5612 		*this = As<Int4>(c) >> 16;
5613 	}
5614 
Int4(RValue<UShort4> cast)5615 	Int4::Int4(RValue<UShort4> cast) : XYZW(this)
5616 	{
5617 		int swizzle[8] = {0, 8, 1, 9, 2, 10, 3, 11};
5618 		Value *c = Nucleus::createShuffleVector(cast.value, Short8(0, 0, 0, 0, 0, 0, 0, 0).loadValue(), swizzle);
5619 		Value *d = Nucleus::createBitCast(c, Int4::getType());
5620 		storeValue(d);
5621 	}
5622 
Int4(int xyzw)5623 	Int4::Int4(int xyzw) : XYZW(this)
5624 	{
5625 		constant(xyzw, xyzw, xyzw, xyzw);
5626 	}
5627 
Int4(int x,int yzw)5628 	Int4::Int4(int x, int yzw) : XYZW(this)
5629 	{
5630 		constant(x, yzw, yzw, yzw);
5631 	}
5632 
Int4(int x,int y,int zw)5633 	Int4::Int4(int x, int y, int zw) : XYZW(this)
5634 	{
5635 		constant(x, y, zw, zw);
5636 	}
5637 
Int4(int x,int y,int z,int w)5638 	Int4::Int4(int x, int y, int z, int w) : XYZW(this)
5639 	{
5640 		constant(x, y, z, w);
5641 	}
5642 
constant(int x,int y,int z,int w)5643 	void Int4::constant(int x, int y, int z, int w)
5644 	{
5645 		int64_t constantVector[4] = {x, y, z, w};
5646 		storeValue(Nucleus::createConstantVector(constantVector, getType()));
5647 	}
5648 
Int4(RValue<Int4> rhs)5649 	Int4::Int4(RValue<Int4> rhs) : XYZW(this)
5650 	{
5651 		storeValue(rhs.value);
5652 	}
5653 
Int4(const Int4 & rhs)5654 	Int4::Int4(const Int4 &rhs) : XYZW(this)
5655 	{
5656 		Value *value = rhs.loadValue();
5657 		storeValue(value);
5658 	}
5659 
Int4(const Reference<Int4> & rhs)5660 	Int4::Int4(const Reference<Int4> &rhs) : XYZW(this)
5661 	{
5662 		Value *value = rhs.loadValue();
5663 		storeValue(value);
5664 	}
5665 
Int4(RValue<UInt4> rhs)5666 	Int4::Int4(RValue<UInt4> rhs) : XYZW(this)
5667 	{
5668 		storeValue(rhs.value);
5669 	}
5670 
Int4(const UInt4 & rhs)5671 	Int4::Int4(const UInt4 &rhs) : XYZW(this)
5672 	{
5673 		Value *value = rhs.loadValue();
5674 		storeValue(value);
5675 	}
5676 
Int4(const Reference<UInt4> & rhs)5677 	Int4::Int4(const Reference<UInt4> &rhs) : XYZW(this)
5678 	{
5679 		Value *value = rhs.loadValue();
5680 		storeValue(value);
5681 	}
5682 
Int4(RValue<Int2> lo,RValue<Int2> hi)5683 	Int4::Int4(RValue<Int2> lo, RValue<Int2> hi) : XYZW(this)
5684 	{
5685 		int shuffle[4] = {0, 1, 4, 5};   // Real type is v4i32
5686 		Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
5687 
5688 		storeValue(packed);
5689 	}
5690 
Int4(RValue<Int> rhs)5691 	Int4::Int4(RValue<Int> rhs) : XYZW(this)
5692 	{
5693 		Value *vector = Nucleus::createBitCast(rhs.value, Int4::getType());
5694 
5695 		int swizzle[4] = {0, 0, 0, 0};
5696 		Value *replicate = Nucleus::createShuffleVector(vector, vector, swizzle);
5697 
5698 		storeValue(replicate);
5699 	}
5700 
Int4(const Int & rhs)5701 	Int4::Int4(const Int &rhs) : XYZW(this)
5702 	{
5703 		*this = RValue<Int>(rhs.loadValue());
5704 	}
5705 
Int4(const Reference<Int> & rhs)5706 	Int4::Int4(const Reference<Int> &rhs) : XYZW(this)
5707 	{
5708 		*this = RValue<Int>(rhs.loadValue());
5709 	}
5710 
operator =(RValue<Int4> rhs)5711 	RValue<Int4> Int4::operator=(RValue<Int4> rhs)
5712 	{
5713 		storeValue(rhs.value);
5714 
5715 		return rhs;
5716 	}
5717 
operator =(const Int4 & rhs)5718 	RValue<Int4> Int4::operator=(const Int4 &rhs)
5719 	{
5720 		Value *value = rhs.loadValue();
5721 		storeValue(value);
5722 
5723 		return RValue<Int4>(value);
5724 	}
5725 
operator =(const Reference<Int4> & rhs)5726 	RValue<Int4> Int4::operator=(const Reference<Int4> &rhs)
5727 	{
5728 		Value *value = rhs.loadValue();
5729 		storeValue(value);
5730 
5731 		return RValue<Int4>(value);
5732 	}
5733 
operator +(RValue<Int4> lhs,RValue<Int4> rhs)5734 	RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs)
5735 	{
5736 		return RValue<Int4>(Nucleus::createAdd(lhs.value, rhs.value));
5737 	}
5738 
operator -(RValue<Int4> lhs,RValue<Int4> rhs)5739 	RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs)
5740 	{
5741 		return RValue<Int4>(Nucleus::createSub(lhs.value, rhs.value));
5742 	}
5743 
operator *(RValue<Int4> lhs,RValue<Int4> rhs)5744 	RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs)
5745 	{
5746 		return RValue<Int4>(Nucleus::createMul(lhs.value, rhs.value));
5747 	}
5748 
operator /(RValue<Int4> lhs,RValue<Int4> rhs)5749 	RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs)
5750 	{
5751 		return RValue<Int4>(Nucleus::createSDiv(lhs.value, rhs.value));
5752 	}
5753 
operator %(RValue<Int4> lhs,RValue<Int4> rhs)5754 	RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs)
5755 	{
5756 		return RValue<Int4>(Nucleus::createSRem(lhs.value, rhs.value));
5757 	}
5758 
operator &(RValue<Int4> lhs,RValue<Int4> rhs)5759 	RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs)
5760 	{
5761 		return RValue<Int4>(Nucleus::createAnd(lhs.value, rhs.value));
5762 	}
5763 
operator |(RValue<Int4> lhs,RValue<Int4> rhs)5764 	RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs)
5765 	{
5766 		return RValue<Int4>(Nucleus::createOr(lhs.value, rhs.value));
5767 	}
5768 
operator ^(RValue<Int4> lhs,RValue<Int4> rhs)5769 	RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs)
5770 	{
5771 		return RValue<Int4>(Nucleus::createXor(lhs.value, rhs.value));
5772 	}
5773 
operator <<(RValue<Int4> lhs,unsigned char rhs)5774 	RValue<Int4> operator<<(RValue<Int4> lhs, unsigned char rhs)
5775 	{
5776 		if(emulateIntrinsics)
5777 		{
5778 			Int4 result;
5779 			result = Insert(result, Extract(lhs, 0) << Int(rhs), 0);
5780 			result = Insert(result, Extract(lhs, 1) << Int(rhs), 1);
5781 			result = Insert(result, Extract(lhs, 2) << Int(rhs), 2);
5782 			result = Insert(result, Extract(lhs, 3) << Int(rhs), 3);
5783 
5784 			return result;
5785 		}
5786 		else
5787 		{
5788 			return RValue<Int4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
5789 		}
5790 	}
5791 
operator >>(RValue<Int4> lhs,unsigned char rhs)5792 	RValue<Int4> operator>>(RValue<Int4> lhs, unsigned char rhs)
5793 	{
5794 		if(emulateIntrinsics)
5795 		{
5796 			Int4 result;
5797 			result = Insert(result, Extract(lhs, 0) >> Int(rhs), 0);
5798 			result = Insert(result, Extract(lhs, 1) >> Int(rhs), 1);
5799 			result = Insert(result, Extract(lhs, 2) >> Int(rhs), 2);
5800 			result = Insert(result, Extract(lhs, 3) >> Int(rhs), 3);
5801 
5802 			return result;
5803 		}
5804 		else
5805 		{
5806 			return RValue<Int4>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
5807 		}
5808 	}
5809 
operator <<(RValue<Int4> lhs,RValue<Int4> rhs)5810 	RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs)
5811 	{
5812 		return RValue<Int4>(Nucleus::createShl(lhs.value, rhs.value));
5813 	}
5814 
operator >>(RValue<Int4> lhs,RValue<Int4> rhs)5815 	RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs)
5816 	{
5817 		return RValue<Int4>(Nucleus::createAShr(lhs.value, rhs.value));
5818 	}
5819 
operator +=(Int4 & lhs,RValue<Int4> rhs)5820 	RValue<Int4> operator+=(Int4 &lhs, RValue<Int4> rhs)
5821 	{
5822 		return lhs = lhs + rhs;
5823 	}
5824 
operator -=(Int4 & lhs,RValue<Int4> rhs)5825 	RValue<Int4> operator-=(Int4 &lhs, RValue<Int4> rhs)
5826 	{
5827 		return lhs = lhs - rhs;
5828 	}
5829 
operator *=(Int4 & lhs,RValue<Int4> rhs)5830 	RValue<Int4> operator*=(Int4 &lhs, RValue<Int4> rhs)
5831 	{
5832 		return lhs = lhs * rhs;
5833 	}
5834 
5835 //	RValue<Int4> operator/=(Int4 &lhs, RValue<Int4> rhs)
5836 //	{
5837 //		return lhs = lhs / rhs;
5838 //	}
5839 
5840 //	RValue<Int4> operator%=(Int4 &lhs, RValue<Int4> rhs)
5841 //	{
5842 //		return lhs = lhs % rhs;
5843 //	}
5844 
operator &=(Int4 & lhs,RValue<Int4> rhs)5845 	RValue<Int4> operator&=(Int4 &lhs, RValue<Int4> rhs)
5846 	{
5847 		return lhs = lhs & rhs;
5848 	}
5849 
operator |=(Int4 & lhs,RValue<Int4> rhs)5850 	RValue<Int4> operator|=(Int4 &lhs, RValue<Int4> rhs)
5851 	{
5852 		return lhs = lhs | rhs;
5853 	}
5854 
operator ^=(Int4 & lhs,RValue<Int4> rhs)5855 	RValue<Int4> operator^=(Int4 &lhs, RValue<Int4> rhs)
5856 	{
5857 		return lhs = lhs ^ rhs;
5858 	}
5859 
operator <<=(Int4 & lhs,unsigned char rhs)5860 	RValue<Int4> operator<<=(Int4 &lhs, unsigned char rhs)
5861 	{
5862 		return lhs = lhs << rhs;
5863 	}
5864 
operator >>=(Int4 & lhs,unsigned char rhs)5865 	RValue<Int4> operator>>=(Int4 &lhs, unsigned char rhs)
5866 	{
5867 		return lhs = lhs >> rhs;
5868 	}
5869 
operator +(RValue<Int4> val)5870 	RValue<Int4> operator+(RValue<Int4> val)
5871 	{
5872 		return val;
5873 	}
5874 
operator -(RValue<Int4> val)5875 	RValue<Int4> operator-(RValue<Int4> val)
5876 	{
5877 		return RValue<Int4>(Nucleus::createNeg(val.value));
5878 	}
5879 
operator ~(RValue<Int4> val)5880 	RValue<Int4> operator~(RValue<Int4> val)
5881 	{
5882 		return RValue<Int4>(Nucleus::createNot(val.value));
5883 	}
5884 
CmpEQ(RValue<Int4> x,RValue<Int4> y)5885 	RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y)
5886 	{
5887 		return RValue<Int4>(Nucleus::createICmpEQ(x.value, y.value));
5888 	}
5889 
CmpLT(RValue<Int4> x,RValue<Int4> y)5890 	RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y)
5891 	{
5892 		return RValue<Int4>(Nucleus::createICmpSLT(x.value, y.value));
5893 	}
5894 
CmpLE(RValue<Int4> x,RValue<Int4> y)5895 	RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y)
5896 	{
5897 		return RValue<Int4>(Nucleus::createICmpSLE(x.value, y.value));
5898 	}
5899 
CmpNEQ(RValue<Int4> x,RValue<Int4> y)5900 	RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y)
5901 	{
5902 		return RValue<Int4>(Nucleus::createICmpNE(x.value, y.value));
5903 	}
5904 
CmpNLT(RValue<Int4> x,RValue<Int4> y)5905 	RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y)
5906 	{
5907 		return RValue<Int4>(Nucleus::createICmpSGE(x.value, y.value));
5908 	}
5909 
CmpNLE(RValue<Int4> x,RValue<Int4> y)5910 	RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y)
5911 	{
5912 		return RValue<Int4>(Nucleus::createICmpSGT(x.value, y.value));
5913 	}
5914 
Max(RValue<Int4> x,RValue<Int4> y)5915 	RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y)
5916 	{
5917 		Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
5918 		auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sle, condition, x.value, y.value);
5919 		::basicBlock->appendInst(cmp);
5920 
5921 		Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5922 		auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
5923 		::basicBlock->appendInst(select);
5924 
5925 		return RValue<Int4>(V(result));
5926 	}
5927 
Min(RValue<Int4> x,RValue<Int4> y)5928 	RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y)
5929 	{
5930 		Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
5931 		auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sgt, condition, x.value, y.value);
5932 		::basicBlock->appendInst(cmp);
5933 
5934 		Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5935 		auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
5936 		::basicBlock->appendInst(select);
5937 
5938 		return RValue<Int4>(V(result));
5939 	}
5940 
RoundInt(RValue<Float4> cast)5941 	RValue<Int4> RoundInt(RValue<Float4> cast)
5942 	{
5943 		if(emulateIntrinsics || CPUID::ARM)
5944 		{
5945 			// Push the fractional part off the mantissa. Accurate up to +/-2^22.
5946 			return Int4((cast + Float4(0x00C00000)) - Float4(0x00C00000));
5947 		}
5948 		else
5949 		{
5950 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5951 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Nearbyint, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5952 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
5953 			auto nearbyint = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
5954 			nearbyint->addArg(cast.value);
5955 			::basicBlock->appendInst(nearbyint);
5956 
5957 			return RValue<Int4>(V(result));
5958 		}
5959 	}
5960 
PackSigned(RValue<Int4> x,RValue<Int4> y)5961 	RValue<Short8> PackSigned(RValue<Int4> x, RValue<Int4> y)
5962 	{
5963 		if(emulateIntrinsics)
5964 		{
5965 			Short8 result;
5966 			result = Insert(result, SaturateSigned(Extract(x, 0)), 0);
5967 			result = Insert(result, SaturateSigned(Extract(x, 1)), 1);
5968 			result = Insert(result, SaturateSigned(Extract(x, 2)), 2);
5969 			result = Insert(result, SaturateSigned(Extract(x, 3)), 3);
5970 			result = Insert(result, SaturateSigned(Extract(y, 0)), 4);
5971 			result = Insert(result, SaturateSigned(Extract(y, 1)), 5);
5972 			result = Insert(result, SaturateSigned(Extract(y, 2)), 6);
5973 			result = Insert(result, SaturateSigned(Extract(y, 3)), 7);
5974 
5975 			return result;
5976 		}
5977 		else
5978 		{
5979 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
5980 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5981 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
5982 			auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
5983 			pack->addArg(x.value);
5984 			pack->addArg(y.value);
5985 			::basicBlock->appendInst(pack);
5986 
5987 			return RValue<Short8>(V(result));
5988 		}
5989 	}
5990 
PackUnsigned(RValue<Int4> x,RValue<Int4> y)5991 	RValue<UShort8> PackUnsigned(RValue<Int4> x, RValue<Int4> y)
5992 	{
5993 		if(emulateIntrinsics || !(CPUID::SSE4_1 || CPUID::ARM))
5994 		{
5995 			RValue<Int4> sx = As<Int4>(x);
5996 			RValue<Int4> bx = (sx & ~(sx >> 31)) - Int4(0x8000);
5997 
5998 			RValue<Int4> sy = As<Int4>(y);
5999 			RValue<Int4> by = (sy & ~(sy >> 31)) - Int4(0x8000);
6000 
6001 			return As<UShort8>(PackSigned(bx, by) + Short8(0x8000u));
6002 		}
6003 		else
6004 		{
6005 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
6006 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6007 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
6008 			auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
6009 			pack->addArg(x.value);
6010 			pack->addArg(y.value);
6011 			::basicBlock->appendInst(pack);
6012 
6013 			return RValue<UShort8>(V(result));
6014 		}
6015 	}
6016 
Extract(RValue<Int4> x,int i)6017 	RValue<Int> Extract(RValue<Int4> x, int i)
6018 	{
6019 		return RValue<Int>(Nucleus::createExtractElement(x.value, Int::getType(), i));
6020 	}
6021 
Insert(RValue<Int4> x,RValue<Int> element,int i)6022 	RValue<Int4> Insert(RValue<Int4> x, RValue<Int> element, int i)
6023 	{
6024 		return RValue<Int4>(Nucleus::createInsertElement(x.value, element.value, i));
6025 	}
6026 
SignMask(RValue<Int4> x)6027 	RValue<Int> SignMask(RValue<Int4> x)
6028 	{
6029 		if(emulateIntrinsics || CPUID::ARM)
6030 		{
6031 			Int4 xx = (x >> 31) & Int4(0x00000001, 0x00000002, 0x00000004, 0x00000008);
6032 			return Extract(xx, 0) | Extract(xx, 1) | Extract(xx, 2) | Extract(xx, 3);
6033 		}
6034 		else
6035 		{
6036 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
6037 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6038 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
6039 			auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
6040 			movmsk->addArg(x.value);
6041 			::basicBlock->appendInst(movmsk);
6042 
6043 			return RValue<Int>(V(result));
6044 		}
6045 	}
6046 
Swizzle(RValue<Int4> x,unsigned char select)6047 	RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select)
6048 	{
6049 		return RValue<Int4>(createSwizzle4(x.value, select));
6050 	}
6051 
getType()6052 	Type *Int4::getType()
6053 	{
6054 		return T(Ice::IceType_v4i32);
6055 	}
6056 
UInt4()6057 	UInt4::UInt4() : XYZW(this)
6058 	{
6059 	}
6060 
UInt4(RValue<Float4> cast)6061 	UInt4::UInt4(RValue<Float4> cast) : XYZW(this)
6062 	{
6063 		// Smallest positive value representable in UInt, but not in Int
6064 		const unsigned int ustart = 0x80000000u;
6065 		const float ustartf = float(ustart);
6066 
6067 		// Check if the value can be represented as an Int
6068 		Int4 uiValue = CmpNLT(cast, Float4(ustartf));
6069 		// If the value is too large, subtract ustart and re-add it after conversion.
6070 		uiValue = (uiValue & As<Int4>(As<UInt4>(Int4(cast - Float4(ustartf))) + UInt4(ustart))) |
6071 		// Otherwise, just convert normally
6072 		          (~uiValue & Int4(cast));
6073 		// If the value is negative, store 0, otherwise store the result of the conversion
6074 		storeValue((~(As<Int4>(cast) >> 31) & uiValue).value);
6075 	}
6076 
UInt4(int xyzw)6077 	UInt4::UInt4(int xyzw) : XYZW(this)
6078 	{
6079 		constant(xyzw, xyzw, xyzw, xyzw);
6080 	}
6081 
UInt4(int x,int yzw)6082 	UInt4::UInt4(int x, int yzw) : XYZW(this)
6083 	{
6084 		constant(x, yzw, yzw, yzw);
6085 	}
6086 
UInt4(int x,int y,int zw)6087 	UInt4::UInt4(int x, int y, int zw) : XYZW(this)
6088 	{
6089 		constant(x, y, zw, zw);
6090 	}
6091 
UInt4(int x,int y,int z,int w)6092 	UInt4::UInt4(int x, int y, int z, int w) : XYZW(this)
6093 	{
6094 		constant(x, y, z, w);
6095 	}
6096 
constant(int x,int y,int z,int w)6097 	void UInt4::constant(int x, int y, int z, int w)
6098 	{
6099 		int64_t constantVector[4] = {x, y, z, w};
6100 		storeValue(Nucleus::createConstantVector(constantVector, getType()));
6101 	}
6102 
UInt4(RValue<UInt4> rhs)6103 	UInt4::UInt4(RValue<UInt4> rhs) : XYZW(this)
6104 	{
6105 		storeValue(rhs.value);
6106 	}
6107 
UInt4(const UInt4 & rhs)6108 	UInt4::UInt4(const UInt4 &rhs) : XYZW(this)
6109 	{
6110 		Value *value = rhs.loadValue();
6111 		storeValue(value);
6112 	}
6113 
UInt4(const Reference<UInt4> & rhs)6114 	UInt4::UInt4(const Reference<UInt4> &rhs) : XYZW(this)
6115 	{
6116 		Value *value = rhs.loadValue();
6117 		storeValue(value);
6118 	}
6119 
UInt4(RValue<Int4> rhs)6120 	UInt4::UInt4(RValue<Int4> rhs) : XYZW(this)
6121 	{
6122 		storeValue(rhs.value);
6123 	}
6124 
UInt4(const Int4 & rhs)6125 	UInt4::UInt4(const Int4 &rhs) : XYZW(this)
6126 	{
6127 		Value *value = rhs.loadValue();
6128 		storeValue(value);
6129 	}
6130 
UInt4(const Reference<Int4> & rhs)6131 	UInt4::UInt4(const Reference<Int4> &rhs) : XYZW(this)
6132 	{
6133 		Value *value = rhs.loadValue();
6134 		storeValue(value);
6135 	}
6136 
UInt4(RValue<UInt2> lo,RValue<UInt2> hi)6137 	UInt4::UInt4(RValue<UInt2> lo, RValue<UInt2> hi) : XYZW(this)
6138 	{
6139 		int shuffle[4] = {0, 1, 4, 5};   // Real type is v4i32
6140 		Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
6141 
6142 		storeValue(packed);
6143 	}
6144 
operator =(RValue<UInt4> rhs)6145 	RValue<UInt4> UInt4::operator=(RValue<UInt4> rhs)
6146 	{
6147 		storeValue(rhs.value);
6148 
6149 		return rhs;
6150 	}
6151 
operator =(const UInt4 & rhs)6152 	RValue<UInt4> UInt4::operator=(const UInt4 &rhs)
6153 	{
6154 		Value *value = rhs.loadValue();
6155 		storeValue(value);
6156 
6157 		return RValue<UInt4>(value);
6158 	}
6159 
operator =(const Reference<UInt4> & rhs)6160 	RValue<UInt4> UInt4::operator=(const Reference<UInt4> &rhs)
6161 	{
6162 		Value *value = rhs.loadValue();
6163 		storeValue(value);
6164 
6165 		return RValue<UInt4>(value);
6166 	}
6167 
operator +(RValue<UInt4> lhs,RValue<UInt4> rhs)6168 	RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs)
6169 	{
6170 		return RValue<UInt4>(Nucleus::createAdd(lhs.value, rhs.value));
6171 	}
6172 
operator -(RValue<UInt4> lhs,RValue<UInt4> rhs)6173 	RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs)
6174 	{
6175 		return RValue<UInt4>(Nucleus::createSub(lhs.value, rhs.value));
6176 	}
6177 
operator *(RValue<UInt4> lhs,RValue<UInt4> rhs)6178 	RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs)
6179 	{
6180 		return RValue<UInt4>(Nucleus::createMul(lhs.value, rhs.value));
6181 	}
6182 
operator /(RValue<UInt4> lhs,RValue<UInt4> rhs)6183 	RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs)
6184 	{
6185 		return RValue<UInt4>(Nucleus::createUDiv(lhs.value, rhs.value));
6186 	}
6187 
operator %(RValue<UInt4> lhs,RValue<UInt4> rhs)6188 	RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs)
6189 	{
6190 		return RValue<UInt4>(Nucleus::createURem(lhs.value, rhs.value));
6191 	}
6192 
operator &(RValue<UInt4> lhs,RValue<UInt4> rhs)6193 	RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs)
6194 	{
6195 		return RValue<UInt4>(Nucleus::createAnd(lhs.value, rhs.value));
6196 	}
6197 
operator |(RValue<UInt4> lhs,RValue<UInt4> rhs)6198 	RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs)
6199 	{
6200 		return RValue<UInt4>(Nucleus::createOr(lhs.value, rhs.value));
6201 	}
6202 
operator ^(RValue<UInt4> lhs,RValue<UInt4> rhs)6203 	RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs)
6204 	{
6205 		return RValue<UInt4>(Nucleus::createXor(lhs.value, rhs.value));
6206 	}
6207 
Extract(RValue<UInt4> x,int i)6208 	RValue<UInt> Extract(RValue<UInt4> x, int i)
6209 	{
6210 		return RValue<UInt>(Nucleus::createExtractElement(x.value, UInt::getType(), i));
6211 	}
6212 
Insert(RValue<UInt4> x,RValue<UInt> element,int i)6213 	RValue<UInt4> Insert(RValue<UInt4> x, RValue<UInt> element, int i)
6214 	{
6215 		return RValue<UInt4>(Nucleus::createInsertElement(x.value, element.value, i));
6216 	}
6217 
operator <<(RValue<UInt4> lhs,unsigned char rhs)6218 	RValue<UInt4> operator<<(RValue<UInt4> lhs, unsigned char rhs)
6219 	{
6220 		if(emulateIntrinsics)
6221 		{
6222 			UInt4 result;
6223 			result = Insert(result, Extract(lhs, 0) << UInt(rhs), 0);
6224 			result = Insert(result, Extract(lhs, 1) << UInt(rhs), 1);
6225 			result = Insert(result, Extract(lhs, 2) << UInt(rhs), 2);
6226 			result = Insert(result, Extract(lhs, 3) << UInt(rhs), 3);
6227 
6228 			return result;
6229 		}
6230 		else
6231 		{
6232 			return RValue<UInt4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
6233 		}
6234 	}
6235 
operator >>(RValue<UInt4> lhs,unsigned char rhs)6236 	RValue<UInt4> operator>>(RValue<UInt4> lhs, unsigned char rhs)
6237 	{
6238 		if(emulateIntrinsics)
6239 		{
6240 			UInt4 result;
6241 			result = Insert(result, Extract(lhs, 0) >> UInt(rhs), 0);
6242 			result = Insert(result, Extract(lhs, 1) >> UInt(rhs), 1);
6243 			result = Insert(result, Extract(lhs, 2) >> UInt(rhs), 2);
6244 			result = Insert(result, Extract(lhs, 3) >> UInt(rhs), 3);
6245 
6246 			return result;
6247 		}
6248 		else
6249 		{
6250 			return RValue<UInt4>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
6251 		}
6252 	}
6253 
operator <<(RValue<UInt4> lhs,RValue<UInt4> rhs)6254 	RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs)
6255 	{
6256 		return RValue<UInt4>(Nucleus::createShl(lhs.value, rhs.value));
6257 	}
6258 
operator >>(RValue<UInt4> lhs,RValue<UInt4> rhs)6259 	RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs)
6260 	{
6261 		return RValue<UInt4>(Nucleus::createLShr(lhs.value, rhs.value));
6262 	}
6263 
operator +=(UInt4 & lhs,RValue<UInt4> rhs)6264 	RValue<UInt4> operator+=(UInt4 &lhs, RValue<UInt4> rhs)
6265 	{
6266 		return lhs = lhs + rhs;
6267 	}
6268 
operator -=(UInt4 & lhs,RValue<UInt4> rhs)6269 	RValue<UInt4> operator-=(UInt4 &lhs, RValue<UInt4> rhs)
6270 	{
6271 		return lhs = lhs - rhs;
6272 	}
6273 
operator *=(UInt4 & lhs,RValue<UInt4> rhs)6274 	RValue<UInt4> operator*=(UInt4 &lhs, RValue<UInt4> rhs)
6275 	{
6276 		return lhs = lhs * rhs;
6277 	}
6278 
6279 //	RValue<UInt4> operator/=(UInt4 &lhs, RValue<UInt4> rhs)
6280 //	{
6281 //		return lhs = lhs / rhs;
6282 //	}
6283 
6284 //	RValue<UInt4> operator%=(UInt4 &lhs, RValue<UInt4> rhs)
6285 //	{
6286 //		return lhs = lhs % rhs;
6287 //	}
6288 
operator &=(UInt4 & lhs,RValue<UInt4> rhs)6289 	RValue<UInt4> operator&=(UInt4 &lhs, RValue<UInt4> rhs)
6290 	{
6291 		return lhs = lhs & rhs;
6292 	}
6293 
operator |=(UInt4 & lhs,RValue<UInt4> rhs)6294 	RValue<UInt4> operator|=(UInt4 &lhs, RValue<UInt4> rhs)
6295 	{
6296 		return lhs = lhs | rhs;
6297 	}
6298 
operator ^=(UInt4 & lhs,RValue<UInt4> rhs)6299 	RValue<UInt4> operator^=(UInt4 &lhs, RValue<UInt4> rhs)
6300 	{
6301 		return lhs = lhs ^ rhs;
6302 	}
6303 
operator <<=(UInt4 & lhs,unsigned char rhs)6304 	RValue<UInt4> operator<<=(UInt4 &lhs, unsigned char rhs)
6305 	{
6306 		return lhs = lhs << rhs;
6307 	}
6308 
operator >>=(UInt4 & lhs,unsigned char rhs)6309 	RValue<UInt4> operator>>=(UInt4 &lhs, unsigned char rhs)
6310 	{
6311 		return lhs = lhs >> rhs;
6312 	}
6313 
operator +(RValue<UInt4> val)6314 	RValue<UInt4> operator+(RValue<UInt4> val)
6315 	{
6316 		return val;
6317 	}
6318 
operator -(RValue<UInt4> val)6319 	RValue<UInt4> operator-(RValue<UInt4> val)
6320 	{
6321 		return RValue<UInt4>(Nucleus::createNeg(val.value));
6322 	}
6323 
operator ~(RValue<UInt4> val)6324 	RValue<UInt4> operator~(RValue<UInt4> val)
6325 	{
6326 		return RValue<UInt4>(Nucleus::createNot(val.value));
6327 	}
6328 
CmpEQ(RValue<UInt4> x,RValue<UInt4> y)6329 	RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y)
6330 	{
6331 		return RValue<UInt4>(Nucleus::createICmpEQ(x.value, y.value));
6332 	}
6333 
CmpLT(RValue<UInt4> x,RValue<UInt4> y)6334 	RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y)
6335 	{
6336 		return RValue<UInt4>(Nucleus::createICmpULT(x.value, y.value));
6337 	}
6338 
CmpLE(RValue<UInt4> x,RValue<UInt4> y)6339 	RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y)
6340 	{
6341 		return RValue<UInt4>(Nucleus::createICmpULE(x.value, y.value));
6342 	}
6343 
CmpNEQ(RValue<UInt4> x,RValue<UInt4> y)6344 	RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y)
6345 	{
6346 		return RValue<UInt4>(Nucleus::createICmpNE(x.value, y.value));
6347 	}
6348 
CmpNLT(RValue<UInt4> x,RValue<UInt4> y)6349 	RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y)
6350 	{
6351 		return RValue<UInt4>(Nucleus::createICmpUGE(x.value, y.value));
6352 	}
6353 
CmpNLE(RValue<UInt4> x,RValue<UInt4> y)6354 	RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y)
6355 	{
6356 		return RValue<UInt4>(Nucleus::createICmpUGT(x.value, y.value));
6357 	}
6358 
Max(RValue<UInt4> x,RValue<UInt4> y)6359 	RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y)
6360 	{
6361 		Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
6362 		auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ule, condition, x.value, y.value);
6363 		::basicBlock->appendInst(cmp);
6364 
6365 		Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
6366 		auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
6367 		::basicBlock->appendInst(select);
6368 
6369 		return RValue<UInt4>(V(result));
6370 	}
6371 
Min(RValue<UInt4> x,RValue<UInt4> y)6372 	RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y)
6373 	{
6374 		Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
6375 		auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ugt, condition, x.value, y.value);
6376 		::basicBlock->appendInst(cmp);
6377 
6378 		Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
6379 		auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
6380 		::basicBlock->appendInst(select);
6381 
6382 		return RValue<UInt4>(V(result));
6383 	}
6384 
getType()6385 	Type *UInt4::getType()
6386 	{
6387 		return T(Ice::IceType_v4i32);
6388 	}
6389 
Half(RValue<Float> cast)6390 	Half::Half(RValue<Float> cast)
6391 	{
6392 		UInt fp32i = As<UInt>(cast);
6393 		UInt abs = fp32i & 0x7FFFFFFF;
6394 		UShort fp16i((fp32i & 0x80000000) >> 16); // sign
6395 
6396 		If(abs > 0x47FFEFFF) // Infinity
6397 		{
6398 			fp16i |= UShort(0x7FFF);
6399 		}
6400 		Else
6401 		{
6402 			If(abs < 0x38800000) // Denormal
6403 			{
6404 				Int mantissa = (abs & 0x007FFFFF) | 0x00800000;
6405 				Int e = 113 - (abs >> 23);
6406 				abs = IfThenElse(e < 24, mantissa >> e, Int(0));
6407 				fp16i |= UShort((abs + 0x00000FFF + ((abs >> 13) & 1)) >> 13);
6408 			}
6409 			Else
6410 			{
6411 				fp16i |= UShort((abs + 0xC8000000 + 0x00000FFF + ((abs >> 13) & 1)) >> 13);
6412 			}
6413 		}
6414 
6415 		storeValue(fp16i.loadValue());
6416 	}
6417 
getType()6418 	Type *Half::getType()
6419 	{
6420 		return T(Ice::IceType_i16);
6421 	}
6422 
Float(RValue<Int> cast)6423 	Float::Float(RValue<Int> cast)
6424 	{
6425 		Value *integer = Nucleus::createSIToFP(cast.value, Float::getType());
6426 
6427 		storeValue(integer);
6428 	}
6429 
Float(RValue<UInt> cast)6430 	Float::Float(RValue<UInt> cast)
6431 	{
6432 		RValue<Float> result = Float(Int(cast & UInt(0x7FFFFFFF))) +
6433 		                       As<Float>((As<Int>(cast) >> 31) & As<Int>(Float(0x80000000u)));
6434 
6435 		storeValue(result.value);
6436 	}
6437 
Float(RValue<Half> cast)6438 	Float::Float(RValue<Half> cast)
6439 	{
6440 		Int fp16i(As<UShort>(cast));
6441 
6442 		Int s = (fp16i >> 15) & 0x00000001;
6443 		Int e = (fp16i >> 10) & 0x0000001F;
6444 		Int m = fp16i & 0x000003FF;
6445 
6446 		UInt fp32i(s << 31);
6447 		If(e == 0)
6448 		{
6449 			If(m != 0)
6450 			{
6451 				While((m & 0x00000400) == 0)
6452 				{
6453 					m <<= 1;
6454 					e -= 1;
6455 				}
6456 
6457 				fp32i |= As<UInt>(((e + (127 - 15) + 1) << 23) | ((m & ~0x00000400) << 13));
6458 			}
6459 		}
6460 		Else
6461 		{
6462 			fp32i |= As<UInt>(((e + (127 - 15)) << 23) | (m << 13));
6463 		}
6464 
6465 		storeValue(As<Float>(fp32i).value);
6466 	}
6467 
Float(float x)6468 	Float::Float(float x)
6469 	{
6470 		storeValue(Nucleus::createConstantFloat(x));
6471 	}
6472 
Float(RValue<Float> rhs)6473 	Float::Float(RValue<Float> rhs)
6474 	{
6475 		storeValue(rhs.value);
6476 	}
6477 
Float(const Float & rhs)6478 	Float::Float(const Float &rhs)
6479 	{
6480 		Value *value = rhs.loadValue();
6481 		storeValue(value);
6482 	}
6483 
Float(const Reference<Float> & rhs)6484 	Float::Float(const Reference<Float> &rhs)
6485 	{
6486 		Value *value = rhs.loadValue();
6487 		storeValue(value);
6488 	}
6489 
operator =(RValue<Float> rhs)6490 	RValue<Float> Float::operator=(RValue<Float> rhs)
6491 	{
6492 		storeValue(rhs.value);
6493 
6494 		return rhs;
6495 	}
6496 
operator =(const Float & rhs)6497 	RValue<Float> Float::operator=(const Float &rhs)
6498 	{
6499 		Value *value = rhs.loadValue();
6500 		storeValue(value);
6501 
6502 		return RValue<Float>(value);
6503 	}
6504 
operator =(const Reference<Float> & rhs)6505 	RValue<Float> Float::operator=(const Reference<Float> &rhs)
6506 	{
6507 		Value *value = rhs.loadValue();
6508 		storeValue(value);
6509 
6510 		return RValue<Float>(value);
6511 	}
6512 
operator +(RValue<Float> lhs,RValue<Float> rhs)6513 	RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs)
6514 	{
6515 		return RValue<Float>(Nucleus::createFAdd(lhs.value, rhs.value));
6516 	}
6517 
operator -(RValue<Float> lhs,RValue<Float> rhs)6518 	RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs)
6519 	{
6520 		return RValue<Float>(Nucleus::createFSub(lhs.value, rhs.value));
6521 	}
6522 
operator *(RValue<Float> lhs,RValue<Float> rhs)6523 	RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs)
6524 	{
6525 		return RValue<Float>(Nucleus::createFMul(lhs.value, rhs.value));
6526 	}
6527 
operator /(RValue<Float> lhs,RValue<Float> rhs)6528 	RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs)
6529 	{
6530 		return RValue<Float>(Nucleus::createFDiv(lhs.value, rhs.value));
6531 	}
6532 
operator +=(Float & lhs,RValue<Float> rhs)6533 	RValue<Float> operator+=(Float &lhs, RValue<Float> rhs)
6534 	{
6535 		return lhs = lhs + rhs;
6536 	}
6537 
operator -=(Float & lhs,RValue<Float> rhs)6538 	RValue<Float> operator-=(Float &lhs, RValue<Float> rhs)
6539 	{
6540 		return lhs = lhs - rhs;
6541 	}
6542 
operator *=(Float & lhs,RValue<Float> rhs)6543 	RValue<Float> operator*=(Float &lhs, RValue<Float> rhs)
6544 	{
6545 		return lhs = lhs * rhs;
6546 	}
6547 
operator /=(Float & lhs,RValue<Float> rhs)6548 	RValue<Float> operator/=(Float &lhs, RValue<Float> rhs)
6549 	{
6550 		return lhs = lhs / rhs;
6551 	}
6552 
operator +(RValue<Float> val)6553 	RValue<Float> operator+(RValue<Float> val)
6554 	{
6555 		return val;
6556 	}
6557 
operator -(RValue<Float> val)6558 	RValue<Float> operator-(RValue<Float> val)
6559 	{
6560 		return RValue<Float>(Nucleus::createFNeg(val.value));
6561 	}
6562 
operator <(RValue<Float> lhs,RValue<Float> rhs)6563 	RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs)
6564 	{
6565 		return RValue<Bool>(Nucleus::createFCmpOLT(lhs.value, rhs.value));
6566 	}
6567 
operator <=(RValue<Float> lhs,RValue<Float> rhs)6568 	RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs)
6569 	{
6570 		return RValue<Bool>(Nucleus::createFCmpOLE(lhs.value, rhs.value));
6571 	}
6572 
operator >(RValue<Float> lhs,RValue<Float> rhs)6573 	RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs)
6574 	{
6575 		return RValue<Bool>(Nucleus::createFCmpOGT(lhs.value, rhs.value));
6576 	}
6577 
operator >=(RValue<Float> lhs,RValue<Float> rhs)6578 	RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs)
6579 	{
6580 		return RValue<Bool>(Nucleus::createFCmpOGE(lhs.value, rhs.value));
6581 	}
6582 
operator !=(RValue<Float> lhs,RValue<Float> rhs)6583 	RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs)
6584 	{
6585 		return RValue<Bool>(Nucleus::createFCmpONE(lhs.value, rhs.value));
6586 	}
6587 
operator ==(RValue<Float> lhs,RValue<Float> rhs)6588 	RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs)
6589 	{
6590 		return RValue<Bool>(Nucleus::createFCmpOEQ(lhs.value, rhs.value));
6591 	}
6592 
Abs(RValue<Float> x)6593 	RValue<Float> Abs(RValue<Float> x)
6594 	{
6595 		return IfThenElse(x > 0.0f, x, -x);
6596 	}
6597 
Max(RValue<Float> x,RValue<Float> y)6598 	RValue<Float> Max(RValue<Float> x, RValue<Float> y)
6599 	{
6600 		return IfThenElse(x > y, x, y);
6601 	}
6602 
Min(RValue<Float> x,RValue<Float> y)6603 	RValue<Float> Min(RValue<Float> x, RValue<Float> y)
6604 	{
6605 		return IfThenElse(x < y, x, y);
6606 	}
6607 
Rcp_pp(RValue<Float> x,bool exactAtPow2)6608 	RValue<Float> Rcp_pp(RValue<Float> x, bool exactAtPow2)
6609 	{
6610 		return 1.0f / x;
6611 	}
6612 
RcpSqrt_pp(RValue<Float> x)6613 	RValue<Float> RcpSqrt_pp(RValue<Float> x)
6614 	{
6615 		return Rcp_pp(Sqrt(x));
6616 	}
6617 
Sqrt(RValue<Float> x)6618 	RValue<Float> Sqrt(RValue<Float> x)
6619 	{
6620 		Ice::Variable *result = ::function->makeVariable(Ice::IceType_f32);
6621 		const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Sqrt, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6622 		auto target = ::context->getConstantUndef(Ice::IceType_i32);
6623 		auto sqrt = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
6624 		sqrt->addArg(x.value);
6625 		::basicBlock->appendInst(sqrt);
6626 
6627 		return RValue<Float>(V(result));
6628 	}
6629 
Round(RValue<Float> x)6630 	RValue<Float> Round(RValue<Float> x)
6631 	{
6632 		return Float4(Round(Float4(x))).x;
6633 	}
6634 
Trunc(RValue<Float> x)6635 	RValue<Float> Trunc(RValue<Float> x)
6636 	{
6637 		return Float4(Trunc(Float4(x))).x;
6638 	}
6639 
Frac(RValue<Float> x)6640 	RValue<Float> Frac(RValue<Float> x)
6641 	{
6642 		return Float4(Frac(Float4(x))).x;
6643 	}
6644 
Floor(RValue<Float> x)6645 	RValue<Float> Floor(RValue<Float> x)
6646 	{
6647 		return Float4(Floor(Float4(x))).x;
6648 	}
6649 
Ceil(RValue<Float> x)6650 	RValue<Float> Ceil(RValue<Float> x)
6651 	{
6652 		return Float4(Ceil(Float4(x))).x;
6653 	}
6654 
getType()6655 	Type *Float::getType()
6656 	{
6657 		return T(Ice::IceType_f32);
6658 	}
6659 
Float2(RValue<Float4> cast)6660 	Float2::Float2(RValue<Float4> cast)
6661 	{
6662 		storeValue(Nucleus::createBitCast(cast.value, getType()));
6663 	}
6664 
getType()6665 	Type *Float2::getType()
6666 	{
6667 		return T(Type_v2f32);
6668 	}
6669 
Float4(RValue<Byte4> cast)6670 	Float4::Float4(RValue<Byte4> cast) : XYZW(this)
6671 	{
6672 		Value *a = Int4(cast).loadValue();
6673 		Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
6674 
6675 		storeValue(xyzw);
6676 	}
6677 
Float4(RValue<SByte4> cast)6678 	Float4::Float4(RValue<SByte4> cast) : XYZW(this)
6679 	{
6680 		Value *a = Int4(cast).loadValue();
6681 		Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
6682 
6683 		storeValue(xyzw);
6684 	}
6685 
Float4(RValue<Short4> cast)6686 	Float4::Float4(RValue<Short4> cast) : XYZW(this)
6687 	{
6688 		Int4 c(cast);
6689 		storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
6690 	}
6691 
Float4(RValue<UShort4> cast)6692 	Float4::Float4(RValue<UShort4> cast) : XYZW(this)
6693 	{
6694 		Int4 c(cast);
6695 		storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
6696 	}
6697 
Float4(RValue<Int4> cast)6698 	Float4::Float4(RValue<Int4> cast) : XYZW(this)
6699 	{
6700 		Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType());
6701 
6702 		storeValue(xyzw);
6703 	}
6704 
Float4(RValue<UInt4> cast)6705 	Float4::Float4(RValue<UInt4> cast) : XYZW(this)
6706 	{
6707 		RValue<Float4> result = Float4(Int4(cast & UInt4(0x7FFFFFFF))) +
6708 		                        As<Float4>((As<Int4>(cast) >> 31) & As<Int4>(Float4(0x80000000u)));
6709 
6710 		storeValue(result.value);
6711 	}
6712 
Float4()6713 	Float4::Float4() : XYZW(this)
6714 	{
6715 	}
6716 
Float4(float xyzw)6717 	Float4::Float4(float xyzw) : XYZW(this)
6718 	{
6719 		constant(xyzw, xyzw, xyzw, xyzw);
6720 	}
6721 
Float4(float x,float yzw)6722 	Float4::Float4(float x, float yzw) : XYZW(this)
6723 	{
6724 		constant(x, yzw, yzw, yzw);
6725 	}
6726 
Float4(float x,float y,float zw)6727 	Float4::Float4(float x, float y, float zw) : XYZW(this)
6728 	{
6729 		constant(x, y, zw, zw);
6730 	}
6731 
Float4(float x,float y,float z,float w)6732 	Float4::Float4(float x, float y, float z, float w) : XYZW(this)
6733 	{
6734 		constant(x, y, z, w);
6735 	}
6736 
constant(float x,float y,float z,float w)6737 	void Float4::constant(float x, float y, float z, float w)
6738 	{
6739 		double constantVector[4] = {x, y, z, w};
6740 		storeValue(Nucleus::createConstantVector(constantVector, getType()));
6741 	}
6742 
Float4(RValue<Float4> rhs)6743 	Float4::Float4(RValue<Float4> rhs) : XYZW(this)
6744 	{
6745 		storeValue(rhs.value);
6746 	}
6747 
Float4(const Float4 & rhs)6748 	Float4::Float4(const Float4 &rhs) : XYZW(this)
6749 	{
6750 		Value *value = rhs.loadValue();
6751 		storeValue(value);
6752 	}
6753 
Float4(const Reference<Float4> & rhs)6754 	Float4::Float4(const Reference<Float4> &rhs) : XYZW(this)
6755 	{
6756 		Value *value = rhs.loadValue();
6757 		storeValue(value);
6758 	}
6759 
Float4(RValue<Float> rhs)6760 	Float4::Float4(RValue<Float> rhs) : XYZW(this)
6761 	{
6762 		Value *vector = Nucleus::createBitCast(rhs.value, Float4::getType());
6763 
6764 		int swizzle[4] = {0, 0, 0, 0};
6765 		Value *replicate = Nucleus::createShuffleVector(vector, vector, swizzle);
6766 
6767 		storeValue(replicate);
6768 	}
6769 
Float4(const Float & rhs)6770 	Float4::Float4(const Float &rhs) : XYZW(this)
6771 	{
6772 		*this = RValue<Float>(rhs.loadValue());
6773 	}
6774 
Float4(const Reference<Float> & rhs)6775 	Float4::Float4(const Reference<Float> &rhs) : XYZW(this)
6776 	{
6777 		*this = RValue<Float>(rhs.loadValue());
6778 	}
6779 
operator =(float x)6780 	RValue<Float4> Float4::operator=(float x)
6781 	{
6782 		return *this = Float4(x, x, x, x);
6783 	}
6784 
operator =(RValue<Float4> rhs)6785 	RValue<Float4> Float4::operator=(RValue<Float4> rhs)
6786 	{
6787 		storeValue(rhs.value);
6788 
6789 		return rhs;
6790 	}
6791 
operator =(const Float4 & rhs)6792 	RValue<Float4> Float4::operator=(const Float4 &rhs)
6793 	{
6794 		Value *value = rhs.loadValue();
6795 		storeValue(value);
6796 
6797 		return RValue<Float4>(value);
6798 	}
6799 
operator =(const Reference<Float4> & rhs)6800 	RValue<Float4> Float4::operator=(const Reference<Float4> &rhs)
6801 	{
6802 		Value *value = rhs.loadValue();
6803 		storeValue(value);
6804 
6805 		return RValue<Float4>(value);
6806 	}
6807 
operator =(RValue<Float> rhs)6808 	RValue<Float4> Float4::operator=(RValue<Float> rhs)
6809 	{
6810 		return *this = Float4(rhs);
6811 	}
6812 
operator =(const Float & rhs)6813 	RValue<Float4> Float4::operator=(const Float &rhs)
6814 	{
6815 		return *this = Float4(rhs);
6816 	}
6817 
operator =(const Reference<Float> & rhs)6818 	RValue<Float4> Float4::operator=(const Reference<Float> &rhs)
6819 	{
6820 		return *this = Float4(rhs);
6821 	}
6822 
operator +(RValue<Float4> lhs,RValue<Float4> rhs)6823 	RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs)
6824 	{
6825 		return RValue<Float4>(Nucleus::createFAdd(lhs.value, rhs.value));
6826 	}
6827 
operator -(RValue<Float4> lhs,RValue<Float4> rhs)6828 	RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs)
6829 	{
6830 		return RValue<Float4>(Nucleus::createFSub(lhs.value, rhs.value));
6831 	}
6832 
operator *(RValue<Float4> lhs,RValue<Float4> rhs)6833 	RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs)
6834 	{
6835 		return RValue<Float4>(Nucleus::createFMul(lhs.value, rhs.value));
6836 	}
6837 
operator /(RValue<Float4> lhs,RValue<Float4> rhs)6838 	RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs)
6839 	{
6840 		return RValue<Float4>(Nucleus::createFDiv(lhs.value, rhs.value));
6841 	}
6842 
operator %(RValue<Float4> lhs,RValue<Float4> rhs)6843 	RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs)
6844 	{
6845 		return RValue<Float4>(Nucleus::createFRem(lhs.value, rhs.value));
6846 	}
6847 
operator +=(Float4 & lhs,RValue<Float4> rhs)6848 	RValue<Float4> operator+=(Float4 &lhs, RValue<Float4> rhs)
6849 	{
6850 		return lhs = lhs + rhs;
6851 	}
6852 
operator -=(Float4 & lhs,RValue<Float4> rhs)6853 	RValue<Float4> operator-=(Float4 &lhs, RValue<Float4> rhs)
6854 	{
6855 		return lhs = lhs - rhs;
6856 	}
6857 
operator *=(Float4 & lhs,RValue<Float4> rhs)6858 	RValue<Float4> operator*=(Float4 &lhs, RValue<Float4> rhs)
6859 	{
6860 		return lhs = lhs * rhs;
6861 	}
6862 
operator /=(Float4 & lhs,RValue<Float4> rhs)6863 	RValue<Float4> operator/=(Float4 &lhs, RValue<Float4> rhs)
6864 	{
6865 		return lhs = lhs / rhs;
6866 	}
6867 
operator %=(Float4 & lhs,RValue<Float4> rhs)6868 	RValue<Float4> operator%=(Float4 &lhs, RValue<Float4> rhs)
6869 	{
6870 		return lhs = lhs % rhs;
6871 	}
6872 
operator +(RValue<Float4> val)6873 	RValue<Float4> operator+(RValue<Float4> val)
6874 	{
6875 		return val;
6876 	}
6877 
operator -(RValue<Float4> val)6878 	RValue<Float4> operator-(RValue<Float4> val)
6879 	{
6880 		return RValue<Float4>(Nucleus::createFNeg(val.value));
6881 	}
6882 
Abs(RValue<Float4> x)6883 	RValue<Float4> Abs(RValue<Float4> x)
6884 	{
6885 		Value *vector = Nucleus::createBitCast(x.value, Int4::getType());
6886 		int64_t constantVector[4] = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF};
6887 		Value *result = Nucleus::createAnd(vector, V(Nucleus::createConstantVector(constantVector, Int4::getType())));
6888 
6889 		return As<Float4>(result);
6890 	}
6891 
Max(RValue<Float4> x,RValue<Float4> y)6892 	RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y)
6893 	{
6894 		Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
6895 		auto cmp = Ice::InstFcmp::create(::function, Ice::InstFcmp::Ogt, condition, x.value, y.value);
6896 		::basicBlock->appendInst(cmp);
6897 
6898 		Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6899 		auto select = Ice::InstSelect::create(::function, result, condition, x.value, y.value);
6900 		::basicBlock->appendInst(select);
6901 
6902 		return RValue<Float4>(V(result));
6903 	}
6904 
Min(RValue<Float4> x,RValue<Float4> y)6905 	RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y)
6906 	{
6907 		Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
6908 		auto cmp = Ice::InstFcmp::create(::function, Ice::InstFcmp::Olt, condition, x.value, y.value);
6909 		::basicBlock->appendInst(cmp);
6910 
6911 		Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6912 		auto select = Ice::InstSelect::create(::function, result, condition, x.value, y.value);
6913 		::basicBlock->appendInst(select);
6914 
6915 		return RValue<Float4>(V(result));
6916 	}
6917 
Rcp_pp(RValue<Float4> x,bool exactAtPow2)6918 	RValue<Float4> Rcp_pp(RValue<Float4> x, bool exactAtPow2)
6919 	{
6920 		return Float4(1.0f) / x;
6921 	}
6922 
RcpSqrt_pp(RValue<Float4> x)6923 	RValue<Float4> RcpSqrt_pp(RValue<Float4> x)
6924 	{
6925 		return Rcp_pp(Sqrt(x));
6926 	}
6927 
Sqrt(RValue<Float4> x)6928 	RValue<Float4> Sqrt(RValue<Float4> x)
6929 	{
6930 		if(emulateIntrinsics || CPUID::ARM)
6931 		{
6932 			Float4 result;
6933 			result.x = Sqrt(Float(Float4(x).x));
6934 			result.y = Sqrt(Float(Float4(x).y));
6935 			result.z = Sqrt(Float(Float4(x).z));
6936 			result.w = Sqrt(Float(Float4(x).w));
6937 
6938 			return result;
6939 		}
6940 		else
6941 		{
6942 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6943 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Sqrt, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6944 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
6945 			auto sqrt = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
6946 			sqrt->addArg(x.value);
6947 			::basicBlock->appendInst(sqrt);
6948 
6949 			return RValue<Float4>(V(result));
6950 		}
6951 	}
6952 
Insert(RValue<Float4> x,RValue<Float> element,int i)6953 	RValue<Float4> Insert(RValue<Float4> x, RValue<Float> element, int i)
6954 	{
6955 		return RValue<Float4>(Nucleus::createInsertElement(x.value, element.value, i));
6956 	}
6957 
Extract(RValue<Float4> x,int i)6958 	RValue<Float> Extract(RValue<Float4> x, int i)
6959 	{
6960 		return RValue<Float>(Nucleus::createExtractElement(x.value, Float::getType(), i));
6961 	}
6962 
Swizzle(RValue<Float4> x,unsigned char select)6963 	RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select)
6964 	{
6965 		return RValue<Float4>(createSwizzle4(x.value, select));
6966 	}
6967 
ShuffleLowHigh(RValue<Float4> x,RValue<Float4> y,unsigned char imm)6968 	RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
6969 	{
6970 		int shuffle[4] =
6971 		{
6972 			((imm >> 0) & 0x03) + 0,
6973 			((imm >> 2) & 0x03) + 0,
6974 			((imm >> 4) & 0x03) + 4,
6975 			((imm >> 6) & 0x03) + 4,
6976 		};
6977 
6978 		return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
6979 	}
6980 
UnpackLow(RValue<Float4> x,RValue<Float4> y)6981 	RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y)
6982 	{
6983 		int shuffle[4] = {0, 4, 1, 5};
6984 		return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
6985 	}
6986 
UnpackHigh(RValue<Float4> x,RValue<Float4> y)6987 	RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y)
6988 	{
6989 		int shuffle[4] = {2, 6, 3, 7};
6990 		return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
6991 	}
6992 
Mask(Float4 & lhs,RValue<Float4> rhs,unsigned char select)6993 	RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select)
6994 	{
6995 		Value *vector = lhs.loadValue();
6996 		Value *result = createMask4(vector, rhs.value, select);
6997 		lhs.storeValue(result);
6998 
6999 		return RValue<Float4>(result);
7000 	}
7001 
SignMask(RValue<Float4> x)7002 	RValue<Int> SignMask(RValue<Float4> x)
7003 	{
7004 		if(emulateIntrinsics || CPUID::ARM)
7005 		{
7006 			Int4 xx = (As<Int4>(x) >> 31) & Int4(0x00000001, 0x00000002, 0x00000004, 0x00000008);
7007 			return Extract(xx, 0) | Extract(xx, 1) | Extract(xx, 2) | Extract(xx, 3);
7008 		}
7009 		else
7010 		{
7011 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
7012 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
7013 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
7014 			auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
7015 			movmsk->addArg(x.value);
7016 			::basicBlock->appendInst(movmsk);
7017 
7018 			return RValue<Int>(V(result));
7019 		}
7020 	}
7021 
CmpEQ(RValue<Float4> x,RValue<Float4> y)7022 	RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y)
7023 	{
7024 		return RValue<Int4>(Nucleus::createFCmpOEQ(x.value, y.value));
7025 	}
7026 
CmpLT(RValue<Float4> x,RValue<Float4> y)7027 	RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y)
7028 	{
7029 		return RValue<Int4>(Nucleus::createFCmpOLT(x.value, y.value));
7030 	}
7031 
CmpLE(RValue<Float4> x,RValue<Float4> y)7032 	RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y)
7033 	{
7034 		return RValue<Int4>(Nucleus::createFCmpOLE(x.value, y.value));
7035 	}
7036 
CmpNEQ(RValue<Float4> x,RValue<Float4> y)7037 	RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y)
7038 	{
7039 		return RValue<Int4>(Nucleus::createFCmpONE(x.value, y.value));
7040 	}
7041 
CmpNLT(RValue<Float4> x,RValue<Float4> y)7042 	RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y)
7043 	{
7044 		return RValue<Int4>(Nucleus::createFCmpOGE(x.value, y.value));
7045 	}
7046 
CmpNLE(RValue<Float4> x,RValue<Float4> y)7047 	RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y)
7048 	{
7049 		return RValue<Int4>(Nucleus::createFCmpOGT(x.value, y.value));
7050 	}
7051 
IsInf(RValue<Float4> x)7052 	RValue<Int4> IsInf(RValue<Float4> x)
7053 	{
7054 		return CmpEQ(As<Int4>(x) & Int4(0x7FFFFFFF), Int4(0x7F800000));
7055 	}
7056 
IsNan(RValue<Float4> x)7057 	RValue<Int4> IsNan(RValue<Float4> x)
7058 	{
7059 		return ~CmpEQ(x, x);
7060 	}
7061 
Round(RValue<Float4> x)7062 	RValue<Float4> Round(RValue<Float4> x)
7063 	{
7064 		if(emulateIntrinsics || CPUID::ARM)
7065 		{
7066 			// Push the fractional part off the mantissa. Accurate up to +/-2^22.
7067 			return (x + Float4(0x00C00000)) - Float4(0x00C00000);
7068 		}
7069 		else if(CPUID::SSE4_1)
7070 		{
7071 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
7072 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
7073 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
7074 			auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
7075 			round->addArg(x.value);
7076 			round->addArg(::context->getConstantInt32(0));
7077 			::basicBlock->appendInst(round);
7078 
7079 			return RValue<Float4>(V(result));
7080 		}
7081 		else
7082 		{
7083 			return Float4(RoundInt(x));
7084 		}
7085 	}
7086 
Trunc(RValue<Float4> x)7087 	RValue<Float4> Trunc(RValue<Float4> x)
7088 	{
7089 		if(CPUID::SSE4_1)
7090 		{
7091 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
7092 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
7093 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
7094 			auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
7095 			round->addArg(x.value);
7096 			round->addArg(::context->getConstantInt32(3));
7097 			::basicBlock->appendInst(round);
7098 
7099 			return RValue<Float4>(V(result));
7100 		}
7101 		else
7102 		{
7103 			return Float4(Int4(x));
7104 		}
7105 	}
7106 
Frac(RValue<Float4> x)7107 	RValue<Float4> Frac(RValue<Float4> x)
7108 	{
7109 		Float4 frc;
7110 
7111 		if(CPUID::SSE4_1)
7112 		{
7113 			frc = x - Floor(x);
7114 		}
7115 		else
7116 		{
7117 			frc = x - Float4(Int4(x));   // Signed fractional part.
7118 
7119 			frc += As<Float4>(As<Int4>(CmpNLE(Float4(0.0f), frc)) & As<Int4>(Float4(1, 1, 1, 1)));   // Add 1.0 if negative.
7120 		}
7121 
7122 		// x - floor(x) can be 1.0 for very small negative x.
7123 		// Clamp against the value just below 1.0.
7124 		return Min(frc, As<Float4>(Int4(0x3F7FFFFF)));
7125 	}
7126 
Floor(RValue<Float4> x)7127 	RValue<Float4> Floor(RValue<Float4> x)
7128 	{
7129 		if(CPUID::SSE4_1)
7130 		{
7131 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
7132 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
7133 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
7134 			auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
7135 			round->addArg(x.value);
7136 			round->addArg(::context->getConstantInt32(1));
7137 			::basicBlock->appendInst(round);
7138 
7139 			return RValue<Float4>(V(result));
7140 		}
7141 		else
7142 		{
7143 			return x - Frac(x);
7144 		}
7145 	}
7146 
Ceil(RValue<Float4> x)7147 	RValue<Float4> Ceil(RValue<Float4> x)
7148 	{
7149 		if(CPUID::SSE4_1)
7150 		{
7151 			Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
7152 			const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
7153 			auto target = ::context->getConstantUndef(Ice::IceType_i32);
7154 			auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
7155 			round->addArg(x.value);
7156 			round->addArg(::context->getConstantInt32(2));
7157 			::basicBlock->appendInst(round);
7158 
7159 			return RValue<Float4>(V(result));
7160 		}
7161 		else
7162 		{
7163 			return -Floor(-x);
7164 		}
7165 	}
7166 
getType()7167 	Type *Float4::getType()
7168 	{
7169 		return T(Ice::IceType_v4f32);
7170 	}
7171 
operator +(RValue<Pointer<Byte>> lhs,int offset)7172 	RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset)
7173 	{
7174 		return lhs + RValue<Int>(Nucleus::createConstantInt(offset));
7175 	}
7176 
operator +(RValue<Pointer<Byte>> lhs,RValue<Int> offset)7177 	RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
7178 	{
7179 		return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value, false));
7180 	}
7181 
operator +(RValue<Pointer<Byte>> lhs,RValue<UInt> offset)7182 	RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
7183 	{
7184 		return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value, true));
7185 	}
7186 
operator +=(Pointer<Byte> & lhs,int offset)7187 	RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, int offset)
7188 	{
7189 		return lhs = lhs + offset;
7190 	}
7191 
operator +=(Pointer<Byte> & lhs,RValue<Int> offset)7192 	RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<Int> offset)
7193 	{
7194 		return lhs = lhs + offset;
7195 	}
7196 
operator +=(Pointer<Byte> & lhs,RValue<UInt> offset)7197 	RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<UInt> offset)
7198 	{
7199 		return lhs = lhs + offset;
7200 	}
7201 
operator -(RValue<Pointer<Byte>> lhs,int offset)7202 	RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset)
7203 	{
7204 		return lhs + -offset;
7205 	}
7206 
operator -(RValue<Pointer<Byte>> lhs,RValue<Int> offset)7207 	RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
7208 	{
7209 		return lhs + -offset;
7210 	}
7211 
operator -(RValue<Pointer<Byte>> lhs,RValue<UInt> offset)7212 	RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
7213 	{
7214 		return lhs + -offset;
7215 	}
7216 
operator -=(Pointer<Byte> & lhs,int offset)7217 	RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, int offset)
7218 	{
7219 		return lhs = lhs - offset;
7220 	}
7221 
operator -=(Pointer<Byte> & lhs,RValue<Int> offset)7222 	RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<Int> offset)
7223 	{
7224 		return lhs = lhs - offset;
7225 	}
7226 
operator -=(Pointer<Byte> & lhs,RValue<UInt> offset)7227 	RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<UInt> offset)
7228 	{
7229 		return lhs = lhs - offset;
7230 	}
7231 
Return()7232 	void Return()
7233 	{
7234 		Nucleus::createRetVoid();
7235 		Nucleus::setInsertBlock(Nucleus::createBasicBlock());
7236 		Nucleus::createUnreachable();
7237 	}
7238 
Return(RValue<Int> ret)7239 	void Return(RValue<Int> ret)
7240 	{
7241 		Nucleus::createRet(ret.value);
7242 		Nucleus::setInsertBlock(Nucleus::createBasicBlock());
7243 		Nucleus::createUnreachable();
7244 	}
7245 
branch(RValue<Bool> cmp,BasicBlock * bodyBB,BasicBlock * endBB)7246 	void branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB)
7247 	{
7248 		Nucleus::createCondBr(cmp.value, bodyBB, endBB);
7249 		Nucleus::setInsertBlock(bodyBB);
7250 	}
7251 
Ticks()7252 	RValue<Long> Ticks()
7253 	{
7254 		assert(false && "UNIMPLEMENTED"); return RValue<Long>(V(nullptr));
7255 	}
7256 }
7257