1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
15 #include "Nucleus.hpp"
17 #include "Reactor.hpp"
18 #include "Routine.hpp"
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"
28 #include "llvm/Support/FileSystem.h"
29 #include "llvm/Support/raw_os_ostream.h"
31 #define WIN32_LEAN_AND_MEAN
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;
48 std::mutex codegenMutex;
50 sw::BasicBlock *falseBB = nullptr;
52 Ice::ELFFileStreamer *elfFile = nullptr;
53 Ice::Fdstream *out = nullptr;
61 EmulatedV2 = 2 << EmulatedShift,
62 EmulatedV4 = 4 << EmulatedShift,
63 EmulatedV8 = 8 << EmulatedShift,
64 EmulatedBits = EmulatedV2 | EmulatedV4 | EmulatedV8,
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,
74 class Value : public Ice::Variable {};
75 class BasicBlock : public Ice::CfgNode {};
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);
85 return reinterpret_cast<Type*>(t);
88 Type *T(EmulatedType t)
90 return reinterpret_cast<Type*>(t);
93 Value *V(Ice::Variable *v)
95 return reinterpret_cast<Value*>(v);
98 Value *C(Ice::Constant *c)
100 return reinterpret_cast<Value*>(c);
103 BasicBlock *B(Ice::CfgNode *b)
105 return reinterpret_cast<BasicBlock*>(b);
108 Optimization optimization[10] = {InstructionCombining, Disabled};
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;
113 inline const SectionHeader *sectionHeader(const ElfHeader *elfHeader)
115 return reinterpret_cast<const SectionHeader*>((intptr_t)elfHeader + elfHeader->e_shoff);
118 inline const SectionHeader *elfSection(const ElfHeader *elfHeader, int index)
120 return §ionHeader(elfHeader)[index];
123 static void *relocateSymbol(const ElfHeader *elfHeader, const Elf32_Rel &relocation, const SectionHeader &relocationTable)
125 const SectionHeader *target = elfSection(elfHeader, relocationTable.sh_info);
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;
133 if(index != SHN_UNDEF)
135 if(table == SHN_UNDEF) return nullptr;
136 const SectionHeader *symbolTable = elfSection(elfHeader, table);
138 uint32_t symtab_entries = symbolTable->sh_size / symbolTable->sh_entsize;
139 if(index >= symtab_entries)
141 assert(index < symtab_entries && "Symbol Index out of range");
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;
149 if(section != SHN_UNDEF && section < SHN_LORESERVE)
151 const SectionHeader *target = elfSection(elfHeader, symbol.st_shndx);
152 symbolValue = reinterpret_cast<void*>((intptr_t)elfHeader + symbol.st_value + target->sh_offset);
160 switch(relocation.getType())
166 *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite);
169 // *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite - (intptr_t)patchSite);
172 assert(false && "Unsupported relocation type");
179 static void *relocateSymbol(const ElfHeader *elfHeader, const Elf64_Rela &relocation, const SectionHeader &relocationTable)
181 const SectionHeader *target = elfSection(elfHeader, relocationTable.sh_info);
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;
189 if(index != SHN_UNDEF)
191 if(table == SHN_UNDEF) return nullptr;
192 const SectionHeader *symbolTable = elfSection(elfHeader, table);
194 uint32_t symtab_entries = symbolTable->sh_size / symbolTable->sh_entsize;
195 if(index >= symtab_entries)
197 assert(index < symtab_entries && "Symbol Index out of range");
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;
205 if(section != SHN_UNDEF && section < SHN_LORESERVE)
207 const SectionHeader *target = elfSection(elfHeader, symbol.st_shndx);
208 symbolValue = reinterpret_cast<void*>((intptr_t)elfHeader + symbol.st_value + target->sh_offset);
216 switch(relocation.getType())
222 // *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite) + relocation->r_addend;
225 *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite - (intptr_t)patchSite) + relocation.r_addend;
227 // case R_X86_64_32S:
228 // *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite) + relocation.r_addend;
231 assert(false && "Unsupported relocation type");
238 void *loadImage(uint8_t *const elfImage)
240 ElfHeader *elfHeader = (ElfHeader*)elfImage;
242 if(!elfHeader->checkMagic())
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);
251 SectionHeader *sectionHeader = (SectionHeader*)(elfImage + elfHeader->e_shoff);
252 void *entry = nullptr;
254 for(int i = 0; i < elfHeader->e_shnum; i++)
256 if(sectionHeader[i].sh_type == SHT_PROGBITS)
258 if(sectionHeader[i].sh_flags & SHF_EXECINSTR)
260 entry = elfImage + sectionHeader[i].sh_offset;
263 else if(sectionHeader[i].sh_type == SHT_REL)
265 assert(sizeof(void*) == 4 && "UNIMPLEMENTED"); // Only expected/implemented for 32-bit code
267 for(int index = 0; index < sectionHeader[i].sh_size / sectionHeader[i].sh_entsize; index++)
269 const Elf32_Rel &relocation = ((const Elf32_Rel*)(elfImage + sectionHeader[i].sh_offset))[index];
270 void *symbol = relocateSymbol(elfHeader, relocation, sectionHeader[i]);
273 else if(sectionHeader[i].sh_type == SHT_RELA)
275 assert(sizeof(void*) == 8 && "UNIMPLEMENTED"); // Only expected/implemented for 64-bit code
277 for(int index = 0; index < sectionHeader[i].sh_size / sectionHeader[i].sh_entsize; index++)
279 const Elf64_Rela &relocation = ((const Elf64_Rela*)(elfImage + sectionHeader[i].sh_offset))[index];
280 void *symbol = relocateSymbol(elfHeader, relocation, sectionHeader[i]);
289 struct ExecutableAllocator
291 ExecutableAllocator() {};
292 template<class U> ExecutableAllocator(const ExecutableAllocator<U> &other) {};
294 using value_type = T;
295 using size_type = std::size_t;
297 T *allocate(size_type n)
299 return (T*)VirtualAlloc(NULL, sizeof(T) * n, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
302 void deallocate(T *p, size_type n)
304 VirtualFree(p, 0, MEM_RELEASE);
308 class ELFMemoryStreamer : public Ice::ELFStreamer, public Routine
310 ELFMemoryStreamer(const ELFMemoryStreamer &) = delete;
311 ELFMemoryStreamer &operator=(const ELFMemoryStreamer &) = delete;
314 ELFMemoryStreamer() : Routine(), entry(nullptr)
317 buffer.reserve(0x1000);
320 virtual ~ELFMemoryStreamer()
322 if(buffer.size() != 0)
325 VirtualProtect(&buffer[0], buffer.size(), oldProtection, &exeProtection);
329 void write8(uint8_t Value) override
331 if(position == (uint64_t)buffer.size())
333 buffer.push_back(Value);
336 else if(position < (uint64_t)buffer.size())
338 buffer[position] = Value;
341 else assert(false && "UNIMPLEMENTED");
344 void writeBytes(llvm::StringRef Bytes) override
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();
352 uint64_t tell() const override { return position; }
354 void seek(uint64_t Off) override { position = Off; }
356 const void *getEntry() override
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
363 entry = loadImage(&buffer[0]);
371 std::vector<uint8_t, ExecutableAllocator<uint8_t>> buffer;
372 std::size_t position;
378 ::codegenMutex.lock(); // Reactor is currently not thread safe
380 Ice::ClFlags &Flags = Ice::ClFlags::Flags;
381 Ice::ClFlags::getParsedClFlags(Flags);
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);
390 static llvm::raw_os_ostream cout(std::cout);
391 static llvm::raw_os_ostream cerr(std::cerr);
393 if(false) // Write out to a file
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);
402 ELFMemoryStreamer *elfMemory = new ELFMemoryStreamer();
403 ::context = new Ice::GlobalContext(&cout, &cout, &cerr, elfMemory);
404 ::routine = elfMemory;
417 ::codegenMutex.unlock();
420 Routine *Nucleus::acquireRoutine(const wchar_t *name, bool runOptimizations)
422 if(basicBlock->getInsts().empty() || basicBlock->getInsts().back().getKind() != Ice::Inst::Ret)
427 std::wstring wideName(name);
428 std::string asciiName(wideName.begin(), wideName.end());
429 ::function->setFunctionName(Ice::GlobalString::createWithString(::context, asciiName));
431 ::function->translate();
432 assert(!::function->hasError());
434 auto *globals = ::function->getGlobalInits().release();
436 if(globals && !globals->empty())
438 ::context->getGlobals()->merge(globals);
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();
455 void Nucleus::optimize()
459 Value *Nucleus::allocateStackVariable(Type *t, int arraySize)
461 Ice::Type type = T(t);
462 int typeSize = Ice::typeWidthInBytes(type);
463 int totalSize = typeSize * (arraySize ? arraySize : 1);
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);
473 BasicBlock *Nucleus::createBasicBlock()
475 return B(::function->makeNode());
478 BasicBlock *Nucleus::getInsertBlock()
480 return B(::basicBlock);
483 void Nucleus::setInsertBlock(BasicBlock *basicBlock)
485 // assert(::basicBlock->getInsts().back().getTerminatorEdges().size() >= 0 && "Previous basic block must have a terminator");
486 ::basicBlock = basicBlock;
489 void Nucleus::createFunction(Type *ReturnType, std::vector<Type*> &Params)
491 uint32_t sequenceNumber = 0;
492 ::function = Ice::Cfg::create(::context, sequenceNumber).release();
493 ::allocator = new Ice::CfgLocalAllocatorScope(::function);
495 for(Type *type : Params)
497 Ice::Variable *arg = ::function->makeVariable(T(type));
498 ::function->addArg(arg);
501 Ice::CfgNode *node = ::function->makeNode();
502 ::function->setEntryNode(node);
506 Value *Nucleus::getArgument(unsigned int index)
508 return V(::function->getArgs()[index]);
511 void Nucleus::createRetVoid()
513 Ice::InstRet *ret = Ice::InstRet::create(::function);
514 ::basicBlock->appendInst(ret);
517 void Nucleus::createRet(Value *v)
519 Ice::InstRet *ret = Ice::InstRet::create(::function, v);
520 ::basicBlock->appendInst(ret);
523 void Nucleus::createBr(BasicBlock *dest)
525 auto br = Ice::InstBr::create(::function, dest);
526 ::basicBlock->appendInst(br);
529 void Nucleus::createCondBr(Value *cond, BasicBlock *ifTrue, BasicBlock *ifFalse)
531 auto br = Ice::InstBr::create(::function, cond, ifTrue, ifFalse);
532 ::basicBlock->appendInst(br);
535 static Value *createArithmetic(Ice::InstArithmetic::OpKind op, Value *lhs, Value *rhs)
537 assert(lhs->getType() == rhs->getType() || (llvm::isa<Ice::Constant>(rhs) && (op == Ice::InstArithmetic::Shl || Ice::InstArithmetic::Lshr || Ice::InstArithmetic::Ashr)));
539 Ice::Variable *result = ::function->makeVariable(lhs->getType());
540 Ice::InstArithmetic *arithmetic = Ice::InstArithmetic::create(::function, op, result, lhs, rhs);
541 ::basicBlock->appendInst(arithmetic);
546 Value *Nucleus::createAdd(Value *lhs, Value *rhs)
548 return createArithmetic(Ice::InstArithmetic::Add, lhs, rhs);
551 Value *Nucleus::createSub(Value *lhs, Value *rhs)
553 return createArithmetic(Ice::InstArithmetic::Sub, lhs, rhs);
556 Value *Nucleus::createMul(Value *lhs, Value *rhs)
558 return createArithmetic(Ice::InstArithmetic::Mul, lhs, rhs);
561 Value *Nucleus::createUDiv(Value *lhs, Value *rhs)
563 return createArithmetic(Ice::InstArithmetic::Udiv, lhs, rhs);
566 Value *Nucleus::createSDiv(Value *lhs, Value *rhs)
568 return createArithmetic(Ice::InstArithmetic::Sdiv, lhs, rhs);
571 Value *Nucleus::createFAdd(Value *lhs, Value *rhs)
573 return createArithmetic(Ice::InstArithmetic::Fadd, lhs, rhs);
576 Value *Nucleus::createFSub(Value *lhs, Value *rhs)
578 return createArithmetic(Ice::InstArithmetic::Fsub, lhs, rhs);
581 Value *Nucleus::createFMul(Value *lhs, Value *rhs)
583 return createArithmetic(Ice::InstArithmetic::Fmul, lhs, rhs);
586 Value *Nucleus::createFDiv(Value *lhs, Value *rhs)
588 return createArithmetic(Ice::InstArithmetic::Fdiv, lhs, rhs);
591 Value *Nucleus::createURem(Value *lhs, Value *rhs)
593 return createArithmetic(Ice::InstArithmetic::Urem, lhs, rhs);
596 Value *Nucleus::createSRem(Value *lhs, Value *rhs)
598 return createArithmetic(Ice::InstArithmetic::Srem, lhs, rhs);
601 Value *Nucleus::createFRem(Value *lhs, Value *rhs)
603 return createArithmetic(Ice::InstArithmetic::Frem, lhs, rhs);
606 Value *Nucleus::createShl(Value *lhs, Value *rhs)
608 return createArithmetic(Ice::InstArithmetic::Shl, lhs, rhs);
611 Value *Nucleus::createLShr(Value *lhs, Value *rhs)
613 return createArithmetic(Ice::InstArithmetic::Lshr, lhs, rhs);
616 Value *Nucleus::createAShr(Value *lhs, Value *rhs)
618 return createArithmetic(Ice::InstArithmetic::Ashr, lhs, rhs);
621 Value *Nucleus::createAnd(Value *lhs, Value *rhs)
623 return createArithmetic(Ice::InstArithmetic::And, lhs, rhs);
626 Value *Nucleus::createOr(Value *lhs, Value *rhs)
628 return createArithmetic(Ice::InstArithmetic::Or, lhs, rhs);
631 Value *Nucleus::createXor(Value *lhs, Value *rhs)
633 return createArithmetic(Ice::InstArithmetic::Xor, lhs, rhs);
636 static Value *createAssign(Ice::Constant *constant)
638 Ice::Variable *value = ::function->makeVariable(constant->getType());
639 auto assign = Ice::InstAssign::create(::function, value, constant);
640 ::basicBlock->appendInst(assign);
645 Value *Nucleus::createNeg(Value *v)
647 return createSub(createNullValue(T(v->getType())), v);
650 Value *Nucleus::createFNeg(Value *v)
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));
657 return createFSub(negativeZero, v);
660 Value *Nucleus::createNot(Value *v)
662 if(Ice::isScalarIntegerType(v->getType()))
664 return createXor(v, C(::context->getConstantInt(v->getType(), -1)));
668 int64_t c[4] = {-1, -1, -1, -1};
669 return createXor(v, createConstantVector(c, T(v->getType())));
673 Value *Nucleus::createLoad(Value *ptr, Type *type, bool isVolatile, unsigned int align)
675 int valueType = (int)reinterpret_cast<intptr_t>(type);
676 Ice::Variable *result = ::function->makeVariable(T(type));
678 if(valueType & EmulatedBits)
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));
690 ::basicBlock->appendInst(load);
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));
703 ::basicBlock->appendInst(load);
706 default: assert(false && "UNIMPLEMENTED");
711 auto load = Ice::InstLoad::create(::function, result, ptr, align);
712 ::basicBlock->appendInst(load);
718 Value *Nucleus::createStore(Value *value, Value *ptr, Type *type, bool isVolatile, unsigned int align)
720 int valueType = (int)reinterpret_cast<intptr_t>(type);
722 if(valueType & EmulatedBits)
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);
735 ::basicBlock->appendInst(store);
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);
749 ::basicBlock->appendInst(store);
752 default: assert(false && "UNIMPLEMENTED");
757 assert(T(value->getType()) == type);
759 auto store = Ice::InstStore::create(::function, value, ptr, align);
760 ::basicBlock->appendInst(store);
766 Value *Nucleus::createGEP(Value *ptr, Type *type, Value *index)
768 assert(index->getType() == Ice::IceType_i32);
770 if(!Ice::isByteSizedType(T(type)))
772 index = createMul(index, createConstantInt((int)Ice::typeWidthInBytes(T(type))));
775 if(sizeof(void*) == 8)
777 index = createSExt(index, T(Ice::IceType_i64));
780 return createAdd(ptr, index);
783 Value *Nucleus::createAtomicAdd(Value *ptr, Value *value)
785 assert(false && "UNIMPLEMENTED"); return nullptr;
788 static Value *createCast(Ice::InstCast::OpKind op, Value *v, Type *destType)
790 if(v->getType() == T(destType))
795 Ice::Variable *result = ::function->makeVariable(T(destType));
796 Ice::InstCast *cast = Ice::InstCast::create(::function, op, result, v);
797 ::basicBlock->appendInst(cast);
802 Value *Nucleus::createTrunc(Value *v, Type *destType)
804 return createCast(Ice::InstCast::Trunc, v, destType);
807 Value *Nucleus::createZExt(Value *v, Type *destType)
809 return createCast(Ice::InstCast::Zext, v, destType);
812 Value *Nucleus::createSExt(Value *v, Type *destType)
814 return createCast(Ice::InstCast::Sext, v, destType);
817 Value *Nucleus::createFPToSI(Value *v, Type *destType)
819 return createCast(Ice::InstCast::Fptosi, v, destType);
822 Value *Nucleus::createUIToFP(Value *v, Type *destType)
824 return createCast(Ice::InstCast::Uitofp, v, destType);
827 Value *Nucleus::createSIToFP(Value *v, Type *destType)
829 return createCast(Ice::InstCast::Sitofp, v, destType);
832 Value *Nucleus::createFPTrunc(Value *v, Type *destType)
834 return createCast(Ice::InstCast::Fptrunc, v, destType);
837 Value *Nucleus::createFPExt(Value *v, Type *destType)
839 return createCast(Ice::InstCast::Fpext, v, destType);
842 Value *Nucleus::createBitCast(Value *v, Type *destType)
844 return createCast(Ice::InstCast::Bitcast, v, destType);
847 static Value *createIntCompare(Ice::InstIcmp::ICond condition, Value *lhs, Value *rhs)
849 assert(lhs->getType() == rhs->getType());
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);
858 Value *Nucleus::createICmpEQ(Value *lhs, Value *rhs)
860 return createIntCompare(Ice::InstIcmp::Eq, lhs, rhs);
863 Value *Nucleus::createICmpNE(Value *lhs, Value *rhs)
865 return createIntCompare(Ice::InstIcmp::Ne, lhs, rhs);
868 Value *Nucleus::createICmpUGT(Value *lhs, Value *rhs)
870 return createIntCompare(Ice::InstIcmp::Ugt, lhs, rhs);
873 Value *Nucleus::createICmpUGE(Value *lhs, Value *rhs)
875 return createIntCompare(Ice::InstIcmp::Uge, lhs, rhs);
878 Value *Nucleus::createICmpULT(Value *lhs, Value *rhs)
880 return createIntCompare(Ice::InstIcmp::Ult, lhs, rhs);
883 Value *Nucleus::createICmpULE(Value *lhs, Value *rhs)
885 return createIntCompare(Ice::InstIcmp::Ule, lhs, rhs);
888 Value *Nucleus::createICmpSGT(Value *lhs, Value *rhs)
890 return createIntCompare(Ice::InstIcmp::Sgt, lhs, rhs);
893 Value *Nucleus::createICmpSGE(Value *lhs, Value *rhs)
895 return createIntCompare(Ice::InstIcmp::Sge, lhs, rhs);
898 Value *Nucleus::createICmpSLT(Value *lhs, Value *rhs)
900 return createIntCompare(Ice::InstIcmp::Slt, lhs, rhs);
903 Value *Nucleus::createICmpSLE(Value *lhs, Value *rhs)
905 return createIntCompare(Ice::InstIcmp::Sle, lhs, rhs);
908 static Value *createFloatCompare(Ice::InstFcmp::FCond condition, Value *lhs, Value *rhs)
910 assert(lhs->getType() == rhs->getType());
911 assert(Ice::isScalarFloatingType(lhs->getType()) || lhs->getType() == Ice::IceType_v4f32);
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);
920 Value *Nucleus::createFCmpOEQ(Value *lhs, Value *rhs)
922 return createFloatCompare(Ice::InstFcmp::Oeq, lhs, rhs);
925 Value *Nucleus::createFCmpOGT(Value *lhs, Value *rhs)
927 return createFloatCompare(Ice::InstFcmp::Ogt, lhs, rhs);
930 Value *Nucleus::createFCmpOGE(Value *lhs, Value *rhs)
932 return createFloatCompare(Ice::InstFcmp::Oge, lhs, rhs);
935 Value *Nucleus::createFCmpOLT(Value *lhs, Value *rhs)
937 return createFloatCompare(Ice::InstFcmp::Olt, lhs, rhs);
940 Value *Nucleus::createFCmpOLE(Value *lhs, Value *rhs)
942 return createFloatCompare(Ice::InstFcmp::Ole, lhs, rhs);
945 Value *Nucleus::createFCmpONE(Value *lhs, Value *rhs)
947 return createFloatCompare(Ice::InstFcmp::One, lhs, rhs);
950 Value *Nucleus::createFCmpORD(Value *lhs, Value *rhs)
952 return createFloatCompare(Ice::InstFcmp::Ord, lhs, rhs);
955 Value *Nucleus::createFCmpUNO(Value *lhs, Value *rhs)
957 return createFloatCompare(Ice::InstFcmp::Uno, lhs, rhs);
960 Value *Nucleus::createFCmpUEQ(Value *lhs, Value *rhs)
962 return createFloatCompare(Ice::InstFcmp::Ueq, lhs, rhs);
965 Value *Nucleus::createFCmpUGT(Value *lhs, Value *rhs)
967 return createFloatCompare(Ice::InstFcmp::Ugt, lhs, rhs);
970 Value *Nucleus::createFCmpUGE(Value *lhs, Value *rhs)
972 return createFloatCompare(Ice::InstFcmp::Uge, lhs, rhs);
975 Value *Nucleus::createFCmpULT(Value *lhs, Value *rhs)
977 return createFloatCompare(Ice::InstFcmp::Ult, lhs, rhs);
980 Value *Nucleus::createFCmpULE(Value *lhs, Value *rhs)
982 return createFloatCompare(Ice::InstFcmp::Ule, lhs, rhs);
985 Value *Nucleus::createFCmpUNE(Value *lhs, Value *rhs)
987 return createFloatCompare(Ice::InstFcmp::Une, lhs, rhs);
990 Value *Nucleus::createExtractElement(Value *vector, Type *type, int index)
992 auto result = ::function->makeVariable(T(type));
993 auto extract = Ice::InstExtractElement::create(::function, result, vector, ::context->getConstantInt32(index));
994 ::basicBlock->appendInst(extract);
999 Value *Nucleus::createInsertElement(Value *vector, Value *element, int index)
1001 auto result = ::function->makeVariable(vector->getType());
1002 auto insert = Ice::InstInsertElement::create(::function, result, vector, element, ::context->getConstantInt32(index));
1003 ::basicBlock->appendInst(insert);
1008 Value *Nucleus::createShuffleVector(Value *V1, Value *V2, const int *select)
1010 assert(V1->getType() == V2->getType());
1012 int size = Ice::typeNumElements(V1->getType());
1013 auto result = ::function->makeVariable(V1->getType());
1014 auto shuffle = Ice::InstShuffleVector::create(::function, result, V1, V2);
1016 for(int i = 0; i < size; i++)
1018 shuffle->addIndex(llvm::cast<Ice::ConstantInteger32>(::context->getConstantInt32(select[i])));
1021 ::basicBlock->appendInst(shuffle);
1026 Value *Nucleus::createSelect(Value *C, Value *ifTrue, Value *ifFalse)
1028 assert(ifTrue->getType() == ifFalse->getType());
1030 auto result = ::function->makeVariable(ifTrue->getType());
1031 auto *select = Ice::InstSelect::create(::function, result, C, ifTrue, ifFalse);
1032 ::basicBlock->appendInst(select);
1037 Value *Nucleus::createSwitch(Value *v, BasicBlock *Dest, unsigned NumCases)
1039 assert(false && "UNIMPLEMENTED"); return nullptr;
1042 void Nucleus::addSwitchCase(Value *Switch, int Case, BasicBlock *Branch)
1044 assert(false && "UNIMPLEMENTED"); return;
1047 void Nucleus::createUnreachable()
1049 Ice::InstUnreachable *unreachable = Ice::InstUnreachable::create(::function);
1050 ::basicBlock->appendInst(unreachable);
1053 static Value *createSwizzle4(Value *val, unsigned char select)
1057 (select >> 0) & 0x03,
1058 (select >> 2) & 0x03,
1059 (select >> 4) & 0x03,
1060 (select >> 6) & 0x03,
1063 return Nucleus::createShuffleVector(val, val, swizzle);
1066 static Value *createMask4(Value *lhs, Value *rhs, unsigned char select)
1068 assert(false && "UNIMPLEMENTED"); return nullptr;
1071 Value *Nucleus::createConstantPointer(const void *address, Type *Ty, unsigned int align)
1073 if(sizeof(void*) == 8)
1075 return createAssign(::context->getConstantInt64(reinterpret_cast<intptr_t>(address)));
1079 return createAssign(::context->getConstantInt32(reinterpret_cast<intptr_t>(address)));
1083 Type *Nucleus::getPointerType(Type *ElementType)
1085 if(sizeof(void*) == 8)
1087 return T(Ice::IceType_i64);
1091 return T(Ice::IceType_i32);
1095 Value *Nucleus::createNullValue(Type *Ty)
1097 if(Ice::isVectorType(T(Ty)))
1099 int64_t c[4] = {0, 0, 0, 0};
1100 return createConstantVector(c, Ty);
1104 return createAssign(::context->getConstantZero(T(Ty)));
1108 Value *Nucleus::createConstantLong(int64_t i)
1110 return createAssign(::context->getConstantInt64(i));
1113 Value *Nucleus::createConstantInt(int i)
1115 return createAssign(::context->getConstantInt32(i));
1118 Value *Nucleus::createConstantInt(unsigned int i)
1120 return createAssign(::context->getConstantInt32(i));
1123 Value *Nucleus::createConstantBool(bool b)
1125 return createAssign(::context->getConstantInt1(b));
1128 Value *Nucleus::createConstantByte(signed char i)
1130 return createAssign(::context->getConstantInt8(i));
1133 Value *Nucleus::createConstantByte(unsigned char i)
1135 return createAssign(::context->getConstantInt8(i));
1138 Value *Nucleus::createConstantShort(short i)
1140 return createAssign(::context->getConstantInt16(i));
1143 Value *Nucleus::createConstantShort(unsigned short i)
1145 return createAssign(::context->getConstantInt16(i));
1148 Value *Nucleus::createConstantFloat(float x)
1150 return createAssign(::context->getConstantFloat(x));
1153 Value *Nucleus::createNullPointer(Type *Ty)
1157 return createNullValue(T(sizeof(void*) == 8 ? Ice::IceType_i64 : Ice::IceType_i32));
1161 return createConstantPointer(nullptr, Ty);
1165 Value *Nucleus::createConstantVector(const int64_t *constants, Type *type)
1167 const int vectorSize = 16;
1168 assert(Ice::typeWidthInBytes(T(type)) == vectorSize);
1169 const int alignment = vectorSize;
1170 auto globalPool = ::function->getGlobalPool();
1172 const int64_t *i = constants;
1173 const double *f = reinterpret_cast<const double*>(constants);
1174 Ice::VariableDeclaration::DataInitializer *dataInitializer = nullptr;
1176 switch((int)reinterpret_cast<intptr_t>(type))
1178 case Ice::IceType_v4i32:
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);
1185 case Ice::IceType_v4f32:
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);
1192 case Ice::IceType_v8i16:
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);
1199 case Ice::IceType_v16i8:
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);
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);
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);
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);
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);
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);
1242 assert(false && "Unknown constant vector type" && type);
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);
1252 ::function->addGlobal(variableDeclaration);
1254 constexpr int32_t offset = 0;
1255 Ice::Operand *ptr = ::context->getConstantSym(offset, name);
1257 Ice::Variable *result = ::function->makeVariable(T(type));
1258 auto load = Ice::InstLoad::create(::function, result, ptr, alignment);
1259 ::basicBlock->appendInst(load);
1264 Value *Nucleus::createConstantVector(const double *constants, Type *type)
1266 return createConstantVector((const int64_t*)constants, type);
1269 Type *Void::getType()
1271 return T(Ice::IceType_void);
1274 Bool::Bool(Argument<Bool> argument)
1276 storeValue(argument.value);
1285 storeValue(Nucleus::createConstantBool(x));
1288 Bool::Bool(RValue<Bool> rhs)
1290 storeValue(rhs.value);
1293 Bool::Bool(const Bool &rhs)
1295 Value *value = rhs.loadValue();
1299 Bool::Bool(const Reference<Bool> &rhs)
1301 Value *value = rhs.loadValue();
1305 RValue<Bool> Bool::operator=(RValue<Bool> rhs) const
1307 storeValue(rhs.value);
1312 RValue<Bool> Bool::operator=(const Bool &rhs) const
1314 Value *value = rhs.loadValue();
1317 return RValue<Bool>(value);
1320 RValue<Bool> Bool::operator=(const Reference<Bool> &rhs) const
1322 Value *value = rhs.loadValue();
1325 return RValue<Bool>(value);
1328 RValue<Bool> operator!(RValue<Bool> val)
1330 return RValue<Bool>(Nucleus::createNot(val.value));
1333 RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs)
1335 return RValue<Bool>(Nucleus::createAnd(lhs.value, rhs.value));
1338 RValue<Bool> operator||(RValue<Bool> lhs, RValue<Bool> rhs)
1340 return RValue<Bool>(Nucleus::createOr(lhs.value, rhs.value));
1343 Type *Bool::getType()
1345 return T(Ice::IceType_i1);
1348 Byte::Byte(Argument<Byte> argument)
1350 storeValue(argument.value);
1353 Byte::Byte(RValue<Int> cast)
1355 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
1357 storeValue(integer);
1360 Byte::Byte(RValue<UInt> cast)
1362 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
1364 storeValue(integer);
1367 Byte::Byte(RValue<UShort> cast)
1369 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
1371 storeValue(integer);
1380 storeValue(Nucleus::createConstantByte((unsigned char)x));
1383 Byte::Byte(unsigned char x)
1385 storeValue(Nucleus::createConstantByte(x));
1388 Byte::Byte(RValue<Byte> rhs)
1390 storeValue(rhs.value);
1393 Byte::Byte(const Byte &rhs)
1395 Value *value = rhs.loadValue();
1399 Byte::Byte(const Reference<Byte> &rhs)
1401 Value *value = rhs.loadValue();
1405 RValue<Byte> Byte::operator=(RValue<Byte> rhs) const
1407 storeValue(rhs.value);
1412 RValue<Byte> Byte::operator=(const Byte &rhs) const
1414 Value *value = rhs.loadValue();
1417 return RValue<Byte>(value);
1420 RValue<Byte> Byte::operator=(const Reference<Byte> &rhs) const
1422 Value *value = rhs.loadValue();
1425 return RValue<Byte>(value);
1428 RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs)
1430 return RValue<Byte>(Nucleus::createAdd(lhs.value, rhs.value));
1433 RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs)
1435 return RValue<Byte>(Nucleus::createSub(lhs.value, rhs.value));
1438 RValue<Byte> operator*(RValue<Byte> lhs, RValue<Byte> rhs)
1440 return RValue<Byte>(Nucleus::createMul(lhs.value, rhs.value));
1443 RValue<Byte> operator/(RValue<Byte> lhs, RValue<Byte> rhs)
1445 return RValue<Byte>(Nucleus::createUDiv(lhs.value, rhs.value));
1448 RValue<Byte> operator%(RValue<Byte> lhs, RValue<Byte> rhs)
1450 return RValue<Byte>(Nucleus::createURem(lhs.value, rhs.value));
1453 RValue<Byte> operator&(RValue<Byte> lhs, RValue<Byte> rhs)
1455 return RValue<Byte>(Nucleus::createAnd(lhs.value, rhs.value));
1458 RValue<Byte> operator|(RValue<Byte> lhs, RValue<Byte> rhs)
1460 return RValue<Byte>(Nucleus::createOr(lhs.value, rhs.value));
1463 RValue<Byte> operator^(RValue<Byte> lhs, RValue<Byte> rhs)
1465 return RValue<Byte>(Nucleus::createXor(lhs.value, rhs.value));
1468 RValue<Byte> operator<<(RValue<Byte> lhs, RValue<Byte> rhs)
1470 return RValue<Byte>(Nucleus::createShl(lhs.value, rhs.value));
1473 RValue<Byte> operator>>(RValue<Byte> lhs, RValue<Byte> rhs)
1475 return RValue<Byte>(Nucleus::createLShr(lhs.value, rhs.value));
1478 RValue<Byte> operator+=(const Byte &lhs, RValue<Byte> rhs)
1480 return lhs = lhs + rhs;
1483 RValue<Byte> operator-=(const Byte &lhs, RValue<Byte> rhs)
1485 return lhs = lhs - rhs;
1488 RValue<Byte> operator*=(const Byte &lhs, RValue<Byte> rhs)
1490 return lhs = lhs * rhs;
1493 RValue<Byte> operator/=(const Byte &lhs, RValue<Byte> rhs)
1495 return lhs = lhs / rhs;
1498 RValue<Byte> operator%=(const Byte &lhs, RValue<Byte> rhs)
1500 return lhs = lhs % rhs;
1503 RValue<Byte> operator&=(const Byte &lhs, RValue<Byte> rhs)
1505 return lhs = lhs & rhs;
1508 RValue<Byte> operator|=(const Byte &lhs, RValue<Byte> rhs)
1510 return lhs = lhs | rhs;
1513 RValue<Byte> operator^=(const Byte &lhs, RValue<Byte> rhs)
1515 return lhs = lhs ^ rhs;
1518 RValue<Byte> operator<<=(const Byte &lhs, RValue<Byte> rhs)
1520 return lhs = lhs << rhs;
1523 RValue<Byte> operator>>=(const Byte &lhs, RValue<Byte> rhs)
1525 return lhs = lhs >> rhs;
1528 RValue<Byte> operator+(RValue<Byte> val)
1533 RValue<Byte> operator-(RValue<Byte> val)
1535 return RValue<Byte>(Nucleus::createNeg(val.value));
1538 RValue<Byte> operator~(RValue<Byte> val)
1540 return RValue<Byte>(Nucleus::createNot(val.value));
1543 RValue<Byte> operator++(const Byte &val, int) // Post-increment
1545 RValue<Byte> res = val;
1550 const Byte &operator++(const Byte &val) // Pre-increment
1556 RValue<Byte> operator--(const Byte &val, int) // Post-decrement
1558 RValue<Byte> res = val;
1563 const Byte &operator--(const Byte &val) // Pre-decrement
1569 RValue<Bool> operator<(RValue<Byte> lhs, RValue<Byte> rhs)
1571 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1574 RValue<Bool> operator<=(RValue<Byte> lhs, RValue<Byte> rhs)
1576 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1579 RValue<Bool> operator>(RValue<Byte> lhs, RValue<Byte> rhs)
1581 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1584 RValue<Bool> operator>=(RValue<Byte> lhs, RValue<Byte> rhs)
1586 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1589 RValue<Bool> operator!=(RValue<Byte> lhs, RValue<Byte> rhs)
1591 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1594 RValue<Bool> operator==(RValue<Byte> lhs, RValue<Byte> rhs)
1596 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1599 Type *Byte::getType()
1601 return T(Ice::IceType_i8);
1604 SByte::SByte(Argument<SByte> argument)
1606 storeValue(argument.value);
1609 SByte::SByte(RValue<Int> cast)
1611 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1613 storeValue(integer);
1616 SByte::SByte(RValue<Short> cast)
1618 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1620 storeValue(integer);
1627 SByte::SByte(signed char x)
1629 storeValue(Nucleus::createConstantByte(x));
1632 SByte::SByte(RValue<SByte> rhs)
1634 storeValue(rhs.value);
1637 SByte::SByte(const SByte &rhs)
1639 Value *value = rhs.loadValue();
1643 SByte::SByte(const Reference<SByte> &rhs)
1645 Value *value = rhs.loadValue();
1649 RValue<SByte> SByte::operator=(RValue<SByte> rhs) const
1651 storeValue(rhs.value);
1656 RValue<SByte> SByte::operator=(const SByte &rhs) const
1658 Value *value = rhs.loadValue();
1661 return RValue<SByte>(value);
1664 RValue<SByte> SByte::operator=(const Reference<SByte> &rhs) const
1666 Value *value = rhs.loadValue();
1669 return RValue<SByte>(value);
1672 RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs)
1674 return RValue<SByte>(Nucleus::createAdd(lhs.value, rhs.value));
1677 RValue<SByte> operator-(RValue<SByte> lhs, RValue<SByte> rhs)
1679 return RValue<SByte>(Nucleus::createSub(lhs.value, rhs.value));
1682 RValue<SByte> operator*(RValue<SByte> lhs, RValue<SByte> rhs)
1684 return RValue<SByte>(Nucleus::createMul(lhs.value, rhs.value));
1687 RValue<SByte> operator/(RValue<SByte> lhs, RValue<SByte> rhs)
1689 return RValue<SByte>(Nucleus::createSDiv(lhs.value, rhs.value));
1692 RValue<SByte> operator%(RValue<SByte> lhs, RValue<SByte> rhs)
1694 return RValue<SByte>(Nucleus::createSRem(lhs.value, rhs.value));
1697 RValue<SByte> operator&(RValue<SByte> lhs, RValue<SByte> rhs)
1699 return RValue<SByte>(Nucleus::createAnd(lhs.value, rhs.value));
1702 RValue<SByte> operator|(RValue<SByte> lhs, RValue<SByte> rhs)
1704 return RValue<SByte>(Nucleus::createOr(lhs.value, rhs.value));
1707 RValue<SByte> operator^(RValue<SByte> lhs, RValue<SByte> rhs)
1709 return RValue<SByte>(Nucleus::createXor(lhs.value, rhs.value));
1712 RValue<SByte> operator<<(RValue<SByte> lhs, RValue<SByte> rhs)
1714 return RValue<SByte>(Nucleus::createShl(lhs.value, rhs.value));
1717 RValue<SByte> operator>>(RValue<SByte> lhs, RValue<SByte> rhs)
1719 return RValue<SByte>(Nucleus::createAShr(lhs.value, rhs.value));
1722 RValue<SByte> operator+=(const SByte &lhs, RValue<SByte> rhs)
1724 return lhs = lhs + rhs;
1727 RValue<SByte> operator-=(const SByte &lhs, RValue<SByte> rhs)
1729 return lhs = lhs - rhs;
1732 RValue<SByte> operator*=(const SByte &lhs, RValue<SByte> rhs)
1734 return lhs = lhs * rhs;
1737 RValue<SByte> operator/=(const SByte &lhs, RValue<SByte> rhs)
1739 return lhs = lhs / rhs;
1742 RValue<SByte> operator%=(const SByte &lhs, RValue<SByte> rhs)
1744 return lhs = lhs % rhs;
1747 RValue<SByte> operator&=(const SByte &lhs, RValue<SByte> rhs)
1749 return lhs = lhs & rhs;
1752 RValue<SByte> operator|=(const SByte &lhs, RValue<SByte> rhs)
1754 return lhs = lhs | rhs;
1757 RValue<SByte> operator^=(const SByte &lhs, RValue<SByte> rhs)
1759 return lhs = lhs ^ rhs;
1762 RValue<SByte> operator<<=(const SByte &lhs, RValue<SByte> rhs)
1764 return lhs = lhs << rhs;
1767 RValue<SByte> operator>>=(const SByte &lhs, RValue<SByte> rhs)
1769 return lhs = lhs >> rhs;
1772 RValue<SByte> operator+(RValue<SByte> val)
1777 RValue<SByte> operator-(RValue<SByte> val)
1779 return RValue<SByte>(Nucleus::createNeg(val.value));
1782 RValue<SByte> operator~(RValue<SByte> val)
1784 return RValue<SByte>(Nucleus::createNot(val.value));
1787 RValue<SByte> operator++(const SByte &val, int) // Post-increment
1789 RValue<SByte> res = val;
1794 const SByte &operator++(const SByte &val) // Pre-increment
1800 RValue<SByte> operator--(const SByte &val, int) // Post-decrement
1802 RValue<SByte> res = val;
1807 const SByte &operator--(const SByte &val) // Pre-decrement
1813 RValue<Bool> operator<(RValue<SByte> lhs, RValue<SByte> rhs)
1815 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
1818 RValue<Bool> operator<=(RValue<SByte> lhs, RValue<SByte> rhs)
1820 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
1823 RValue<Bool> operator>(RValue<SByte> lhs, RValue<SByte> rhs)
1825 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
1828 RValue<Bool> operator>=(RValue<SByte> lhs, RValue<SByte> rhs)
1830 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
1833 RValue<Bool> operator!=(RValue<SByte> lhs, RValue<SByte> rhs)
1835 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1838 RValue<Bool> operator==(RValue<SByte> lhs, RValue<SByte> rhs)
1840 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1843 Type *SByte::getType()
1845 return T(Ice::IceType_i8);
1848 Short::Short(Argument<Short> argument)
1850 storeValue(argument.value);
1853 Short::Short(RValue<Int> cast)
1855 Value *integer = Nucleus::createTrunc(cast.value, Short::getType());
1857 storeValue(integer);
1864 Short::Short(short x)
1866 storeValue(Nucleus::createConstantShort(x));
1869 Short::Short(RValue<Short> rhs)
1871 storeValue(rhs.value);
1874 Short::Short(const Short &rhs)
1876 Value *value = rhs.loadValue();
1880 Short::Short(const Reference<Short> &rhs)
1882 Value *value = rhs.loadValue();
1886 RValue<Short> Short::operator=(RValue<Short> rhs) const
1888 storeValue(rhs.value);
1893 RValue<Short> Short::operator=(const Short &rhs) const
1895 Value *value = rhs.loadValue();
1898 return RValue<Short>(value);
1901 RValue<Short> Short::operator=(const Reference<Short> &rhs) const
1903 Value *value = rhs.loadValue();
1906 return RValue<Short>(value);
1909 RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs)
1911 return RValue<Short>(Nucleus::createAdd(lhs.value, rhs.value));
1914 RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs)
1916 return RValue<Short>(Nucleus::createSub(lhs.value, rhs.value));
1919 RValue<Short> operator*(RValue<Short> lhs, RValue<Short> rhs)
1921 return RValue<Short>(Nucleus::createMul(lhs.value, rhs.value));
1924 RValue<Short> operator/(RValue<Short> lhs, RValue<Short> rhs)
1926 return RValue<Short>(Nucleus::createSDiv(lhs.value, rhs.value));
1929 RValue<Short> operator%(RValue<Short> lhs, RValue<Short> rhs)
1931 return RValue<Short>(Nucleus::createSRem(lhs.value, rhs.value));
1934 RValue<Short> operator&(RValue<Short> lhs, RValue<Short> rhs)
1936 return RValue<Short>(Nucleus::createAnd(lhs.value, rhs.value));
1939 RValue<Short> operator|(RValue<Short> lhs, RValue<Short> rhs)
1941 return RValue<Short>(Nucleus::createOr(lhs.value, rhs.value));
1944 RValue<Short> operator^(RValue<Short> lhs, RValue<Short> rhs)
1946 return RValue<Short>(Nucleus::createXor(lhs.value, rhs.value));
1949 RValue<Short> operator<<(RValue<Short> lhs, RValue<Short> rhs)
1951 return RValue<Short>(Nucleus::createShl(lhs.value, rhs.value));
1954 RValue<Short> operator>>(RValue<Short> lhs, RValue<Short> rhs)
1956 return RValue<Short>(Nucleus::createAShr(lhs.value, rhs.value));
1959 RValue<Short> operator+=(const Short &lhs, RValue<Short> rhs)
1961 return lhs = lhs + rhs;
1964 RValue<Short> operator-=(const Short &lhs, RValue<Short> rhs)
1966 return lhs = lhs - rhs;
1969 RValue<Short> operator*=(const Short &lhs, RValue<Short> rhs)
1971 return lhs = lhs * rhs;
1974 RValue<Short> operator/=(const Short &lhs, RValue<Short> rhs)
1976 return lhs = lhs / rhs;
1979 RValue<Short> operator%=(const Short &lhs, RValue<Short> rhs)
1981 return lhs = lhs % rhs;
1984 RValue<Short> operator&=(const Short &lhs, RValue<Short> rhs)
1986 return lhs = lhs & rhs;
1989 RValue<Short> operator|=(const Short &lhs, RValue<Short> rhs)
1991 return lhs = lhs | rhs;
1994 RValue<Short> operator^=(const Short &lhs, RValue<Short> rhs)
1996 return lhs = lhs ^ rhs;
1999 RValue<Short> operator<<=(const Short &lhs, RValue<Short> rhs)
2001 return lhs = lhs << rhs;
2004 RValue<Short> operator>>=(const Short &lhs, RValue<Short> rhs)
2006 return lhs = lhs >> rhs;
2009 RValue<Short> operator+(RValue<Short> val)
2014 RValue<Short> operator-(RValue<Short> val)
2016 return RValue<Short>(Nucleus::createNeg(val.value));
2019 RValue<Short> operator~(RValue<Short> val)
2021 return RValue<Short>(Nucleus::createNot(val.value));
2024 RValue<Short> operator++(const Short &val, int) // Post-increment
2026 RValue<Short> res = val;
2031 const Short &operator++(const Short &val) // Pre-increment
2037 RValue<Short> operator--(const Short &val, int) // Post-decrement
2039 RValue<Short> res = val;
2044 const Short &operator--(const Short &val) // Pre-decrement
2050 RValue<Bool> operator<(RValue<Short> lhs, RValue<Short> rhs)
2052 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
2055 RValue<Bool> operator<=(RValue<Short> lhs, RValue<Short> rhs)
2057 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
2060 RValue<Bool> operator>(RValue<Short> lhs, RValue<Short> rhs)
2062 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
2065 RValue<Bool> operator>=(RValue<Short> lhs, RValue<Short> rhs)
2067 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
2070 RValue<Bool> operator!=(RValue<Short> lhs, RValue<Short> rhs)
2072 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
2075 RValue<Bool> operator==(RValue<Short> lhs, RValue<Short> rhs)
2077 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
2080 Type *Short::getType()
2082 return T(Ice::IceType_i16);
2085 UShort::UShort(Argument<UShort> argument)
2087 storeValue(argument.value);
2090 UShort::UShort(RValue<UInt> cast)
2092 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
2094 storeValue(integer);
2097 UShort::UShort(RValue<Int> cast)
2099 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
2101 storeValue(integer);
2108 UShort::UShort(unsigned short x)
2110 storeValue(Nucleus::createConstantShort(x));
2113 UShort::UShort(RValue<UShort> rhs)
2115 storeValue(rhs.value);
2118 UShort::UShort(const UShort &rhs)
2120 Value *value = rhs.loadValue();
2124 UShort::UShort(const Reference<UShort> &rhs)
2126 Value *value = rhs.loadValue();
2130 RValue<UShort> UShort::operator=(RValue<UShort> rhs) const
2132 storeValue(rhs.value);
2137 RValue<UShort> UShort::operator=(const UShort &rhs) const
2139 Value *value = rhs.loadValue();
2142 return RValue<UShort>(value);
2145 RValue<UShort> UShort::operator=(const Reference<UShort> &rhs) const
2147 Value *value = rhs.loadValue();
2150 return RValue<UShort>(value);
2153 RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs)
2155 return RValue<UShort>(Nucleus::createAdd(lhs.value, rhs.value));
2158 RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs)
2160 return RValue<UShort>(Nucleus::createSub(lhs.value, rhs.value));
2163 RValue<UShort> operator*(RValue<UShort> lhs, RValue<UShort> rhs)
2165 return RValue<UShort>(Nucleus::createMul(lhs.value, rhs.value));
2168 RValue<UShort> operator/(RValue<UShort> lhs, RValue<UShort> rhs)
2170 return RValue<UShort>(Nucleus::createUDiv(lhs.value, rhs.value));
2173 RValue<UShort> operator%(RValue<UShort> lhs, RValue<UShort> rhs)
2175 return RValue<UShort>(Nucleus::createURem(lhs.value, rhs.value));
2178 RValue<UShort> operator&(RValue<UShort> lhs, RValue<UShort> rhs)
2180 return RValue<UShort>(Nucleus::createAnd(lhs.value, rhs.value));
2183 RValue<UShort> operator|(RValue<UShort> lhs, RValue<UShort> rhs)
2185 return RValue<UShort>(Nucleus::createOr(lhs.value, rhs.value));
2188 RValue<UShort> operator^(RValue<UShort> lhs, RValue<UShort> rhs)
2190 return RValue<UShort>(Nucleus::createXor(lhs.value, rhs.value));
2193 RValue<UShort> operator<<(RValue<UShort> lhs, RValue<UShort> rhs)
2195 return RValue<UShort>(Nucleus::createShl(lhs.value, rhs.value));
2198 RValue<UShort> operator>>(RValue<UShort> lhs, RValue<UShort> rhs)
2200 return RValue<UShort>(Nucleus::createLShr(lhs.value, rhs.value));
2203 RValue<UShort> operator+=(const UShort &lhs, RValue<UShort> rhs)
2205 return lhs = lhs + rhs;
2208 RValue<UShort> operator-=(const UShort &lhs, RValue<UShort> rhs)
2210 return lhs = lhs - rhs;
2213 RValue<UShort> operator*=(const UShort &lhs, RValue<UShort> rhs)
2215 return lhs = lhs * rhs;
2218 RValue<UShort> operator/=(const UShort &lhs, RValue<UShort> rhs)
2220 return lhs = lhs / rhs;
2223 RValue<UShort> operator%=(const UShort &lhs, RValue<UShort> rhs)
2225 return lhs = lhs % rhs;
2228 RValue<UShort> operator&=(const UShort &lhs, RValue<UShort> rhs)
2230 return lhs = lhs & rhs;
2233 RValue<UShort> operator|=(const UShort &lhs, RValue<UShort> rhs)
2235 return lhs = lhs | rhs;
2238 RValue<UShort> operator^=(const UShort &lhs, RValue<UShort> rhs)
2240 return lhs = lhs ^ rhs;
2243 RValue<UShort> operator<<=(const UShort &lhs, RValue<UShort> rhs)
2245 return lhs = lhs << rhs;
2248 RValue<UShort> operator>>=(const UShort &lhs, RValue<UShort> rhs)
2250 return lhs = lhs >> rhs;
2253 RValue<UShort> operator+(RValue<UShort> val)
2258 RValue<UShort> operator-(RValue<UShort> val)
2260 return RValue<UShort>(Nucleus::createNeg(val.value));
2263 RValue<UShort> operator~(RValue<UShort> val)
2265 return RValue<UShort>(Nucleus::createNot(val.value));
2268 RValue<UShort> operator++(const UShort &val, int) // Post-increment
2270 RValue<UShort> res = val;
2275 const UShort &operator++(const UShort &val) // Pre-increment
2281 RValue<UShort> operator--(const UShort &val, int) // Post-decrement
2283 RValue<UShort> res = val;
2288 const UShort &operator--(const UShort &val) // Pre-decrement
2294 RValue<Bool> operator<(RValue<UShort> lhs, RValue<UShort> rhs)
2296 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
2299 RValue<Bool> operator<=(RValue<UShort> lhs, RValue<UShort> rhs)
2301 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
2304 RValue<Bool> operator>(RValue<UShort> lhs, RValue<UShort> rhs)
2306 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
2309 RValue<Bool> operator>=(RValue<UShort> lhs, RValue<UShort> rhs)
2311 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
2314 RValue<Bool> operator!=(RValue<UShort> lhs, RValue<UShort> rhs)
2316 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
2319 RValue<Bool> operator==(RValue<UShort> lhs, RValue<UShort> rhs)
2321 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
2324 Type *UShort::getType()
2326 return T(Ice::IceType_i16);
2329 Byte4::Byte4(RValue<Byte8> cast)
2331 // xyzw.parent = this;
2333 storeValue(Nucleus::createBitCast(cast.value, getType()));
2336 Byte4::Byte4(const Reference<Byte4> &rhs)
2338 // xyzw.parent = this;
2340 Value *value = rhs.loadValue();
2344 Type *Byte4::getType()
2346 return T(Type_v4i8);
2349 Type *SByte4::getType()
2351 return T(Type_v4i8);
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)
2360 int64_t constantVector[8] = {x0, x1, x2, x3, x4, x5, x6, x7};
2361 storeValue(Nucleus::createConstantVector(constantVector, getType()));
2364 Byte8::Byte8(RValue<Byte8> rhs)
2366 storeValue(rhs.value);
2369 Byte8::Byte8(const Byte8 &rhs)
2371 Value *value = rhs.loadValue();
2375 Byte8::Byte8(const Reference<Byte8> &rhs)
2377 Value *value = rhs.loadValue();
2381 RValue<Byte8> Byte8::operator=(RValue<Byte8> rhs) const
2383 storeValue(rhs.value);
2388 RValue<Byte8> Byte8::operator=(const Byte8 &rhs) const
2390 Value *value = rhs.loadValue();
2393 return RValue<Byte8>(value);
2396 RValue<Byte8> Byte8::operator=(const Reference<Byte8> &rhs) const
2398 Value *value = rhs.loadValue();
2401 return RValue<Byte8>(value);
2404 RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs)
2406 return RValue<Byte8>(Nucleus::createAdd(lhs.value, rhs.value));
2409 RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs)
2411 return RValue<Byte8>(Nucleus::createSub(lhs.value, rhs.value));
2414 // RValue<Byte8> operator*(RValue<Byte8> lhs, RValue<Byte8> rhs)
2416 // return RValue<Byte8>(Nucleus::createMul(lhs.value, rhs.value));
2419 // RValue<Byte8> operator/(RValue<Byte8> lhs, RValue<Byte8> rhs)
2421 // return RValue<Byte8>(Nucleus::createUDiv(lhs.value, rhs.value));
2424 // RValue<Byte8> operator%(RValue<Byte8> lhs, RValue<Byte8> rhs)
2426 // return RValue<Byte8>(Nucleus::createURem(lhs.value, rhs.value));
2429 RValue<Byte8> operator&(RValue<Byte8> lhs, RValue<Byte8> rhs)
2431 return RValue<Byte8>(Nucleus::createAnd(lhs.value, rhs.value));
2434 RValue<Byte8> operator|(RValue<Byte8> lhs, RValue<Byte8> rhs)
2436 return RValue<Byte8>(Nucleus::createOr(lhs.value, rhs.value));
2439 RValue<Byte8> operator^(RValue<Byte8> lhs, RValue<Byte8> rhs)
2441 return RValue<Byte8>(Nucleus::createXor(lhs.value, rhs.value));
2444 // RValue<Byte8> operator<<(RValue<Byte8> lhs, unsigned char rhs)
2446 // return RValue<Byte8>(Nucleus::createShl(lhs.value, C(::context->getConstantInt32(rhs))));
2449 // RValue<Byte8> operator>>(RValue<Byte8> lhs, unsigned char rhs)
2451 // return RValue<Byte8>(Nucleus::createLShr(lhs.value, C(::context->getConstantInt32(rhs))));
2454 RValue<Byte8> operator+=(const Byte8 &lhs, RValue<Byte8> rhs)
2456 return lhs = lhs + rhs;
2459 RValue<Byte8> operator-=(const Byte8 &lhs, RValue<Byte8> rhs)
2461 return lhs = lhs - rhs;
2464 // RValue<Byte8> operator*=(const Byte8 &lhs, RValue<Byte8> rhs)
2466 // return lhs = lhs * rhs;
2469 // RValue<Byte8> operator/=(const Byte8 &lhs, RValue<Byte8> rhs)
2471 // return lhs = lhs / rhs;
2474 // RValue<Byte8> operator%=(const Byte8 &lhs, RValue<Byte8> rhs)
2476 // return lhs = lhs % rhs;
2479 RValue<Byte8> operator&=(const Byte8 &lhs, RValue<Byte8> rhs)
2481 return lhs = lhs & rhs;
2484 RValue<Byte8> operator|=(const Byte8 &lhs, RValue<Byte8> rhs)
2486 return lhs = lhs | rhs;
2489 RValue<Byte8> operator^=(const Byte8 &lhs, RValue<Byte8> rhs)
2491 return lhs = lhs ^ rhs;
2494 // RValue<Byte8> operator<<=(const Byte8 &lhs, RValue<Byte8> rhs)
2496 // return lhs = lhs << rhs;
2499 // RValue<Byte8> operator>>=(const Byte8 &lhs, RValue<Byte8> rhs)
2501 // return lhs = lhs >> rhs;
2504 // RValue<Byte8> operator+(RValue<Byte8> val)
2509 // RValue<Byte8> operator-(RValue<Byte8> val)
2511 // return RValue<Byte8>(Nucleus::createNeg(val.value));
2514 RValue<Byte8> operator~(RValue<Byte8> val)
2516 return RValue<Byte8>(Nucleus::createNot(val.value));
2519 RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y)
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);
2529 return RValue<Byte8>(V(result));
2532 RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y)
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);
2542 return RValue<Byte8>(V(result));
2545 RValue<Short4> Unpack(RValue<Byte4> x)
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));
2551 RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y)
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));
2557 RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y)
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));
2564 RValue<Int> SignMask(RValue<Byte8> x)
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);
2573 return RValue<Int>(V(result));
2576 // RValue<Byte8> CmpGT(RValue<Byte8> x, RValue<Byte8> y)
2578 // return RValue<Byte8>(createIntCompare(Ice::InstIcmp::Ugt, x.value, y.value));
2581 RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y)
2583 return RValue<Byte8>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
2586 Type *Byte8::getType()
2588 return T(Type_v8i8);
2593 // xyzw.parent = this;
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)
2598 // xyzw.parent = this;
2600 int64_t constantVector[8] = { x0, x1, x2, x3, x4, x5, x6, x7 };
2601 Value *vector = V(Nucleus::createConstantVector(constantVector, getType()));
2603 storeValue(Nucleus::createBitCast(vector, getType()));
2606 SByte8::SByte8(RValue<SByte8> rhs)
2608 // xyzw.parent = this;
2610 storeValue(rhs.value);
2613 SByte8::SByte8(const SByte8 &rhs)
2615 // xyzw.parent = this;
2617 Value *value = rhs.loadValue();
2621 SByte8::SByte8(const Reference<SByte8> &rhs)
2623 // xyzw.parent = this;
2625 Value *value = rhs.loadValue();
2629 RValue<SByte8> SByte8::operator=(RValue<SByte8> rhs) const
2631 storeValue(rhs.value);
2636 RValue<SByte8> SByte8::operator=(const SByte8 &rhs) const
2638 Value *value = rhs.loadValue();
2641 return RValue<SByte8>(value);
2644 RValue<SByte8> SByte8::operator=(const Reference<SByte8> &rhs) const
2646 Value *value = rhs.loadValue();
2649 return RValue<SByte8>(value);
2652 RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs)
2654 return RValue<SByte8>(Nucleus::createAdd(lhs.value, rhs.value));
2657 RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs)
2659 return RValue<SByte8>(Nucleus::createSub(lhs.value, rhs.value));
2662 // RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs)
2664 // return RValue<SByte8>(Nucleus::createMul(lhs.value, rhs.value));
2667 // RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs)
2669 // return RValue<SByte8>(Nucleus::createSDiv(lhs.value, rhs.value));
2672 // RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs)
2674 // return RValue<SByte8>(Nucleus::createSRem(lhs.value, rhs.value));
2677 RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs)
2679 return RValue<SByte8>(Nucleus::createAnd(lhs.value, rhs.value));
2682 RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs)
2684 return RValue<SByte8>(Nucleus::createOr(lhs.value, rhs.value));
2687 RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs)
2689 return RValue<SByte8>(Nucleus::createXor(lhs.value, rhs.value));
2692 // RValue<SByte8> operator<<(RValue<SByte8> lhs, unsigned char rhs)
2694 // return RValue<SByte8>(Nucleus::createShl(lhs.value, C(::context->getConstantInt32(rhs))));
2697 // RValue<SByte8> operator>>(RValue<SByte8> lhs, unsigned char rhs)
2699 // return RValue<SByte8>(Nucleus::createAShr(lhs.value, C(::context->getConstantInt32(rhs))));
2702 RValue<SByte8> operator+=(const SByte8 &lhs, RValue<SByte8> rhs)
2704 return lhs = lhs + rhs;
2707 RValue<SByte8> operator-=(const SByte8 &lhs, RValue<SByte8> rhs)
2709 return lhs = lhs - rhs;
2712 // RValue<SByte8> operator*=(const SByte8 &lhs, RValue<SByte8> rhs)
2714 // return lhs = lhs * rhs;
2717 // RValue<SByte8> operator/=(const SByte8 &lhs, RValue<SByte8> rhs)
2719 // return lhs = lhs / rhs;
2722 // RValue<SByte8> operator%=(const SByte8 &lhs, RValue<SByte8> rhs)
2724 // return lhs = lhs % rhs;
2727 RValue<SByte8> operator&=(const SByte8 &lhs, RValue<SByte8> rhs)
2729 return lhs = lhs & rhs;
2732 RValue<SByte8> operator|=(const SByte8 &lhs, RValue<SByte8> rhs)
2734 return lhs = lhs | rhs;
2737 RValue<SByte8> operator^=(const SByte8 &lhs, RValue<SByte8> rhs)
2739 return lhs = lhs ^ rhs;
2742 // RValue<SByte8> operator<<=(const SByte8 &lhs, RValue<SByte8> rhs)
2744 // return lhs = lhs << rhs;
2747 // RValue<SByte8> operator>>=(const SByte8 &lhs, RValue<SByte8> rhs)
2749 // return lhs = lhs >> rhs;
2752 // RValue<SByte8> operator+(RValue<SByte8> val)
2757 // RValue<SByte8> operator-(RValue<SByte8> val)
2759 // return RValue<SByte8>(Nucleus::createNeg(val.value));
2762 RValue<SByte8> operator~(RValue<SByte8> val)
2764 return RValue<SByte8>(Nucleus::createNot(val.value));
2767 RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y)
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);
2777 return RValue<SByte8>(V(result));
2780 RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y)
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);
2790 return RValue<SByte8>(V(result));
2793 RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y)
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));
2799 RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y)
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));
2806 RValue<Int> SignMask(RValue<SByte8> x)
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);
2815 return RValue<Int>(V(result));
2818 RValue<Byte8> CmpGT(RValue<SByte8> x, RValue<SByte8> y)
2820 return RValue<Byte8>(createIntCompare(Ice::InstIcmp::Sgt, x.value, y.value));
2823 RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y)
2825 return RValue<Byte8>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
2828 Type *SByte8::getType()
2830 return T(Type_v8i8);
2833 Byte16::Byte16(RValue<Byte16> rhs)
2835 // xyzw.parent = this;
2837 storeValue(rhs.value);
2840 Byte16::Byte16(const Byte16 &rhs)
2842 // xyzw.parent = this;
2844 Value *value = rhs.loadValue();
2848 Byte16::Byte16(const Reference<Byte16> &rhs)
2850 // xyzw.parent = this;
2852 Value *value = rhs.loadValue();
2856 RValue<Byte16> Byte16::operator=(RValue<Byte16> rhs) const
2858 storeValue(rhs.value);
2863 RValue<Byte16> Byte16::operator=(const Byte16 &rhs) const
2865 Value *value = rhs.loadValue();
2868 return RValue<Byte16>(value);
2871 RValue<Byte16> Byte16::operator=(const Reference<Byte16> &rhs) const
2873 Value *value = rhs.loadValue();
2876 return RValue<Byte16>(value);
2879 Type *Byte16::getType()
2881 return T(Ice::IceType_v16i8);
2884 Type *SByte16::getType()
2886 return T(Ice::IceType_v16i8);
2889 Short2::Short2(RValue<Short4> cast)
2891 assert(false && "UNIMPLEMENTED");
2894 Type *Short2::getType()
2896 return T(Type_v2i16);
2899 UShort2::UShort2(RValue<UShort4> cast)
2901 assert(false && "UNIMPLEMENTED");
2904 Type *UShort2::getType()
2906 return T(Type_v2i16);
2909 Short4::Short4(RValue<Int> cast)
2911 Value *extend = Nucleus::createZExt(cast.value, Long::getType());
2912 Value *swizzle = Swizzle(RValue<Short4>(extend), 0x00).value;
2914 storeValue(swizzle);
2917 Short4::Short4(RValue<Int4> cast)
2919 assert(false && "UNIMPLEMENTED");
2922 // Short4::Short4(RValue<Float> cast)
2926 Short4::Short4(RValue<Float4> cast)
2928 assert(false && "UNIMPLEMENTED");
2933 // xyzw.parent = this;
2936 Short4::Short4(short xyzw)
2938 // xyzw.parent = this;
2940 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
2941 storeValue(Nucleus::createConstantVector(constantVector, getType()));
2944 Short4::Short4(short x, short y, short z, short w)
2946 // xyzw.parent = this;
2948 int64_t constantVector[4] = {x, y, z, w};
2949 storeValue(Nucleus::createConstantVector(constantVector, getType()));
2952 Short4::Short4(RValue<Short4> rhs)
2954 // xyzw.parent = this;
2956 storeValue(rhs.value);
2959 Short4::Short4(const Short4 &rhs)
2961 // xyzw.parent = this;
2963 Value *value = rhs.loadValue();
2967 Short4::Short4(const Reference<Short4> &rhs)
2969 // xyzw.parent = this;
2971 Value *value = rhs.loadValue();
2975 Short4::Short4(RValue<UShort4> rhs)
2977 // xyzw.parent = this;
2979 storeValue(rhs.value);
2982 Short4::Short4(const UShort4 &rhs)
2984 // xyzw.parent = this;
2986 storeValue(rhs.loadValue());
2989 Short4::Short4(const Reference<UShort4> &rhs)
2991 // xyzw.parent = this;
2993 storeValue(rhs.loadValue());
2996 RValue<Short4> Short4::operator=(RValue<Short4> rhs) const
2998 storeValue(rhs.value);
3003 RValue<Short4> Short4::operator=(const Short4 &rhs) const
3005 Value *value = rhs.loadValue();
3008 return RValue<Short4>(value);
3011 RValue<Short4> Short4::operator=(const Reference<Short4> &rhs) const
3013 Value *value = rhs.loadValue();
3016 return RValue<Short4>(value);
3019 RValue<Short4> Short4::operator=(RValue<UShort4> rhs) const
3021 storeValue(rhs.value);
3023 return RValue<Short4>(rhs);
3026 RValue<Short4> Short4::operator=(const UShort4 &rhs) const
3028 Value *value = rhs.loadValue();
3031 return RValue<Short4>(value);
3034 RValue<Short4> Short4::operator=(const Reference<UShort4> &rhs) const
3036 Value *value = rhs.loadValue();
3039 return RValue<Short4>(value);
3042 RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs)
3044 return RValue<Short4>(Nucleus::createAdd(lhs.value, rhs.value));
3047 RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs)
3049 return RValue<Short4>(Nucleus::createSub(lhs.value, rhs.value));
3052 RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs)
3054 return RValue<Short4>(Nucleus::createMul(lhs.value, rhs.value));
3057 // RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs)
3059 // return RValue<Short4>(Nucleus::createSDiv(lhs.value, rhs.value));
3062 // RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs)
3064 // return RValue<Short4>(Nucleus::createSRem(lhs.value, rhs.value));
3067 RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs)
3069 return RValue<Short4>(Nucleus::createAnd(lhs.value, rhs.value));
3072 RValue<Short4> operator|(RValue<Short4> lhs, RValue<Short4> rhs)
3074 return RValue<Short4>(Nucleus::createOr(lhs.value, rhs.value));
3077 RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs)
3079 return RValue<Short4>(Nucleus::createXor(lhs.value, rhs.value));
3082 RValue<Short4> operator<<(RValue<Short4> lhs, unsigned char rhs)
3084 return RValue<Short4>(Nucleus::createShl(lhs.value, C(::context->getConstantInt32(rhs))));
3087 RValue<Short4> operator>>(RValue<Short4> lhs, unsigned char rhs)
3089 return RValue<Short4>(Nucleus::createAShr(lhs.value, C(::context->getConstantInt32(rhs))));
3092 RValue<Short4> operator<<(RValue<Short4> lhs, RValue<Long1> rhs)
3094 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
3096 assert(false && "UNIMPLEMENTED"); return RValue<Short4>(V(nullptr));
3099 RValue<Short4> operator>>(RValue<Short4> lhs, RValue<Long1> rhs)
3101 // return RValue<Short4>(Nucleus::createAShr(lhs.value, rhs.value));
3103 assert(false && "UNIMPLEMENTED"); return RValue<Short4>(V(nullptr));
3106 RValue<Short4> operator+=(const Short4 &lhs, RValue<Short4> rhs)
3108 return lhs = lhs + rhs;
3111 RValue<Short4> operator-=(const Short4 &lhs, RValue<Short4> rhs)
3113 return lhs = lhs - rhs;
3116 RValue<Short4> operator*=(const Short4 &lhs, RValue<Short4> rhs)
3118 return lhs = lhs * rhs;
3121 // RValue<Short4> operator/=(const Short4 &lhs, RValue<Short4> rhs)
3123 // return lhs = lhs / rhs;
3126 // RValue<Short4> operator%=(const Short4 &lhs, RValue<Short4> rhs)
3128 // return lhs = lhs % rhs;
3131 RValue<Short4> operator&=(const Short4 &lhs, RValue<Short4> rhs)
3133 return lhs = lhs & rhs;
3136 RValue<Short4> operator|=(const Short4 &lhs, RValue<Short4> rhs)
3138 return lhs = lhs | rhs;
3141 RValue<Short4> operator^=(const Short4 &lhs, RValue<Short4> rhs)
3143 return lhs = lhs ^ rhs;
3146 RValue<Short4> operator<<=(const Short4 &lhs, unsigned char rhs)
3148 return lhs = lhs << rhs;
3151 RValue<Short4> operator>>=(const Short4 &lhs, unsigned char rhs)
3153 return lhs = lhs >> rhs;
3156 RValue<Short4> operator<<=(const Short4 &lhs, RValue<Long1> rhs)
3158 return lhs = lhs << rhs;
3161 RValue<Short4> operator>>=(const Short4 &lhs, RValue<Long1> rhs)
3163 return lhs = lhs >> rhs;
3166 // RValue<Short4> operator+(RValue<Short4> val)
3171 RValue<Short4> operator-(RValue<Short4> val)
3173 return RValue<Short4>(Nucleus::createNeg(val.value));
3176 RValue<Short4> operator~(RValue<Short4> val)
3178 return RValue<Short4>(Nucleus::createNot(val.value));
3181 RValue<Short4> RoundShort4(RValue<Float4> cast)
3183 assert(false && "UNIMPLEMENTED"); return RValue<Short4>(V(nullptr));
3186 RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y)
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);
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);
3196 return RValue<Short4>(V(result));
3199 RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y)
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);
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);
3209 return RValue<Short4>(V(result));
3212 RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y)
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);
3222 return RValue<Short4>(V(result));
3225 RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y)
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);
3235 return RValue<Short4>(V(result));
3238 RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y)
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);
3248 return RValue<UShort4>(V(result));
3251 RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y)
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);
3261 return RValue<Int2>(V(result));
3264 RValue<SByte8> Pack(RValue<Short4> x, RValue<Short4> y)
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);
3274 return As<SByte8>(Swizzle(As<Int4>(V(result)), 0x88));
3277 RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y)
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));
3283 RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y)
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));
3290 RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select)
3292 // Real type is v8i16
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,
3305 return RValue<Short4>(Nucleus::createShuffleVector(x.value, x.value, shuffle));
3308 RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i)
3310 return RValue<Short4>(Nucleus::createInsertElement(val.value, element.value, i));
3313 RValue<Short> Extract(RValue<Short4> val, int i)
3315 return RValue<Short>(Nucleus::createExtractElement(val.value, Int::getType(), i));
3318 RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y)
3320 return RValue<Short4>(createIntCompare(Ice::InstIcmp::Sgt, x.value, y.value));
3323 RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y)
3325 return RValue<Short4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
3328 Type *Short4::getType()
3330 return T(Type_v4i16);
3333 UShort4::UShort4(RValue<Int4> cast)
3335 *this = Short4(cast);
3338 UShort4::UShort4(RValue<Float4> cast, bool saturate)
3340 assert(false && "UNIMPLEMENTED");
3345 // xyzw.parent = this;
3348 UShort4::UShort4(unsigned short xyzw)
3350 // xyzw.parent = this;
3352 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
3353 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3356 UShort4::UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w)
3358 // xyzw.parent = this;
3360 int64_t constantVector[4] = {x, y, z, w};
3361 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3364 UShort4::UShort4(RValue<UShort4> rhs)
3366 // xyzw.parent = this;
3368 storeValue(rhs.value);
3371 UShort4::UShort4(const UShort4 &rhs)
3373 // xyzw.parent = this;
3375 Value *value = rhs.loadValue();
3379 UShort4::UShort4(const Reference<UShort4> &rhs)
3381 // xyzw.parent = this;
3383 Value *value = rhs.loadValue();
3387 UShort4::UShort4(RValue<Short4> rhs)
3389 // xyzw.parent = this;
3391 storeValue(rhs.value);
3394 UShort4::UShort4(const Short4 &rhs)
3396 // xyzw.parent = this;
3398 Value *value = rhs.loadValue();
3402 UShort4::UShort4(const Reference<Short4> &rhs)
3404 // xyzw.parent = this;
3406 Value *value = rhs.loadValue();
3410 RValue<UShort4> UShort4::operator=(RValue<UShort4> rhs) const
3412 storeValue(rhs.value);
3417 RValue<UShort4> UShort4::operator=(const UShort4 &rhs) const
3419 Value *value = rhs.loadValue();
3422 return RValue<UShort4>(value);
3425 RValue<UShort4> UShort4::operator=(const Reference<UShort4> &rhs) const
3427 Value *value = rhs.loadValue();
3430 return RValue<UShort4>(value);
3433 RValue<UShort4> UShort4::operator=(RValue<Short4> rhs) const
3435 storeValue(rhs.value);
3437 return RValue<UShort4>(rhs);
3440 RValue<UShort4> UShort4::operator=(const Short4 &rhs) const
3442 Value *value = rhs.loadValue();
3445 return RValue<UShort4>(value);
3448 RValue<UShort4> UShort4::operator=(const Reference<Short4> &rhs) const
3450 Value *value = rhs.loadValue();
3453 return RValue<UShort4>(value);
3456 RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs)
3458 return RValue<Short4>(Nucleus::createAdd(lhs.value, rhs.value));
3461 RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs)
3463 return RValue<UShort4>(Nucleus::createSub(lhs.value, rhs.value));
3466 RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs)
3468 return RValue<UShort4>(Nucleus::createMul(lhs.value, rhs.value));
3471 RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs)
3473 return RValue<UShort4>(Nucleus::createAnd(lhs.value, rhs.value));
3476 RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs)
3478 return RValue<UShort4>(Nucleus::createOr(lhs.value, rhs.value));
3481 RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs)
3483 return RValue<UShort4>(Nucleus::createXor(lhs.value, rhs.value));
3486 RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs)
3488 return RValue<UShort4>(Nucleus::createShl(lhs.value, C(::context->getConstantInt32(rhs))));
3491 RValue<UShort4> operator>>(RValue<UShort4> lhs, unsigned char rhs)
3493 return RValue<UShort4>(Nucleus::createLShr(lhs.value, C(::context->getConstantInt32(rhs))));
3496 RValue<UShort4> operator<<(RValue<UShort4> lhs, RValue<Long1> rhs)
3498 assert(false && "UNIMPLEMENTED"); return RValue<UShort4>(V(nullptr));
3501 RValue<UShort4> operator>>(RValue<UShort4> lhs, RValue<Long1> rhs)
3503 assert(false && "UNIMPLEMENTED"); return RValue<UShort4>(V(nullptr));
3506 RValue<UShort4> operator<<=(const UShort4 &lhs, unsigned char rhs)
3508 return lhs = lhs << rhs;
3511 RValue<UShort4> operator>>=(const UShort4 &lhs, unsigned char rhs)
3513 return lhs = lhs >> rhs;
3516 RValue<UShort4> operator<<=(const UShort4 &lhs, RValue<Long1> rhs)
3518 return lhs = lhs << rhs;
3521 RValue<UShort4> operator>>=(const UShort4 &lhs, RValue<Long1> rhs)
3523 return lhs = lhs >> rhs;
3526 RValue<UShort4> operator~(RValue<UShort4> val)
3528 return RValue<UShort4>(Nucleus::createNot(val.value));
3531 RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y)
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);
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);
3541 return RValue<UShort4>(V(result));
3544 RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y)
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);
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);
3554 return RValue<UShort4>(V(result));
3557 RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y)
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);
3567 return RValue<UShort4>(V(result));
3570 RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y)
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);
3580 return RValue<UShort4>(V(result));
3583 RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y)
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);
3593 return RValue<UShort4>(V(result));
3596 RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y)
3598 assert(false && "UNIMPLEMENTED"); return RValue<UShort4>(V(nullptr));
3601 RValue<Byte8> Pack(RValue<UShort4> x, RValue<UShort4> y)
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);
3611 return As<Byte8>(Swizzle(As<Int4>(V(result)), 0x88));
3614 Type *UShort4::getType()
3616 return T(Type_v4i16);
3619 Short8::Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7)
3621 // xyzw.parent = this;
3623 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
3624 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3627 Short8::Short8(RValue<Short8> rhs)
3629 // xyzw.parent = this;
3631 storeValue(rhs.value);
3634 Short8::Short8(const Reference<Short8> &rhs)
3636 // xyzw.parent = this;
3638 Value *value = rhs.loadValue();
3642 Short8::Short8(RValue<Short4> lo, RValue<Short4> hi)
3644 assert(false && "UNIMPLEMENTED");
3647 RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs)
3649 return RValue<Short8>(Nucleus::createAdd(lhs.value, rhs.value));
3652 RValue<Short8> operator&(RValue<Short8> lhs, RValue<Short8> rhs)
3654 return RValue<Short8>(Nucleus::createAnd(lhs.value, rhs.value));
3657 RValue<Short8> operator<<(RValue<Short8> lhs, unsigned char rhs)
3659 return RValue<Short8>(Nucleus::createShl(lhs.value, C(::context->getConstantInt32(rhs))));
3662 RValue<Short8> operator>>(RValue<Short8> lhs, unsigned char rhs)
3664 return RValue<Short8>(Nucleus::createAShr(lhs.value, C(::context->getConstantInt32(rhs))));
3667 RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y)
3669 assert(false && "UNIMPLEMENTED"); return RValue<Int4>(V(nullptr));
3672 RValue<Int4> Abs(RValue<Int4> x)
3674 assert(false && "UNIMPLEMENTED"); return RValue<Int4>(V(nullptr));
3677 RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y)
3679 assert(false && "UNIMPLEMENTED"); return RValue<Short8>(V(nullptr));
3682 Type *Short8::getType()
3684 return T(Ice::IceType_v8i16);
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)
3689 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
3690 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3693 UShort8::UShort8(RValue<UShort8> rhs)
3695 storeValue(rhs.value);
3698 UShort8::UShort8(const Reference<UShort8> &rhs)
3700 Value *value = rhs.loadValue();
3704 UShort8::UShort8(RValue<UShort4> lo, RValue<UShort4> hi)
3706 assert(false && "UNIMPLEMENTED");
3709 RValue<UShort8> UShort8::operator=(RValue<UShort8> rhs) const
3711 storeValue(rhs.value);
3716 RValue<UShort8> UShort8::operator=(const UShort8 &rhs) const
3718 Value *value = rhs.loadValue();
3721 return RValue<UShort8>(value);
3724 RValue<UShort8> UShort8::operator=(const Reference<UShort8> &rhs) const
3726 Value *value = rhs.loadValue();
3729 return RValue<UShort8>(value);
3732 RValue<UShort8> operator&(RValue<UShort8> lhs, RValue<UShort8> rhs)
3734 return RValue<UShort8>(Nucleus::createAnd(lhs.value, rhs.value));
3737 RValue<UShort8> operator<<(RValue<UShort8> lhs, unsigned char rhs)
3739 return RValue<UShort8>(Nucleus::createShl(lhs.value, C(::context->getConstantInt32(rhs))));
3742 RValue<UShort8> operator>>(RValue<UShort8> lhs, unsigned char rhs)
3744 return RValue<UShort8>(Nucleus::createLShr(lhs.value, C(::context->getConstantInt32(rhs))));
3747 RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs)
3749 return RValue<UShort8>(Nucleus::createAdd(lhs.value, rhs.value));
3752 RValue<UShort8> operator*(RValue<UShort8> lhs, RValue<UShort8> rhs)
3754 return RValue<UShort8>(Nucleus::createMul(lhs.value, rhs.value));
3757 RValue<UShort8> operator+=(const UShort8 &lhs, RValue<UShort8> rhs)
3759 return lhs = lhs + rhs;
3762 RValue<UShort8> operator~(RValue<UShort8> val)
3764 return RValue<UShort8>(Nucleus::createNot(val.value));
3767 RValue<UShort8> Swizzle(RValue<UShort8> x, char select0, char select1, char select2, char select3, char select4, char select5, char select6, char select7)
3769 assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
3772 RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y)
3774 assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
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)
3780 // assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
3783 Type *UShort8::getType()
3785 return T(Ice::IceType_v8i16);
3788 Int::Int(Argument<Int> argument)
3790 storeValue(argument.value);
3793 Int::Int(RValue<Byte> cast)
3795 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3797 storeValue(integer);
3800 Int::Int(RValue<SByte> cast)
3802 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3804 storeValue(integer);
3807 Int::Int(RValue<Short> cast)
3809 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3811 storeValue(integer);
3814 Int::Int(RValue<UShort> cast)
3816 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3818 storeValue(integer);
3821 Int::Int(RValue<Int2> cast)
3823 *this = Extract(cast, 0);
3826 Int::Int(RValue<Long> cast)
3828 Value *integer = Nucleus::createTrunc(cast.value, Int::getType());
3830 storeValue(integer);
3833 Int::Int(RValue<Float> cast)
3835 Value *integer = Nucleus::createFPToSI(cast.value, Int::getType());
3837 storeValue(integer);
3846 storeValue(Nucleus::createConstantInt(x));
3849 Int::Int(RValue<Int> rhs)
3851 storeValue(rhs.value);
3854 Int::Int(RValue<UInt> rhs)
3856 storeValue(rhs.value);
3859 Int::Int(const Int &rhs)
3861 Value *value = rhs.loadValue();
3865 Int::Int(const Reference<Int> &rhs)
3867 Value *value = rhs.loadValue();
3871 Int::Int(const UInt &rhs)
3873 Value *value = rhs.loadValue();
3877 Int::Int(const Reference<UInt> &rhs)
3879 Value *value = rhs.loadValue();
3883 RValue<Int> Int::operator=(int rhs) const
3885 return RValue<Int>(storeValue(Nucleus::createConstantInt(rhs)));
3888 RValue<Int> Int::operator=(RValue<Int> rhs) const
3890 storeValue(rhs.value);
3895 RValue<Int> Int::operator=(RValue<UInt> rhs) const
3897 storeValue(rhs.value);
3899 return RValue<Int>(rhs);
3902 RValue<Int> Int::operator=(const Int &rhs) const
3904 Value *value = rhs.loadValue();
3907 return RValue<Int>(value);
3910 RValue<Int> Int::operator=(const Reference<Int> &rhs) const
3912 Value *value = rhs.loadValue();
3915 return RValue<Int>(value);
3918 RValue<Int> Int::operator=(const UInt &rhs) const
3920 Value *value = rhs.loadValue();
3923 return RValue<Int>(value);
3926 RValue<Int> Int::operator=(const Reference<UInt> &rhs) const
3928 Value *value = rhs.loadValue();
3931 return RValue<Int>(value);
3934 RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs)
3936 return RValue<Int>(Nucleus::createAdd(lhs.value, rhs.value));
3939 RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs)
3941 return RValue<Int>(Nucleus::createSub(lhs.value, rhs.value));
3944 RValue<Int> operator*(RValue<Int> lhs, RValue<Int> rhs)
3946 return RValue<Int>(Nucleus::createMul(lhs.value, rhs.value));
3949 RValue<Int> operator/(RValue<Int> lhs, RValue<Int> rhs)
3951 return RValue<Int>(Nucleus::createSDiv(lhs.value, rhs.value));
3954 RValue<Int> operator%(RValue<Int> lhs, RValue<Int> rhs)
3956 return RValue<Int>(Nucleus::createSRem(lhs.value, rhs.value));
3959 RValue<Int> operator&(RValue<Int> lhs, RValue<Int> rhs)
3961 return RValue<Int>(Nucleus::createAnd(lhs.value, rhs.value));
3964 RValue<Int> operator|(RValue<Int> lhs, RValue<Int> rhs)
3966 return RValue<Int>(Nucleus::createOr(lhs.value, rhs.value));
3969 RValue<Int> operator^(RValue<Int> lhs, RValue<Int> rhs)
3971 return RValue<Int>(Nucleus::createXor(lhs.value, rhs.value));
3974 RValue<Int> operator<<(RValue<Int> lhs, RValue<Int> rhs)
3976 return RValue<Int>(Nucleus::createShl(lhs.value, rhs.value));
3979 RValue<Int> operator>>(RValue<Int> lhs, RValue<Int> rhs)
3981 return RValue<Int>(Nucleus::createAShr(lhs.value, rhs.value));
3984 RValue<Int> operator+=(const Int &lhs, RValue<Int> rhs)
3986 return lhs = lhs + rhs;
3989 RValue<Int> operator-=(const Int &lhs, RValue<Int> rhs)
3991 return lhs = lhs - rhs;
3994 RValue<Int> operator*=(const Int &lhs, RValue<Int> rhs)
3996 return lhs = lhs * rhs;
3999 RValue<Int> operator/=(const Int &lhs, RValue<Int> rhs)
4001 return lhs = lhs / rhs;
4004 RValue<Int> operator%=(const Int &lhs, RValue<Int> rhs)
4006 return lhs = lhs % rhs;
4009 RValue<Int> operator&=(const Int &lhs, RValue<Int> rhs)
4011 return lhs = lhs & rhs;
4014 RValue<Int> operator|=(const Int &lhs, RValue<Int> rhs)
4016 return lhs = lhs | rhs;
4019 RValue<Int> operator^=(const Int &lhs, RValue<Int> rhs)
4021 return lhs = lhs ^ rhs;
4024 RValue<Int> operator<<=(const Int &lhs, RValue<Int> rhs)
4026 return lhs = lhs << rhs;
4029 RValue<Int> operator>>=(const Int &lhs, RValue<Int> rhs)
4031 return lhs = lhs >> rhs;
4034 RValue<Int> operator+(RValue<Int> val)
4039 RValue<Int> operator-(RValue<Int> val)
4041 return RValue<Int>(Nucleus::createNeg(val.value));
4044 RValue<Int> operator~(RValue<Int> val)
4046 return RValue<Int>(Nucleus::createNot(val.value));
4049 RValue<Int> operator++(const Int &val, int) // Post-increment
4051 RValue<UInt> res = val;
4056 const Int &operator++(const Int &val) // Pre-increment
4062 RValue<Int> operator--(const Int &val, int) // Post-decrement
4064 RValue<Int> res = val;
4069 const Int &operator--(const Int &val) // Pre-decrement
4075 RValue<Bool> operator<(RValue<Int> lhs, RValue<Int> rhs)
4077 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
4080 RValue<Bool> operator<=(RValue<Int> lhs, RValue<Int> rhs)
4082 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
4085 RValue<Bool> operator>(RValue<Int> lhs, RValue<Int> rhs)
4087 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
4090 RValue<Bool> operator>=(RValue<Int> lhs, RValue<Int> rhs)
4092 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
4095 RValue<Bool> operator!=(RValue<Int> lhs, RValue<Int> rhs)
4097 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
4100 RValue<Bool> operator==(RValue<Int> lhs, RValue<Int> rhs)
4102 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
4105 RValue<Int> Max(RValue<Int> x, RValue<Int> y)
4107 return IfThenElse(x > y, x, y);
4110 RValue<Int> Min(RValue<Int> x, RValue<Int> y)
4112 return IfThenElse(x < y, x, y);
4115 RValue<Int> Clamp(RValue<Int> x, RValue<Int> min, RValue<Int> max)
4117 return Min(Max(x, min), max);
4120 RValue<Int> RoundInt(RValue<Float> cast)
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);
4126 return RValue<Int>(V(result));
4129 Type *Int::getType()
4131 return T(Ice::IceType_i32);
4134 Long::Long(RValue<Int> cast)
4136 Value *integer = Nucleus::createSExt(cast.value, Long::getType());
4138 storeValue(integer);
4141 Long::Long(RValue<UInt> cast)
4143 Value *integer = Nucleus::createZExt(cast.value, Long::getType());
4145 storeValue(integer);
4152 Long::Long(RValue<Long> rhs)
4154 storeValue(rhs.value);
4157 RValue<Long> Long::operator=(int64_t rhs) const
4159 return RValue<Long>(storeValue(Nucleus::createConstantLong(rhs)));
4162 RValue<Long> Long::operator=(RValue<Long> rhs) const
4164 storeValue(rhs.value);
4169 RValue<Long> Long::operator=(const Long &rhs) const
4171 Value *value = rhs.loadValue();
4174 return RValue<Long>(value);
4177 RValue<Long> Long::operator=(const Reference<Long> &rhs) const
4179 Value *value = rhs.loadValue();
4182 return RValue<Long>(value);
4185 RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs)
4187 return RValue<Long>(Nucleus::createAdd(lhs.value, rhs.value));
4190 RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs)
4192 return RValue<Long>(Nucleus::createSub(lhs.value, rhs.value));
4195 RValue<Long> operator+=(const Long &lhs, RValue<Long> rhs)
4197 return lhs = lhs + rhs;
4200 RValue<Long> operator-=(const Long &lhs, RValue<Long> rhs)
4202 return lhs = lhs - rhs;
4205 RValue<Long> AddAtomic(RValue<Pointer<Long> > x, RValue<Long> y)
4207 return RValue<Long>(Nucleus::createAtomicAdd(x.value, y.value));
4210 Type *Long::getType()
4212 return T(Ice::IceType_i64);
4215 Long1::Long1(const RValue<UInt> cast)
4217 assert(false && "UNIMPLEMENTED");
4220 Long1::Long1(RValue<Long1> rhs)
4222 storeValue(rhs.value);
4225 Type *Long1::getType()
4227 assert(false && "UNIMPLEMENTED"); return nullptr;
4230 UInt::UInt(Argument<UInt> argument)
4232 storeValue(argument.value);
4235 UInt::UInt(RValue<UShort> cast)
4237 Value *integer = Nucleus::createZExt(cast.value, UInt::getType());
4239 storeValue(integer);
4242 UInt::UInt(RValue<Long> cast)
4244 Value *integer = Nucleus::createTrunc(cast.value, UInt::getType());
4246 storeValue(integer);
4249 UInt::UInt(RValue<Float> cast)
4251 assert(false && "UNIMPLEMENTED");
4260 storeValue(Nucleus::createConstantInt(x));
4263 UInt::UInt(unsigned int x)
4265 storeValue(Nucleus::createConstantInt(x));
4268 UInt::UInt(RValue<UInt> rhs)
4270 storeValue(rhs.value);
4273 UInt::UInt(RValue<Int> rhs)
4275 storeValue(rhs.value);
4278 UInt::UInt(const UInt &rhs)
4280 Value *value = rhs.loadValue();
4284 UInt::UInt(const Reference<UInt> &rhs)
4286 Value *value = rhs.loadValue();
4290 UInt::UInt(const Int &rhs)
4292 Value *value = rhs.loadValue();
4296 UInt::UInt(const Reference<Int> &rhs)
4298 Value *value = rhs.loadValue();
4302 RValue<UInt> UInt::operator=(unsigned int rhs) const
4304 return RValue<UInt>(storeValue(Nucleus::createConstantInt(rhs)));
4307 RValue<UInt> UInt::operator=(RValue<UInt> rhs) const
4309 storeValue(rhs.value);
4314 RValue<UInt> UInt::operator=(RValue<Int> rhs) const
4316 storeValue(rhs.value);
4318 return RValue<UInt>(rhs);
4321 RValue<UInt> UInt::operator=(const UInt &rhs) const
4323 Value *value = rhs.loadValue();
4326 return RValue<UInt>(value);
4329 RValue<UInt> UInt::operator=(const Reference<UInt> &rhs) const
4331 Value *value = rhs.loadValue();
4334 return RValue<UInt>(value);
4337 RValue<UInt> UInt::operator=(const Int &rhs) const
4339 Value *value = rhs.loadValue();
4342 return RValue<UInt>(value);
4345 RValue<UInt> UInt::operator=(const Reference<Int> &rhs) const
4347 Value *value = rhs.loadValue();
4350 return RValue<UInt>(value);
4353 RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs)
4355 return RValue<UInt>(Nucleus::createAdd(lhs.value, rhs.value));
4358 RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs)
4360 return RValue<UInt>(Nucleus::createSub(lhs.value, rhs.value));
4363 RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs)
4365 return RValue<UInt>(Nucleus::createMul(lhs.value, rhs.value));
4368 RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs)
4370 return RValue<UInt>(Nucleus::createUDiv(lhs.value, rhs.value));
4373 RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs)
4375 return RValue<UInt>(Nucleus::createURem(lhs.value, rhs.value));
4378 RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs)
4380 return RValue<UInt>(Nucleus::createAnd(lhs.value, rhs.value));
4383 RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs)
4385 return RValue<UInt>(Nucleus::createOr(lhs.value, rhs.value));
4388 RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs)
4390 return RValue<UInt>(Nucleus::createXor(lhs.value, rhs.value));
4393 RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs)
4395 return RValue<UInt>(Nucleus::createShl(lhs.value, rhs.value));
4398 RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs)
4400 return RValue<UInt>(Nucleus::createLShr(lhs.value, rhs.value));
4403 RValue<UInt> operator+=(const UInt &lhs, RValue<UInt> rhs)
4405 return lhs = lhs + rhs;
4408 RValue<UInt> operator-=(const UInt &lhs, RValue<UInt> rhs)
4410 return lhs = lhs - rhs;
4413 RValue<UInt> operator*=(const UInt &lhs, RValue<UInt> rhs)
4415 return lhs = lhs * rhs;
4418 RValue<UInt> operator/=(const UInt &lhs, RValue<UInt> rhs)
4420 return lhs = lhs / rhs;
4423 RValue<UInt> operator%=(const UInt &lhs, RValue<UInt> rhs)
4425 return lhs = lhs % rhs;
4428 RValue<UInt> operator&=(const UInt &lhs, RValue<UInt> rhs)
4430 return lhs = lhs & rhs;
4433 RValue<UInt> operator|=(const UInt &lhs, RValue<UInt> rhs)
4435 return lhs = lhs | rhs;
4438 RValue<UInt> operator^=(const UInt &lhs, RValue<UInt> rhs)
4440 return lhs = lhs ^ rhs;
4443 RValue<UInt> operator<<=(const UInt &lhs, RValue<UInt> rhs)
4445 return lhs = lhs << rhs;
4448 RValue<UInt> operator>>=(const UInt &lhs, RValue<UInt> rhs)
4450 return lhs = lhs >> rhs;
4453 RValue<UInt> operator+(RValue<UInt> val)
4458 RValue<UInt> operator-(RValue<UInt> val)
4460 return RValue<UInt>(Nucleus::createNeg(val.value));
4463 RValue<UInt> operator~(RValue<UInt> val)
4465 return RValue<UInt>(Nucleus::createNot(val.value));
4468 RValue<UInt> operator++(const UInt &val, int) // Post-increment
4470 RValue<UInt> res = val;
4475 const UInt &operator++(const UInt &val) // Pre-increment
4481 RValue<UInt> operator--(const UInt &val, int) // Post-decrement
4483 RValue<UInt> res = val;
4488 const UInt &operator--(const UInt &val) // Pre-decrement
4494 RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y)
4496 return IfThenElse(x > y, x, y);
4499 RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y)
4501 return IfThenElse(x < y, x, y);
4504 RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max)
4506 return Min(Max(x, min), max);
4509 RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs)
4511 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
4514 RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs)
4516 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
4519 RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs)
4521 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
4524 RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs)
4526 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
4529 RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs)
4531 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
4534 RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs)
4536 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
4539 // RValue<UInt> RoundUInt(RValue<Float> cast)
4541 // assert(false && "UNIMPLEMENTED"); return RValue<UInt>(V(nullptr));
4544 Type *UInt::getType()
4546 return T(Ice::IceType_i32);
4549 // Int2::Int2(RValue<Int> cast)
4551 // Value *extend = Nucleus::createZExt(cast.value, Long::getType());
4552 // Value *vector = Nucleus::createBitCast(extend, Int2::getType());
4554 // Constant *shuffle[2];
4555 // shuffle[0] = Nucleus::createConstantInt(0);
4556 // shuffle[1] = Nucleus::createConstantInt(0);
4558 // Value *replicate = Nucleus::createShuffleVector(vector, UndefValue::get(Int2::getType()), Nucleus::createConstantVector(shuffle, 2));
4560 // storeValue(replicate);
4563 Int2::Int2(RValue<Int4> cast)
4565 storeValue(Nucleus::createBitCast(cast.value, getType()));
4570 // xy.parent = this;
4573 Int2::Int2(int x, int y)
4575 // xy.parent = this;
4577 int64_t constantVector[2] = {x, y};
4578 storeValue(Nucleus::createConstantVector(constantVector, getType()));
4581 Int2::Int2(RValue<Int2> rhs)
4583 // xy.parent = this;
4585 storeValue(rhs.value);
4588 Int2::Int2(const Int2 &rhs)
4590 // xy.parent = this;
4592 Value *value = rhs.loadValue();
4596 Int2::Int2(const Reference<Int2> &rhs)
4598 // xy.parent = this;
4600 Value *value = rhs.loadValue();
4604 Int2::Int2(RValue<Int> lo, RValue<Int> hi)
4606 assert(false && "UNIMPLEMENTED");
4609 RValue<Int2> Int2::operator=(RValue<Int2> rhs) const
4611 storeValue(rhs.value);
4616 RValue<Int2> Int2::operator=(const Int2 &rhs) const
4618 Value *value = rhs.loadValue();
4621 return RValue<Int2>(value);
4624 RValue<Int2> Int2::operator=(const Reference<Int2> &rhs) const
4626 Value *value = rhs.loadValue();
4629 return RValue<Int2>(value);
4632 RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs)
4634 return RValue<Int2>(Nucleus::createAdd(lhs.value, rhs.value));
4637 RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs)
4639 return RValue<Int2>(Nucleus::createSub(lhs.value, rhs.value));
4642 // RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs)
4644 // return RValue<Int2>(Nucleus::createMul(lhs.value, rhs.value));
4647 // RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs)
4649 // return RValue<Int2>(Nucleus::createSDiv(lhs.value, rhs.value));
4652 // RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs)
4654 // return RValue<Int2>(Nucleus::createSRem(lhs.value, rhs.value));
4657 RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs)
4659 return RValue<Int2>(Nucleus::createAnd(lhs.value, rhs.value));
4662 RValue<Int2> operator|(RValue<Int2> lhs, RValue<Int2> rhs)
4664 return RValue<Int2>(Nucleus::createOr(lhs.value, rhs.value));
4667 RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs)
4669 return RValue<Int2>(Nucleus::createXor(lhs.value, rhs.value));
4672 RValue<Int2> operator<<(RValue<Int2> lhs, unsigned char rhs)
4674 return RValue<Int2>(Nucleus::createShl(lhs.value, C(::context->getConstantInt32(rhs))));
4677 RValue<Int2> operator>>(RValue<Int2> lhs, unsigned char rhs)
4679 return RValue<Int2>(Nucleus::createAShr(lhs.value, C(::context->getConstantInt32(rhs))));
4682 RValue<Int2> operator<<(RValue<Int2> lhs, RValue<Long1> rhs)
4684 assert(false && "UNIMPLEMENTED"); return RValue<Int2>(V(nullptr));
4687 RValue<Int2> operator>>(RValue<Int2> lhs, RValue<Long1> rhs)
4689 assert(false && "UNIMPLEMENTED"); return RValue<Int2>(V(nullptr));
4692 RValue<Int2> operator+=(const Int2 &lhs, RValue<Int2> rhs)
4694 return lhs = lhs + rhs;
4697 RValue<Int2> operator-=(const Int2 &lhs, RValue<Int2> rhs)
4699 return lhs = lhs - rhs;
4702 // RValue<Int2> operator*=(const Int2 &lhs, RValue<Int2> rhs)
4704 // return lhs = lhs * rhs;
4707 // RValue<Int2> operator/=(const Int2 &lhs, RValue<Int2> rhs)
4709 // return lhs = lhs / rhs;
4712 // RValue<Int2> operator%=(const Int2 &lhs, RValue<Int2> rhs)
4714 // return lhs = lhs % rhs;
4717 RValue<Int2> operator&=(const Int2 &lhs, RValue<Int2> rhs)
4719 return lhs = lhs & rhs;
4722 RValue<Int2> operator|=(const Int2 &lhs, RValue<Int2> rhs)
4724 return lhs = lhs | rhs;
4727 RValue<Int2> operator^=(const Int2 &lhs, RValue<Int2> rhs)
4729 return lhs = lhs ^ rhs;
4732 RValue<Int2> operator<<=(const Int2 &lhs, unsigned char rhs)
4734 return lhs = lhs << rhs;
4737 RValue<Int2> operator>>=(const Int2 &lhs, unsigned char rhs)
4739 return lhs = lhs >> rhs;
4742 RValue<Int2> operator<<=(const Int2 &lhs, RValue<Long1> rhs)
4744 return lhs = lhs << rhs;
4747 RValue<Int2> operator>>=(const Int2 &lhs, RValue<Long1> rhs)
4749 return lhs = lhs >> rhs;
4752 // RValue<Int2> operator+(RValue<Int2> val)
4757 // RValue<Int2> operator-(RValue<Int2> val)
4759 // return RValue<Int2>(Nucleus::createNeg(val.value));
4762 RValue<Int2> operator~(RValue<Int2> val)
4764 return RValue<Int2>(Nucleus::createNot(val.value));
4767 RValue<Long1> UnpackLow(RValue<Int2> x, RValue<Int2> y)
4769 assert(false && "UNIMPLEMENTED"); return RValue<Long1>(V(nullptr));
4772 RValue<Long1> UnpackHigh(RValue<Int2> x, RValue<Int2> y)
4774 assert(false && "UNIMPLEMENTED"); return RValue<Long1>(V(nullptr));
4777 RValue<Int> Extract(RValue<Int2> val, int i)
4779 return RValue<Int>(Nucleus::createExtractElement(val.value, Int::getType(), i));
4782 RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i)
4784 return RValue<Int2>(Nucleus::createInsertElement(val.value, element.value, i));
4787 Type *Int2::getType()
4789 return T(Type_v2i32);
4794 // xy.parent = this;
4797 UInt2::UInt2(unsigned int x, unsigned int y)
4799 // xy.parent = this;
4801 int64_t constantVector[2] = {x, y};
4802 storeValue(Nucleus::createConstantVector(constantVector, getType()));
4805 UInt2::UInt2(RValue<UInt2> rhs)
4807 // xy.parent = this;
4809 storeValue(rhs.value);
4812 UInt2::UInt2(const UInt2 &rhs)
4814 // xy.parent = this;
4816 Value *value = rhs.loadValue();
4820 UInt2::UInt2(const Reference<UInt2> &rhs)
4822 // xy.parent = this;
4824 Value *value = rhs.loadValue();
4828 RValue<UInt2> UInt2::operator=(RValue<UInt2> rhs) const
4830 storeValue(rhs.value);
4835 RValue<UInt2> UInt2::operator=(const UInt2 &rhs) const
4837 Value *value = rhs.loadValue();
4840 return RValue<UInt2>(value);
4843 RValue<UInt2> UInt2::operator=(const Reference<UInt2> &rhs) const
4845 Value *value = rhs.loadValue();
4848 return RValue<UInt2>(value);
4851 RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs)
4853 return RValue<UInt2>(Nucleus::createAdd(lhs.value, rhs.value));
4856 RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs)
4858 return RValue<UInt2>(Nucleus::createSub(lhs.value, rhs.value));
4861 // RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs)
4863 // return RValue<UInt2>(Nucleus::createMul(lhs.value, rhs.value));
4866 // RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs)
4868 // return RValue<UInt2>(Nucleus::createUDiv(lhs.value, rhs.value));
4871 // RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs)
4873 // return RValue<UInt2>(Nucleus::createURem(lhs.value, rhs.value));
4876 RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs)
4878 return RValue<UInt2>(Nucleus::createAnd(lhs.value, rhs.value));
4881 RValue<UInt2> operator|(RValue<UInt2> lhs, RValue<UInt2> rhs)
4883 return RValue<UInt2>(Nucleus::createOr(lhs.value, rhs.value));
4886 RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs)
4888 return RValue<UInt2>(Nucleus::createXor(lhs.value, rhs.value));
4891 RValue<UInt2> operator<<(RValue<UInt2> lhs, unsigned char rhs)
4893 return RValue<UInt2>(Nucleus::createShl(lhs.value, C(::context->getConstantInt32(rhs))));
4896 RValue<UInt2> operator>>(RValue<UInt2> lhs, unsigned char rhs)
4898 return RValue<UInt2>(Nucleus::createLShr(lhs.value, C(::context->getConstantInt32(rhs))));
4901 RValue<UInt2> operator<<(RValue<UInt2> lhs, RValue<Long1> rhs)
4903 assert(false && "UNIMPLEMENTED"); return RValue<UInt2>(V(nullptr));
4906 RValue<UInt2> operator>>(RValue<UInt2> lhs, RValue<Long1> rhs)
4908 assert(false && "UNIMPLEMENTED"); return RValue<UInt2>(V(nullptr));
4911 RValue<UInt2> operator+=(const UInt2 &lhs, RValue<UInt2> rhs)
4913 return lhs = lhs + rhs;
4916 RValue<UInt2> operator-=(const UInt2 &lhs, RValue<UInt2> rhs)
4918 return lhs = lhs - rhs;
4921 // RValue<UInt2> operator*=(const UInt2 &lhs, RValue<UInt2> rhs)
4923 // return lhs = lhs * rhs;
4926 // RValue<UInt2> operator/=(const UInt2 &lhs, RValue<UInt2> rhs)
4928 // return lhs = lhs / rhs;
4931 // RValue<UInt2> operator%=(const UInt2 &lhs, RValue<UInt2> rhs)
4933 // return lhs = lhs % rhs;
4936 RValue<UInt2> operator&=(const UInt2 &lhs, RValue<UInt2> rhs)
4938 return lhs = lhs & rhs;
4941 RValue<UInt2> operator|=(const UInt2 &lhs, RValue<UInt2> rhs)
4943 return lhs = lhs | rhs;
4946 RValue<UInt2> operator^=(const UInt2 &lhs, RValue<UInt2> rhs)
4948 return lhs = lhs ^ rhs;
4951 RValue<UInt2> operator<<=(const UInt2 &lhs, unsigned char rhs)
4953 return lhs = lhs << rhs;
4956 RValue<UInt2> operator>>=(const UInt2 &lhs, unsigned char rhs)
4958 return lhs = lhs >> rhs;
4961 RValue<UInt2> operator<<=(const UInt2 &lhs, RValue<Long1> rhs)
4963 return lhs = lhs << rhs;
4966 RValue<UInt2> operator>>=(const UInt2 &lhs, RValue<Long1> rhs)
4968 return lhs = lhs >> rhs;
4971 // RValue<UInt2> operator+(RValue<UInt2> val)
4976 // RValue<UInt2> operator-(RValue<UInt2> val)
4978 // return RValue<UInt2>(Nucleus::createNeg(val.value));
4981 RValue<UInt2> operator~(RValue<UInt2> val)
4983 return RValue<UInt2>(Nucleus::createNot(val.value));
4986 Type *UInt2::getType()
4988 return T(Type_v2i32);
4991 Int4::Int4(RValue<Byte4> cast)
4993 assert(false && "UNIMPLEMENTED");
4996 Int4::Int4(RValue<SByte4> cast)
4998 assert(false && "UNIMPLEMENTED");
5001 Int4::Int4(RValue<Float4> cast)
5003 // xyzw.parent = this;
5005 Value *xyzw = Nucleus::createFPToSI(cast.value, Int4::getType());
5010 Int4::Int4(RValue<Short4> cast)
5012 assert(false && "UNIMPLEMENTED");
5015 Int4::Int4(RValue<UShort4> cast)
5017 assert(false && "UNIMPLEMENTED");
5022 // xyzw.parent = this;
5025 Int4::Int4(int xyzw)
5027 constant(xyzw, xyzw, xyzw, xyzw);
5030 Int4::Int4(int x, int yzw)
5032 constant(x, yzw, yzw, yzw);
5035 Int4::Int4(int x, int y, int zw)
5037 constant(x, y, zw, zw);
5040 Int4::Int4(int x, int y, int z, int w)
5042 constant(x, y, z, w);
5045 void Int4::constant(int x, int y, int z, int w)
5047 // xyzw.parent = this;
5049 int64_t constantVector[4] = {x, y, z, w};
5050 storeValue(Nucleus::createConstantVector(constantVector, getType()));
5053 Int4::Int4(RValue<Int4> rhs)
5055 // xyzw.parent = this;
5057 storeValue(rhs.value);
5060 Int4::Int4(const Int4 &rhs)
5062 // xyzw.parent = this;
5064 Value *value = rhs.loadValue();
5068 Int4::Int4(const Reference<Int4> &rhs)
5070 // xyzw.parent = this;
5072 Value *value = rhs.loadValue();
5076 Int4::Int4(RValue<UInt4> rhs)
5078 // xyzw.parent = this;
5080 storeValue(rhs.value);
5083 Int4::Int4(const UInt4 &rhs)
5085 // xyzw.parent = this;
5087 Value *value = rhs.loadValue();
5091 Int4::Int4(const Reference<UInt4> &rhs)
5093 // xyzw.parent = this;
5095 Value *value = rhs.loadValue();
5099 Int4::Int4(RValue<Int2> lo, RValue<Int2> hi)
5101 assert(false && "UNIMPLEMENTED");
5104 Int4::Int4(RValue<Int> rhs)
5106 // xyzw.parent = this;
5108 assert(false && "UNIMPLEMENTED");
5111 Int4::Int4(const Int &rhs)
5113 // xyzw.parent = this;
5115 *this = RValue<Int>(rhs.loadValue());
5118 Int4::Int4(const Reference<Int> &rhs)
5120 // xyzw.parent = this;
5122 *this = RValue<Int>(rhs.loadValue());
5125 RValue<Int4> Int4::operator=(RValue<Int4> rhs) const
5127 storeValue(rhs.value);
5132 RValue<Int4> Int4::operator=(const Int4 &rhs) const
5134 Value *value = rhs.loadValue();
5137 return RValue<Int4>(value);
5140 RValue<Int4> Int4::operator=(const Reference<Int4> &rhs) const
5142 Value *value = rhs.loadValue();
5145 return RValue<Int4>(value);
5148 RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs)
5150 return RValue<Int4>(Nucleus::createAdd(lhs.value, rhs.value));
5153 RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs)
5155 return RValue<Int4>(Nucleus::createSub(lhs.value, rhs.value));
5158 RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs)
5160 return RValue<Int4>(Nucleus::createMul(lhs.value, rhs.value));
5163 RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs)
5165 return RValue<Int4>(Nucleus::createSDiv(lhs.value, rhs.value));
5168 RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs)
5170 return RValue<Int4>(Nucleus::createSRem(lhs.value, rhs.value));
5173 RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs)
5175 return RValue<Int4>(Nucleus::createAnd(lhs.value, rhs.value));
5178 RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs)
5180 return RValue<Int4>(Nucleus::createOr(lhs.value, rhs.value));
5183 RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs)
5185 return RValue<Int4>(Nucleus::createXor(lhs.value, rhs.value));
5188 RValue<Int4> operator<<(RValue<Int4> lhs, unsigned char rhs)
5190 return RValue<Int4>(Nucleus::createShl(lhs.value, C(::context->getConstantInt32(rhs))));
5193 RValue<Int4> operator>>(RValue<Int4> lhs, unsigned char rhs)
5195 return RValue<Int4>(Nucleus::createAShr(lhs.value, C(::context->getConstantInt32(rhs))));
5198 RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs)
5200 return RValue<Int4>(Nucleus::createShl(lhs.value, rhs.value));
5203 RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs)
5205 return RValue<Int4>(Nucleus::createAShr(lhs.value, rhs.value));
5208 RValue<Int4> operator+=(const Int4 &lhs, RValue<Int4> rhs)
5210 return lhs = lhs + rhs;
5213 RValue<Int4> operator-=(const Int4 &lhs, RValue<Int4> rhs)
5215 return lhs = lhs - rhs;
5218 RValue<Int4> operator*=(const Int4 &lhs, RValue<Int4> rhs)
5220 return lhs = lhs * rhs;
5223 // RValue<Int4> operator/=(const Int4 &lhs, RValue<Int4> rhs)
5225 // return lhs = lhs / rhs;
5228 // RValue<Int4> operator%=(const Int4 &lhs, RValue<Int4> rhs)
5230 // return lhs = lhs % rhs;
5233 RValue<Int4> operator&=(const Int4 &lhs, RValue<Int4> rhs)
5235 return lhs = lhs & rhs;
5238 RValue<Int4> operator|=(const Int4 &lhs, RValue<Int4> rhs)
5240 return lhs = lhs | rhs;
5243 RValue<Int4> operator^=(const Int4 &lhs, RValue<Int4> rhs)
5245 return lhs = lhs ^ rhs;
5248 RValue<Int4> operator<<=(const Int4 &lhs, unsigned char rhs)
5250 return lhs = lhs << rhs;
5253 RValue<Int4> operator>>=(const Int4 &lhs, unsigned char rhs)
5255 return lhs = lhs >> rhs;
5258 RValue<Int4> operator+(RValue<Int4> val)
5263 RValue<Int4> operator-(RValue<Int4> val)
5265 return RValue<Int4>(Nucleus::createNeg(val.value));
5268 RValue<Int4> operator~(RValue<Int4> val)
5270 return RValue<Int4>(Nucleus::createNot(val.value));
5273 RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y)
5275 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
5278 RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y)
5280 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLT(x.value, y.value), Int4::getType()));
5283 RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y)
5285 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLE(x.value, y.value), Int4::getType()));
5288 RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y)
5290 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
5293 RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y)
5295 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGE(x.value, y.value), Int4::getType()));
5298 RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y)
5300 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGT(x.value, y.value), Int4::getType()));
5303 RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y)
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);
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);
5313 return RValue<Int4>(V(result));
5316 RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y)
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);
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);
5326 return RValue<Int4>(V(result));
5329 RValue<Int4> RoundInt(RValue<Float4> cast)
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);
5335 return RValue<Int4>(V(result));
5338 RValue<Short8> Pack(RValue<Int4> x, RValue<Int4> y)
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);
5348 return RValue<Short8>(V(result));
5351 RValue<Int> Extract(RValue<Int4> x, int i)
5353 return RValue<Int>(Nucleus::createExtractElement(x.value, Int::getType(), i));
5356 RValue<Int4> Insert(RValue<Int4> x, RValue<Int> element, int i)
5358 return RValue<Int4>(Nucleus::createInsertElement(x.value, element.value, i));
5361 RValue<Int> SignMask(RValue<Int4> x)
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);
5370 return RValue<Int>(V(result));
5373 RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select)
5375 return RValue<Int4>(createSwizzle4(x.value, select));
5378 Type *Int4::getType()
5380 return T(Ice::IceType_v4i32);
5383 UInt4::UInt4(RValue<Float4> cast)
5385 // xyzw.parent = this;
5387 assert(false && "UNIMPLEMENTED");
5392 // xyzw.parent = this;
5395 UInt4::UInt4(int xyzw)
5397 constant(xyzw, xyzw, xyzw, xyzw);
5400 UInt4::UInt4(int x, int yzw)
5402 constant(x, yzw, yzw, yzw);
5405 UInt4::UInt4(int x, int y, int zw)
5407 constant(x, y, zw, zw);
5410 UInt4::UInt4(int x, int y, int z, int w)
5412 constant(x, y, z, w);
5415 void UInt4::constant(int x, int y, int z, int w)
5417 // xyzw.parent = this;
5419 int64_t constantVector[4] = {x, y, z, w};
5420 storeValue(Nucleus::createConstantVector(constantVector, getType()));
5423 UInt4::UInt4(RValue<UInt4> rhs)
5425 // xyzw.parent = this;
5427 storeValue(rhs.value);
5430 UInt4::UInt4(const UInt4 &rhs)
5432 // xyzw.parent = this;
5434 Value *value = rhs.loadValue();
5438 UInt4::UInt4(const Reference<UInt4> &rhs)
5440 // xyzw.parent = this;
5442 Value *value = rhs.loadValue();
5446 UInt4::UInt4(RValue<Int4> rhs)
5448 // xyzw.parent = this;
5450 storeValue(rhs.value);
5453 UInt4::UInt4(const Int4 &rhs)
5455 // xyzw.parent = this;
5457 Value *value = rhs.loadValue();
5461 UInt4::UInt4(const Reference<Int4> &rhs)
5463 // xyzw.parent = this;
5465 Value *value = rhs.loadValue();
5469 UInt4::UInt4(RValue<UInt2> lo, RValue<UInt2> hi)
5471 assert(false && "UNIMPLEMENTED");
5474 RValue<UInt4> UInt4::operator=(RValue<UInt4> rhs) const
5476 storeValue(rhs.value);
5481 RValue<UInt4> UInt4::operator=(const UInt4 &rhs) const
5483 Value *value = rhs.loadValue();
5486 return RValue<UInt4>(value);
5489 RValue<UInt4> UInt4::operator=(const Reference<UInt4> &rhs) const
5491 Value *value = rhs.loadValue();
5494 return RValue<UInt4>(value);
5497 RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs)
5499 return RValue<UInt4>(Nucleus::createAdd(lhs.value, rhs.value));
5502 RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs)
5504 return RValue<UInt4>(Nucleus::createSub(lhs.value, rhs.value));
5507 RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs)
5509 return RValue<UInt4>(Nucleus::createMul(lhs.value, rhs.value));
5512 RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs)
5514 return RValue<UInt4>(Nucleus::createUDiv(lhs.value, rhs.value));
5517 RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs)
5519 return RValue<UInt4>(Nucleus::createURem(lhs.value, rhs.value));
5522 RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs)
5524 return RValue<UInt4>(Nucleus::createAnd(lhs.value, rhs.value));
5527 RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs)
5529 return RValue<UInt4>(Nucleus::createOr(lhs.value, rhs.value));
5532 RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs)
5534 return RValue<UInt4>(Nucleus::createXor(lhs.value, rhs.value));
5537 RValue<UInt4> operator<<(RValue<UInt4> lhs, unsigned char rhs)
5539 return RValue<UInt4>(Nucleus::createShl(lhs.value, C(::context->getConstantInt32(rhs))));
5542 RValue<UInt4> operator>>(RValue<UInt4> lhs, unsigned char rhs)
5544 return RValue<UInt4>(Nucleus::createLShr(lhs.value, C(::context->getConstantInt32(rhs))));
5547 RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs)
5549 return RValue<UInt4>(Nucleus::createShl(lhs.value, rhs.value));
5552 RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs)
5554 return RValue<UInt4>(Nucleus::createLShr(lhs.value, rhs.value));
5557 RValue<UInt4> operator+=(const UInt4 &lhs, RValue<UInt4> rhs)
5559 return lhs = lhs + rhs;
5562 RValue<UInt4> operator-=(const UInt4 &lhs, RValue<UInt4> rhs)
5564 return lhs = lhs - rhs;
5567 RValue<UInt4> operator*=(const UInt4 &lhs, RValue<UInt4> rhs)
5569 return lhs = lhs * rhs;
5572 // RValue<UInt4> operator/=(const UInt4 &lhs, RValue<UInt4> rhs)
5574 // return lhs = lhs / rhs;
5577 // RValue<UInt4> operator%=(const UInt4 &lhs, RValue<UInt4> rhs)
5579 // return lhs = lhs % rhs;
5582 RValue<UInt4> operator&=(const UInt4 &lhs, RValue<UInt4> rhs)
5584 return lhs = lhs & rhs;
5587 RValue<UInt4> operator|=(const UInt4 &lhs, RValue<UInt4> rhs)
5589 return lhs = lhs | rhs;
5592 RValue<UInt4> operator^=(const UInt4 &lhs, RValue<UInt4> rhs)
5594 return lhs = lhs ^ rhs;
5597 RValue<UInt4> operator<<=(const UInt4 &lhs, unsigned char rhs)
5599 return lhs = lhs << rhs;
5602 RValue<UInt4> operator>>=(const UInt4 &lhs, unsigned char rhs)
5604 return lhs = lhs >> rhs;
5607 RValue<UInt4> operator+(RValue<UInt4> val)
5612 RValue<UInt4> operator-(RValue<UInt4> val)
5614 return RValue<UInt4>(Nucleus::createNeg(val.value));
5617 RValue<UInt4> operator~(RValue<UInt4> val)
5619 return RValue<UInt4>(Nucleus::createNot(val.value));
5622 RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y)
5624 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
5627 RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y)
5629 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULT(x.value, y.value), Int4::getType()));
5632 RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y)
5634 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULE(x.value, y.value), Int4::getType()));
5637 RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y)
5639 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
5642 RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y)
5644 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGE(x.value, y.value), Int4::getType()));
5647 RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y)
5649 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGT(x.value, y.value), Int4::getType()));
5652 RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y)
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);
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);
5662 return RValue<UInt4>(V(result));
5665 RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y)
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);
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);
5675 return RValue<UInt4>(V(result));
5678 RValue<UShort8> Pack(RValue<UInt4> x, RValue<UInt4> y)
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);
5688 return RValue<UShort8>(V(result));
5691 Type *UInt4::getType()
5693 return T(Ice::IceType_v4i32);
5696 Float::Float(RValue<Int> cast)
5698 Value *integer = Nucleus::createSIToFP(cast.value, Float::getType());
5700 storeValue(integer);
5707 Float::Float(float x)
5709 storeValue(Nucleus::createConstantFloat(x));
5712 Float::Float(RValue<Float> rhs)
5714 storeValue(rhs.value);
5717 Float::Float(const Float &rhs)
5719 Value *value = rhs.loadValue();
5723 Float::Float(const Reference<Float> &rhs)
5725 Value *value = rhs.loadValue();
5729 RValue<Float> Float::operator=(RValue<Float> rhs) const
5731 storeValue(rhs.value);
5736 RValue<Float> Float::operator=(const Float &rhs) const
5738 Value *value = rhs.loadValue();
5741 return RValue<Float>(value);
5744 RValue<Float> Float::operator=(const Reference<Float> &rhs) const
5746 Value *value = rhs.loadValue();
5749 return RValue<Float>(value);
5752 RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs)
5754 return RValue<Float>(Nucleus::createFAdd(lhs.value, rhs.value));
5757 RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs)
5759 return RValue<Float>(Nucleus::createFSub(lhs.value, rhs.value));
5762 RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs)
5764 return RValue<Float>(Nucleus::createFMul(lhs.value, rhs.value));
5767 RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs)
5769 return RValue<Float>(Nucleus::createFDiv(lhs.value, rhs.value));
5772 RValue<Float> operator+=(const Float &lhs, RValue<Float> rhs)
5774 return lhs = lhs + rhs;
5777 RValue<Float> operator-=(const Float &lhs, RValue<Float> rhs)
5779 return lhs = lhs - rhs;
5782 RValue<Float> operator*=(const Float &lhs, RValue<Float> rhs)
5784 return lhs = lhs * rhs;
5787 RValue<Float> operator/=(const Float &lhs, RValue<Float> rhs)
5789 return lhs = lhs / rhs;
5792 RValue<Float> operator+(RValue<Float> val)
5797 RValue<Float> operator-(RValue<Float> val)
5799 return RValue<Float>(Nucleus::createFNeg(val.value));
5802 RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs)
5804 return RValue<Bool>(Nucleus::createFCmpOLT(lhs.value, rhs.value));
5807 RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs)
5809 return RValue<Bool>(Nucleus::createFCmpOLE(lhs.value, rhs.value));
5812 RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs)
5814 return RValue<Bool>(Nucleus::createFCmpOGT(lhs.value, rhs.value));
5817 RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs)
5819 return RValue<Bool>(Nucleus::createFCmpOGE(lhs.value, rhs.value));
5822 RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs)
5824 return RValue<Bool>(Nucleus::createFCmpONE(lhs.value, rhs.value));
5827 RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs)
5829 return RValue<Bool>(Nucleus::createFCmpOEQ(lhs.value, rhs.value));
5832 RValue<Float> Abs(RValue<Float> x)
5834 return IfThenElse(x > 0.0f, x, -x);
5837 RValue<Float> Max(RValue<Float> x, RValue<Float> y)
5839 return IfThenElse(x > y, x, y);
5842 RValue<Float> Min(RValue<Float> x, RValue<Float> y)
5844 return IfThenElse(x < y, x, y);
5847 RValue<Float> Rcp_pp(RValue<Float> x, bool exactAtPow2)
5852 RValue<Float> RcpSqrt_pp(RValue<Float> x)
5854 return Rcp_pp(Sqrt(x));
5857 RValue<Float> Sqrt(RValue<Float> x)
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);
5866 return RValue<Float>(V(result));
5869 RValue<Float> Round(RValue<Float> x)
5871 return Float4(Round(Float4(x))).x;
5874 RValue<Float> Trunc(RValue<Float> x)
5876 return Float4(Trunc(Float4(x))).x;
5879 RValue<Float> Frac(RValue<Float> x)
5881 return Float4(Frac(Float4(x))).x;
5884 RValue<Float> Floor(RValue<Float> x)
5886 return Float4(Floor(Float4(x))).x;
5889 RValue<Float> Ceil(RValue<Float> x)
5891 return Float4(Ceil(Float4(x))).x;
5894 Type *Float::getType()
5896 return T(Ice::IceType_f32);
5899 Float2::Float2(RValue<Float4> cast)
5901 storeValue(Nucleus::createBitCast(cast.value, getType()));
5904 Type *Float2::getType()
5906 return T(Type_v2f32);
5909 Float4::Float4(RValue<Byte4> cast)
5913 assert(false && "UNIMPLEMENTED");
5916 Float4::Float4(RValue<SByte4> cast)
5920 assert(false && "UNIMPLEMENTED");
5923 Float4::Float4(RValue<Short4> cast)
5928 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
5931 Float4::Float4(RValue<UShort4> cast)
5936 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
5939 Float4::Float4(RValue<Int4> cast)
5943 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType());
5948 Float4::Float4(RValue<UInt4> cast)
5952 Value *xyzw = Nucleus::createUIToFP(cast.value, Float4::getType());
5962 Float4::Float4(float xyzw)
5964 constant(xyzw, xyzw, xyzw, xyzw);
5967 Float4::Float4(float x, float yzw)
5969 constant(x, yzw, yzw, yzw);
5972 Float4::Float4(float x, float y, float zw)
5974 constant(x, y, zw, zw);
5977 Float4::Float4(float x, float y, float z, float w)
5979 constant(x, y, z, w);
5982 void Float4::constant(float x, float y, float z, float w)
5986 double constantVector[4] = {x, y, z, w};
5987 storeValue(Nucleus::createConstantVector(constantVector, getType()));
5990 Float4::Float4(RValue<Float4> rhs)
5994 storeValue(rhs.value);
5997 Float4::Float4(const Float4 &rhs)
6001 Value *value = rhs.loadValue();
6005 Float4::Float4(const Reference<Float4> &rhs)
6009 Value *value = rhs.loadValue();
6013 Float4::Float4(RValue<Float> rhs)
6017 assert(false && "UNIMPLEMENTED");
6020 Float4::Float4(const Float &rhs)
6024 *this = RValue<Float>(rhs.loadValue());
6027 Float4::Float4(const Reference<Float> &rhs)
6031 *this = RValue<Float>(rhs.loadValue());
6034 RValue<Float4> Float4::operator=(float x) const
6036 return *this = Float4(x, x, x, x);
6039 RValue<Float4> Float4::operator=(RValue<Float4> rhs) const
6041 storeValue(rhs.value);
6046 RValue<Float4> Float4::operator=(const Float4 &rhs) const
6048 Value *value = rhs.loadValue();
6051 return RValue<Float4>(value);
6054 RValue<Float4> Float4::operator=(const Reference<Float4> &rhs) const
6056 Value *value = rhs.loadValue();
6059 return RValue<Float4>(value);
6062 RValue<Float4> Float4::operator=(RValue<Float> rhs) const
6064 return *this = Float4(rhs);
6067 RValue<Float4> Float4::operator=(const Float &rhs) const
6069 return *this = Float4(rhs);
6072 RValue<Float4> Float4::operator=(const Reference<Float> &rhs) const
6074 return *this = Float4(rhs);
6077 RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs)
6079 return RValue<Float4>(Nucleus::createFAdd(lhs.value, rhs.value));
6082 RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs)
6084 return RValue<Float4>(Nucleus::createFSub(lhs.value, rhs.value));
6087 RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs)
6089 return RValue<Float4>(Nucleus::createFMul(lhs.value, rhs.value));
6092 RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs)
6094 return RValue<Float4>(Nucleus::createFDiv(lhs.value, rhs.value));
6097 RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs)
6099 return RValue<Float4>(Nucleus::createFRem(lhs.value, rhs.value));
6102 RValue<Float4> operator+=(const Float4 &lhs, RValue<Float4> rhs)
6104 return lhs = lhs + rhs;
6107 RValue<Float4> operator-=(const Float4 &lhs, RValue<Float4> rhs)
6109 return lhs = lhs - rhs;
6112 RValue<Float4> operator*=(const Float4 &lhs, RValue<Float4> rhs)
6114 return lhs = lhs * rhs;
6117 RValue<Float4> operator/=(const Float4 &lhs, RValue<Float4> rhs)
6119 return lhs = lhs / rhs;
6122 RValue<Float4> operator%=(const Float4 &lhs, RValue<Float4> rhs)
6124 return lhs = lhs % rhs;
6127 RValue<Float4> operator+(RValue<Float4> val)
6132 RValue<Float4> operator-(RValue<Float4> val)
6134 return RValue<Float4>(Nucleus::createFNeg(val.value));
6137 RValue<Float4> Abs(RValue<Float4> x)
6139 assert(false && "UNIMPLEMENTED"); return RValue<Float4>(V(nullptr));
6142 RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y)
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);
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);
6152 return RValue<Float4>(V(result));
6155 RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y)
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);
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);
6165 return RValue<Float4>(V(result));
6168 RValue<Float4> Rcp_pp(RValue<Float4> x, bool exactAtPow2)
6170 return Float4(1.0f) / x;
6173 RValue<Float4> RcpSqrt_pp(RValue<Float4> x)
6175 return Rcp_pp(Sqrt(x));
6178 RValue<Float4> Sqrt(RValue<Float4> x)
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);
6187 return RValue<Float4>(V(result));
6190 RValue<Float4> Insert(RValue<Float4> x, RValue<Float> element, int i)
6192 return RValue<Float4>(Nucleus::createInsertElement(x.value, element.value, i));
6195 RValue<Float> Extract(RValue<Float4> x, int i)
6197 return RValue<Float>(Nucleus::createExtractElement(x.value, Float::getType(), i));
6200 RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select)
6202 return RValue<Float4>(createSwizzle4(x.value, select));
6205 RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
6209 ((imm >> 0) & 0x03) + 0,
6210 ((imm >> 2) & 0x03) + 0,
6211 ((imm >> 4) & 0x03) + 4,
6212 ((imm >> 6) & 0x03) + 4,
6215 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
6218 RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y)
6220 int shuffle[4] = {0, 4, 1, 5};
6221 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
6224 RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y)
6226 int shuffle[4] = {2, 6, 3, 7};
6227 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
6230 RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select)
6232 Value *vector = lhs.loadValue();
6233 Value *shuffle = createMask4(vector, rhs.value, select);
6234 lhs.storeValue(shuffle);
6236 return RValue<Float4>(shuffle);
6239 RValue<Int> SignMask(RValue<Float4> x)
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);
6248 return RValue<Int>(V(result));
6251 RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y)
6253 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOEQ(x.value, y.value), Int4::getType()));
6256 RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y)
6258 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOLT(x.value, y.value), Int4::getType()));
6261 RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y)
6263 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOLE(x.value, y.value), Int4::getType()));
6266 RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y)
6268 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpONE(x.value, y.value), Int4::getType()));
6271 RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y)
6273 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOGE(x.value, y.value), Int4::getType()));
6276 RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y)
6278 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOGT(x.value, y.value), Int4::getType()));
6281 RValue<Float4> Round(RValue<Float4> x)
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);
6291 return RValue<Float4>(V(result));
6294 RValue<Float4> Trunc(RValue<Float4> x)
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);
6304 return RValue<Float4>(V(result));
6307 RValue<Float4> Frac(RValue<Float4> x)
6309 return x - Floor(x);
6312 RValue<Float4> Floor(RValue<Float4> x)
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);
6322 return RValue<Float4>(V(result));
6325 RValue<Float4> Ceil(RValue<Float4> x)
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);
6335 return RValue<Float4>(V(result));
6338 Type *Float4::getType()
6340 return T(Ice::IceType_v4f32);
6343 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset)
6345 return lhs + RValue<Int>(Nucleus::createConstantInt(offset));
6348 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
6350 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value));
6353 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
6355 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value));
6358 RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, int offset)
6360 return lhs = lhs + offset;
6363 RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, RValue<Int> offset)
6365 return lhs = lhs + offset;
6368 RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, RValue<UInt> offset)
6370 return lhs = lhs + offset;
6373 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset)
6375 return lhs + -offset;
6378 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
6380 return lhs + -offset;
6383 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
6385 return lhs + -offset;
6388 RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, int offset)
6390 return lhs = lhs - offset;
6393 RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, RValue<Int> offset)
6395 return lhs = lhs - offset;
6398 RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, RValue<UInt> offset)
6400 return lhs = lhs - offset;
6405 Nucleus::createRetVoid();
6406 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
6407 Nucleus::createUnreachable();
6410 void Return(bool ret)
6412 Nucleus::createRet(Nucleus::createConstantInt(ret));
6413 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
6414 Nucleus::createUnreachable();
6417 void Return(const Int &ret)
6419 Nucleus::createRet(ret.loadValue());
6420 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
6421 Nucleus::createUnreachable();
6424 bool branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB)
6426 Nucleus::createCondBr(cmp.value, bodyBB, endBB);
6427 Nucleus::setInsertBlock(bodyBB);
6432 void endIf(BasicBlock *falseBB)
6434 ::falseBB = falseBB;
6437 bool elseBlock(BasicBlock *falseBB)
6439 assert(falseBB && "Else not preceded by If");
6440 falseBB->getInsts().back().setDeleted();
6441 Nucleus::setInsertBlock(falseBB);
6446 BasicBlock *beginElse()
6448 BasicBlock *falseBB = ::falseBB;
6449 ::falseBB = nullptr;
6454 RValue<Long> Ticks()
6456 assert(false && "UNIMPLEMENTED"); return RValue<Long>(V(nullptr));