OSDN Git Service

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