OSDN Git Service

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