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