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