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 "Optimizer.hpp"
22 #include "src/IceTypes.h"
23 #include "src/IceCfg.h"
24 #include "src/IceELFStreamer.h"
25 #include "src/IceGlobalContext.h"
26 #include "src/IceCfgNode.h"
27 #include "src/IceELFObjectWriter.h"
28 #include "src/IceGlobalInits.h"
30 #include "llvm/Support/FileSystem.h"
31 #include "llvm/Support/raw_os_ostream.h"
34 #ifndef WIN32_LEAN_AND_MEAN
35 #define WIN32_LEAN_AND_MEAN
36 #endif // !WIN32_LEAN_AND_MEAN
43 #if !defined(MAP_ANONYMOUS)
44 #define MAP_ANONYMOUS MAP_ANON
55 Ice::GlobalContext *context = nullptr;
56 Ice::Cfg *function = nullptr;
57 Ice::CfgNode *basicBlock = nullptr;
58 Ice::CfgLocalAllocatorScope *allocator = nullptr;
59 sw::Routine *routine = nullptr;
61 std::mutex codegenMutex;
63 Ice::ELFFileStreamer *elfFile = nullptr;
64 Ice::Fdstream *out = nullptr;
69 #if !defined(__i386__) && defined(_M_IX86)
73 #if !defined(__x86_64__) && (defined(_M_AMD64) || defined (_M_X64))
80 const static bool SSE4_1;
83 static void cpuid(int registers[4], int info)
85 #if defined(__i386__) || defined(__x86_64__)
87 __cpuid(registers, info);
89 __asm volatile("cpuid": "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]): "a" (info));
99 static bool detectSSE4_1()
101 #if defined(__i386__) || defined(__x86_64__)
104 return (registers[2] & 0x00080000) != 0;
111 const bool CPUID::SSE4_1 = CPUID::detectSSE4_1();
119 EmulatedV2 = 2 << EmulatedShift,
120 EmulatedV4 = 4 << EmulatedShift,
121 EmulatedV8 = 8 << EmulatedShift,
122 EmulatedBits = EmulatedV2 | EmulatedV4 | EmulatedV8,
124 Type_v2i32 = Ice::IceType_v4i32 | EmulatedV2,
125 Type_v4i16 = Ice::IceType_v8i16 | EmulatedV4,
126 Type_v2i16 = Ice::IceType_v8i16 | EmulatedV2,
127 Type_v8i8 = Ice::IceType_v16i8 | EmulatedV8,
128 Type_v4i8 = Ice::IceType_v16i8 | EmulatedV4,
129 Type_v2f32 = Ice::IceType_v4f32 | EmulatedV2,
132 class Value : public Ice::Operand {};
133 class SwitchCases : public Ice::InstSwitch {};
134 class BasicBlock : public Ice::CfgNode {};
138 static_assert(static_cast<unsigned int>(Ice::IceType_NUM) < static_cast<unsigned int>(EmulatedBits), "Ice::Type overlaps with our emulated types!");
139 return (Ice::Type)(reinterpret_cast<std::intptr_t>(t) & ~EmulatedBits);
144 return reinterpret_cast<Type*>(t);
147 Type *T(EmulatedType t)
149 return reinterpret_cast<Type*>(t);
152 Value *V(Ice::Operand *v)
154 return reinterpret_cast<Value*>(v);
157 BasicBlock *B(Ice::CfgNode *b)
159 return reinterpret_cast<BasicBlock*>(b);
162 static size_t typeSize(Type *type)
164 if(reinterpret_cast<std::intptr_t>(type) & EmulatedBits)
166 switch(reinterpret_cast<std::intptr_t>(type))
168 case Type_v2i32: return 8;
169 case Type_v4i16: return 8;
170 case Type_v2i16: return 4;
171 case Type_v8i8: return 8;
172 case Type_v4i8: return 4;
173 case Type_v2f32: return 8;
174 default: assert(false);
178 return Ice::typeWidthInBytes(T(type));
181 Optimization optimization[10] = {InstructionCombining, Disabled};
183 using ElfHeader = std::conditional<sizeof(void*) == 8, Elf64_Ehdr, Elf32_Ehdr>::type;
184 using SectionHeader = std::conditional<sizeof(void*) == 8, Elf64_Shdr, Elf32_Shdr>::type;
186 inline const SectionHeader *sectionHeader(const ElfHeader *elfHeader)
188 return reinterpret_cast<const SectionHeader*>((intptr_t)elfHeader + elfHeader->e_shoff);
191 inline const SectionHeader *elfSection(const ElfHeader *elfHeader, int index)
193 return §ionHeader(elfHeader)[index];
196 static void *relocateSymbol(const ElfHeader *elfHeader, const Elf32_Rel &relocation, const SectionHeader &relocationTable)
198 const SectionHeader *target = elfSection(elfHeader, relocationTable.sh_info);
200 intptr_t address = (intptr_t)elfHeader + target->sh_offset;
201 int32_t *patchSite = (int*)(address + relocation.r_offset);
202 uint32_t index = relocation.getSymbol();
203 int table = relocationTable.sh_link;
204 void *symbolValue = nullptr;
206 if(index != SHN_UNDEF)
208 if(table == SHN_UNDEF) return nullptr;
209 const SectionHeader *symbolTable = elfSection(elfHeader, table);
211 uint32_t symtab_entries = symbolTable->sh_size / symbolTable->sh_entsize;
212 if(index >= symtab_entries)
214 assert(index < symtab_entries && "Symbol Index out of range");
218 intptr_t symbolAddress = (intptr_t)elfHeader + symbolTable->sh_offset;
219 Elf32_Sym &symbol = ((Elf32_Sym*)symbolAddress)[index];
220 uint16_t section = symbol.st_shndx;
222 if(section != SHN_UNDEF && section < SHN_LORESERVE)
224 const SectionHeader *target = elfSection(elfHeader, symbol.st_shndx);
225 symbolValue = reinterpret_cast<void*>((intptr_t)elfHeader + symbol.st_value + target->sh_offset);
233 #if defined(__i386__)
234 switch(relocation.getType())
240 *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite);
243 // *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite - (intptr_t)patchSite);
246 assert(false && "Unsupported relocation type");
249 #elif defined(__arm__)
250 switch(relocation.getType())
255 case R_ARM_MOVW_ABS_NC:
257 uint32_t thumb = 0; // Calls to Thumb code not supported.
258 uint32_t lo = (uint32_t)symbolValue | thumb;
259 *patchSite = (*patchSite & 0xFFF0F000) | ((lo & 0xF000) << 4) | (lo & 0x0FFF);
264 uint32_t hi = (uint32_t)(symbolValue) >> 16;
265 *patchSite = (*patchSite & 0xFFF0F000) | ((hi & 0xF000) << 4) | (hi & 0x0FFF);
269 assert(false && "Unsupported relocation type");
277 static void *relocateSymbol(const ElfHeader *elfHeader, const Elf64_Rela &relocation, const SectionHeader &relocationTable)
279 const SectionHeader *target = elfSection(elfHeader, relocationTable.sh_info);
281 intptr_t address = (intptr_t)elfHeader + target->sh_offset;
282 int32_t *patchSite = (int*)(address + relocation.r_offset);
283 uint32_t index = relocation.getSymbol();
284 int table = relocationTable.sh_link;
285 void *symbolValue = nullptr;
287 if(index != SHN_UNDEF)
289 if(table == SHN_UNDEF) return nullptr;
290 const SectionHeader *symbolTable = elfSection(elfHeader, table);
292 uint32_t symtab_entries = symbolTable->sh_size / symbolTable->sh_entsize;
293 if(index >= symtab_entries)
295 assert(index < symtab_entries && "Symbol Index out of range");
299 intptr_t symbolAddress = (intptr_t)elfHeader + symbolTable->sh_offset;
300 Elf64_Sym &symbol = ((Elf64_Sym*)symbolAddress)[index];
301 uint16_t section = symbol.st_shndx;
303 if(section != SHN_UNDEF && section < SHN_LORESERVE)
305 const SectionHeader *target = elfSection(elfHeader, symbol.st_shndx);
306 symbolValue = reinterpret_cast<void*>((intptr_t)elfHeader + symbol.st_value + target->sh_offset);
314 #if defined(__x86_64__)
315 switch(relocation.getType())
321 *(int64_t*)patchSite = (int64_t)((intptr_t)symbolValue + *(int64_t*)patchSite) + relocation.r_addend;
324 *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite - (intptr_t)patchSite) + relocation.r_addend;
327 *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite) + relocation.r_addend;
330 assert(false && "Unsupported relocation type");
338 void *loadImage(uint8_t *const elfImage, size_t &codeSize)
340 ElfHeader *elfHeader = (ElfHeader*)elfImage;
342 if(!elfHeader->checkMagic())
347 // Expect ELF bitness to match platform
348 assert(sizeof(void*) == 8 ? elfHeader->getFileClass() == ELFCLASS64 : elfHeader->getFileClass() == ELFCLASS32);
349 #if defined(__i386__)
350 assert(sizeof(void*) == 4 && elfHeader->e_machine == EM_386);
351 #elif defined(__x86_64__)
352 assert(sizeof(void*) == 8 && elfHeader->e_machine == EM_X86_64);
353 #elif defined(__arm__)
354 assert(sizeof(void*) == 4 && elfHeader->e_machine == EM_ARM);
356 #error "Unsupported platform"
359 SectionHeader *sectionHeader = (SectionHeader*)(elfImage + elfHeader->e_shoff);
360 void *entry = nullptr;
362 for(int i = 0; i < elfHeader->e_shnum; i++)
364 if(sectionHeader[i].sh_type == SHT_PROGBITS)
366 if(sectionHeader[i].sh_flags & SHF_EXECINSTR)
368 entry = elfImage + sectionHeader[i].sh_offset;
369 codeSize = sectionHeader[i].sh_size;
372 else if(sectionHeader[i].sh_type == SHT_REL)
374 assert(sizeof(void*) == 4 && "UNIMPLEMENTED"); // Only expected/implemented for 32-bit code
376 for(Elf32_Word index = 0; index < sectionHeader[i].sh_size / sectionHeader[i].sh_entsize; index++)
378 const Elf32_Rel &relocation = ((const Elf32_Rel*)(elfImage + sectionHeader[i].sh_offset))[index];
379 relocateSymbol(elfHeader, relocation, sectionHeader[i]);
382 else if(sectionHeader[i].sh_type == SHT_RELA)
384 assert(sizeof(void*) == 8 && "UNIMPLEMENTED"); // Only expected/implemented for 64-bit code
386 for(Elf32_Word index = 0; index < sectionHeader[i].sh_size / sectionHeader[i].sh_entsize; index++)
388 const Elf64_Rela &relocation = ((const Elf64_Rela*)(elfImage + sectionHeader[i].sh_offset))[index];
389 relocateSymbol(elfHeader, relocation, sectionHeader[i]);
398 struct ExecutableAllocator
400 ExecutableAllocator() {};
401 template<class U> ExecutableAllocator(const ExecutableAllocator<U> &other) {};
403 using value_type = T;
404 using size_type = std::size_t;
406 T *allocate(size_type n)
409 return (T*)VirtualAlloc(NULL, sizeof(T) * n, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
411 return (T*)mmap(nullptr, sizeof(T) * n, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
415 void deallocate(T *p, size_type n)
418 VirtualFree(p, 0, MEM_RELEASE);
420 munmap(p, sizeof(T) * n);
425 class ELFMemoryStreamer : public Ice::ELFStreamer, public Routine
427 ELFMemoryStreamer(const ELFMemoryStreamer &) = delete;
428 ELFMemoryStreamer &operator=(const ELFMemoryStreamer &) = delete;
431 ELFMemoryStreamer() : Routine(), entry(nullptr)
434 buffer.reserve(0x1000);
437 virtual ~ELFMemoryStreamer()
440 if(buffer.size() != 0)
443 VirtualProtect(&buffer[0], buffer.size(), oldProtection, &exeProtection);
448 void write8(uint8_t Value) override
450 if(position == (uint64_t)buffer.size())
452 buffer.push_back(Value);
455 else if(position < (uint64_t)buffer.size())
457 buffer[position] = Value;
460 else assert(false && "UNIMPLEMENTED");
463 void writeBytes(llvm::StringRef Bytes) override
465 std::size_t oldSize = buffer.size();
466 buffer.resize(oldSize + Bytes.size());
467 memcpy(&buffer[oldSize], Bytes.begin(), Bytes.size());
468 position += Bytes.size();
471 uint64_t tell() const override { return position; }
473 void seek(uint64_t Off) override { position = Off; }
475 const void *getEntry() override
480 VirtualProtect(&buffer[0], buffer.size(), PAGE_EXECUTE_READWRITE, &oldProtection);
482 mprotect(&buffer[0], buffer.size(), PROT_READ | PROT_WRITE | PROT_EXEC);
485 position = std::numeric_limits<std::size_t>::max(); // Can't stream more data after this
488 entry = loadImage(&buffer[0], codeSize);
491 FlushInstructionCache(GetCurrentProcess(), NULL, 0);
493 __builtin___clear_cache((char*)entry, (char*)entry + codeSize);
502 std::vector<uint8_t, ExecutableAllocator<uint8_t>> buffer;
503 std::size_t position;
512 ::codegenMutex.lock(); // Reactor is currently not thread safe
514 Ice::ClFlags &Flags = Ice::ClFlags::Flags;
515 Ice::ClFlags::getParsedClFlags(Flags);
518 Flags.setTargetArch(Ice::Target_ARM32);
519 Flags.setTargetInstructionSet(Ice::ARM32InstructionSet_HWDivArm);
521 Flags.setTargetArch(sizeof(void*) == 8 ? Ice::Target_X8664 : Ice::Target_X8632);
522 Flags.setTargetInstructionSet(CPUID::SSE4_1 ? Ice::X86InstructionSet_SSE4_1 : Ice::X86InstructionSet_SSE2);
524 Flags.setOutFileType(Ice::FT_Elf);
525 Flags.setOptLevel(Ice::Opt_2);
526 Flags.setApplicationBinaryInterface(Ice::ABI_Platform);
527 Flags.setVerbose(false ? Ice::IceV_Most : Ice::IceV_None);
528 Flags.setDisableHybridAssembly(true);
530 static llvm::raw_os_ostream cout(std::cout);
531 static llvm::raw_os_ostream cerr(std::cerr);
533 if(false) // Write out to a file
535 std::error_code errorCode;
536 ::out = new Ice::Fdstream("out.o", errorCode, llvm::sys::fs::F_None);
537 ::elfFile = new Ice::ELFFileStreamer(*out);
538 ::context = new Ice::GlobalContext(&cout, &cout, &cerr, elfFile);
542 ELFMemoryStreamer *elfMemory = new ELFMemoryStreamer();
543 ::context = new Ice::GlobalContext(&cout, &cout, &cerr, elfMemory);
544 ::routine = elfMemory;
557 ::codegenMutex.unlock();
560 Routine *Nucleus::acquireRoutine(const wchar_t *name, bool runOptimizations)
562 if(basicBlock->getInsts().empty() || basicBlock->getInsts().back().getKind() != Ice::Inst::Ret)
567 std::wstring wideName(name);
568 std::string asciiName(wideName.begin(), wideName.end());
569 ::function->setFunctionName(Ice::GlobalString::createWithString(::context, asciiName));
573 ::function->translate();
574 assert(!::function->hasError());
576 auto *globals = ::function->getGlobalInits().release();
578 if(globals && !globals->empty())
580 ::context->getGlobals()->merge(globals);
583 ::context->emitFileHeader();
584 ::function->emitIAS();
585 auto assembler = ::function->releaseAssembler();
586 auto objectWriter = ::context->getObjectWriter();
587 assembler->alignFunction();
588 objectWriter->writeFunctionCode(::function->getFunctionName(), false, assembler.get());
589 ::context->lowerGlobals("last");
590 ::context->lowerConstants();
591 ::context->lowerJumpTables();
592 objectWriter->setUndefinedSyms(::context->getConstantExternSyms());
593 objectWriter->writeNonUserSections();
598 void Nucleus::optimize()
600 sw::optimize(::function);
603 Value *Nucleus::allocateStackVariable(Type *t, int arraySize)
605 Ice::Type type = T(t);
606 int typeSize = Ice::typeWidthInBytes(type);
607 int totalSize = typeSize * (arraySize ? arraySize : 1);
609 auto bytes = Ice::ConstantInteger32::create(::context, type, totalSize);
610 auto address = ::function->makeVariable(T(getPointerType(t)));
611 auto alloca = Ice::InstAlloca::create(::function, address, bytes, typeSize);
612 ::function->getEntryNode()->getInsts().push_front(alloca);
617 BasicBlock *Nucleus::createBasicBlock()
619 return B(::function->makeNode());
622 BasicBlock *Nucleus::getInsertBlock()
624 return B(::basicBlock);
627 void Nucleus::setInsertBlock(BasicBlock *basicBlock)
629 // assert(::basicBlock->getInsts().back().getTerminatorEdges().size() >= 0 && "Previous basic block must have a terminator");
630 ::basicBlock = basicBlock;
633 void Nucleus::createFunction(Type *ReturnType, std::vector<Type*> &Params)
635 uint32_t sequenceNumber = 0;
636 ::function = Ice::Cfg::create(::context, sequenceNumber).release();
637 ::allocator = new Ice::CfgLocalAllocatorScope(::function);
639 for(Type *type : Params)
641 Ice::Variable *arg = ::function->makeVariable(T(type));
642 ::function->addArg(arg);
645 Ice::CfgNode *node = ::function->makeNode();
646 ::function->setEntryNode(node);
650 Value *Nucleus::getArgument(unsigned int index)
652 return V(::function->getArgs()[index]);
655 void Nucleus::createRetVoid()
657 Ice::InstRet *ret = Ice::InstRet::create(::function);
658 ::basicBlock->appendInst(ret);
661 void Nucleus::createRet(Value *v)
663 Ice::InstRet *ret = Ice::InstRet::create(::function, v);
664 ::basicBlock->appendInst(ret);
667 void Nucleus::createBr(BasicBlock *dest)
669 auto br = Ice::InstBr::create(::function, dest);
670 ::basicBlock->appendInst(br);
673 void Nucleus::createCondBr(Value *cond, BasicBlock *ifTrue, BasicBlock *ifFalse)
675 auto br = Ice::InstBr::create(::function, cond, ifTrue, ifFalse);
676 ::basicBlock->appendInst(br);
679 static bool isCommutative(Ice::InstArithmetic::OpKind op)
683 case Ice::InstArithmetic::Add:
684 case Ice::InstArithmetic::Fadd:
685 case Ice::InstArithmetic::Mul:
686 case Ice::InstArithmetic::Fmul:
687 case Ice::InstArithmetic::And:
688 case Ice::InstArithmetic::Or:
689 case Ice::InstArithmetic::Xor:
696 static Value *createArithmetic(Ice::InstArithmetic::OpKind op, Value *lhs, Value *rhs)
698 assert(lhs->getType() == rhs->getType() || (llvm::isa<Ice::Constant>(rhs) && (op == Ice::InstArithmetic::Shl || Ice::InstArithmetic::Lshr || Ice::InstArithmetic::Ashr)));
700 bool swapOperands = llvm::isa<Ice::Constant>(lhs) && isCommutative(op);
702 Ice::Variable *result = ::function->makeVariable(lhs->getType());
703 Ice::InstArithmetic *arithmetic = Ice::InstArithmetic::create(::function, op, result, swapOperands ? rhs : lhs, swapOperands ? lhs : rhs);
704 ::basicBlock->appendInst(arithmetic);
709 Value *Nucleus::createAdd(Value *lhs, Value *rhs)
711 return createArithmetic(Ice::InstArithmetic::Add, lhs, rhs);
714 Value *Nucleus::createSub(Value *lhs, Value *rhs)
716 return createArithmetic(Ice::InstArithmetic::Sub, lhs, rhs);
719 Value *Nucleus::createMul(Value *lhs, Value *rhs)
721 return createArithmetic(Ice::InstArithmetic::Mul, lhs, rhs);
724 Value *Nucleus::createUDiv(Value *lhs, Value *rhs)
726 return createArithmetic(Ice::InstArithmetic::Udiv, lhs, rhs);
729 Value *Nucleus::createSDiv(Value *lhs, Value *rhs)
731 return createArithmetic(Ice::InstArithmetic::Sdiv, lhs, rhs);
734 Value *Nucleus::createFAdd(Value *lhs, Value *rhs)
736 return createArithmetic(Ice::InstArithmetic::Fadd, lhs, rhs);
739 Value *Nucleus::createFSub(Value *lhs, Value *rhs)
741 return createArithmetic(Ice::InstArithmetic::Fsub, lhs, rhs);
744 Value *Nucleus::createFMul(Value *lhs, Value *rhs)
746 return createArithmetic(Ice::InstArithmetic::Fmul, lhs, rhs);
749 Value *Nucleus::createFDiv(Value *lhs, Value *rhs)
751 return createArithmetic(Ice::InstArithmetic::Fdiv, lhs, rhs);
754 Value *Nucleus::createURem(Value *lhs, Value *rhs)
756 return createArithmetic(Ice::InstArithmetic::Urem, lhs, rhs);
759 Value *Nucleus::createSRem(Value *lhs, Value *rhs)
761 return createArithmetic(Ice::InstArithmetic::Srem, lhs, rhs);
764 Value *Nucleus::createFRem(Value *lhs, Value *rhs)
766 return createArithmetic(Ice::InstArithmetic::Frem, lhs, rhs);
769 Value *Nucleus::createShl(Value *lhs, Value *rhs)
771 return createArithmetic(Ice::InstArithmetic::Shl, lhs, rhs);
774 Value *Nucleus::createLShr(Value *lhs, Value *rhs)
776 return createArithmetic(Ice::InstArithmetic::Lshr, lhs, rhs);
779 Value *Nucleus::createAShr(Value *lhs, Value *rhs)
781 return createArithmetic(Ice::InstArithmetic::Ashr, lhs, rhs);
784 Value *Nucleus::createAnd(Value *lhs, Value *rhs)
786 return createArithmetic(Ice::InstArithmetic::And, lhs, rhs);
789 Value *Nucleus::createOr(Value *lhs, Value *rhs)
791 return createArithmetic(Ice::InstArithmetic::Or, lhs, rhs);
794 Value *Nucleus::createXor(Value *lhs, Value *rhs)
796 return createArithmetic(Ice::InstArithmetic::Xor, lhs, rhs);
799 Value *Nucleus::createNeg(Value *v)
801 return createSub(createNullValue(T(v->getType())), v);
804 Value *Nucleus::createFNeg(Value *v)
806 double c[4] = {-0.0, -0.0, -0.0, -0.0};
807 Value *negativeZero = Ice::isVectorType(v->getType()) ?
808 createConstantVector(c, T(v->getType())) :
809 V(::context->getConstantFloat(-0.0f));
811 return createFSub(negativeZero, v);
814 Value *Nucleus::createNot(Value *v)
816 if(Ice::isScalarIntegerType(v->getType()))
818 return createXor(v, V(::context->getConstantInt(v->getType(), -1)));
822 int64_t c[4] = {-1, -1, -1, -1};
823 return createXor(v, createConstantVector(c, T(v->getType())));
827 Value *Nucleus::createLoad(Value *ptr, Type *type, bool isVolatile, unsigned int align)
829 int valueType = (int)reinterpret_cast<intptr_t>(type);
830 Ice::Variable *result = ::function->makeVariable(T(type));
832 if(valueType & EmulatedBits)
834 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::LoadSubVector, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
835 auto target = ::context->getConstantUndef(Ice::IceType_i32);
836 auto load = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
838 load->addArg(::context->getConstantInt32(typeSize(type)));
839 ::basicBlock->appendInst(load);
843 auto load = Ice::InstLoad::create(::function, result, ptr, align);
844 ::basicBlock->appendInst(load);
850 Value *Nucleus::createStore(Value *value, Value *ptr, Type *type, bool isVolatile, unsigned int align)
852 int valueType = (int)reinterpret_cast<intptr_t>(type);
854 if(valueType & EmulatedBits)
856 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::StoreSubVector, Ice::Intrinsics::SideEffects_T, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_T};
857 auto target = ::context->getConstantUndef(Ice::IceType_i32);
858 auto store = Ice::InstIntrinsicCall::create(::function, 3, nullptr, target, intrinsic);
859 store->addArg(value);
861 store->addArg(::context->getConstantInt32(typeSize(type)));
862 ::basicBlock->appendInst(store);
866 assert(T(value->getType()) == type);
868 auto store = Ice::InstStore::create(::function, value, ptr, align);
869 ::basicBlock->appendInst(store);
875 Value *Nucleus::createGEP(Value *ptr, Type *type, Value *index, bool unsignedIndex)
877 assert(index->getType() == Ice::IceType_i32);
879 if(auto *constant = llvm::dyn_cast<Ice::ConstantInteger32>(index))
881 int32_t offset = constant->getValue() * (int)typeSize(type);
888 return createAdd(ptr, createConstantInt(offset));
891 if(!Ice::isByteSizedType(T(type)))
893 index = createMul(index, createConstantInt((int)typeSize(type)));
896 if(sizeof(void*) == 8)
900 index = createZExt(index, T(Ice::IceType_i64));
904 index = createSExt(index, T(Ice::IceType_i64));
908 return createAdd(ptr, index);
911 Value *Nucleus::createAtomicAdd(Value *ptr, Value *value)
913 assert(false && "UNIMPLEMENTED"); return nullptr;
916 static Value *createCast(Ice::InstCast::OpKind op, Value *v, Type *destType)
918 if(v->getType() == T(destType))
923 Ice::Variable *result = ::function->makeVariable(T(destType));
924 Ice::InstCast *cast = Ice::InstCast::create(::function, op, result, v);
925 ::basicBlock->appendInst(cast);
930 Value *Nucleus::createTrunc(Value *v, Type *destType)
932 return createCast(Ice::InstCast::Trunc, v, destType);
935 Value *Nucleus::createZExt(Value *v, Type *destType)
937 return createCast(Ice::InstCast::Zext, v, destType);
940 Value *Nucleus::createSExt(Value *v, Type *destType)
942 return createCast(Ice::InstCast::Sext, v, destType);
945 Value *Nucleus::createFPToSI(Value *v, Type *destType)
947 return createCast(Ice::InstCast::Fptosi, v, destType);
950 Value *Nucleus::createSIToFP(Value *v, Type *destType)
952 return createCast(Ice::InstCast::Sitofp, v, destType);
955 Value *Nucleus::createFPTrunc(Value *v, Type *destType)
957 return createCast(Ice::InstCast::Fptrunc, v, destType);
960 Value *Nucleus::createFPExt(Value *v, Type *destType)
962 return createCast(Ice::InstCast::Fpext, v, destType);
965 Value *Nucleus::createBitCast(Value *v, Type *destType)
967 return createCast(Ice::InstCast::Bitcast, v, destType);
970 static Value *createIntCompare(Ice::InstIcmp::ICond condition, Value *lhs, Value *rhs)
972 assert(lhs->getType() == rhs->getType());
974 auto result = ::function->makeVariable(Ice::isScalarIntegerType(lhs->getType()) ? Ice::IceType_i1 : lhs->getType());
975 auto cmp = Ice::InstIcmp::create(::function, condition, result, lhs, rhs);
976 ::basicBlock->appendInst(cmp);
981 Value *Nucleus::createICmpEQ(Value *lhs, Value *rhs)
983 return createIntCompare(Ice::InstIcmp::Eq, lhs, rhs);
986 Value *Nucleus::createICmpNE(Value *lhs, Value *rhs)
988 return createIntCompare(Ice::InstIcmp::Ne, lhs, rhs);
991 Value *Nucleus::createICmpUGT(Value *lhs, Value *rhs)
993 return createIntCompare(Ice::InstIcmp::Ugt, lhs, rhs);
996 Value *Nucleus::createICmpUGE(Value *lhs, Value *rhs)
998 return createIntCompare(Ice::InstIcmp::Uge, lhs, rhs);
1001 Value *Nucleus::createICmpULT(Value *lhs, Value *rhs)
1003 return createIntCompare(Ice::InstIcmp::Ult, lhs, rhs);
1006 Value *Nucleus::createICmpULE(Value *lhs, Value *rhs)
1008 return createIntCompare(Ice::InstIcmp::Ule, lhs, rhs);
1011 Value *Nucleus::createICmpSGT(Value *lhs, Value *rhs)
1013 return createIntCompare(Ice::InstIcmp::Sgt, lhs, rhs);
1016 Value *Nucleus::createICmpSGE(Value *lhs, Value *rhs)
1018 return createIntCompare(Ice::InstIcmp::Sge, lhs, rhs);
1021 Value *Nucleus::createICmpSLT(Value *lhs, Value *rhs)
1023 return createIntCompare(Ice::InstIcmp::Slt, lhs, rhs);
1026 Value *Nucleus::createICmpSLE(Value *lhs, Value *rhs)
1028 return createIntCompare(Ice::InstIcmp::Sle, lhs, rhs);
1031 static Value *createFloatCompare(Ice::InstFcmp::FCond condition, Value *lhs, Value *rhs)
1033 assert(lhs->getType() == rhs->getType());
1034 assert(Ice::isScalarFloatingType(lhs->getType()) || lhs->getType() == Ice::IceType_v4f32);
1036 auto result = ::function->makeVariable(Ice::isScalarFloatingType(lhs->getType()) ? Ice::IceType_i1 : Ice::IceType_v4i32);
1037 auto cmp = Ice::InstFcmp::create(::function, condition, result, lhs, rhs);
1038 ::basicBlock->appendInst(cmp);
1043 Value *Nucleus::createFCmpOEQ(Value *lhs, Value *rhs)
1045 return createFloatCompare(Ice::InstFcmp::Oeq, lhs, rhs);
1048 Value *Nucleus::createFCmpOGT(Value *lhs, Value *rhs)
1050 return createFloatCompare(Ice::InstFcmp::Ogt, lhs, rhs);
1053 Value *Nucleus::createFCmpOGE(Value *lhs, Value *rhs)
1055 return createFloatCompare(Ice::InstFcmp::Oge, lhs, rhs);
1058 Value *Nucleus::createFCmpOLT(Value *lhs, Value *rhs)
1060 return createFloatCompare(Ice::InstFcmp::Olt, lhs, rhs);
1063 Value *Nucleus::createFCmpOLE(Value *lhs, Value *rhs)
1065 return createFloatCompare(Ice::InstFcmp::Ole, lhs, rhs);
1068 Value *Nucleus::createFCmpONE(Value *lhs, Value *rhs)
1070 return createFloatCompare(Ice::InstFcmp::One, lhs, rhs);
1073 Value *Nucleus::createFCmpORD(Value *lhs, Value *rhs)
1075 return createFloatCompare(Ice::InstFcmp::Ord, lhs, rhs);
1078 Value *Nucleus::createFCmpUNO(Value *lhs, Value *rhs)
1080 return createFloatCompare(Ice::InstFcmp::Uno, lhs, rhs);
1083 Value *Nucleus::createFCmpUEQ(Value *lhs, Value *rhs)
1085 return createFloatCompare(Ice::InstFcmp::Ueq, lhs, rhs);
1088 Value *Nucleus::createFCmpUGT(Value *lhs, Value *rhs)
1090 return createFloatCompare(Ice::InstFcmp::Ugt, lhs, rhs);
1093 Value *Nucleus::createFCmpUGE(Value *lhs, Value *rhs)
1095 return createFloatCompare(Ice::InstFcmp::Uge, lhs, rhs);
1098 Value *Nucleus::createFCmpULT(Value *lhs, Value *rhs)
1100 return createFloatCompare(Ice::InstFcmp::Ult, lhs, rhs);
1103 Value *Nucleus::createFCmpULE(Value *lhs, Value *rhs)
1105 return createFloatCompare(Ice::InstFcmp::Ule, lhs, rhs);
1108 Value *Nucleus::createFCmpUNE(Value *lhs, Value *rhs)
1110 return createFloatCompare(Ice::InstFcmp::Une, lhs, rhs);
1113 Value *Nucleus::createExtractElement(Value *vector, Type *type, int index)
1115 auto result = ::function->makeVariable(T(type));
1116 auto extract = Ice::InstExtractElement::create(::function, result, vector, ::context->getConstantInt32(index));
1117 ::basicBlock->appendInst(extract);
1122 Value *Nucleus::createInsertElement(Value *vector, Value *element, int index)
1124 auto result = ::function->makeVariable(vector->getType());
1125 auto insert = Ice::InstInsertElement::create(::function, result, vector, element, ::context->getConstantInt32(index));
1126 ::basicBlock->appendInst(insert);
1131 Value *Nucleus::createShuffleVector(Value *V1, Value *V2, const int *select)
1133 assert(V1->getType() == V2->getType());
1135 int size = Ice::typeNumElements(V1->getType());
1136 auto result = ::function->makeVariable(V1->getType());
1137 auto shuffle = Ice::InstShuffleVector::create(::function, result, V1, V2);
1139 for(int i = 0; i < size; i++)
1141 shuffle->addIndex(llvm::cast<Ice::ConstantInteger32>(::context->getConstantInt32(select[i])));
1144 ::basicBlock->appendInst(shuffle);
1149 Value *Nucleus::createSelect(Value *C, Value *ifTrue, Value *ifFalse)
1151 assert(ifTrue->getType() == ifFalse->getType());
1153 auto result = ::function->makeVariable(ifTrue->getType());
1154 auto *select = Ice::InstSelect::create(::function, result, C, ifTrue, ifFalse);
1155 ::basicBlock->appendInst(select);
1160 SwitchCases *Nucleus::createSwitch(Value *control, BasicBlock *defaultBranch, unsigned numCases)
1162 auto switchInst = Ice::InstSwitch::create(::function, numCases, control, defaultBranch);
1163 ::basicBlock->appendInst(switchInst);
1165 return reinterpret_cast<SwitchCases*>(switchInst);
1168 void Nucleus::addSwitchCase(SwitchCases *switchCases, int label, BasicBlock *branch)
1170 switchCases->addBranch(label, label, branch);
1173 void Nucleus::createUnreachable()
1175 Ice::InstUnreachable *unreachable = Ice::InstUnreachable::create(::function);
1176 ::basicBlock->appendInst(unreachable);
1179 static Value *createSwizzle4(Value *val, unsigned char select)
1183 (select >> 0) & 0x03,
1184 (select >> 2) & 0x03,
1185 (select >> 4) & 0x03,
1186 (select >> 6) & 0x03,
1189 return Nucleus::createShuffleVector(val, val, swizzle);
1192 static Value *createMask4(Value *lhs, Value *rhs, unsigned char select)
1194 int64_t mask[4] = {0, 0, 0, 0};
1196 mask[(select >> 0) & 0x03] = -1;
1197 mask[(select >> 2) & 0x03] = -1;
1198 mask[(select >> 4) & 0x03] = -1;
1199 mask[(select >> 6) & 0x03] = -1;
1201 Value *condition = Nucleus::createConstantVector(mask, T(Ice::IceType_v4i1));
1202 Value *result = Nucleus::createSelect(condition, rhs, lhs);
1207 Type *Nucleus::getPointerType(Type *ElementType)
1209 if(sizeof(void*) == 8)
1211 return T(Ice::IceType_i64);
1215 return T(Ice::IceType_i32);
1219 Value *Nucleus::createNullValue(Type *Ty)
1221 if(Ice::isVectorType(T(Ty)))
1223 assert(Ice::typeNumElements(T(Ty)) <= 16);
1224 int64_t c[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1225 return createConstantVector(c, Ty);
1229 return V(::context->getConstantZero(T(Ty)));
1233 Value *Nucleus::createConstantLong(int64_t i)
1235 return V(::context->getConstantInt64(i));
1238 Value *Nucleus::createConstantInt(int i)
1240 return V(::context->getConstantInt32(i));
1243 Value *Nucleus::createConstantInt(unsigned int i)
1245 return V(::context->getConstantInt32(i));
1248 Value *Nucleus::createConstantBool(bool b)
1250 return V(::context->getConstantInt1(b));
1253 Value *Nucleus::createConstantByte(signed char i)
1255 return V(::context->getConstantInt8(i));
1258 Value *Nucleus::createConstantByte(unsigned char i)
1260 return V(::context->getConstantInt8(i));
1263 Value *Nucleus::createConstantShort(short i)
1265 return V(::context->getConstantInt16(i));
1268 Value *Nucleus::createConstantShort(unsigned short i)
1270 return V(::context->getConstantInt16(i));
1273 Value *Nucleus::createConstantFloat(float x)
1275 return V(::context->getConstantFloat(x));
1278 Value *Nucleus::createNullPointer(Type *Ty)
1280 return createNullValue(T(sizeof(void*) == 8 ? Ice::IceType_i64 : Ice::IceType_i32));
1283 Value *Nucleus::createConstantVector(const int64_t *constants, Type *type)
1285 const int vectorSize = 16;
1286 assert(Ice::typeWidthInBytes(T(type)) == vectorSize);
1287 const int alignment = vectorSize;
1288 auto globalPool = ::function->getGlobalPool();
1290 const int64_t *i = constants;
1291 const double *f = reinterpret_cast<const double*>(constants);
1292 Ice::VariableDeclaration::DataInitializer *dataInitializer = nullptr;
1294 switch((int)reinterpret_cast<intptr_t>(type))
1296 case Ice::IceType_v4i32:
1297 case Ice::IceType_v4i1:
1299 const int initializer[4] = {(int)i[0], (int)i[1], (int)i[2], (int)i[3]};
1300 static_assert(sizeof(initializer) == vectorSize, "!");
1301 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1304 case Ice::IceType_v4f32:
1306 const float initializer[4] = {(float)f[0], (float)f[1], (float)f[2], (float)f[3]};
1307 static_assert(sizeof(initializer) == vectorSize, "!");
1308 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1311 case Ice::IceType_v8i16:
1312 case Ice::IceType_v8i1:
1314 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]};
1315 static_assert(sizeof(initializer) == vectorSize, "!");
1316 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1319 case Ice::IceType_v16i8:
1320 case Ice::IceType_v16i1:
1322 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]};
1323 static_assert(sizeof(initializer) == vectorSize, "!");
1324 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1329 const int initializer[4] = {(int)i[0], (int)i[1], (int)i[0], (int)i[1]};
1330 static_assert(sizeof(initializer) == vectorSize, "!");
1331 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1336 const float initializer[4] = {(float)f[0], (float)f[1], (float)f[0], (float)f[1]};
1337 static_assert(sizeof(initializer) == vectorSize, "!");
1338 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1343 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]};
1344 static_assert(sizeof(initializer) == vectorSize, "!");
1345 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1350 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]};
1351 static_assert(sizeof(initializer) == vectorSize, "!");
1352 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1357 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]};
1358 static_assert(sizeof(initializer) == vectorSize, "!");
1359 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1363 assert(false && "Unknown constant vector type" && type);
1366 auto name = Ice::GlobalString::createWithoutString(::context);
1367 auto *variableDeclaration = Ice::VariableDeclaration::create(globalPool);
1368 variableDeclaration->setName(name);
1369 variableDeclaration->setAlignment(alignment);
1370 variableDeclaration->setIsConstant(true);
1371 variableDeclaration->addInitializer(dataInitializer);
1373 ::function->addGlobal(variableDeclaration);
1375 constexpr int32_t offset = 0;
1376 Ice::Operand *ptr = ::context->getConstantSym(offset, name);
1378 Ice::Variable *result = ::function->makeVariable(T(type));
1379 auto load = Ice::InstLoad::create(::function, result, ptr, alignment);
1380 ::basicBlock->appendInst(load);
1385 Value *Nucleus::createConstantVector(const double *constants, Type *type)
1387 return createConstantVector((const int64_t*)constants, type);
1390 Type *Void::getType()
1392 return T(Ice::IceType_void);
1395 Bool::Bool(Argument<Bool> argument)
1397 storeValue(argument.value);
1402 storeValue(Nucleus::createConstantBool(x));
1405 Bool::Bool(RValue<Bool> rhs)
1407 storeValue(rhs.value);
1410 Bool::Bool(const Bool &rhs)
1412 Value *value = rhs.loadValue();
1416 Bool::Bool(const Reference<Bool> &rhs)
1418 Value *value = rhs.loadValue();
1422 RValue<Bool> Bool::operator=(RValue<Bool> rhs)
1424 storeValue(rhs.value);
1429 RValue<Bool> Bool::operator=(const Bool &rhs)
1431 Value *value = rhs.loadValue();
1434 return RValue<Bool>(value);
1437 RValue<Bool> Bool::operator=(const Reference<Bool> &rhs)
1439 Value *value = rhs.loadValue();
1442 return RValue<Bool>(value);
1445 RValue<Bool> operator!(RValue<Bool> val)
1447 return RValue<Bool>(Nucleus::createNot(val.value));
1450 RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs)
1452 return RValue<Bool>(Nucleus::createAnd(lhs.value, rhs.value));
1455 RValue<Bool> operator||(RValue<Bool> lhs, RValue<Bool> rhs)
1457 return RValue<Bool>(Nucleus::createOr(lhs.value, rhs.value));
1460 Type *Bool::getType()
1462 return T(Ice::IceType_i1);
1465 Byte::Byte(Argument<Byte> argument)
1467 storeValue(argument.value);
1470 Byte::Byte(RValue<Int> cast)
1472 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
1474 storeValue(integer);
1477 Byte::Byte(RValue<UInt> cast)
1479 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
1481 storeValue(integer);
1484 Byte::Byte(RValue<UShort> cast)
1486 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
1488 storeValue(integer);
1493 storeValue(Nucleus::createConstantByte((unsigned char)x));
1496 Byte::Byte(unsigned char x)
1498 storeValue(Nucleus::createConstantByte(x));
1501 Byte::Byte(RValue<Byte> rhs)
1503 storeValue(rhs.value);
1506 Byte::Byte(const Byte &rhs)
1508 Value *value = rhs.loadValue();
1512 Byte::Byte(const Reference<Byte> &rhs)
1514 Value *value = rhs.loadValue();
1518 RValue<Byte> Byte::operator=(RValue<Byte> rhs)
1520 storeValue(rhs.value);
1525 RValue<Byte> Byte::operator=(const Byte &rhs)
1527 Value *value = rhs.loadValue();
1530 return RValue<Byte>(value);
1533 RValue<Byte> Byte::operator=(const Reference<Byte> &rhs)
1535 Value *value = rhs.loadValue();
1538 return RValue<Byte>(value);
1541 RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs)
1543 return RValue<Byte>(Nucleus::createAdd(lhs.value, rhs.value));
1546 RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs)
1548 return RValue<Byte>(Nucleus::createSub(lhs.value, rhs.value));
1551 RValue<Byte> operator*(RValue<Byte> lhs, RValue<Byte> rhs)
1553 return RValue<Byte>(Nucleus::createMul(lhs.value, rhs.value));
1556 RValue<Byte> operator/(RValue<Byte> lhs, RValue<Byte> rhs)
1558 return RValue<Byte>(Nucleus::createUDiv(lhs.value, rhs.value));
1561 RValue<Byte> operator%(RValue<Byte> lhs, RValue<Byte> rhs)
1563 return RValue<Byte>(Nucleus::createURem(lhs.value, rhs.value));
1566 RValue<Byte> operator&(RValue<Byte> lhs, RValue<Byte> rhs)
1568 return RValue<Byte>(Nucleus::createAnd(lhs.value, rhs.value));
1571 RValue<Byte> operator|(RValue<Byte> lhs, RValue<Byte> rhs)
1573 return RValue<Byte>(Nucleus::createOr(lhs.value, rhs.value));
1576 RValue<Byte> operator^(RValue<Byte> lhs, RValue<Byte> rhs)
1578 return RValue<Byte>(Nucleus::createXor(lhs.value, rhs.value));
1581 RValue<Byte> operator<<(RValue<Byte> lhs, RValue<Byte> rhs)
1583 return RValue<Byte>(Nucleus::createShl(lhs.value, rhs.value));
1586 RValue<Byte> operator>>(RValue<Byte> lhs, RValue<Byte> rhs)
1588 return RValue<Byte>(Nucleus::createLShr(lhs.value, rhs.value));
1591 RValue<Byte> operator+=(Byte &lhs, RValue<Byte> rhs)
1593 return lhs = lhs + rhs;
1596 RValue<Byte> operator-=(Byte &lhs, RValue<Byte> rhs)
1598 return lhs = lhs - rhs;
1601 RValue<Byte> operator*=(Byte &lhs, RValue<Byte> rhs)
1603 return lhs = lhs * rhs;
1606 RValue<Byte> operator/=(Byte &lhs, RValue<Byte> rhs)
1608 return lhs = lhs / rhs;
1611 RValue<Byte> operator%=(Byte &lhs, RValue<Byte> rhs)
1613 return lhs = lhs % rhs;
1616 RValue<Byte> operator&=(Byte &lhs, RValue<Byte> rhs)
1618 return lhs = lhs & rhs;
1621 RValue<Byte> operator|=(Byte &lhs, RValue<Byte> rhs)
1623 return lhs = lhs | rhs;
1626 RValue<Byte> operator^=(Byte &lhs, RValue<Byte> rhs)
1628 return lhs = lhs ^ rhs;
1631 RValue<Byte> operator<<=(Byte &lhs, RValue<Byte> rhs)
1633 return lhs = lhs << rhs;
1636 RValue<Byte> operator>>=(Byte &lhs, RValue<Byte> rhs)
1638 return lhs = lhs >> rhs;
1641 RValue<Byte> operator+(RValue<Byte> val)
1646 RValue<Byte> operator-(RValue<Byte> val)
1648 return RValue<Byte>(Nucleus::createNeg(val.value));
1651 RValue<Byte> operator~(RValue<Byte> val)
1653 return RValue<Byte>(Nucleus::createNot(val.value));
1656 RValue<Byte> operator++(Byte &val, int) // Post-increment
1658 RValue<Byte> res = val;
1663 const Byte &operator++(Byte &val) // Pre-increment
1669 RValue<Byte> operator--(Byte &val, int) // Post-decrement
1671 RValue<Byte> res = val;
1676 const Byte &operator--(Byte &val) // Pre-decrement
1682 RValue<Bool> operator<(RValue<Byte> lhs, RValue<Byte> rhs)
1684 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1687 RValue<Bool> operator<=(RValue<Byte> lhs, RValue<Byte> rhs)
1689 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1692 RValue<Bool> operator>(RValue<Byte> lhs, RValue<Byte> rhs)
1694 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1697 RValue<Bool> operator>=(RValue<Byte> lhs, RValue<Byte> rhs)
1699 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1702 RValue<Bool> operator!=(RValue<Byte> lhs, RValue<Byte> rhs)
1704 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1707 RValue<Bool> operator==(RValue<Byte> lhs, RValue<Byte> rhs)
1709 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1712 Type *Byte::getType()
1714 return T(Ice::IceType_i8);
1717 SByte::SByte(Argument<SByte> argument)
1719 storeValue(argument.value);
1722 SByte::SByte(RValue<Int> cast)
1724 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1726 storeValue(integer);
1729 SByte::SByte(RValue<Short> cast)
1731 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1733 storeValue(integer);
1736 SByte::SByte(signed char x)
1738 storeValue(Nucleus::createConstantByte(x));
1741 SByte::SByte(RValue<SByte> rhs)
1743 storeValue(rhs.value);
1746 SByte::SByte(const SByte &rhs)
1748 Value *value = rhs.loadValue();
1752 SByte::SByte(const Reference<SByte> &rhs)
1754 Value *value = rhs.loadValue();
1758 RValue<SByte> SByte::operator=(RValue<SByte> rhs)
1760 storeValue(rhs.value);
1765 RValue<SByte> SByte::operator=(const SByte &rhs)
1767 Value *value = rhs.loadValue();
1770 return RValue<SByte>(value);
1773 RValue<SByte> SByte::operator=(const Reference<SByte> &rhs)
1775 Value *value = rhs.loadValue();
1778 return RValue<SByte>(value);
1781 RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs)
1783 return RValue<SByte>(Nucleus::createAdd(lhs.value, rhs.value));
1786 RValue<SByte> operator-(RValue<SByte> lhs, RValue<SByte> rhs)
1788 return RValue<SByte>(Nucleus::createSub(lhs.value, rhs.value));
1791 RValue<SByte> operator*(RValue<SByte> lhs, RValue<SByte> rhs)
1793 return RValue<SByte>(Nucleus::createMul(lhs.value, rhs.value));
1796 RValue<SByte> operator/(RValue<SByte> lhs, RValue<SByte> rhs)
1798 return RValue<SByte>(Nucleus::createSDiv(lhs.value, rhs.value));
1801 RValue<SByte> operator%(RValue<SByte> lhs, RValue<SByte> rhs)
1803 return RValue<SByte>(Nucleus::createSRem(lhs.value, rhs.value));
1806 RValue<SByte> operator&(RValue<SByte> lhs, RValue<SByte> rhs)
1808 return RValue<SByte>(Nucleus::createAnd(lhs.value, rhs.value));
1811 RValue<SByte> operator|(RValue<SByte> lhs, RValue<SByte> rhs)
1813 return RValue<SByte>(Nucleus::createOr(lhs.value, rhs.value));
1816 RValue<SByte> operator^(RValue<SByte> lhs, RValue<SByte> rhs)
1818 return RValue<SByte>(Nucleus::createXor(lhs.value, rhs.value));
1821 RValue<SByte> operator<<(RValue<SByte> lhs, RValue<SByte> rhs)
1823 return RValue<SByte>(Nucleus::createShl(lhs.value, rhs.value));
1826 RValue<SByte> operator>>(RValue<SByte> lhs, RValue<SByte> rhs)
1828 return RValue<SByte>(Nucleus::createAShr(lhs.value, rhs.value));
1831 RValue<SByte> operator+=(SByte &lhs, RValue<SByte> rhs)
1833 return lhs = lhs + rhs;
1836 RValue<SByte> operator-=(SByte &lhs, RValue<SByte> rhs)
1838 return lhs = lhs - rhs;
1841 RValue<SByte> operator*=(SByte &lhs, RValue<SByte> rhs)
1843 return lhs = lhs * rhs;
1846 RValue<SByte> operator/=(SByte &lhs, RValue<SByte> rhs)
1848 return lhs = lhs / rhs;
1851 RValue<SByte> operator%=(SByte &lhs, RValue<SByte> rhs)
1853 return lhs = lhs % rhs;
1856 RValue<SByte> operator&=(SByte &lhs, RValue<SByte> rhs)
1858 return lhs = lhs & rhs;
1861 RValue<SByte> operator|=(SByte &lhs, RValue<SByte> rhs)
1863 return lhs = lhs | rhs;
1866 RValue<SByte> operator^=(SByte &lhs, RValue<SByte> rhs)
1868 return lhs = lhs ^ rhs;
1871 RValue<SByte> operator<<=(SByte &lhs, RValue<SByte> rhs)
1873 return lhs = lhs << rhs;
1876 RValue<SByte> operator>>=(SByte &lhs, RValue<SByte> rhs)
1878 return lhs = lhs >> rhs;
1881 RValue<SByte> operator+(RValue<SByte> val)
1886 RValue<SByte> operator-(RValue<SByte> val)
1888 return RValue<SByte>(Nucleus::createNeg(val.value));
1891 RValue<SByte> operator~(RValue<SByte> val)
1893 return RValue<SByte>(Nucleus::createNot(val.value));
1896 RValue<SByte> operator++(SByte &val, int) // Post-increment
1898 RValue<SByte> res = val;
1903 const SByte &operator++(SByte &val) // Pre-increment
1909 RValue<SByte> operator--(SByte &val, int) // Post-decrement
1911 RValue<SByte> res = val;
1916 const SByte &operator--(SByte &val) // Pre-decrement
1922 RValue<Bool> operator<(RValue<SByte> lhs, RValue<SByte> rhs)
1924 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
1927 RValue<Bool> operator<=(RValue<SByte> lhs, RValue<SByte> rhs)
1929 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
1932 RValue<Bool> operator>(RValue<SByte> lhs, RValue<SByte> rhs)
1934 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
1937 RValue<Bool> operator>=(RValue<SByte> lhs, RValue<SByte> rhs)
1939 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
1942 RValue<Bool> operator!=(RValue<SByte> lhs, RValue<SByte> rhs)
1944 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1947 RValue<Bool> operator==(RValue<SByte> lhs, RValue<SByte> rhs)
1949 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1952 Type *SByte::getType()
1954 return T(Ice::IceType_i8);
1957 Short::Short(Argument<Short> argument)
1959 storeValue(argument.value);
1962 Short::Short(RValue<Int> cast)
1964 Value *integer = Nucleus::createTrunc(cast.value, Short::getType());
1966 storeValue(integer);
1969 Short::Short(short x)
1971 storeValue(Nucleus::createConstantShort(x));
1974 Short::Short(RValue<Short> rhs)
1976 storeValue(rhs.value);
1979 Short::Short(const Short &rhs)
1981 Value *value = rhs.loadValue();
1985 Short::Short(const Reference<Short> &rhs)
1987 Value *value = rhs.loadValue();
1991 RValue<Short> Short::operator=(RValue<Short> rhs)
1993 storeValue(rhs.value);
1998 RValue<Short> Short::operator=(const Short &rhs)
2000 Value *value = rhs.loadValue();
2003 return RValue<Short>(value);
2006 RValue<Short> Short::operator=(const Reference<Short> &rhs)
2008 Value *value = rhs.loadValue();
2011 return RValue<Short>(value);
2014 RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs)
2016 return RValue<Short>(Nucleus::createAdd(lhs.value, rhs.value));
2019 RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs)
2021 return RValue<Short>(Nucleus::createSub(lhs.value, rhs.value));
2024 RValue<Short> operator*(RValue<Short> lhs, RValue<Short> rhs)
2026 return RValue<Short>(Nucleus::createMul(lhs.value, rhs.value));
2029 RValue<Short> operator/(RValue<Short> lhs, RValue<Short> rhs)
2031 return RValue<Short>(Nucleus::createSDiv(lhs.value, rhs.value));
2034 RValue<Short> operator%(RValue<Short> lhs, RValue<Short> rhs)
2036 return RValue<Short>(Nucleus::createSRem(lhs.value, rhs.value));
2039 RValue<Short> operator&(RValue<Short> lhs, RValue<Short> rhs)
2041 return RValue<Short>(Nucleus::createAnd(lhs.value, rhs.value));
2044 RValue<Short> operator|(RValue<Short> lhs, RValue<Short> rhs)
2046 return RValue<Short>(Nucleus::createOr(lhs.value, rhs.value));
2049 RValue<Short> operator^(RValue<Short> lhs, RValue<Short> rhs)
2051 return RValue<Short>(Nucleus::createXor(lhs.value, rhs.value));
2054 RValue<Short> operator<<(RValue<Short> lhs, RValue<Short> rhs)
2056 return RValue<Short>(Nucleus::createShl(lhs.value, rhs.value));
2059 RValue<Short> operator>>(RValue<Short> lhs, RValue<Short> rhs)
2061 return RValue<Short>(Nucleus::createAShr(lhs.value, rhs.value));
2064 RValue<Short> operator+=(Short &lhs, RValue<Short> rhs)
2066 return lhs = lhs + rhs;
2069 RValue<Short> operator-=(Short &lhs, RValue<Short> rhs)
2071 return lhs = lhs - rhs;
2074 RValue<Short> operator*=(Short &lhs, RValue<Short> rhs)
2076 return lhs = lhs * rhs;
2079 RValue<Short> operator/=(Short &lhs, RValue<Short> rhs)
2081 return lhs = lhs / rhs;
2084 RValue<Short> operator%=(Short &lhs, RValue<Short> rhs)
2086 return lhs = lhs % rhs;
2089 RValue<Short> operator&=(Short &lhs, RValue<Short> rhs)
2091 return lhs = lhs & rhs;
2094 RValue<Short> operator|=(Short &lhs, RValue<Short> rhs)
2096 return lhs = lhs | rhs;
2099 RValue<Short> operator^=(Short &lhs, RValue<Short> rhs)
2101 return lhs = lhs ^ rhs;
2104 RValue<Short> operator<<=(Short &lhs, RValue<Short> rhs)
2106 return lhs = lhs << rhs;
2109 RValue<Short> operator>>=(Short &lhs, RValue<Short> rhs)
2111 return lhs = lhs >> rhs;
2114 RValue<Short> operator+(RValue<Short> val)
2119 RValue<Short> operator-(RValue<Short> val)
2121 return RValue<Short>(Nucleus::createNeg(val.value));
2124 RValue<Short> operator~(RValue<Short> val)
2126 return RValue<Short>(Nucleus::createNot(val.value));
2129 RValue<Short> operator++(Short &val, int) // Post-increment
2131 RValue<Short> res = val;
2136 const Short &operator++(Short &val) // Pre-increment
2142 RValue<Short> operator--(Short &val, int) // Post-decrement
2144 RValue<Short> res = val;
2149 const Short &operator--(Short &val) // Pre-decrement
2155 RValue<Bool> operator<(RValue<Short> lhs, RValue<Short> rhs)
2157 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
2160 RValue<Bool> operator<=(RValue<Short> lhs, RValue<Short> rhs)
2162 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
2165 RValue<Bool> operator>(RValue<Short> lhs, RValue<Short> rhs)
2167 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
2170 RValue<Bool> operator>=(RValue<Short> lhs, RValue<Short> rhs)
2172 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
2175 RValue<Bool> operator!=(RValue<Short> lhs, RValue<Short> rhs)
2177 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
2180 RValue<Bool> operator==(RValue<Short> lhs, RValue<Short> rhs)
2182 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
2185 Type *Short::getType()
2187 return T(Ice::IceType_i16);
2190 UShort::UShort(Argument<UShort> argument)
2192 storeValue(argument.value);
2195 UShort::UShort(RValue<UInt> cast)
2197 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
2199 storeValue(integer);
2202 UShort::UShort(RValue<Int> cast)
2204 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
2206 storeValue(integer);
2209 UShort::UShort(unsigned short x)
2211 storeValue(Nucleus::createConstantShort(x));
2214 UShort::UShort(RValue<UShort> rhs)
2216 storeValue(rhs.value);
2219 UShort::UShort(const UShort &rhs)
2221 Value *value = rhs.loadValue();
2225 UShort::UShort(const Reference<UShort> &rhs)
2227 Value *value = rhs.loadValue();
2231 RValue<UShort> UShort::operator=(RValue<UShort> rhs)
2233 storeValue(rhs.value);
2238 RValue<UShort> UShort::operator=(const UShort &rhs)
2240 Value *value = rhs.loadValue();
2243 return RValue<UShort>(value);
2246 RValue<UShort> UShort::operator=(const Reference<UShort> &rhs)
2248 Value *value = rhs.loadValue();
2251 return RValue<UShort>(value);
2254 RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs)
2256 return RValue<UShort>(Nucleus::createAdd(lhs.value, rhs.value));
2259 RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs)
2261 return RValue<UShort>(Nucleus::createSub(lhs.value, rhs.value));
2264 RValue<UShort> operator*(RValue<UShort> lhs, RValue<UShort> rhs)
2266 return RValue<UShort>(Nucleus::createMul(lhs.value, rhs.value));
2269 RValue<UShort> operator/(RValue<UShort> lhs, RValue<UShort> rhs)
2271 return RValue<UShort>(Nucleus::createUDiv(lhs.value, rhs.value));
2274 RValue<UShort> operator%(RValue<UShort> lhs, RValue<UShort> rhs)
2276 return RValue<UShort>(Nucleus::createURem(lhs.value, rhs.value));
2279 RValue<UShort> operator&(RValue<UShort> lhs, RValue<UShort> rhs)
2281 return RValue<UShort>(Nucleus::createAnd(lhs.value, rhs.value));
2284 RValue<UShort> operator|(RValue<UShort> lhs, RValue<UShort> rhs)
2286 return RValue<UShort>(Nucleus::createOr(lhs.value, rhs.value));
2289 RValue<UShort> operator^(RValue<UShort> lhs, RValue<UShort> rhs)
2291 return RValue<UShort>(Nucleus::createXor(lhs.value, rhs.value));
2294 RValue<UShort> operator<<(RValue<UShort> lhs, RValue<UShort> rhs)
2296 return RValue<UShort>(Nucleus::createShl(lhs.value, rhs.value));
2299 RValue<UShort> operator>>(RValue<UShort> lhs, RValue<UShort> rhs)
2301 return RValue<UShort>(Nucleus::createLShr(lhs.value, rhs.value));
2304 RValue<UShort> operator+=(UShort &lhs, RValue<UShort> rhs)
2306 return lhs = lhs + rhs;
2309 RValue<UShort> operator-=(UShort &lhs, RValue<UShort> rhs)
2311 return lhs = lhs - rhs;
2314 RValue<UShort> operator*=(UShort &lhs, RValue<UShort> rhs)
2316 return lhs = lhs * rhs;
2319 RValue<UShort> operator/=(UShort &lhs, RValue<UShort> rhs)
2321 return lhs = lhs / rhs;
2324 RValue<UShort> operator%=(UShort &lhs, RValue<UShort> rhs)
2326 return lhs = lhs % rhs;
2329 RValue<UShort> operator&=(UShort &lhs, RValue<UShort> rhs)
2331 return lhs = lhs & rhs;
2334 RValue<UShort> operator|=(UShort &lhs, RValue<UShort> rhs)
2336 return lhs = lhs | rhs;
2339 RValue<UShort> operator^=(UShort &lhs, RValue<UShort> rhs)
2341 return lhs = lhs ^ rhs;
2344 RValue<UShort> operator<<=(UShort &lhs, RValue<UShort> rhs)
2346 return lhs = lhs << rhs;
2349 RValue<UShort> operator>>=(UShort &lhs, RValue<UShort> rhs)
2351 return lhs = lhs >> rhs;
2354 RValue<UShort> operator+(RValue<UShort> val)
2359 RValue<UShort> operator-(RValue<UShort> val)
2361 return RValue<UShort>(Nucleus::createNeg(val.value));
2364 RValue<UShort> operator~(RValue<UShort> val)
2366 return RValue<UShort>(Nucleus::createNot(val.value));
2369 RValue<UShort> operator++(UShort &val, int) // Post-increment
2371 RValue<UShort> res = val;
2376 const UShort &operator++(UShort &val) // Pre-increment
2382 RValue<UShort> operator--(UShort &val, int) // Post-decrement
2384 RValue<UShort> res = val;
2389 const UShort &operator--(UShort &val) // Pre-decrement
2395 RValue<Bool> operator<(RValue<UShort> lhs, RValue<UShort> rhs)
2397 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
2400 RValue<Bool> operator<=(RValue<UShort> lhs, RValue<UShort> rhs)
2402 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
2405 RValue<Bool> operator>(RValue<UShort> lhs, RValue<UShort> rhs)
2407 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
2410 RValue<Bool> operator>=(RValue<UShort> lhs, RValue<UShort> rhs)
2412 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
2415 RValue<Bool> operator!=(RValue<UShort> lhs, RValue<UShort> rhs)
2417 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
2420 RValue<Bool> operator==(RValue<UShort> lhs, RValue<UShort> rhs)
2422 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
2425 Type *UShort::getType()
2427 return T(Ice::IceType_i16);
2430 Byte4::Byte4(RValue<Byte8> cast)
2432 storeValue(Nucleus::createBitCast(cast.value, getType()));
2435 Byte4::Byte4(const Reference<Byte4> &rhs)
2437 Value *value = rhs.loadValue();
2441 Type *Byte4::getType()
2443 return T(Type_v4i8);
2446 Type *SByte4::getType()
2448 return T(Type_v4i8);
2451 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)
2453 int64_t constantVector[8] = {x0, x1, x2, x3, x4, x5, x6, x7};
2454 storeValue(Nucleus::createConstantVector(constantVector, getType()));
2457 Byte8::Byte8(RValue<Byte8> rhs)
2459 storeValue(rhs.value);
2462 Byte8::Byte8(const Byte8 &rhs)
2464 Value *value = rhs.loadValue();
2468 Byte8::Byte8(const Reference<Byte8> &rhs)
2470 Value *value = rhs.loadValue();
2474 RValue<Byte8> Byte8::operator=(RValue<Byte8> rhs)
2476 storeValue(rhs.value);
2481 RValue<Byte8> Byte8::operator=(const Byte8 &rhs)
2483 Value *value = rhs.loadValue();
2486 return RValue<Byte8>(value);
2489 RValue<Byte8> Byte8::operator=(const Reference<Byte8> &rhs)
2491 Value *value = rhs.loadValue();
2494 return RValue<Byte8>(value);
2497 RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs)
2499 return RValue<Byte8>(Nucleus::createAdd(lhs.value, rhs.value));
2502 RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs)
2504 return RValue<Byte8>(Nucleus::createSub(lhs.value, rhs.value));
2507 // RValue<Byte8> operator*(RValue<Byte8> lhs, RValue<Byte8> rhs)
2509 // return RValue<Byte8>(Nucleus::createMul(lhs.value, rhs.value));
2512 // RValue<Byte8> operator/(RValue<Byte8> lhs, RValue<Byte8> rhs)
2514 // return RValue<Byte8>(Nucleus::createUDiv(lhs.value, rhs.value));
2517 // RValue<Byte8> operator%(RValue<Byte8> lhs, RValue<Byte8> rhs)
2519 // return RValue<Byte8>(Nucleus::createURem(lhs.value, rhs.value));
2522 RValue<Byte8> operator&(RValue<Byte8> lhs, RValue<Byte8> rhs)
2524 return RValue<Byte8>(Nucleus::createAnd(lhs.value, rhs.value));
2527 RValue<Byte8> operator|(RValue<Byte8> lhs, RValue<Byte8> rhs)
2529 return RValue<Byte8>(Nucleus::createOr(lhs.value, rhs.value));
2532 RValue<Byte8> operator^(RValue<Byte8> lhs, RValue<Byte8> rhs)
2534 return RValue<Byte8>(Nucleus::createXor(lhs.value, rhs.value));
2537 // RValue<Byte8> operator<<(RValue<Byte8> lhs, unsigned char rhs)
2539 // return RValue<Byte8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
2542 // RValue<Byte8> operator>>(RValue<Byte8> lhs, unsigned char rhs)
2544 // return RValue<Byte8>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
2547 RValue<Byte8> operator+=(Byte8 &lhs, RValue<Byte8> rhs)
2549 return lhs = lhs + rhs;
2552 RValue<Byte8> operator-=(Byte8 &lhs, RValue<Byte8> rhs)
2554 return lhs = lhs - rhs;
2557 // RValue<Byte8> operator*=(Byte8 &lhs, RValue<Byte8> rhs)
2559 // return lhs = lhs * rhs;
2562 // RValue<Byte8> operator/=(Byte8 &lhs, RValue<Byte8> rhs)
2564 // return lhs = lhs / rhs;
2567 // RValue<Byte8> operator%=(Byte8 &lhs, RValue<Byte8> rhs)
2569 // return lhs = lhs % rhs;
2572 RValue<Byte8> operator&=(Byte8 &lhs, RValue<Byte8> rhs)
2574 return lhs = lhs & rhs;
2577 RValue<Byte8> operator|=(Byte8 &lhs, RValue<Byte8> rhs)
2579 return lhs = lhs | rhs;
2582 RValue<Byte8> operator^=(Byte8 &lhs, RValue<Byte8> rhs)
2584 return lhs = lhs ^ rhs;
2587 // RValue<Byte8> operator<<=(Byte8 &lhs, RValue<Byte8> rhs)
2589 // return lhs = lhs << rhs;
2592 // RValue<Byte8> operator>>=(Byte8 &lhs, RValue<Byte8> rhs)
2594 // return lhs = lhs >> rhs;
2597 // RValue<Byte8> operator+(RValue<Byte8> val)
2602 // RValue<Byte8> operator-(RValue<Byte8> val)
2604 // return RValue<Byte8>(Nucleus::createNeg(val.value));
2607 RValue<Byte8> operator~(RValue<Byte8> val)
2609 return RValue<Byte8>(Nucleus::createNot(val.value));
2612 RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y)
2614 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
2615 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2616 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2617 auto paddusb = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
2618 paddusb->addArg(x.value);
2619 paddusb->addArg(y.value);
2620 ::basicBlock->appendInst(paddusb);
2622 return RValue<Byte8>(V(result));
2625 RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y)
2627 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
2628 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2629 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2630 auto psubusw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
2631 psubusw->addArg(x.value);
2632 psubusw->addArg(y.value);
2633 ::basicBlock->appendInst(psubusw);
2635 return RValue<Byte8>(V(result));
2638 RValue<Short4> Unpack(RValue<Byte4> x)
2640 int shuffle[16] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7}; // Real type is v16i8
2641 return RValue<Short4>(Nucleus::createShuffleVector(x.value, x.value, shuffle));
2644 RValue<Short4> Unpack(RValue<Byte4> x, RValue<Byte4> y)
2646 return UnpackLow(As<Byte8>(x), As<Byte8>(y));
2649 RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y)
2651 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
2652 return RValue<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
2655 RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y)
2657 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
2658 auto lowHigh = RValue<Byte16>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
2659 return As<Short4>(Swizzle(As<Int4>(lowHigh), 0xEE));
2662 RValue<Int> SignMask(RValue<Byte8> x)
2664 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
2665 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2666 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2667 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
2668 movmsk->addArg(x.value);
2669 ::basicBlock->appendInst(movmsk);
2671 return RValue<Int>(V(result));
2674 // RValue<Byte8> CmpGT(RValue<Byte8> x, RValue<Byte8> y)
2676 // return RValue<Byte8>(createIntCompare(Ice::InstIcmp::Ugt, x.value, y.value));
2679 RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y)
2681 return RValue<Byte8>(Nucleus::createICmpEQ(x.value, y.value));
2684 Type *Byte8::getType()
2686 return T(Type_v8i8);
2689 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)
2691 int64_t constantVector[8] = { x0, x1, x2, x3, x4, x5, x6, x7 };
2692 Value *vector = V(Nucleus::createConstantVector(constantVector, getType()));
2694 storeValue(Nucleus::createBitCast(vector, getType()));
2697 SByte8::SByte8(RValue<SByte8> rhs)
2699 storeValue(rhs.value);
2702 SByte8::SByte8(const SByte8 &rhs)
2704 Value *value = rhs.loadValue();
2708 SByte8::SByte8(const Reference<SByte8> &rhs)
2710 Value *value = rhs.loadValue();
2714 RValue<SByte8> SByte8::operator=(RValue<SByte8> rhs)
2716 storeValue(rhs.value);
2721 RValue<SByte8> SByte8::operator=(const SByte8 &rhs)
2723 Value *value = rhs.loadValue();
2726 return RValue<SByte8>(value);
2729 RValue<SByte8> SByte8::operator=(const Reference<SByte8> &rhs)
2731 Value *value = rhs.loadValue();
2734 return RValue<SByte8>(value);
2737 RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs)
2739 return RValue<SByte8>(Nucleus::createAdd(lhs.value, rhs.value));
2742 RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs)
2744 return RValue<SByte8>(Nucleus::createSub(lhs.value, rhs.value));
2747 // RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs)
2749 // return RValue<SByte8>(Nucleus::createMul(lhs.value, rhs.value));
2752 // RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs)
2754 // return RValue<SByte8>(Nucleus::createSDiv(lhs.value, rhs.value));
2757 // RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs)
2759 // return RValue<SByte8>(Nucleus::createSRem(lhs.value, rhs.value));
2762 RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs)
2764 return RValue<SByte8>(Nucleus::createAnd(lhs.value, rhs.value));
2767 RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs)
2769 return RValue<SByte8>(Nucleus::createOr(lhs.value, rhs.value));
2772 RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs)
2774 return RValue<SByte8>(Nucleus::createXor(lhs.value, rhs.value));
2777 // RValue<SByte8> operator<<(RValue<SByte8> lhs, unsigned char rhs)
2779 // return RValue<SByte8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
2782 // RValue<SByte8> operator>>(RValue<SByte8> lhs, unsigned char rhs)
2784 // return RValue<SByte8>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
2787 RValue<SByte8> operator+=(SByte8 &lhs, RValue<SByte8> rhs)
2789 return lhs = lhs + rhs;
2792 RValue<SByte8> operator-=(SByte8 &lhs, RValue<SByte8> rhs)
2794 return lhs = lhs - rhs;
2797 // RValue<SByte8> operator*=(SByte8 &lhs, RValue<SByte8> rhs)
2799 // return lhs = lhs * rhs;
2802 // RValue<SByte8> operator/=(SByte8 &lhs, RValue<SByte8> rhs)
2804 // return lhs = lhs / rhs;
2807 // RValue<SByte8> operator%=(SByte8 &lhs, RValue<SByte8> rhs)
2809 // return lhs = lhs % rhs;
2812 RValue<SByte8> operator&=(SByte8 &lhs, RValue<SByte8> rhs)
2814 return lhs = lhs & rhs;
2817 RValue<SByte8> operator|=(SByte8 &lhs, RValue<SByte8> rhs)
2819 return lhs = lhs | rhs;
2822 RValue<SByte8> operator^=(SByte8 &lhs, RValue<SByte8> rhs)
2824 return lhs = lhs ^ rhs;
2827 // RValue<SByte8> operator<<=(SByte8 &lhs, RValue<SByte8> rhs)
2829 // return lhs = lhs << rhs;
2832 // RValue<SByte8> operator>>=(SByte8 &lhs, RValue<SByte8> rhs)
2834 // return lhs = lhs >> rhs;
2837 // RValue<SByte8> operator+(RValue<SByte8> val)
2842 // RValue<SByte8> operator-(RValue<SByte8> val)
2844 // return RValue<SByte8>(Nucleus::createNeg(val.value));
2847 RValue<SByte8> operator~(RValue<SByte8> val)
2849 return RValue<SByte8>(Nucleus::createNot(val.value));
2852 RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y)
2854 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
2855 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2856 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2857 auto paddsb = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
2858 paddsb->addArg(x.value);
2859 paddsb->addArg(y.value);
2860 ::basicBlock->appendInst(paddsb);
2862 return RValue<SByte8>(V(result));
2865 RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y)
2867 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
2868 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2869 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2870 auto psubsb = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
2871 psubsb->addArg(x.value);
2872 psubsb->addArg(y.value);
2873 ::basicBlock->appendInst(psubsb);
2875 return RValue<SByte8>(V(result));
2878 RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y)
2880 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
2881 return RValue<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
2884 RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y)
2886 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
2887 auto lowHigh = RValue<Byte16>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
2888 return As<Short4>(Swizzle(As<Int4>(lowHigh), 0xEE));
2891 RValue<Int> SignMask(RValue<SByte8> x)
2893 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
2894 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2895 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2896 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
2897 movmsk->addArg(x.value);
2898 ::basicBlock->appendInst(movmsk);
2900 return RValue<Int>(V(result));
2903 RValue<Byte8> CmpGT(RValue<SByte8> x, RValue<SByte8> y)
2905 return RValue<Byte8>(createIntCompare(Ice::InstIcmp::Sgt, x.value, y.value));
2908 RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y)
2910 return RValue<Byte8>(Nucleus::createICmpEQ(x.value, y.value));
2913 Type *SByte8::getType()
2915 return T(Type_v8i8);
2918 Byte16::Byte16(RValue<Byte16> rhs)
2920 storeValue(rhs.value);
2923 Byte16::Byte16(const Byte16 &rhs)
2925 Value *value = rhs.loadValue();
2929 Byte16::Byte16(const Reference<Byte16> &rhs)
2931 Value *value = rhs.loadValue();
2935 RValue<Byte16> Byte16::operator=(RValue<Byte16> rhs)
2937 storeValue(rhs.value);
2942 RValue<Byte16> Byte16::operator=(const Byte16 &rhs)
2944 Value *value = rhs.loadValue();
2947 return RValue<Byte16>(value);
2950 RValue<Byte16> Byte16::operator=(const Reference<Byte16> &rhs)
2952 Value *value = rhs.loadValue();
2955 return RValue<Byte16>(value);
2958 Type *Byte16::getType()
2960 return T(Ice::IceType_v16i8);
2963 Type *SByte16::getType()
2965 return T(Ice::IceType_v16i8);
2968 Short2::Short2(RValue<Short4> cast)
2970 storeValue(Nucleus::createBitCast(cast.value, getType()));
2973 Type *Short2::getType()
2975 return T(Type_v2i16);
2978 UShort2::UShort2(RValue<UShort4> cast)
2980 storeValue(Nucleus::createBitCast(cast.value, getType()));
2983 Type *UShort2::getType()
2985 return T(Type_v2i16);
2988 Short4::Short4(RValue<Int> cast)
2990 Value *vector = loadValue();
2991 Value *element = Nucleus::createTrunc(cast.value, Short::getType());
2992 Value *insert = Nucleus::createInsertElement(vector, element, 0);
2993 Value *swizzle = Swizzle(RValue<Short4>(insert), 0x00).value;
2995 storeValue(swizzle);
2998 Short4::Short4(RValue<Int4> cast)
3000 int select[8] = {0, 2, 4, 6, 0, 2, 4, 6};
3001 Value *short8 = Nucleus::createBitCast(cast.value, Short8::getType());
3002 Value *packed = Nucleus::createShuffleVector(short8, short8, select);
3004 Value *int2 = RValue<Int2>(Int2(RValue<Int4>(packed))).value;
3005 Value *short4 = Nucleus::createBitCast(int2, Short4::getType());
3010 // Short4::Short4(RValue<Float> cast)
3014 Short4::Short4(RValue<Float4> cast)
3016 assert(false && "UNIMPLEMENTED");
3019 Short4::Short4(short xyzw)
3021 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
3022 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3025 Short4::Short4(short x, short y, short z, short w)
3027 int64_t constantVector[4] = {x, y, z, w};
3028 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3031 Short4::Short4(RValue<Short4> rhs)
3033 storeValue(rhs.value);
3036 Short4::Short4(const Short4 &rhs)
3038 Value *value = rhs.loadValue();
3042 Short4::Short4(const Reference<Short4> &rhs)
3044 Value *value = rhs.loadValue();
3048 Short4::Short4(RValue<UShort4> rhs)
3050 storeValue(rhs.value);
3053 Short4::Short4(const UShort4 &rhs)
3055 storeValue(rhs.loadValue());
3058 Short4::Short4(const Reference<UShort4> &rhs)
3060 storeValue(rhs.loadValue());
3063 RValue<Short4> Short4::operator=(RValue<Short4> rhs)
3065 storeValue(rhs.value);
3070 RValue<Short4> Short4::operator=(const Short4 &rhs)
3072 Value *value = rhs.loadValue();
3075 return RValue<Short4>(value);
3078 RValue<Short4> Short4::operator=(const Reference<Short4> &rhs)
3080 Value *value = rhs.loadValue();
3083 return RValue<Short4>(value);
3086 RValue<Short4> Short4::operator=(RValue<UShort4> rhs)
3088 storeValue(rhs.value);
3090 return RValue<Short4>(rhs);
3093 RValue<Short4> Short4::operator=(const UShort4 &rhs)
3095 Value *value = rhs.loadValue();
3098 return RValue<Short4>(value);
3101 RValue<Short4> Short4::operator=(const Reference<UShort4> &rhs)
3103 Value *value = rhs.loadValue();
3106 return RValue<Short4>(value);
3109 RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs)
3111 return RValue<Short4>(Nucleus::createAdd(lhs.value, rhs.value));
3114 RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs)
3116 return RValue<Short4>(Nucleus::createSub(lhs.value, rhs.value));
3119 RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs)
3121 return RValue<Short4>(Nucleus::createMul(lhs.value, rhs.value));
3124 // RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs)
3126 // return RValue<Short4>(Nucleus::createSDiv(lhs.value, rhs.value));
3129 // RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs)
3131 // return RValue<Short4>(Nucleus::createSRem(lhs.value, rhs.value));
3134 RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs)
3136 return RValue<Short4>(Nucleus::createAnd(lhs.value, rhs.value));
3139 RValue<Short4> operator|(RValue<Short4> lhs, RValue<Short4> rhs)
3141 return RValue<Short4>(Nucleus::createOr(lhs.value, rhs.value));
3144 RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs)
3146 return RValue<Short4>(Nucleus::createXor(lhs.value, rhs.value));
3149 RValue<Short4> operator<<(RValue<Short4> lhs, unsigned char rhs)
3151 return RValue<Short4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
3154 RValue<Short4> operator>>(RValue<Short4> lhs, unsigned char rhs)
3156 return RValue<Short4>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
3159 RValue<Short4> operator+=(Short4 &lhs, RValue<Short4> rhs)
3161 return lhs = lhs + rhs;
3164 RValue<Short4> operator-=(Short4 &lhs, RValue<Short4> rhs)
3166 return lhs = lhs - rhs;
3169 RValue<Short4> operator*=(Short4 &lhs, RValue<Short4> rhs)
3171 return lhs = lhs * rhs;
3174 // RValue<Short4> operator/=(Short4 &lhs, RValue<Short4> rhs)
3176 // return lhs = lhs / rhs;
3179 // RValue<Short4> operator%=(Short4 &lhs, RValue<Short4> rhs)
3181 // return lhs = lhs % rhs;
3184 RValue<Short4> operator&=(Short4 &lhs, RValue<Short4> rhs)
3186 return lhs = lhs & rhs;
3189 RValue<Short4> operator|=(Short4 &lhs, RValue<Short4> rhs)
3191 return lhs = lhs | rhs;
3194 RValue<Short4> operator^=(Short4 &lhs, RValue<Short4> rhs)
3196 return lhs = lhs ^ rhs;
3199 RValue<Short4> operator<<=(Short4 &lhs, unsigned char rhs)
3201 return lhs = lhs << rhs;
3204 RValue<Short4> operator>>=(Short4 &lhs, unsigned char rhs)
3206 return lhs = lhs >> rhs;
3209 // RValue<Short4> operator+(RValue<Short4> val)
3214 RValue<Short4> operator-(RValue<Short4> val)
3216 return RValue<Short4>(Nucleus::createNeg(val.value));
3219 RValue<Short4> operator~(RValue<Short4> val)
3221 return RValue<Short4>(Nucleus::createNot(val.value));
3224 RValue<Short4> RoundShort4(RValue<Float4> cast)
3226 RValue<Int4> int4 = RoundInt(cast);
3227 return As<Short4>(Pack(int4, int4));
3230 RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y)
3232 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3233 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sle, condition, x.value, y.value);
3234 ::basicBlock->appendInst(cmp);
3236 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3237 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3238 ::basicBlock->appendInst(select);
3240 return RValue<Short4>(V(result));
3243 RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y)
3245 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3246 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sgt, condition, x.value, y.value);
3247 ::basicBlock->appendInst(cmp);
3249 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3250 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3251 ::basicBlock->appendInst(select);
3253 return RValue<Short4>(V(result));
3256 RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y)
3258 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3259 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3260 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3261 auto paddsw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3262 paddsw->addArg(x.value);
3263 paddsw->addArg(y.value);
3264 ::basicBlock->appendInst(paddsw);
3266 return RValue<Short4>(V(result));
3269 RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y)
3271 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3272 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3273 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3274 auto psubsw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3275 psubsw->addArg(x.value);
3276 psubsw->addArg(y.value);
3277 ::basicBlock->appendInst(psubsw);
3279 return RValue<Short4>(V(result));
3282 RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y)
3284 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3285 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::MultiplyHighSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3286 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3287 auto pmulhw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3288 pmulhw->addArg(x.value);
3289 pmulhw->addArg(y.value);
3290 ::basicBlock->appendInst(pmulhw);
3292 return RValue<Short4>(V(result));
3295 RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y)
3297 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3298 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::MultiplyAddPairs, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3299 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3300 auto pmaddwd = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3301 pmaddwd->addArg(x.value);
3302 pmaddwd->addArg(y.value);
3303 ::basicBlock->appendInst(pmaddwd);
3305 return RValue<Int2>(V(result));
3308 RValue<SByte8> Pack(RValue<Short4> x, RValue<Short4> y)
3310 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
3311 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3312 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3313 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3314 pack->addArg(x.value);
3315 pack->addArg(y.value);
3316 ::basicBlock->appendInst(pack);
3318 return As<SByte8>(Swizzle(As<Int4>(V(result)), 0x88));
3321 RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y)
3323 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11}; // Real type is v8i16
3324 return RValue<Int2>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
3327 RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y)
3329 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11}; // Real type is v8i16
3330 auto lowHigh = RValue<Short8>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
3331 return As<Int2>(Swizzle(As<Int4>(lowHigh), 0xEE));
3334 RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select)
3336 // Real type is v8i16
3339 (select >> 0) & 0x03,
3340 (select >> 2) & 0x03,
3341 (select >> 4) & 0x03,
3342 (select >> 6) & 0x03,
3343 (select >> 0) & 0x03,
3344 (select >> 2) & 0x03,
3345 (select >> 4) & 0x03,
3346 (select >> 6) & 0x03,
3349 return RValue<Short4>(Nucleus::createShuffleVector(x.value, x.value, shuffle));
3352 RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i)
3354 return RValue<Short4>(Nucleus::createInsertElement(val.value, element.value, i));
3357 RValue<Short> Extract(RValue<Short4> val, int i)
3359 return RValue<Short>(Nucleus::createExtractElement(val.value, Short::getType(), i));
3362 RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y)
3364 return RValue<Short4>(createIntCompare(Ice::InstIcmp::Sgt, x.value, y.value));
3367 RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y)
3369 return RValue<Short4>(Nucleus::createICmpEQ(x.value, y.value));
3372 Type *Short4::getType()
3374 return T(Type_v4i16);
3377 UShort4::UShort4(RValue<Int4> cast)
3379 *this = Short4(cast);
3382 UShort4::UShort4(RValue<Float4> cast, bool saturate)
3388 Int4 int4(Min(cast, Float4(0xFFFF))); // packusdw takes care of 0x0000 saturation
3389 *this = As<Short4>(Pack(As<UInt4>(int4), As<UInt4>(int4)));
3393 *this = Short4(Int4(Max(Min(cast, Float4(0xFFFF)), Float4(0x0000))));
3398 *this = Short4(Int4(cast));
3402 UShort4::UShort4(unsigned short xyzw)
3404 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
3405 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3408 UShort4::UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w)
3410 int64_t constantVector[4] = {x, y, z, w};
3411 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3414 UShort4::UShort4(RValue<UShort4> rhs)
3416 storeValue(rhs.value);
3419 UShort4::UShort4(const UShort4 &rhs)
3421 Value *value = rhs.loadValue();
3425 UShort4::UShort4(const Reference<UShort4> &rhs)
3427 Value *value = rhs.loadValue();
3431 UShort4::UShort4(RValue<Short4> rhs)
3433 storeValue(rhs.value);
3436 UShort4::UShort4(const Short4 &rhs)
3438 Value *value = rhs.loadValue();
3442 UShort4::UShort4(const Reference<Short4> &rhs)
3444 Value *value = rhs.loadValue();
3448 RValue<UShort4> UShort4::operator=(RValue<UShort4> rhs)
3450 storeValue(rhs.value);
3455 RValue<UShort4> UShort4::operator=(const UShort4 &rhs)
3457 Value *value = rhs.loadValue();
3460 return RValue<UShort4>(value);
3463 RValue<UShort4> UShort4::operator=(const Reference<UShort4> &rhs)
3465 Value *value = rhs.loadValue();
3468 return RValue<UShort4>(value);
3471 RValue<UShort4> UShort4::operator=(RValue<Short4> rhs)
3473 storeValue(rhs.value);
3475 return RValue<UShort4>(rhs);
3478 RValue<UShort4> UShort4::operator=(const Short4 &rhs)
3480 Value *value = rhs.loadValue();
3483 return RValue<UShort4>(value);
3486 RValue<UShort4> UShort4::operator=(const Reference<Short4> &rhs)
3488 Value *value = rhs.loadValue();
3491 return RValue<UShort4>(value);
3494 RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs)
3496 return RValue<UShort4>(Nucleus::createAdd(lhs.value, rhs.value));
3499 RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs)
3501 return RValue<UShort4>(Nucleus::createSub(lhs.value, rhs.value));
3504 RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs)
3506 return RValue<UShort4>(Nucleus::createMul(lhs.value, rhs.value));
3509 RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs)
3511 return RValue<UShort4>(Nucleus::createAnd(lhs.value, rhs.value));
3514 RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs)
3516 return RValue<UShort4>(Nucleus::createOr(lhs.value, rhs.value));
3519 RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs)
3521 return RValue<UShort4>(Nucleus::createXor(lhs.value, rhs.value));
3524 RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs)
3526 return RValue<UShort4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
3529 RValue<UShort4> operator>>(RValue<UShort4> lhs, unsigned char rhs)
3531 return RValue<UShort4>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
3534 RValue<UShort4> operator<<=(UShort4 &lhs, unsigned char rhs)
3536 return lhs = lhs << rhs;
3539 RValue<UShort4> operator>>=(UShort4 &lhs, unsigned char rhs)
3541 return lhs = lhs >> rhs;
3544 RValue<UShort4> operator~(RValue<UShort4> val)
3546 return RValue<UShort4>(Nucleus::createNot(val.value));
3549 RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y)
3551 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3552 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ule, condition, x.value, y.value);
3553 ::basicBlock->appendInst(cmp);
3555 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3556 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3557 ::basicBlock->appendInst(select);
3559 return RValue<UShort4>(V(result));
3562 RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y)
3564 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3565 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ugt, condition, x.value, y.value);
3566 ::basicBlock->appendInst(cmp);
3568 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3569 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3570 ::basicBlock->appendInst(select);
3572 return RValue<UShort4>(V(result));
3575 RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y)
3577 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3578 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3579 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3580 auto paddusw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3581 paddusw->addArg(x.value);
3582 paddusw->addArg(y.value);
3583 ::basicBlock->appendInst(paddusw);
3585 return RValue<UShort4>(V(result));
3588 RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y)
3590 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3591 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3592 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3593 auto psubusw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3594 psubusw->addArg(x.value);
3595 psubusw->addArg(y.value);
3596 ::basicBlock->appendInst(psubusw);
3598 return RValue<UShort4>(V(result));
3601 RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y)
3603 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3604 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::MultiplyHighUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3605 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3606 auto pmulhuw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3607 pmulhuw->addArg(x.value);
3608 pmulhuw->addArg(y.value);
3609 ::basicBlock->appendInst(pmulhuw);
3611 return RValue<UShort4>(V(result));
3614 RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y)
3616 assert(false && "UNIMPLEMENTED"); return RValue<UShort4>(V(nullptr));
3619 RValue<Byte8> Pack(RValue<UShort4> x, RValue<UShort4> y)
3621 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
3622 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3623 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3624 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3625 pack->addArg(x.value);
3626 pack->addArg(y.value);
3627 ::basicBlock->appendInst(pack);
3629 return As<Byte8>(Swizzle(As<Int4>(V(result)), 0x88));
3632 Type *UShort4::getType()
3634 return T(Type_v4i16);
3637 Short8::Short8(short c)
3639 int64_t constantVector[8] = {c, c, c, c, c, c, c, c};
3640 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3643 Short8::Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7)
3645 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
3646 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3649 Short8::Short8(RValue<Short8> rhs)
3651 storeValue(rhs.value);
3654 Short8::Short8(const Reference<Short8> &rhs)
3656 Value *value = rhs.loadValue();
3660 Short8::Short8(RValue<Short4> lo, RValue<Short4> hi)
3662 int shuffle[8] = {0, 1, 2, 3, 8, 9, 10, 11}; // Real type is v8i16
3663 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
3668 RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs)
3670 return RValue<Short8>(Nucleus::createAdd(lhs.value, rhs.value));
3673 RValue<Short8> operator&(RValue<Short8> lhs, RValue<Short8> rhs)
3675 return RValue<Short8>(Nucleus::createAnd(lhs.value, rhs.value));
3678 RValue<Short8> operator<<(RValue<Short8> lhs, unsigned char rhs)
3680 return RValue<Short8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
3683 RValue<Short8> operator>>(RValue<Short8> lhs, unsigned char rhs)
3685 return RValue<Short8>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
3688 RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y)
3690 assert(false && "UNIMPLEMENTED"); return RValue<Int4>(V(nullptr));
3693 RValue<Int4> Abs(RValue<Int4> x)
3695 auto negative = x >> 31;
3696 return (x ^ negative) - negative;
3699 RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y)
3701 assert(false && "UNIMPLEMENTED"); return RValue<Short8>(V(nullptr));
3704 Type *Short8::getType()
3706 return T(Ice::IceType_v8i16);
3709 UShort8::UShort8(unsigned short c)
3711 int64_t constantVector[8] = {c, c, c, c, c, c, c, c};
3712 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3715 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)
3717 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
3718 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3721 UShort8::UShort8(RValue<UShort8> rhs)
3723 storeValue(rhs.value);
3726 UShort8::UShort8(const Reference<UShort8> &rhs)
3728 Value *value = rhs.loadValue();
3732 UShort8::UShort8(RValue<UShort4> lo, RValue<UShort4> hi)
3734 int shuffle[8] = {0, 1, 2, 3, 8, 9, 10, 11}; // Real type is v8i16
3735 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
3740 RValue<UShort8> UShort8::operator=(RValue<UShort8> rhs)
3742 storeValue(rhs.value);
3747 RValue<UShort8> UShort8::operator=(const UShort8 &rhs)
3749 Value *value = rhs.loadValue();
3752 return RValue<UShort8>(value);
3755 RValue<UShort8> UShort8::operator=(const Reference<UShort8> &rhs)
3757 Value *value = rhs.loadValue();
3760 return RValue<UShort8>(value);
3763 RValue<UShort8> operator&(RValue<UShort8> lhs, RValue<UShort8> rhs)
3765 return RValue<UShort8>(Nucleus::createAnd(lhs.value, rhs.value));
3768 RValue<UShort8> operator<<(RValue<UShort8> lhs, unsigned char rhs)
3770 return RValue<UShort8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
3773 RValue<UShort8> operator>>(RValue<UShort8> lhs, unsigned char rhs)
3775 return RValue<UShort8>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
3778 RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs)
3780 return RValue<UShort8>(Nucleus::createAdd(lhs.value, rhs.value));
3783 RValue<UShort8> operator*(RValue<UShort8> lhs, RValue<UShort8> rhs)
3785 return RValue<UShort8>(Nucleus::createMul(lhs.value, rhs.value));
3788 RValue<UShort8> operator+=(UShort8 &lhs, RValue<UShort8> rhs)
3790 return lhs = lhs + rhs;
3793 RValue<UShort8> operator~(RValue<UShort8> val)
3795 return RValue<UShort8>(Nucleus::createNot(val.value));
3798 RValue<UShort8> Swizzle(RValue<UShort8> x, char select0, char select1, char select2, char select3, char select4, char select5, char select6, char select7)
3800 assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
3803 RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y)
3805 assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
3808 // FIXME: Implement as Shuffle(x, y, Select(i0, ..., i16)) and Shuffle(x, y, SELECT_PACK_REPEAT(element))
3809 // RValue<UShort8> PackRepeat(RValue<Byte16> x, RValue<Byte16> y, int element)
3811 // assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
3814 Type *UShort8::getType()
3816 return T(Ice::IceType_v8i16);
3819 Int::Int(Argument<Int> argument)
3821 storeValue(argument.value);
3824 Int::Int(RValue<Byte> cast)
3826 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3828 storeValue(integer);
3831 Int::Int(RValue<SByte> cast)
3833 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3835 storeValue(integer);
3838 Int::Int(RValue<Short> cast)
3840 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3842 storeValue(integer);
3845 Int::Int(RValue<UShort> cast)
3847 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3849 storeValue(integer);
3852 Int::Int(RValue<Int2> cast)
3854 *this = Extract(cast, 0);
3857 Int::Int(RValue<Long> cast)
3859 Value *integer = Nucleus::createTrunc(cast.value, Int::getType());
3861 storeValue(integer);
3864 Int::Int(RValue<Float> cast)
3866 Value *integer = Nucleus::createFPToSI(cast.value, Int::getType());
3868 storeValue(integer);
3873 storeValue(Nucleus::createConstantInt(x));
3876 Int::Int(RValue<Int> rhs)
3878 storeValue(rhs.value);
3881 Int::Int(RValue<UInt> rhs)
3883 storeValue(rhs.value);
3886 Int::Int(const Int &rhs)
3888 Value *value = rhs.loadValue();
3892 Int::Int(const Reference<Int> &rhs)
3894 Value *value = rhs.loadValue();
3898 Int::Int(const UInt &rhs)
3900 Value *value = rhs.loadValue();
3904 Int::Int(const Reference<UInt> &rhs)
3906 Value *value = rhs.loadValue();
3910 RValue<Int> Int::operator=(int rhs)
3912 return RValue<Int>(storeValue(Nucleus::createConstantInt(rhs)));
3915 RValue<Int> Int::operator=(RValue<Int> rhs)
3917 storeValue(rhs.value);
3922 RValue<Int> Int::operator=(RValue<UInt> rhs)
3924 storeValue(rhs.value);
3926 return RValue<Int>(rhs);
3929 RValue<Int> Int::operator=(const Int &rhs)
3931 Value *value = rhs.loadValue();
3934 return RValue<Int>(value);
3937 RValue<Int> Int::operator=(const Reference<Int> &rhs)
3939 Value *value = rhs.loadValue();
3942 return RValue<Int>(value);
3945 RValue<Int> Int::operator=(const UInt &rhs)
3947 Value *value = rhs.loadValue();
3950 return RValue<Int>(value);
3953 RValue<Int> Int::operator=(const Reference<UInt> &rhs)
3955 Value *value = rhs.loadValue();
3958 return RValue<Int>(value);
3961 RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs)
3963 return RValue<Int>(Nucleus::createAdd(lhs.value, rhs.value));
3966 RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs)
3968 return RValue<Int>(Nucleus::createSub(lhs.value, rhs.value));
3971 RValue<Int> operator*(RValue<Int> lhs, RValue<Int> rhs)
3973 return RValue<Int>(Nucleus::createMul(lhs.value, rhs.value));
3976 RValue<Int> operator/(RValue<Int> lhs, RValue<Int> rhs)
3978 return RValue<Int>(Nucleus::createSDiv(lhs.value, rhs.value));
3981 RValue<Int> operator%(RValue<Int> lhs, RValue<Int> rhs)
3983 return RValue<Int>(Nucleus::createSRem(lhs.value, rhs.value));
3986 RValue<Int> operator&(RValue<Int> lhs, RValue<Int> rhs)
3988 return RValue<Int>(Nucleus::createAnd(lhs.value, rhs.value));
3991 RValue<Int> operator|(RValue<Int> lhs, RValue<Int> rhs)
3993 return RValue<Int>(Nucleus::createOr(lhs.value, rhs.value));
3996 RValue<Int> operator^(RValue<Int> lhs, RValue<Int> rhs)
3998 return RValue<Int>(Nucleus::createXor(lhs.value, rhs.value));
4001 RValue<Int> operator<<(RValue<Int> lhs, RValue<Int> rhs)
4003 return RValue<Int>(Nucleus::createShl(lhs.value, rhs.value));
4006 RValue<Int> operator>>(RValue<Int> lhs, RValue<Int> rhs)
4008 return RValue<Int>(Nucleus::createAShr(lhs.value, rhs.value));
4011 RValue<Int> operator+=(Int &lhs, RValue<Int> rhs)
4013 return lhs = lhs + rhs;
4016 RValue<Int> operator-=(Int &lhs, RValue<Int> rhs)
4018 return lhs = lhs - rhs;
4021 RValue<Int> operator*=(Int &lhs, RValue<Int> rhs)
4023 return lhs = lhs * rhs;
4026 RValue<Int> operator/=(Int &lhs, RValue<Int> rhs)
4028 return lhs = lhs / rhs;
4031 RValue<Int> operator%=(Int &lhs, RValue<Int> rhs)
4033 return lhs = lhs % rhs;
4036 RValue<Int> operator&=(Int &lhs, RValue<Int> rhs)
4038 return lhs = lhs & rhs;
4041 RValue<Int> operator|=(Int &lhs, RValue<Int> rhs)
4043 return lhs = lhs | rhs;
4046 RValue<Int> operator^=(Int &lhs, RValue<Int> rhs)
4048 return lhs = lhs ^ rhs;
4051 RValue<Int> operator<<=(Int &lhs, RValue<Int> rhs)
4053 return lhs = lhs << rhs;
4056 RValue<Int> operator>>=(Int &lhs, RValue<Int> rhs)
4058 return lhs = lhs >> rhs;
4061 RValue<Int> operator+(RValue<Int> val)
4066 RValue<Int> operator-(RValue<Int> val)
4068 return RValue<Int>(Nucleus::createNeg(val.value));
4071 RValue<Int> operator~(RValue<Int> val)
4073 return RValue<Int>(Nucleus::createNot(val.value));
4076 RValue<Int> operator++(Int &val, int) // Post-increment
4078 RValue<Int> res = val;
4083 const Int &operator++(Int &val) // Pre-increment
4089 RValue<Int> operator--(Int &val, int) // Post-decrement
4091 RValue<Int> res = val;
4096 const Int &operator--(Int &val) // Pre-decrement
4102 RValue<Bool> operator<(RValue<Int> lhs, RValue<Int> rhs)
4104 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
4107 RValue<Bool> operator<=(RValue<Int> lhs, RValue<Int> rhs)
4109 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
4112 RValue<Bool> operator>(RValue<Int> lhs, RValue<Int> rhs)
4114 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
4117 RValue<Bool> operator>=(RValue<Int> lhs, RValue<Int> rhs)
4119 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
4122 RValue<Bool> operator!=(RValue<Int> lhs, RValue<Int> rhs)
4124 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
4127 RValue<Bool> operator==(RValue<Int> lhs, RValue<Int> rhs)
4129 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
4132 RValue<Int> Max(RValue<Int> x, RValue<Int> y)
4134 return IfThenElse(x > y, x, y);
4137 RValue<Int> Min(RValue<Int> x, RValue<Int> y)
4139 return IfThenElse(x < y, x, y);
4142 RValue<Int> Clamp(RValue<Int> x, RValue<Int> min, RValue<Int> max)
4144 return Min(Max(x, min), max);
4147 RValue<Int> RoundInt(RValue<Float> cast)
4149 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
4150 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Nearbyint, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
4151 auto target = ::context->getConstantUndef(Ice::IceType_i32);
4152 auto nearbyint = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
4153 nearbyint->addArg(cast.value);
4154 ::basicBlock->appendInst(nearbyint);
4156 return RValue<Int>(V(result));
4159 Type *Int::getType()
4161 return T(Ice::IceType_i32);
4164 Long::Long(RValue<Int> cast)
4166 Value *integer = Nucleus::createSExt(cast.value, Long::getType());
4168 storeValue(integer);
4171 Long::Long(RValue<UInt> cast)
4173 Value *integer = Nucleus::createZExt(cast.value, Long::getType());
4175 storeValue(integer);
4178 Long::Long(RValue<Long> rhs)
4180 storeValue(rhs.value);
4183 RValue<Long> Long::operator=(int64_t rhs)
4185 return RValue<Long>(storeValue(Nucleus::createConstantLong(rhs)));
4188 RValue<Long> Long::operator=(RValue<Long> rhs)
4190 storeValue(rhs.value);
4195 RValue<Long> Long::operator=(const Long &rhs)
4197 Value *value = rhs.loadValue();
4200 return RValue<Long>(value);
4203 RValue<Long> Long::operator=(const Reference<Long> &rhs)
4205 Value *value = rhs.loadValue();
4208 return RValue<Long>(value);
4211 RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs)
4213 return RValue<Long>(Nucleus::createAdd(lhs.value, rhs.value));
4216 RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs)
4218 return RValue<Long>(Nucleus::createSub(lhs.value, rhs.value));
4221 RValue<Long> operator+=(Long &lhs, RValue<Long> rhs)
4223 return lhs = lhs + rhs;
4226 RValue<Long> operator-=(Long &lhs, RValue<Long> rhs)
4228 return lhs = lhs - rhs;
4231 RValue<Long> AddAtomic(RValue<Pointer<Long> > x, RValue<Long> y)
4233 return RValue<Long>(Nucleus::createAtomicAdd(x.value, y.value));
4236 Type *Long::getType()
4238 return T(Ice::IceType_i64);
4241 UInt::UInt(Argument<UInt> argument)
4243 storeValue(argument.value);
4246 UInt::UInt(RValue<UShort> cast)
4248 Value *integer = Nucleus::createZExt(cast.value, UInt::getType());
4250 storeValue(integer);
4253 UInt::UInt(RValue<Long> cast)
4255 Value *integer = Nucleus::createTrunc(cast.value, UInt::getType());
4257 storeValue(integer);
4260 UInt::UInt(RValue<Float> cast)
4262 // Smallest positive value representable in UInt, but not in Int
4263 const unsigned int ustart = 0x80000000u;
4264 const float ustartf = float(ustart);
4266 // If the value is negative, store 0, otherwise store the result of the conversion
4267 storeValue((~(As<Int>(cast) >> 31) &
4268 // Check if the value can be represented as an Int
4269 IfThenElse(cast >= ustartf,
4270 // If the value is too large, subtract ustart and re-add it after conversion.
4271 As<Int>(As<UInt>(Int(cast - Float(ustartf))) + UInt(ustart)),
4272 // Otherwise, just convert normally
4278 storeValue(Nucleus::createConstantInt(x));
4281 UInt::UInt(unsigned int x)
4283 storeValue(Nucleus::createConstantInt(x));
4286 UInt::UInt(RValue<UInt> rhs)
4288 storeValue(rhs.value);
4291 UInt::UInt(RValue<Int> rhs)
4293 storeValue(rhs.value);
4296 UInt::UInt(const UInt &rhs)
4298 Value *value = rhs.loadValue();
4302 UInt::UInt(const Reference<UInt> &rhs)
4304 Value *value = rhs.loadValue();
4308 UInt::UInt(const Int &rhs)
4310 Value *value = rhs.loadValue();
4314 UInt::UInt(const Reference<Int> &rhs)
4316 Value *value = rhs.loadValue();
4320 RValue<UInt> UInt::operator=(unsigned int rhs)
4322 return RValue<UInt>(storeValue(Nucleus::createConstantInt(rhs)));
4325 RValue<UInt> UInt::operator=(RValue<UInt> rhs)
4327 storeValue(rhs.value);
4332 RValue<UInt> UInt::operator=(RValue<Int> rhs)
4334 storeValue(rhs.value);
4336 return RValue<UInt>(rhs);
4339 RValue<UInt> UInt::operator=(const UInt &rhs)
4341 Value *value = rhs.loadValue();
4344 return RValue<UInt>(value);
4347 RValue<UInt> UInt::operator=(const Reference<UInt> &rhs)
4349 Value *value = rhs.loadValue();
4352 return RValue<UInt>(value);
4355 RValue<UInt> UInt::operator=(const Int &rhs)
4357 Value *value = rhs.loadValue();
4360 return RValue<UInt>(value);
4363 RValue<UInt> UInt::operator=(const Reference<Int> &rhs)
4365 Value *value = rhs.loadValue();
4368 return RValue<UInt>(value);
4371 RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs)
4373 return RValue<UInt>(Nucleus::createAdd(lhs.value, rhs.value));
4376 RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs)
4378 return RValue<UInt>(Nucleus::createSub(lhs.value, rhs.value));
4381 RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs)
4383 return RValue<UInt>(Nucleus::createMul(lhs.value, rhs.value));
4386 RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs)
4388 return RValue<UInt>(Nucleus::createUDiv(lhs.value, rhs.value));
4391 RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs)
4393 return RValue<UInt>(Nucleus::createURem(lhs.value, rhs.value));
4396 RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs)
4398 return RValue<UInt>(Nucleus::createAnd(lhs.value, rhs.value));
4401 RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs)
4403 return RValue<UInt>(Nucleus::createOr(lhs.value, rhs.value));
4406 RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs)
4408 return RValue<UInt>(Nucleus::createXor(lhs.value, rhs.value));
4411 RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs)
4413 return RValue<UInt>(Nucleus::createShl(lhs.value, rhs.value));
4416 RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs)
4418 return RValue<UInt>(Nucleus::createLShr(lhs.value, rhs.value));
4421 RValue<UInt> operator+=(UInt &lhs, RValue<UInt> rhs)
4423 return lhs = lhs + rhs;
4426 RValue<UInt> operator-=(UInt &lhs, RValue<UInt> rhs)
4428 return lhs = lhs - rhs;
4431 RValue<UInt> operator*=(UInt &lhs, RValue<UInt> rhs)
4433 return lhs = lhs * rhs;
4436 RValue<UInt> operator/=(UInt &lhs, RValue<UInt> rhs)
4438 return lhs = lhs / rhs;
4441 RValue<UInt> operator%=(UInt &lhs, RValue<UInt> rhs)
4443 return lhs = lhs % rhs;
4446 RValue<UInt> operator&=(UInt &lhs, RValue<UInt> rhs)
4448 return lhs = lhs & rhs;
4451 RValue<UInt> operator|=(UInt &lhs, RValue<UInt> rhs)
4453 return lhs = lhs | rhs;
4456 RValue<UInt> operator^=(UInt &lhs, RValue<UInt> rhs)
4458 return lhs = lhs ^ rhs;
4461 RValue<UInt> operator<<=(UInt &lhs, RValue<UInt> rhs)
4463 return lhs = lhs << rhs;
4466 RValue<UInt> operator>>=(UInt &lhs, RValue<UInt> rhs)
4468 return lhs = lhs >> rhs;
4471 RValue<UInt> operator+(RValue<UInt> val)
4476 RValue<UInt> operator-(RValue<UInt> val)
4478 return RValue<UInt>(Nucleus::createNeg(val.value));
4481 RValue<UInt> operator~(RValue<UInt> val)
4483 return RValue<UInt>(Nucleus::createNot(val.value));
4486 RValue<UInt> operator++(UInt &val, int) // Post-increment
4488 RValue<UInt> res = val;
4493 const UInt &operator++(UInt &val) // Pre-increment
4499 RValue<UInt> operator--(UInt &val, int) // Post-decrement
4501 RValue<UInt> res = val;
4506 const UInt &operator--(UInt &val) // Pre-decrement
4512 RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y)
4514 return IfThenElse(x > y, x, y);
4517 RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y)
4519 return IfThenElse(x < y, x, y);
4522 RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max)
4524 return Min(Max(x, min), max);
4527 RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs)
4529 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
4532 RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs)
4534 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
4537 RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs)
4539 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
4542 RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs)
4544 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
4547 RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs)
4549 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
4552 RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs)
4554 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
4557 // RValue<UInt> RoundUInt(RValue<Float> cast)
4559 // assert(false && "UNIMPLEMENTED"); return RValue<UInt>(V(nullptr));
4562 Type *UInt::getType()
4564 return T(Ice::IceType_i32);
4567 // Int2::Int2(RValue<Int> cast)
4569 // Value *extend = Nucleus::createZExt(cast.value, Long::getType());
4570 // Value *vector = Nucleus::createBitCast(extend, Int2::getType());
4572 // Constant *shuffle[2];
4573 // shuffle[0] = Nucleus::createConstantInt(0);
4574 // shuffle[1] = Nucleus::createConstantInt(0);
4576 // Value *replicate = Nucleus::createShuffleVector(vector, UndefValue::get(Int2::getType()), Nucleus::createConstantVector(shuffle, 2));
4578 // storeValue(replicate);
4581 Int2::Int2(RValue<Int4> cast)
4583 storeValue(Nucleus::createBitCast(cast.value, getType()));
4586 Int2::Int2(int x, int y)
4588 int64_t constantVector[2] = {x, y};
4589 storeValue(Nucleus::createConstantVector(constantVector, getType()));
4592 Int2::Int2(RValue<Int2> rhs)
4594 storeValue(rhs.value);
4597 Int2::Int2(const Int2 &rhs)
4599 Value *value = rhs.loadValue();
4603 Int2::Int2(const Reference<Int2> &rhs)
4605 Value *value = rhs.loadValue();
4609 Int2::Int2(RValue<Int> lo, RValue<Int> hi)
4611 int shuffle[4] = {0, 4, 1, 5};
4612 Value *packed = Nucleus::createShuffleVector(Int4(lo).loadValue(), Int4(hi).loadValue(), shuffle);
4614 storeValue(Nucleus::createBitCast(packed, Int2::getType()));
4617 RValue<Int2> Int2::operator=(RValue<Int2> rhs)
4619 storeValue(rhs.value);
4624 RValue<Int2> Int2::operator=(const Int2 &rhs)
4626 Value *value = rhs.loadValue();
4629 return RValue<Int2>(value);
4632 RValue<Int2> Int2::operator=(const Reference<Int2> &rhs)
4634 Value *value = rhs.loadValue();
4637 return RValue<Int2>(value);
4640 RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs)
4642 return RValue<Int2>(Nucleus::createAdd(lhs.value, rhs.value));
4645 RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs)
4647 return RValue<Int2>(Nucleus::createSub(lhs.value, rhs.value));
4650 // RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs)
4652 // return RValue<Int2>(Nucleus::createMul(lhs.value, rhs.value));
4655 // RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs)
4657 // return RValue<Int2>(Nucleus::createSDiv(lhs.value, rhs.value));
4660 // RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs)
4662 // return RValue<Int2>(Nucleus::createSRem(lhs.value, rhs.value));
4665 RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs)
4667 return RValue<Int2>(Nucleus::createAnd(lhs.value, rhs.value));
4670 RValue<Int2> operator|(RValue<Int2> lhs, RValue<Int2> rhs)
4672 return RValue<Int2>(Nucleus::createOr(lhs.value, rhs.value));
4675 RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs)
4677 return RValue<Int2>(Nucleus::createXor(lhs.value, rhs.value));
4680 RValue<Int2> operator<<(RValue<Int2> lhs, unsigned char rhs)
4682 return RValue<Int2>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
4685 RValue<Int2> operator>>(RValue<Int2> lhs, unsigned char rhs)
4687 return RValue<Int2>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
4690 RValue<Int2> operator+=(Int2 &lhs, RValue<Int2> rhs)
4692 return lhs = lhs + rhs;
4695 RValue<Int2> operator-=(Int2 &lhs, RValue<Int2> rhs)
4697 return lhs = lhs - rhs;
4700 // RValue<Int2> operator*=(Int2 &lhs, RValue<Int2> rhs)
4702 // return lhs = lhs * rhs;
4705 // RValue<Int2> operator/=(Int2 &lhs, RValue<Int2> rhs)
4707 // return lhs = lhs / rhs;
4710 // RValue<Int2> operator%=(Int2 &lhs, RValue<Int2> rhs)
4712 // return lhs = lhs % rhs;
4715 RValue<Int2> operator&=(Int2 &lhs, RValue<Int2> rhs)
4717 return lhs = lhs & rhs;
4720 RValue<Int2> operator|=(Int2 &lhs, RValue<Int2> rhs)
4722 return lhs = lhs | rhs;
4725 RValue<Int2> operator^=(Int2 &lhs, RValue<Int2> rhs)
4727 return lhs = lhs ^ rhs;
4730 RValue<Int2> operator<<=(Int2 &lhs, unsigned char rhs)
4732 return lhs = lhs << rhs;
4735 RValue<Int2> operator>>=(Int2 &lhs, unsigned char rhs)
4737 return lhs = lhs >> rhs;
4740 // RValue<Int2> operator+(RValue<Int2> val)
4745 // RValue<Int2> operator-(RValue<Int2> val)
4747 // return RValue<Int2>(Nucleus::createNeg(val.value));
4750 RValue<Int2> operator~(RValue<Int2> val)
4752 return RValue<Int2>(Nucleus::createNot(val.value));
4755 RValue<Short4> UnpackLow(RValue<Int2> x, RValue<Int2> y)
4757 int shuffle[4] = {0, 4, 1, 5}; // Real type is v4i32
4758 return As<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
4761 RValue<Short4> UnpackHigh(RValue<Int2> x, RValue<Int2> y)
4763 int shuffle[4] = {0, 4, 1, 5}; // Real type is v4i32
4764 auto lowHigh = RValue<Int4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
4765 return As<Short4>(Swizzle(lowHigh, 0xEE));
4768 RValue<Int> Extract(RValue<Int2> val, int i)
4770 return RValue<Int>(Nucleus::createExtractElement(val.value, Int::getType(), i));
4773 RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i)
4775 return RValue<Int2>(Nucleus::createInsertElement(val.value, element.value, i));
4778 Type *Int2::getType()
4780 return T(Type_v2i32);
4783 UInt2::UInt2(unsigned int x, unsigned int y)
4785 int64_t constantVector[2] = {x, y};
4786 storeValue(Nucleus::createConstantVector(constantVector, getType()));
4789 UInt2::UInt2(RValue<UInt2> rhs)
4791 storeValue(rhs.value);
4794 UInt2::UInt2(const UInt2 &rhs)
4796 Value *value = rhs.loadValue();
4800 UInt2::UInt2(const Reference<UInt2> &rhs)
4802 Value *value = rhs.loadValue();
4806 RValue<UInt2> UInt2::operator=(RValue<UInt2> rhs)
4808 storeValue(rhs.value);
4813 RValue<UInt2> UInt2::operator=(const UInt2 &rhs)
4815 Value *value = rhs.loadValue();
4818 return RValue<UInt2>(value);
4821 RValue<UInt2> UInt2::operator=(const Reference<UInt2> &rhs)
4823 Value *value = rhs.loadValue();
4826 return RValue<UInt2>(value);
4829 RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs)
4831 return RValue<UInt2>(Nucleus::createAdd(lhs.value, rhs.value));
4834 RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs)
4836 return RValue<UInt2>(Nucleus::createSub(lhs.value, rhs.value));
4839 // RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs)
4841 // return RValue<UInt2>(Nucleus::createMul(lhs.value, rhs.value));
4844 // RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs)
4846 // return RValue<UInt2>(Nucleus::createUDiv(lhs.value, rhs.value));
4849 // RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs)
4851 // return RValue<UInt2>(Nucleus::createURem(lhs.value, rhs.value));
4854 RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs)
4856 return RValue<UInt2>(Nucleus::createAnd(lhs.value, rhs.value));
4859 RValue<UInt2> operator|(RValue<UInt2> lhs, RValue<UInt2> rhs)
4861 return RValue<UInt2>(Nucleus::createOr(lhs.value, rhs.value));
4864 RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs)
4866 return RValue<UInt2>(Nucleus::createXor(lhs.value, rhs.value));
4869 RValue<UInt2> operator<<(RValue<UInt2> lhs, unsigned char rhs)
4871 return RValue<UInt2>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
4874 RValue<UInt2> operator>>(RValue<UInt2> lhs, unsigned char rhs)
4876 return RValue<UInt2>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
4879 RValue<UInt2> operator+=(UInt2 &lhs, RValue<UInt2> rhs)
4881 return lhs = lhs + rhs;
4884 RValue<UInt2> operator-=(UInt2 &lhs, RValue<UInt2> rhs)
4886 return lhs = lhs - rhs;
4889 // RValue<UInt2> operator*=(UInt2 &lhs, RValue<UInt2> rhs)
4891 // return lhs = lhs * rhs;
4894 // RValue<UInt2> operator/=(UInt2 &lhs, RValue<UInt2> rhs)
4896 // return lhs = lhs / rhs;
4899 // RValue<UInt2> operator%=(UInt2 &lhs, RValue<UInt2> rhs)
4901 // return lhs = lhs % rhs;
4904 RValue<UInt2> operator&=(UInt2 &lhs, RValue<UInt2> rhs)
4906 return lhs = lhs & rhs;
4909 RValue<UInt2> operator|=(UInt2 &lhs, RValue<UInt2> rhs)
4911 return lhs = lhs | rhs;
4914 RValue<UInt2> operator^=(UInt2 &lhs, RValue<UInt2> rhs)
4916 return lhs = lhs ^ rhs;
4919 RValue<UInt2> operator<<=(UInt2 &lhs, unsigned char rhs)
4921 return lhs = lhs << rhs;
4924 RValue<UInt2> operator>>=(UInt2 &lhs, unsigned char rhs)
4926 return lhs = lhs >> rhs;
4929 // RValue<UInt2> operator+(RValue<UInt2> val)
4934 // RValue<UInt2> operator-(RValue<UInt2> val)
4936 // return RValue<UInt2>(Nucleus::createNeg(val.value));
4939 RValue<UInt2> operator~(RValue<UInt2> val)
4941 return RValue<UInt2>(Nucleus::createNot(val.value));
4944 Type *UInt2::getType()
4946 return T(Type_v2i32);
4949 Int4::Int4(RValue<Byte4> cast)
4951 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
4952 Value *a = Nucleus::createInsertElement(loadValue(), x, 0);
4955 int swizzle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23};
4956 Value *b = Nucleus::createBitCast(a, Byte16::getType());
4957 Value *c = Nucleus::createShuffleVector(b, V(Nucleus::createNullValue(Byte16::getType())), swizzle);
4959 int swizzle2[8] = {0, 8, 1, 9, 2, 10, 3, 11};
4960 Value *d = Nucleus::createBitCast(c, Short8::getType());
4961 e = Nucleus::createShuffleVector(d, V(Nucleus::createNullValue(Short8::getType())), swizzle2);
4963 Value *f = Nucleus::createBitCast(e, Int4::getType());
4967 Int4::Int4(RValue<SByte4> cast)
4969 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
4970 Value *a = Nucleus::createInsertElement(loadValue(), x, 0);
4973 int swizzle[16] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7};
4974 Value *b = Nucleus::createBitCast(a, Byte16::getType());
4975 Value *c = Nucleus::createShuffleVector(b, b, swizzle);
4977 int swizzle2[8] = {0, 0, 1, 1, 2, 2, 3, 3};
4978 Value *d = Nucleus::createBitCast(c, Short8::getType());
4979 e = Nucleus::createShuffleVector(d, d, swizzle2);
4981 Value *f = Nucleus::createBitCast(e, Int4::getType());
4982 Value *g = Nucleus::createAShr(f, V(::context->getConstantInt32(24)));
4986 Int4::Int4(RValue<Float4> cast)
4988 Value *xyzw = Nucleus::createFPToSI(cast.value, Int4::getType());
4993 Int4::Int4(RValue<Short4> cast)
4995 int swizzle[8] = {0, 0, 1, 1, 2, 2, 3, 3};
4996 Value *c = Nucleus::createShuffleVector(cast.value, cast.value, swizzle);
4997 Value *d = Nucleus::createBitCast(c, Int4::getType());
4998 Value *e = Nucleus::createAShr(d, V(::context->getConstantInt32(16)));
5002 Int4::Int4(RValue<UShort4> cast)
5004 int swizzle[8] = {0, 8, 1, 9, 2, 10, 3, 11};
5005 Value *c = Nucleus::createShuffleVector(cast.value, Short8(0, 0, 0, 0, 0, 0, 0, 0).loadValue(), swizzle);
5006 Value *d = Nucleus::createBitCast(c, Int4::getType());
5010 Int4::Int4(int xyzw)
5012 constant(xyzw, xyzw, xyzw, xyzw);
5015 Int4::Int4(int x, int yzw)
5017 constant(x, yzw, yzw, yzw);
5020 Int4::Int4(int x, int y, int zw)
5022 constant(x, y, zw, zw);
5025 Int4::Int4(int x, int y, int z, int w)
5027 constant(x, y, z, w);
5030 void Int4::constant(int x, int y, int z, int w)
5032 int64_t constantVector[4] = {x, y, z, w};
5033 storeValue(Nucleus::createConstantVector(constantVector, getType()));
5036 Int4::Int4(RValue<Int4> rhs)
5038 storeValue(rhs.value);
5041 Int4::Int4(const Int4 &rhs)
5043 Value *value = rhs.loadValue();
5047 Int4::Int4(const Reference<Int4> &rhs)
5049 Value *value = rhs.loadValue();
5053 Int4::Int4(RValue<UInt4> rhs)
5055 storeValue(rhs.value);
5058 Int4::Int4(const UInt4 &rhs)
5060 Value *value = rhs.loadValue();
5064 Int4::Int4(const Reference<UInt4> &rhs)
5066 Value *value = rhs.loadValue();
5070 Int4::Int4(RValue<Int2> lo, RValue<Int2> hi)
5072 int shuffle[4] = {0, 1, 4, 5}; // Real type is v4i32
5073 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
5078 Int4::Int4(RValue<Int> rhs)
5080 Value *vector = Nucleus::createBitCast(rhs.value, Int4::getType());
5082 int swizzle[4] = {0, 0, 0, 0};
5083 Value *replicate = Nucleus::createShuffleVector(vector, vector, swizzle);
5085 storeValue(replicate);
5088 Int4::Int4(const Int &rhs)
5090 *this = RValue<Int>(rhs.loadValue());
5093 Int4::Int4(const Reference<Int> &rhs)
5095 *this = RValue<Int>(rhs.loadValue());
5098 RValue<Int4> Int4::operator=(RValue<Int4> rhs)
5100 storeValue(rhs.value);
5105 RValue<Int4> Int4::operator=(const Int4 &rhs)
5107 Value *value = rhs.loadValue();
5110 return RValue<Int4>(value);
5113 RValue<Int4> Int4::operator=(const Reference<Int4> &rhs)
5115 Value *value = rhs.loadValue();
5118 return RValue<Int4>(value);
5121 RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs)
5123 return RValue<Int4>(Nucleus::createAdd(lhs.value, rhs.value));
5126 RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs)
5128 return RValue<Int4>(Nucleus::createSub(lhs.value, rhs.value));
5131 RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs)
5133 return RValue<Int4>(Nucleus::createMul(lhs.value, rhs.value));
5136 RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs)
5138 return RValue<Int4>(Nucleus::createSDiv(lhs.value, rhs.value));
5141 RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs)
5143 return RValue<Int4>(Nucleus::createSRem(lhs.value, rhs.value));
5146 RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs)
5148 return RValue<Int4>(Nucleus::createAnd(lhs.value, rhs.value));
5151 RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs)
5153 return RValue<Int4>(Nucleus::createOr(lhs.value, rhs.value));
5156 RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs)
5158 return RValue<Int4>(Nucleus::createXor(lhs.value, rhs.value));
5161 RValue<Int4> operator<<(RValue<Int4> lhs, unsigned char rhs)
5163 return RValue<Int4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
5166 RValue<Int4> operator>>(RValue<Int4> lhs, unsigned char rhs)
5168 return RValue<Int4>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
5171 RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs)
5173 return RValue<Int4>(Nucleus::createShl(lhs.value, rhs.value));
5176 RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs)
5178 return RValue<Int4>(Nucleus::createAShr(lhs.value, rhs.value));
5181 RValue<Int4> operator+=(Int4 &lhs, RValue<Int4> rhs)
5183 return lhs = lhs + rhs;
5186 RValue<Int4> operator-=(Int4 &lhs, RValue<Int4> rhs)
5188 return lhs = lhs - rhs;
5191 RValue<Int4> operator*=(Int4 &lhs, RValue<Int4> rhs)
5193 return lhs = lhs * rhs;
5196 // RValue<Int4> operator/=(Int4 &lhs, RValue<Int4> rhs)
5198 // return lhs = lhs / rhs;
5201 // RValue<Int4> operator%=(Int4 &lhs, RValue<Int4> rhs)
5203 // return lhs = lhs % rhs;
5206 RValue<Int4> operator&=(Int4 &lhs, RValue<Int4> rhs)
5208 return lhs = lhs & rhs;
5211 RValue<Int4> operator|=(Int4 &lhs, RValue<Int4> rhs)
5213 return lhs = lhs | rhs;
5216 RValue<Int4> operator^=(Int4 &lhs, RValue<Int4> rhs)
5218 return lhs = lhs ^ rhs;
5221 RValue<Int4> operator<<=(Int4 &lhs, unsigned char rhs)
5223 return lhs = lhs << rhs;
5226 RValue<Int4> operator>>=(Int4 &lhs, unsigned char rhs)
5228 return lhs = lhs >> rhs;
5231 RValue<Int4> operator+(RValue<Int4> val)
5236 RValue<Int4> operator-(RValue<Int4> val)
5238 return RValue<Int4>(Nucleus::createNeg(val.value));
5241 RValue<Int4> operator~(RValue<Int4> val)
5243 return RValue<Int4>(Nucleus::createNot(val.value));
5246 RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y)
5248 return RValue<Int4>(Nucleus::createICmpEQ(x.value, y.value));
5251 RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y)
5253 return RValue<Int4>(Nucleus::createICmpSLT(x.value, y.value));
5256 RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y)
5258 return RValue<Int4>(Nucleus::createICmpSLE(x.value, y.value));
5261 RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y)
5263 return RValue<Int4>(Nucleus::createICmpNE(x.value, y.value));
5266 RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y)
5268 return RValue<Int4>(Nucleus::createICmpSGE(x.value, y.value));
5271 RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y)
5273 return RValue<Int4>(Nucleus::createICmpSGT(x.value, y.value));
5276 RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y)
5278 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
5279 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sle, condition, x.value, y.value);
5280 ::basicBlock->appendInst(cmp);
5282 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5283 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
5284 ::basicBlock->appendInst(select);
5286 return RValue<Int4>(V(result));
5289 RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y)
5291 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
5292 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sgt, condition, x.value, y.value);
5293 ::basicBlock->appendInst(cmp);
5295 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5296 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
5297 ::basicBlock->appendInst(select);
5299 return RValue<Int4>(V(result));
5302 RValue<Int4> RoundInt(RValue<Float4> cast)
5304 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5305 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Nearbyint, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5306 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5307 auto nearbyint = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
5308 nearbyint->addArg(cast.value);
5309 ::basicBlock->appendInst(nearbyint);
5311 return RValue<Int4>(V(result));
5314 RValue<Short8> Pack(RValue<Int4> x, RValue<Int4> y)
5316 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
5317 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5318 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5319 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
5320 pack->addArg(x.value);
5321 pack->addArg(y.value);
5322 ::basicBlock->appendInst(pack);
5324 return RValue<Short8>(V(result));
5327 RValue<Int> Extract(RValue<Int4> x, int i)
5329 return RValue<Int>(Nucleus::createExtractElement(x.value, Int::getType(), i));
5332 RValue<Int4> Insert(RValue<Int4> x, RValue<Int> element, int i)
5334 return RValue<Int4>(Nucleus::createInsertElement(x.value, element.value, i));
5337 RValue<Int> SignMask(RValue<Int4> x)
5339 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
5340 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5341 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5342 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
5343 movmsk->addArg(x.value);
5344 ::basicBlock->appendInst(movmsk);
5346 return RValue<Int>(V(result));
5349 RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select)
5351 return RValue<Int4>(createSwizzle4(x.value, select));
5354 Type *Int4::getType()
5356 return T(Ice::IceType_v4i32);
5359 UInt4::UInt4(RValue<Float4> cast)
5361 // Smallest positive value representable in UInt, but not in Int
5362 const unsigned int ustart = 0x80000000u;
5363 const float ustartf = float(ustart);
5365 // Check if the value can be represented as an Int
5366 Int4 uiValue = CmpNLT(cast, Float4(ustartf));
5367 // If the value is too large, subtract ustart and re-add it after conversion.
5368 uiValue = (uiValue & As<Int4>(As<UInt4>(Int4(cast - Float4(ustartf))) + UInt4(ustart))) |
5369 // Otherwise, just convert normally
5370 (~uiValue & Int4(cast));
5371 // If the value is negative, store 0, otherwise store the result of the conversion
5372 storeValue((~(As<Int4>(cast) >> 31) & uiValue).value);
5375 UInt4::UInt4(int xyzw)
5377 constant(xyzw, xyzw, xyzw, xyzw);
5380 UInt4::UInt4(int x, int yzw)
5382 constant(x, yzw, yzw, yzw);
5385 UInt4::UInt4(int x, int y, int zw)
5387 constant(x, y, zw, zw);
5390 UInt4::UInt4(int x, int y, int z, int w)
5392 constant(x, y, z, w);
5395 void UInt4::constant(int x, int y, int z, int w)
5397 int64_t constantVector[4] = {x, y, z, w};
5398 storeValue(Nucleus::createConstantVector(constantVector, getType()));
5401 UInt4::UInt4(RValue<UInt4> rhs)
5403 storeValue(rhs.value);
5406 UInt4::UInt4(const UInt4 &rhs)
5408 Value *value = rhs.loadValue();
5412 UInt4::UInt4(const Reference<UInt4> &rhs)
5414 Value *value = rhs.loadValue();
5418 UInt4::UInt4(RValue<Int4> rhs)
5420 storeValue(rhs.value);
5423 UInt4::UInt4(const Int4 &rhs)
5425 Value *value = rhs.loadValue();
5429 UInt4::UInt4(const Reference<Int4> &rhs)
5431 Value *value = rhs.loadValue();
5435 UInt4::UInt4(RValue<UInt2> lo, RValue<UInt2> hi)
5437 int shuffle[4] = {0, 1, 4, 5}; // Real type is v4i32
5438 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
5443 RValue<UInt4> UInt4::operator=(RValue<UInt4> rhs)
5445 storeValue(rhs.value);
5450 RValue<UInt4> UInt4::operator=(const UInt4 &rhs)
5452 Value *value = rhs.loadValue();
5455 return RValue<UInt4>(value);
5458 RValue<UInt4> UInt4::operator=(const Reference<UInt4> &rhs)
5460 Value *value = rhs.loadValue();
5463 return RValue<UInt4>(value);
5466 RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs)
5468 return RValue<UInt4>(Nucleus::createAdd(lhs.value, rhs.value));
5471 RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs)
5473 return RValue<UInt4>(Nucleus::createSub(lhs.value, rhs.value));
5476 RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs)
5478 return RValue<UInt4>(Nucleus::createMul(lhs.value, rhs.value));
5481 RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs)
5483 return RValue<UInt4>(Nucleus::createUDiv(lhs.value, rhs.value));
5486 RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs)
5488 return RValue<UInt4>(Nucleus::createURem(lhs.value, rhs.value));
5491 RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs)
5493 return RValue<UInt4>(Nucleus::createAnd(lhs.value, rhs.value));
5496 RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs)
5498 return RValue<UInt4>(Nucleus::createOr(lhs.value, rhs.value));
5501 RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs)
5503 return RValue<UInt4>(Nucleus::createXor(lhs.value, rhs.value));
5506 RValue<UInt4> operator<<(RValue<UInt4> lhs, unsigned char rhs)
5508 return RValue<UInt4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
5511 RValue<UInt4> operator>>(RValue<UInt4> lhs, unsigned char rhs)
5513 return RValue<UInt4>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
5516 RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs)
5518 return RValue<UInt4>(Nucleus::createShl(lhs.value, rhs.value));
5521 RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs)
5523 return RValue<UInt4>(Nucleus::createLShr(lhs.value, rhs.value));
5526 RValue<UInt4> operator+=(UInt4 &lhs, RValue<UInt4> rhs)
5528 return lhs = lhs + rhs;
5531 RValue<UInt4> operator-=(UInt4 &lhs, RValue<UInt4> rhs)
5533 return lhs = lhs - rhs;
5536 RValue<UInt4> operator*=(UInt4 &lhs, RValue<UInt4> rhs)
5538 return lhs = lhs * rhs;
5541 // RValue<UInt4> operator/=(UInt4 &lhs, RValue<UInt4> rhs)
5543 // return lhs = lhs / rhs;
5546 // RValue<UInt4> operator%=(UInt4 &lhs, RValue<UInt4> rhs)
5548 // return lhs = lhs % rhs;
5551 RValue<UInt4> operator&=(UInt4 &lhs, RValue<UInt4> rhs)
5553 return lhs = lhs & rhs;
5556 RValue<UInt4> operator|=(UInt4 &lhs, RValue<UInt4> rhs)
5558 return lhs = lhs | rhs;
5561 RValue<UInt4> operator^=(UInt4 &lhs, RValue<UInt4> rhs)
5563 return lhs = lhs ^ rhs;
5566 RValue<UInt4> operator<<=(UInt4 &lhs, unsigned char rhs)
5568 return lhs = lhs << rhs;
5571 RValue<UInt4> operator>>=(UInt4 &lhs, unsigned char rhs)
5573 return lhs = lhs >> rhs;
5576 RValue<UInt4> operator+(RValue<UInt4> val)
5581 RValue<UInt4> operator-(RValue<UInt4> val)
5583 return RValue<UInt4>(Nucleus::createNeg(val.value));
5586 RValue<UInt4> operator~(RValue<UInt4> val)
5588 return RValue<UInt4>(Nucleus::createNot(val.value));
5591 RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y)
5593 return RValue<UInt4>(Nucleus::createICmpEQ(x.value, y.value));
5596 RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y)
5598 return RValue<UInt4>(Nucleus::createICmpULT(x.value, y.value));
5601 RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y)
5603 return RValue<UInt4>(Nucleus::createICmpULE(x.value, y.value));
5606 RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y)
5608 return RValue<UInt4>(Nucleus::createICmpNE(x.value, y.value));
5611 RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y)
5613 return RValue<UInt4>(Nucleus::createICmpUGE(x.value, y.value));
5616 RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y)
5618 return RValue<UInt4>(Nucleus::createICmpUGT(x.value, y.value));
5621 RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y)
5623 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
5624 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ule, condition, x.value, y.value);
5625 ::basicBlock->appendInst(cmp);
5627 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5628 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
5629 ::basicBlock->appendInst(select);
5631 return RValue<UInt4>(V(result));
5634 RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y)
5636 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
5637 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ugt, condition, x.value, y.value);
5638 ::basicBlock->appendInst(cmp);
5640 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5641 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
5642 ::basicBlock->appendInst(select);
5644 return RValue<UInt4>(V(result));
5647 RValue<UShort8> Pack(RValue<UInt4> x, RValue<UInt4> y)
5651 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
5652 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5653 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5654 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
5655 pack->addArg(x.value);
5656 pack->addArg(y.value);
5657 ::basicBlock->appendInst(pack);
5659 return RValue<UShort8>(V(result));
5663 RValue<Int4> sx = As<Int4>(x);
5664 RValue<Int4> bx = (sx & ~(sx >> 31)) - Int4(0x8000);
5666 RValue<Int4> sy = As<Int4>(y);
5667 RValue<Int4> by = (sy & ~(sy >> 31)) - Int4(0x8000);
5669 return As<UShort8>(Pack(bx, by) + Short8(0x8000u));
5673 Type *UInt4::getType()
5675 return T(Ice::IceType_v4i32);
5678 Float::Float(RValue<Int> cast)
5680 Value *integer = Nucleus::createSIToFP(cast.value, Float::getType());
5682 storeValue(integer);
5685 Float::Float(float x)
5687 storeValue(Nucleus::createConstantFloat(x));
5690 Float::Float(RValue<Float> rhs)
5692 storeValue(rhs.value);
5695 Float::Float(const Float &rhs)
5697 Value *value = rhs.loadValue();
5701 Float::Float(const Reference<Float> &rhs)
5703 Value *value = rhs.loadValue();
5707 RValue<Float> Float::operator=(RValue<Float> rhs)
5709 storeValue(rhs.value);
5714 RValue<Float> Float::operator=(const Float &rhs)
5716 Value *value = rhs.loadValue();
5719 return RValue<Float>(value);
5722 RValue<Float> Float::operator=(const Reference<Float> &rhs)
5724 Value *value = rhs.loadValue();
5727 return RValue<Float>(value);
5730 RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs)
5732 return RValue<Float>(Nucleus::createFAdd(lhs.value, rhs.value));
5735 RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs)
5737 return RValue<Float>(Nucleus::createFSub(lhs.value, rhs.value));
5740 RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs)
5742 return RValue<Float>(Nucleus::createFMul(lhs.value, rhs.value));
5745 RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs)
5747 return RValue<Float>(Nucleus::createFDiv(lhs.value, rhs.value));
5750 RValue<Float> operator+=(Float &lhs, RValue<Float> rhs)
5752 return lhs = lhs + rhs;
5755 RValue<Float> operator-=(Float &lhs, RValue<Float> rhs)
5757 return lhs = lhs - rhs;
5760 RValue<Float> operator*=(Float &lhs, RValue<Float> rhs)
5762 return lhs = lhs * rhs;
5765 RValue<Float> operator/=(Float &lhs, RValue<Float> rhs)
5767 return lhs = lhs / rhs;
5770 RValue<Float> operator+(RValue<Float> val)
5775 RValue<Float> operator-(RValue<Float> val)
5777 return RValue<Float>(Nucleus::createFNeg(val.value));
5780 RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs)
5782 return RValue<Bool>(Nucleus::createFCmpOLT(lhs.value, rhs.value));
5785 RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs)
5787 return RValue<Bool>(Nucleus::createFCmpOLE(lhs.value, rhs.value));
5790 RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs)
5792 return RValue<Bool>(Nucleus::createFCmpOGT(lhs.value, rhs.value));
5795 RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs)
5797 return RValue<Bool>(Nucleus::createFCmpOGE(lhs.value, rhs.value));
5800 RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs)
5802 return RValue<Bool>(Nucleus::createFCmpONE(lhs.value, rhs.value));
5805 RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs)
5807 return RValue<Bool>(Nucleus::createFCmpOEQ(lhs.value, rhs.value));
5810 RValue<Float> Abs(RValue<Float> x)
5812 return IfThenElse(x > 0.0f, x, -x);
5815 RValue<Float> Max(RValue<Float> x, RValue<Float> y)
5817 return IfThenElse(x > y, x, y);
5820 RValue<Float> Min(RValue<Float> x, RValue<Float> y)
5822 return IfThenElse(x < y, x, y);
5825 RValue<Float> Rcp_pp(RValue<Float> x, bool exactAtPow2)
5830 RValue<Float> RcpSqrt_pp(RValue<Float> x)
5832 return Rcp_pp(Sqrt(x));
5835 RValue<Float> Sqrt(RValue<Float> x)
5837 Ice::Variable *result = ::function->makeVariable(Ice::IceType_f32);
5838 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Sqrt, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5839 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5840 auto sqrt = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
5841 sqrt->addArg(x.value);
5842 ::basicBlock->appendInst(sqrt);
5844 return RValue<Float>(V(result));
5847 RValue<Float> Round(RValue<Float> x)
5849 return Float4(Round(Float4(x))).x;
5852 RValue<Float> Trunc(RValue<Float> x)
5854 return Float4(Trunc(Float4(x))).x;
5857 RValue<Float> Frac(RValue<Float> x)
5859 return Float4(Frac(Float4(x))).x;
5862 RValue<Float> Floor(RValue<Float> x)
5864 return Float4(Floor(Float4(x))).x;
5867 RValue<Float> Ceil(RValue<Float> x)
5869 return Float4(Ceil(Float4(x))).x;
5872 Type *Float::getType()
5874 return T(Ice::IceType_f32);
5877 Float2::Float2(RValue<Float4> cast)
5879 storeValue(Nucleus::createBitCast(cast.value, getType()));
5882 Type *Float2::getType()
5884 return T(Type_v2f32);
5887 Float4::Float4(RValue<Byte4> cast) : FloatXYZW(this)
5889 Value *a = Int4(cast).loadValue();
5890 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
5895 Float4::Float4(RValue<SByte4> cast) : FloatXYZW(this)
5897 Value *a = Int4(cast).loadValue();
5898 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
5903 Float4::Float4(RValue<Short4> cast) : FloatXYZW(this)
5906 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
5909 Float4::Float4(RValue<UShort4> cast) : FloatXYZW(this)
5912 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
5915 Float4::Float4(RValue<Int4> cast) : FloatXYZW(this)
5917 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType());
5922 Float4::Float4(RValue<UInt4> cast) : FloatXYZW(this)
5924 RValue<Float4> result = Float4(Int4(cast & UInt4(0x7FFFFFFF))) +
5925 As<Float4>((As<Int4>(cast) >> 31) & As<Int4>(Float4(0x80000000u)));
5927 storeValue(result.value);
5930 Float4::Float4() : FloatXYZW(this)
5934 Float4::Float4(float xyzw) : FloatXYZW(this)
5936 constant(xyzw, xyzw, xyzw, xyzw);
5939 Float4::Float4(float x, float yzw) : FloatXYZW(this)
5941 constant(x, yzw, yzw, yzw);
5944 Float4::Float4(float x, float y, float zw) : FloatXYZW(this)
5946 constant(x, y, zw, zw);
5949 Float4::Float4(float x, float y, float z, float w) : FloatXYZW(this)
5951 constant(x, y, z, w);
5954 void Float4::constant(float x, float y, float z, float w)
5956 double constantVector[4] = {x, y, z, w};
5957 storeValue(Nucleus::createConstantVector(constantVector, getType()));
5960 Float4::Float4(RValue<Float4> rhs) : FloatXYZW(this)
5962 storeValue(rhs.value);
5965 Float4::Float4(const Float4 &rhs) : FloatXYZW(this)
5967 Value *value = rhs.loadValue();
5971 Float4::Float4(const Reference<Float4> &rhs) : FloatXYZW(this)
5973 Value *value = rhs.loadValue();
5977 Float4::Float4(RValue<Float> rhs) : FloatXYZW(this)
5979 Value *vector = Nucleus::createBitCast(rhs.value, Float4::getType());
5981 int swizzle[4] = {0, 0, 0, 0};
5982 Value *replicate = Nucleus::createShuffleVector(vector, vector, swizzle);
5984 storeValue(replicate);
5987 Float4::Float4(const Float &rhs) : FloatXYZW(this)
5989 *this = RValue<Float>(rhs.loadValue());
5992 Float4::Float4(const Reference<Float> &rhs) : FloatXYZW(this)
5994 *this = RValue<Float>(rhs.loadValue());
5997 RValue<Float4> Float4::operator=(float x)
5999 return *this = Float4(x, x, x, x);
6002 RValue<Float4> Float4::operator=(RValue<Float4> rhs)
6004 storeValue(rhs.value);
6009 RValue<Float4> Float4::operator=(const Float4 &rhs)
6011 Value *value = rhs.loadValue();
6014 return RValue<Float4>(value);
6017 RValue<Float4> Float4::operator=(const Reference<Float4> &rhs)
6019 Value *value = rhs.loadValue();
6022 return RValue<Float4>(value);
6025 RValue<Float4> Float4::operator=(RValue<Float> rhs)
6027 return *this = Float4(rhs);
6030 RValue<Float4> Float4::operator=(const Float &rhs)
6032 return *this = Float4(rhs);
6035 RValue<Float4> Float4::operator=(const Reference<Float> &rhs)
6037 return *this = Float4(rhs);
6040 RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs)
6042 return RValue<Float4>(Nucleus::createFAdd(lhs.value, rhs.value));
6045 RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs)
6047 return RValue<Float4>(Nucleus::createFSub(lhs.value, rhs.value));
6050 RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs)
6052 return RValue<Float4>(Nucleus::createFMul(lhs.value, rhs.value));
6055 RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs)
6057 return RValue<Float4>(Nucleus::createFDiv(lhs.value, rhs.value));
6060 RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs)
6062 return RValue<Float4>(Nucleus::createFRem(lhs.value, rhs.value));
6065 RValue<Float4> operator+=(Float4 &lhs, RValue<Float4> rhs)
6067 return lhs = lhs + rhs;
6070 RValue<Float4> operator-=(Float4 &lhs, RValue<Float4> rhs)
6072 return lhs = lhs - rhs;
6075 RValue<Float4> operator*=(Float4 &lhs, RValue<Float4> rhs)
6077 return lhs = lhs * rhs;
6080 RValue<Float4> operator/=(Float4 &lhs, RValue<Float4> rhs)
6082 return lhs = lhs / rhs;
6085 RValue<Float4> operator%=(Float4 &lhs, RValue<Float4> rhs)
6087 return lhs = lhs % rhs;
6090 RValue<Float4> operator+(RValue<Float4> val)
6095 RValue<Float4> operator-(RValue<Float4> val)
6097 return RValue<Float4>(Nucleus::createFNeg(val.value));
6100 RValue<Float4> Abs(RValue<Float4> x)
6102 Value *vector = Nucleus::createBitCast(x.value, Int4::getType());
6103 int64_t constantVector[4] = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF};
6104 Value *result = Nucleus::createAnd(vector, V(Nucleus::createConstantVector(constantVector, Int4::getType())));
6106 return As<Float4>(result);
6109 RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y)
6111 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
6112 auto cmp = Ice::InstFcmp::create(::function, Ice::InstFcmp::Ogt, condition, x.value, y.value);
6113 ::basicBlock->appendInst(cmp);
6115 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6116 auto select = Ice::InstSelect::create(::function, result, condition, x.value, y.value);
6117 ::basicBlock->appendInst(select);
6119 return RValue<Float4>(V(result));
6122 RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y)
6124 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
6125 auto cmp = Ice::InstFcmp::create(::function, Ice::InstFcmp::Olt, condition, x.value, y.value);
6126 ::basicBlock->appendInst(cmp);
6128 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6129 auto select = Ice::InstSelect::create(::function, result, condition, x.value, y.value);
6130 ::basicBlock->appendInst(select);
6132 return RValue<Float4>(V(result));
6135 RValue<Float4> Rcp_pp(RValue<Float4> x, bool exactAtPow2)
6137 return Float4(1.0f) / x;
6140 RValue<Float4> RcpSqrt_pp(RValue<Float4> x)
6142 return Rcp_pp(Sqrt(x));
6145 RValue<Float4> Sqrt(RValue<Float4> x)
6147 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6148 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Sqrt, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6149 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6150 auto sqrt = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
6151 sqrt->addArg(x.value);
6152 ::basicBlock->appendInst(sqrt);
6154 return RValue<Float4>(V(result));
6157 RValue<Float4> Insert(RValue<Float4> x, RValue<Float> element, int i)
6159 return RValue<Float4>(Nucleus::createInsertElement(x.value, element.value, i));
6162 RValue<Float> Extract(RValue<Float4> x, int i)
6164 return RValue<Float>(Nucleus::createExtractElement(x.value, Float::getType(), i));
6167 RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select)
6169 return RValue<Float4>(createSwizzle4(x.value, select));
6172 RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
6176 ((imm >> 0) & 0x03) + 0,
6177 ((imm >> 2) & 0x03) + 0,
6178 ((imm >> 4) & 0x03) + 4,
6179 ((imm >> 6) & 0x03) + 4,
6182 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
6185 RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y)
6187 int shuffle[4] = {0, 4, 1, 5};
6188 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
6191 RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y)
6193 int shuffle[4] = {2, 6, 3, 7};
6194 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
6197 RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select)
6199 Value *vector = lhs.loadValue();
6200 Value *result = createMask4(vector, rhs.value, select);
6201 lhs.storeValue(result);
6203 return RValue<Float4>(result);
6206 RValue<Int> SignMask(RValue<Float4> x)
6208 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
6209 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6210 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6211 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
6212 movmsk->addArg(x.value);
6213 ::basicBlock->appendInst(movmsk);
6215 return RValue<Int>(V(result));
6218 RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y)
6220 return RValue<Int4>(Nucleus::createFCmpOEQ(x.value, y.value));
6223 RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y)
6225 return RValue<Int4>(Nucleus::createFCmpOLT(x.value, y.value));
6228 RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y)
6230 return RValue<Int4>(Nucleus::createFCmpOLE(x.value, y.value));
6233 RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y)
6235 return RValue<Int4>(Nucleus::createFCmpONE(x.value, y.value));
6238 RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y)
6240 return RValue<Int4>(Nucleus::createFCmpOGE(x.value, y.value));
6243 RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y)
6245 return RValue<Int4>(Nucleus::createFCmpOGT(x.value, y.value));
6248 RValue<Float4> Round(RValue<Float4> x)
6252 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6253 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6254 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6255 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
6256 round->addArg(x.value);
6257 round->addArg(::context->getConstantInt32(0));
6258 ::basicBlock->appendInst(round);
6260 return RValue<Float4>(V(result));
6264 return Float4(RoundInt(x));
6268 RValue<Float4> Trunc(RValue<Float4> x)
6272 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6273 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6274 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6275 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
6276 round->addArg(x.value);
6277 round->addArg(::context->getConstantInt32(3));
6278 ::basicBlock->appendInst(round);
6280 return RValue<Float4>(V(result));
6284 return Float4(Int4(x));
6288 RValue<Float4> Frac(RValue<Float4> x)
6292 return x - Floor(x);
6296 Float4 frc = x - Float4(Int4(x)); // Signed fractional part
6298 return frc + As<Float4>(As<Int4>(CmpNLE(Float4(0.0f), frc)) & As<Int4>(Float4(1, 1, 1, 1)));
6302 RValue<Float4> Floor(RValue<Float4> x)
6306 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6307 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6308 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6309 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
6310 round->addArg(x.value);
6311 round->addArg(::context->getConstantInt32(1));
6312 ::basicBlock->appendInst(round);
6314 return RValue<Float4>(V(result));
6322 RValue<Float4> Ceil(RValue<Float4> x)
6326 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6327 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6328 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6329 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
6330 round->addArg(x.value);
6331 round->addArg(::context->getConstantInt32(2));
6332 ::basicBlock->appendInst(round);
6334 return RValue<Float4>(V(result));
6342 Type *Float4::getType()
6344 return T(Ice::IceType_v4f32);
6347 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset)
6349 return lhs + RValue<Int>(Nucleus::createConstantInt(offset));
6352 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
6354 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value, false));
6357 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
6359 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value, true));
6362 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, int offset)
6364 return lhs = lhs + offset;
6367 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<Int> offset)
6369 return lhs = lhs + offset;
6372 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<UInt> offset)
6374 return lhs = lhs + offset;
6377 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset)
6379 return lhs + -offset;
6382 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
6384 return lhs + -offset;
6387 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
6389 return lhs + -offset;
6392 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, int offset)
6394 return lhs = lhs - offset;
6397 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<Int> offset)
6399 return lhs = lhs - offset;
6402 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<UInt> offset)
6404 return lhs = lhs - offset;
6409 Nucleus::createRetVoid();
6410 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
6411 Nucleus::createUnreachable();
6414 void Return(RValue<Int> ret)
6416 Nucleus::createRet(ret.value);
6417 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
6418 Nucleus::createUnreachable();
6421 bool branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB)
6423 Nucleus::createCondBr(cmp.value, bodyBB, endBB);
6424 Nucleus::setInsertBlock(bodyBB);
6429 RValue<Long> Ticks()
6431 assert(false && "UNIMPLEMENTED"); return RValue<Long>(V(nullptr));