blob: d5a19b25bfb13309470205cc63fcc35f60b6db24 [file] [log] [blame]
Nicolas Capens598f8d82016-09-26 15:09:10 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "Nucleus.hpp"
16
17#include "Reactor.hpp"
18#include "Routine.hpp"
19
20#include "src/IceTypes.h"
21#include "src/IceCfg.h"
22#include "src/IceELFStreamer.h"
23#include "src/IceGlobalContext.h"
24#include "src/IceCfgNode.h"
25#include "src/IceELFObjectWriter.h"
Nicolas Capens8dfd9a72016-10-13 17:44:51 -040026#include "src/IceGlobalInits.h"
Nicolas Capens598f8d82016-09-26 15:09:10 -040027
28#include "llvm/Support/FileSystem.h"
29#include "llvm/Support/raw_os_ostream.h"
30
31#define WIN32_LEAN_AND_MEAN
32#define NOMINMAX
33#include <Windows.h>
34
35#include <mutex>
36#include <limits>
37#include <iostream>
38#include <cassert>
39
40namespace
41{
42 Ice::GlobalContext *context = nullptr;
43 Ice::Cfg *function = nullptr;
44 Ice::CfgNode *basicBlock = nullptr;
45 Ice::CfgLocalAllocatorScope *allocator = nullptr;
46 sw::Routine *routine = nullptr;
47
48 std::mutex codegenMutex;
49
Nicolas Capens9ed1a182016-10-24 09:52:23 -040050 sw::BasicBlock *falseBB = nullptr;
51
Nicolas Capens598f8d82016-09-26 15:09:10 -040052 Ice::ELFFileStreamer *elfFile = nullptr;
53 Ice::Fdstream *out = nullptr;
54}
55
56namespace sw
57{
Nicolas Capens23d99a42016-09-30 14:57:16 -040058 enum EmulatedType
59 {
60 EmulatedShift = 16,
61 EmulatedV2 = 2 << EmulatedShift,
62 EmulatedV4 = 4 << EmulatedShift,
63 EmulatedV8 = 8 << EmulatedShift,
64 EmulatedBits = EmulatedV2 | EmulatedV4 | EmulatedV8,
65
66 Type_v2i32 = Ice::IceType_v4i32 | EmulatedV2,
67 Type_v4i16 = Ice::IceType_v8i16 | EmulatedV4,
68 Type_v2i16 = Ice::IceType_v8i16 | EmulatedV2,
69 Type_v8i8 = Ice::IceType_v16i8 | EmulatedV8,
70 Type_v4i8 = Ice::IceType_v16i8 | EmulatedV4,
Nicolas Capens4cfd4572016-10-20 01:00:19 -040071 Type_v2f32 = Ice::IceType_v4f32 | EmulatedV2,
Nicolas Capens23d99a42016-09-30 14:57:16 -040072 };
73
Nicolas Capens598f8d82016-09-26 15:09:10 -040074 class Value : public Ice::Variable {};
75 class BasicBlock : public Ice::CfgNode {};
76
77 Ice::Type T(Type *t)
78 {
Nicolas Capens23d99a42016-09-30 14:57:16 -040079 static_assert(Ice::IceType_NUM < EmulatedBits, "Ice::Type overlaps with our emulated types!");
80 return (Ice::Type)(reinterpret_cast<std::intptr_t>(t) & ~EmulatedBits);
Nicolas Capens598f8d82016-09-26 15:09:10 -040081 }
82
83 Type *T(Ice::Type t)
84 {
85 return reinterpret_cast<Type*>(t);
86 }
87
Nicolas Capens23d99a42016-09-30 14:57:16 -040088 Type *T(EmulatedType t)
89 {
90 return reinterpret_cast<Type*>(t);
91 }
92
Nicolas Capens598f8d82016-09-26 15:09:10 -040093 Value *V(Ice::Variable *v)
94 {
95 return reinterpret_cast<Value*>(v);
96 }
97
Nicolas Capens327f1df2016-10-21 14:26:34 -040098 Value *C(Ice::Constant *c) // Only safe for casting right-hand side operand
99 {
100 return reinterpret_cast<Value*>(c);
101 }
102
Nicolas Capens611642a2016-09-28 16:45:04 -0400103 BasicBlock *B(Ice::CfgNode *b)
104 {
105 return reinterpret_cast<BasicBlock*>(b);
106 }
107
Nicolas Capens598f8d82016-09-26 15:09:10 -0400108 Optimization optimization[10] = {InstructionCombining, Disabled};
109
Nicolas Capens66478362016-10-13 15:36:36 -0400110 using ElfHeader = std::conditional<sizeof(void*) == 8, Elf64_Ehdr, Elf32_Ehdr>::type;
111 using SectionHeader = std::conditional<sizeof(void*) == 8, Elf64_Shdr, Elf32_Shdr>::type;
112
113 inline const SectionHeader *sectionHeader(const ElfHeader *elfHeader)
114 {
115 return reinterpret_cast<const SectionHeader*>((intptr_t)elfHeader + elfHeader->e_shoff);
116 }
117
118 inline const SectionHeader *elfSection(const ElfHeader *elfHeader, int index)
119 {
120 return &sectionHeader(elfHeader)[index];
121 }
122
123 static void *relocateSymbol(const ElfHeader *elfHeader, const Elf32_Rel &relocation, const SectionHeader &relocationTable)
124 {
125 const SectionHeader *target = elfSection(elfHeader, relocationTable.sh_info);
126
127 intptr_t address = (intptr_t)elfHeader + target->sh_offset;
128 int32_t *patchSite = (int*)(address + relocation.r_offset);
129 uint32_t index = relocation.getSymbol();
130 int table = relocationTable.sh_link;
131 void *symbolValue = nullptr;
132
133 if(index != SHN_UNDEF)
134 {
135 if(table == SHN_UNDEF) return nullptr;
136 const SectionHeader *symbolTable = elfSection(elfHeader, table);
137
138 uint32_t symtab_entries = symbolTable->sh_size / symbolTable->sh_entsize;
139 if(index >= symtab_entries)
140 {
141 assert(index < symtab_entries && "Symbol Index out of range");
142 return nullptr;
143 }
144
145 intptr_t symbolAddress = (intptr_t)elfHeader + symbolTable->sh_offset;
146 Elf32_Sym &symbol = ((Elf32_Sym*)symbolAddress)[index];
147 uint16_t section = symbol.st_shndx;
148
149 if(section != SHN_UNDEF && section < SHN_LORESERVE)
150 {
151 const SectionHeader *target = elfSection(elfHeader, symbol.st_shndx);
152 symbolValue = reinterpret_cast<void*>((intptr_t)elfHeader + symbol.st_value + target->sh_offset);
153 }
154 else
155 {
156 return nullptr;
157 }
158 }
159
160 switch(relocation.getType())
161 {
162 case R_386_NONE:
163 // No relocation
164 break;
165 case R_386_32:
166 *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite);
167 break;
168 // case R_386_PC32:
169 // *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite - (intptr_t)patchSite);
170 // break;
171 default:
172 assert(false && "Unsupported relocation type");
173 return nullptr;
174 }
175
176 return symbolValue;
177 }
178
179 static void *relocateSymbol(const ElfHeader *elfHeader, const Elf64_Rela &relocation, const SectionHeader &relocationTable)
180 {
181 const SectionHeader *target = elfSection(elfHeader, relocationTable.sh_info);
182
183 intptr_t address = (intptr_t)elfHeader + target->sh_offset;
184 int32_t *patchSite = (int*)(address + relocation.r_offset);
185 uint32_t index = relocation.getSymbol();
186 int table = relocationTable.sh_link;
187 void *symbolValue = nullptr;
188
189 if(index != SHN_UNDEF)
190 {
191 if(table == SHN_UNDEF) return nullptr;
192 const SectionHeader *symbolTable = elfSection(elfHeader, table);
193
194 uint32_t symtab_entries = symbolTable->sh_size / symbolTable->sh_entsize;
195 if(index >= symtab_entries)
196 {
197 assert(index < symtab_entries && "Symbol Index out of range");
198 return nullptr;
199 }
200
201 intptr_t symbolAddress = (intptr_t)elfHeader + symbolTable->sh_offset;
202 Elf64_Sym &symbol = ((Elf64_Sym*)symbolAddress)[index];
203 uint16_t section = symbol.st_shndx;
204
205 if(section != SHN_UNDEF && section < SHN_LORESERVE)
206 {
207 const SectionHeader *target = elfSection(elfHeader, symbol.st_shndx);
208 symbolValue = reinterpret_cast<void*>((intptr_t)elfHeader + symbol.st_value + target->sh_offset);
209 }
210 else
211 {
212 return nullptr;
213 }
214 }
215
216 switch(relocation.getType())
217 {
218 case R_X86_64_NONE:
219 // No relocation
220 break;
221 // case R_X86_64_64:
222 // *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite) + relocation->r_addend;
223 // break;
224 case R_X86_64_PC32:
225 *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite - (intptr_t)patchSite) + relocation.r_addend;
226 break;
227 // case R_X86_64_32S:
228 // *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite) + relocation.r_addend;
229 // break;
230 default:
231 assert(false && "Unsupported relocation type");
232 return nullptr;
233 }
234
235 return symbolValue;
236 }
237
Nicolas Capens598f8d82016-09-26 15:09:10 -0400238 void *loadImage(uint8_t *const elfImage)
239 {
Nicolas Capens598f8d82016-09-26 15:09:10 -0400240 ElfHeader *elfHeader = (ElfHeader*)elfImage;
241
242 if(!elfHeader->checkMagic())
243 {
244 return nullptr;
245 }
246
Nicolas Capens66478362016-10-13 15:36:36 -0400247 // Expect ELF bitness to match platform
Nicolas Capens65047112016-11-07 13:01:07 -0500248 assert(sizeof(void*) == 8 ? elfHeader->getFileClass() == ELFCLASS64 : elfHeader->getFileClass() == ELFCLASS32);
Nicolas Capens66478362016-10-13 15:36:36 -0400249 assert(sizeof(void*) == 8 ? elfHeader->e_machine == EM_X86_64 : elfHeader->e_machine == EM_386);
250
Nicolas Capens598f8d82016-09-26 15:09:10 -0400251 SectionHeader *sectionHeader = (SectionHeader*)(elfImage + elfHeader->e_shoff);
252 void *entry = nullptr;
253
254 for(int i = 0; i < elfHeader->e_shnum; i++)
255 {
Nicolas Capens66478362016-10-13 15:36:36 -0400256 if(sectionHeader[i].sh_type == SHT_PROGBITS)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400257 {
Nicolas Capens66478362016-10-13 15:36:36 -0400258 if(sectionHeader[i].sh_flags & SHF_EXECINSTR)
259 {
260 entry = elfImage + sectionHeader[i].sh_offset;
261 }
262 }
263 else if(sectionHeader[i].sh_type == SHT_REL)
264 {
265 assert(sizeof(void*) == 4 && "UNIMPLEMENTED"); // Only expected/implemented for 32-bit code
266
267 for(int index = 0; index < sectionHeader[i].sh_size / sectionHeader[i].sh_entsize; index++)
268 {
269 const Elf32_Rel &relocation = ((const Elf32_Rel*)(elfImage + sectionHeader[i].sh_offset))[index];
270 void *symbol = relocateSymbol(elfHeader, relocation, sectionHeader[i]);
271 }
272 }
273 else if(sectionHeader[i].sh_type == SHT_RELA)
274 {
275 assert(sizeof(void*) == 8 && "UNIMPLEMENTED"); // Only expected/implemented for 64-bit code
276
277 for(int index = 0; index < sectionHeader[i].sh_size / sectionHeader[i].sh_entsize; index++)
278 {
279 const Elf64_Rela &relocation = ((const Elf64_Rela*)(elfImage + sectionHeader[i].sh_offset))[index];
280 void *symbol = relocateSymbol(elfHeader, relocation, sectionHeader[i]);
281 }
Nicolas Capens598f8d82016-09-26 15:09:10 -0400282 }
283 }
284
285 return entry;
286 }
287
288 template<typename T>
289 struct ExecutableAllocator
290 {
291 ExecutableAllocator() {};
292 template<class U> ExecutableAllocator(const ExecutableAllocator<U> &other) {};
293
294 using value_type = T;
295 using size_type = std::size_t;
296
297 T *allocate(size_type n)
298 {
299 return (T*)VirtualAlloc(NULL, sizeof(T) * n, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
300 }
301
302 void deallocate(T *p, size_type n)
303 {
304 VirtualFree(p, 0, MEM_RELEASE);
305 }
306 };
307
308 class ELFMemoryStreamer : public Ice::ELFStreamer, public Routine
309 {
310 ELFMemoryStreamer(const ELFMemoryStreamer &) = delete;
311 ELFMemoryStreamer &operator=(const ELFMemoryStreamer &) = delete;
312
313 public:
Nicolas Capens58274b52016-10-19 23:45:19 -0400314 ELFMemoryStreamer() : Routine(), entry(nullptr)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400315 {
316 position = 0;
317 buffer.reserve(0x1000);
318 }
319
320 virtual ~ELFMemoryStreamer()
321 {
322 if(buffer.size() != 0)
323 {
324 DWORD exeProtection;
325 VirtualProtect(&buffer[0], buffer.size(), oldProtection, &exeProtection);
326 }
327 }
328
329 void write8(uint8_t Value) override
330 {
331 if(position == (uint64_t)buffer.size())
332 {
333 buffer.push_back(Value);
334 position++;
335 }
336 else if(position < (uint64_t)buffer.size())
337 {
338 buffer[position] = Value;
339 position++;
340 }
341 else assert(false && "UNIMPLEMENTED");
342 }
343
344 void writeBytes(llvm::StringRef Bytes) override
345 {
346 std::size_t oldSize = buffer.size();
347 buffer.resize(oldSize + Bytes.size());
348 memcpy(&buffer[oldSize], Bytes.begin(), Bytes.size());
349 position += Bytes.size();
350 }
351
352 uint64_t tell() const override { return position; }
353
354 void seek(uint64_t Off) override { position = Off; }
355
356 const void *getEntry() override
357 {
Nicolas Capens58274b52016-10-19 23:45:19 -0400358 if(!entry)
359 {
360 VirtualProtect(&buffer[0], buffer.size(), PAGE_EXECUTE_READWRITE, &oldProtection);
361 position = std::numeric_limits<std::size_t>::max(); // Can't stream more data after this
Nicolas Capens598f8d82016-09-26 15:09:10 -0400362
Nicolas Capens58274b52016-10-19 23:45:19 -0400363 entry = loadImage(&buffer[0]);
364 }
365
366 return entry;
Nicolas Capens598f8d82016-09-26 15:09:10 -0400367 }
368
369 private:
Nicolas Capens58274b52016-10-19 23:45:19 -0400370 void *entry;
Nicolas Capens598f8d82016-09-26 15:09:10 -0400371 std::vector<uint8_t, ExecutableAllocator<uint8_t>> buffer;
372 std::size_t position;
373 DWORD oldProtection;
374 };
375
376 Nucleus::Nucleus()
377 {
378 ::codegenMutex.lock(); // Reactor is currently not thread safe
379
Nicolas Capens66478362016-10-13 15:36:36 -0400380 Ice::ClFlags &Flags = Ice::ClFlags::Flags;
381 Ice::ClFlags::getParsedClFlags(Flags);
382
383 Flags.setTargetArch(sizeof(void*) == 8 ? Ice::Target_X8664 : Ice::Target_X8632);
384 Flags.setOutFileType(Ice::FT_Elf);
385 Flags.setOptLevel(Ice::Opt_2);
386 Flags.setApplicationBinaryInterface(Ice::ABI_Platform);
Nicolas Capensa8086512016-11-07 17:32:17 -0500387 Flags.setTargetInstructionSet(Ice::X86InstructionSet_SSE4_1);
Nicolas Capens65047112016-11-07 13:01:07 -0500388 Flags.setVerbose(false ? Ice::IceV_All : Ice::IceV_None);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400389
Nicolas Capens65047112016-11-07 13:01:07 -0500390 static llvm::raw_os_ostream cout(std::cout);
391 static llvm::raw_os_ostream cerr(std::cerr);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400392
393 if(false) // Write out to a file
394 {
395 std::error_code errorCode;
396 ::out = new Ice::Fdstream("out.o", errorCode, llvm::sys::fs::F_None);
397 ::elfFile = new Ice::ELFFileStreamer(*out);
Nicolas Capens65047112016-11-07 13:01:07 -0500398 ::context = new Ice::GlobalContext(&cout, &cout, &cerr, elfFile);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400399 }
400 else
401 {
402 ELFMemoryStreamer *elfMemory = new ELFMemoryStreamer();
Nicolas Capens65047112016-11-07 13:01:07 -0500403 ::context = new Ice::GlobalContext(&cout, &cout, &cerr, elfMemory);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400404 ::routine = elfMemory;
405 }
406 }
407
408 Nucleus::~Nucleus()
409 {
410 delete ::allocator;
411 delete ::function;
412 delete ::context;
413
414 delete ::elfFile;
415 delete ::out;
416
417 ::codegenMutex.unlock();
418 }
419
420 Routine *Nucleus::acquireRoutine(const wchar_t *name, bool runOptimizations)
421 {
422 if(basicBlock->getInsts().empty() || basicBlock->getInsts().back().getKind() != Ice::Inst::Ret)
423 {
424 createRetVoid();
425 }
426
427 std::wstring wideName(name);
428 std::string asciiName(wideName.begin(), wideName.end());
429 ::function->setFunctionName(Ice::GlobalString::createWithString(::context, asciiName));
430
431 ::function->translate();
Nicolas Capensde19f392016-10-19 10:29:49 -0400432 assert(!::function->hasError());
433
Nicolas Capens66478362016-10-13 15:36:36 -0400434 auto *globals = ::function->getGlobalInits().release();
435
436 if(globals && !globals->empty())
437 {
438 ::context->getGlobals()->merge(globals);
439 }
Nicolas Capens598f8d82016-09-26 15:09:10 -0400440
441 ::context->emitFileHeader();
442 ::function->emitIAS();
443 auto assembler = ::function->releaseAssembler();
Nicolas Capens66478362016-10-13 15:36:36 -0400444 auto objectWriter = ::context->getObjectWriter();
445 assembler->alignFunction();
446 objectWriter->writeFunctionCode(::function->getFunctionName(), false, assembler.get());
447 ::context->lowerGlobals("last");
Nicolas Capens73dd7a22016-10-20 13:20:34 -0400448 ::context->lowerConstants();
Nicolas Capens66478362016-10-13 15:36:36 -0400449 objectWriter->setUndefinedSyms(::context->getConstantExternSyms());
450 objectWriter->writeNonUserSections();
Nicolas Capens598f8d82016-09-26 15:09:10 -0400451
452 return ::routine;
453 }
454
455 void Nucleus::optimize()
456 {
457 }
458
459 Value *Nucleus::allocateStackVariable(Type *t, int arraySize)
460 {
461 Ice::Type type = T(t);
Nicolas Capensa8f98632016-10-20 11:25:55 -0400462 int typeSize = Ice::typeWidthInBytes(type);
463 int totalSize = typeSize * (arraySize ? arraySize : 1);
Nicolas Capense12780d2016-09-27 14:18:07 -0400464
Nicolas Capensa8f98632016-10-20 11:25:55 -0400465 auto bytes = Ice::ConstantInteger32::create(::context, type, totalSize);
Nicolas Capense12780d2016-09-27 14:18:07 -0400466 auto address = ::function->makeVariable(T(getPointerType(t)));
Nicolas Capensa8f98632016-10-20 11:25:55 -0400467 auto alloca = Ice::InstAlloca::create(::function, address, bytes, typeSize);
Nicolas Capense12780d2016-09-27 14:18:07 -0400468 ::function->getEntryNode()->getInsts().push_front(alloca);
469
470 return V(address);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400471 }
472
473 BasicBlock *Nucleus::createBasicBlock()
474 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400475 return B(::function->makeNode());
Nicolas Capens598f8d82016-09-26 15:09:10 -0400476 }
477
478 BasicBlock *Nucleus::getInsertBlock()
479 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400480 return B(::basicBlock);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400481 }
482
483 void Nucleus::setInsertBlock(BasicBlock *basicBlock)
484 {
Nicolas Capens9ed1a182016-10-24 09:52:23 -0400485 // assert(::basicBlock->getInsts().back().getTerminatorEdges().size() >= 0 && "Previous basic block must have a terminator");
Nicolas Capens611642a2016-09-28 16:45:04 -0400486 ::basicBlock = basicBlock;
Nicolas Capens598f8d82016-09-26 15:09:10 -0400487 }
488
Nicolas Capens598f8d82016-09-26 15:09:10 -0400489 void Nucleus::createFunction(Type *ReturnType, std::vector<Type*> &Params)
490 {
491 uint32_t sequenceNumber = 0;
492 ::function = Ice::Cfg::create(::context, sequenceNumber).release();
493 ::allocator = new Ice::CfgLocalAllocatorScope(::function);
494
495 for(Type *type : Params)
496 {
497 Ice::Variable *arg = ::function->makeVariable(T(type));
498 ::function->addArg(arg);
499 }
500
501 Ice::CfgNode *node = ::function->makeNode();
502 ::function->setEntryNode(node);
503 ::basicBlock = node;
504 }
505
506 Value *Nucleus::getArgument(unsigned int index)
507 {
508 return V(::function->getArgs()[index]);
509 }
510
511 void Nucleus::createRetVoid()
512 {
Nicolas Capensfdcca2d2016-10-20 11:31:36 -0400513 Ice::InstRet *ret = Ice::InstRet::create(::function);
514 ::basicBlock->appendInst(ret);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400515 }
516
517 void Nucleus::createRet(Value *v)
518 {
Nicolas Capensfdcca2d2016-10-20 11:31:36 -0400519 Ice::InstRet *ret = Ice::InstRet::create(::function, v);
520 ::basicBlock->appendInst(ret);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400521 }
522
523 void Nucleus::createBr(BasicBlock *dest)
524 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400525 auto br = Ice::InstBr::create(::function, dest);
526 ::basicBlock->appendInst(br);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400527 }
528
529 void Nucleus::createCondBr(Value *cond, BasicBlock *ifTrue, BasicBlock *ifFalse)
530 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400531 auto br = Ice::InstBr::create(::function, cond, ifTrue, ifFalse);
532 ::basicBlock->appendInst(br);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400533 }
534
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400535 static Value *createArithmetic(Ice::InstArithmetic::OpKind op, Value *lhs, Value *rhs)
536 {
Nicolas Capens327f1df2016-10-21 14:26:34 -0400537 assert(lhs->getType() == rhs->getType() || (llvm::isa<Ice::Constant>(rhs) && (op == Ice::InstArithmetic::Shl || Ice::InstArithmetic::Lshr || Ice::InstArithmetic::Ashr)));
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400538
539 Ice::Variable *result = ::function->makeVariable(lhs->getType());
540 Ice::InstArithmetic *arithmetic = Ice::InstArithmetic::create(::function, op, result, lhs, rhs);
541 ::basicBlock->appendInst(arithmetic);
542
543 return V(result);
544 }
545
Nicolas Capens598f8d82016-09-26 15:09:10 -0400546 Value *Nucleus::createAdd(Value *lhs, Value *rhs)
547 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400548 return createArithmetic(Ice::InstArithmetic::Add, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400549 }
550
551 Value *Nucleus::createSub(Value *lhs, Value *rhs)
552 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400553 return createArithmetic(Ice::InstArithmetic::Sub, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400554 }
555
556 Value *Nucleus::createMul(Value *lhs, Value *rhs)
557 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400558 return createArithmetic(Ice::InstArithmetic::Mul, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400559 }
560
561 Value *Nucleus::createUDiv(Value *lhs, Value *rhs)
562 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400563 return createArithmetic(Ice::InstArithmetic::Udiv, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400564 }
565
566 Value *Nucleus::createSDiv(Value *lhs, Value *rhs)
567 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400568 return createArithmetic(Ice::InstArithmetic::Sdiv, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400569 }
570
571 Value *Nucleus::createFAdd(Value *lhs, Value *rhs)
572 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400573 return createArithmetic(Ice::InstArithmetic::Fadd, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400574 }
575
576 Value *Nucleus::createFSub(Value *lhs, Value *rhs)
577 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400578 return createArithmetic(Ice::InstArithmetic::Fsub, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400579 }
580
581 Value *Nucleus::createFMul(Value *lhs, Value *rhs)
582 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400583 return createArithmetic(Ice::InstArithmetic::Fmul, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400584 }
585
586 Value *Nucleus::createFDiv(Value *lhs, Value *rhs)
587 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400588 return createArithmetic(Ice::InstArithmetic::Fdiv, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400589 }
590
591 Value *Nucleus::createURem(Value *lhs, Value *rhs)
592 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400593 return createArithmetic(Ice::InstArithmetic::Urem, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400594 }
595
596 Value *Nucleus::createSRem(Value *lhs, Value *rhs)
597 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400598 return createArithmetic(Ice::InstArithmetic::Srem, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400599 }
600
601 Value *Nucleus::createFRem(Value *lhs, Value *rhs)
602 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400603 return createArithmetic(Ice::InstArithmetic::Frem, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400604 }
605
606 Value *Nucleus::createShl(Value *lhs, Value *rhs)
607 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400608 return createArithmetic(Ice::InstArithmetic::Shl, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400609 }
610
611 Value *Nucleus::createLShr(Value *lhs, Value *rhs)
612 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400613 return createArithmetic(Ice::InstArithmetic::Lshr, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400614 }
615
616 Value *Nucleus::createAShr(Value *lhs, Value *rhs)
617 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400618 return createArithmetic(Ice::InstArithmetic::Ashr, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400619 }
620
621 Value *Nucleus::createAnd(Value *lhs, Value *rhs)
622 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400623 return createArithmetic(Ice::InstArithmetic::And, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400624 }
625
626 Value *Nucleus::createOr(Value *lhs, Value *rhs)
627 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400628 return createArithmetic(Ice::InstArithmetic::Or, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400629 }
630
631 Value *Nucleus::createXor(Value *lhs, Value *rhs)
632 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400633 return createArithmetic(Ice::InstArithmetic::Xor, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400634 }
635
Nicolas Capens13ac2322016-10-13 14:52:12 -0400636 static Value *createAssign(Ice::Constant *constant)
Nicolas Capensb955d5b2016-09-28 22:36:28 -0400637 {
638 Ice::Variable *value = ::function->makeVariable(constant->getType());
639 auto assign = Ice::InstAssign::create(::function, value, constant);
640 ::basicBlock->appendInst(assign);
641
642 return V(value);
643 }
644
Nicolas Capens598f8d82016-09-26 15:09:10 -0400645 Value *Nucleus::createNeg(Value *v)
646 {
647 assert(false && "UNIMPLEMENTED"); return nullptr;
648 }
649
650 Value *Nucleus::createFNeg(Value *v)
651 {
652 assert(false && "UNIMPLEMENTED"); return nullptr;
653 }
654
655 Value *Nucleus::createNot(Value *v)
656 {
657 assert(false && "UNIMPLEMENTED"); return nullptr;
658 }
659
Nicolas Capense12780d2016-09-27 14:18:07 -0400660 Value *Nucleus::createLoad(Value *ptr, Type *type, bool isVolatile, unsigned int align)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400661 {
Nicolas Capens23d99a42016-09-30 14:57:16 -0400662 int valueType = (int)reinterpret_cast<intptr_t>(type);
663 Ice::Variable *result = ::function->makeVariable(T(type));
664
665 if(valueType & EmulatedBits)
666 {
667 switch(valueType)
668 {
669 case Type_v4i8:
670 case Type_v2i16:
671 {
672 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::LoadSubVector, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
673 auto target = ::context->getConstantUndef(Ice::IceType_i32);
674 auto load = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
675 load->addArg(::context->getConstantInt32(4));
676 load->addArg(ptr);
677 ::basicBlock->appendInst(load);
678 }
679 break;
680 case Type_v2i32:
681 case Type_v8i8:
682 case Type_v4i16:
Nicolas Capens4cfd4572016-10-20 01:00:19 -0400683 case Type_v2f32:
Nicolas Capens23d99a42016-09-30 14:57:16 -0400684 {
685 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::LoadSubVector, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
686 auto target = ::context->getConstantUndef(Ice::IceType_i32);
687 auto load = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
688 load->addArg(::context->getConstantInt32(8));
689 load->addArg(ptr);
690 ::basicBlock->appendInst(load);
691 }
692 break;
693 default: assert(false && "UNIMPLEMENTED");
694 }
695 }
696 else
697 {
698 auto load = Ice::InstLoad::create(::function, result, ptr, align);
699 ::basicBlock->appendInst(load);
700 }
701
702 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400703 }
704
Nicolas Capens6d738712016-09-30 04:15:22 -0400705 Value *Nucleus::createStore(Value *value, Value *ptr, Type *type, bool isVolatile, unsigned int align)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400706 {
Nicolas Capens23d99a42016-09-30 14:57:16 -0400707 int valueType = (int)reinterpret_cast<intptr_t>(type);
708
709 if(valueType & EmulatedBits)
710 {
711 switch(valueType)
712 {
713 case Type_v4i8:
714 case Type_v2i16:
715 {
716 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::StoreSubVector, Ice::Intrinsics::SideEffects_T, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_T};
717 auto target = ::context->getConstantUndef(Ice::IceType_i32);
718 auto store = Ice::InstIntrinsicCall::create(::function, 3, nullptr, target, intrinsic);
719 store->addArg(::context->getConstantInt32(4));
720 store->addArg(value);
721 store->addArg(ptr);
722 ::basicBlock->appendInst(store);
723 }
724 break;
725 case Type_v2i32:
726 case Type_v8i8:
727 case Type_v4i16:
Nicolas Capens4cfd4572016-10-20 01:00:19 -0400728 case Type_v2f32:
Nicolas Capens23d99a42016-09-30 14:57:16 -0400729 {
730 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::StoreSubVector, Ice::Intrinsics::SideEffects_T, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_T};
731 auto target = ::context->getConstantUndef(Ice::IceType_i32);
732 auto store = Ice::InstIntrinsicCall::create(::function, 3, nullptr, target, intrinsic);
733 store->addArg(::context->getConstantInt32(8));
734 store->addArg(value);
735 store->addArg(ptr);
736 ::basicBlock->appendInst(store);
737 }
738 break;
739 default: assert(false && "UNIMPLEMENTED");
740 }
741 }
742 else
743 {
744 assert(T(value->getType()) == type);
745
746 auto store = Ice::InstStore::create(::function, value, ptr, align);
747 ::basicBlock->appendInst(store);
748 }
749
Nicolas Capens598f8d82016-09-26 15:09:10 -0400750 return value;
751 }
752
Nicolas Capens6d738712016-09-30 04:15:22 -0400753 Value *Nucleus::createGEP(Value *ptr, Type *type, Value *index)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400754 {
Nicolas Capens8820f642016-09-30 04:42:43 -0400755 assert(index->getType() == Ice::IceType_i32);
756
757 if(!Ice::isByteSizedType(T(type)))
758 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400759 index = createMul(index, createConstantInt((int)Ice::typeWidthInBytes(T(type))));
Nicolas Capens8820f642016-09-30 04:42:43 -0400760 }
761
762 if(sizeof(void*) == 8)
763 {
764 index = createSExt(index, T(Ice::IceType_i64));
765 }
766
767 return createAdd(ptr, index);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400768 }
769
770 Value *Nucleus::createAtomicAdd(Value *ptr, Value *value)
771 {
772 assert(false && "UNIMPLEMENTED"); return nullptr;
773 }
774
Nicolas Capensa0c2fc52016-09-30 05:04:21 -0400775 static Value *createCast(Ice::InstCast::OpKind op, Value *v, Type *destType)
776 {
Nicolas Capens23d99a42016-09-30 14:57:16 -0400777 if(v->getType() == T(destType))
Nicolas Capensa0c2fc52016-09-30 05:04:21 -0400778 {
779 return v;
780 }
781
782 Ice::Variable *result = ::function->makeVariable(T(destType));
783 Ice::InstCast *cast = Ice::InstCast::create(::function, op, result, v);
784 ::basicBlock->appendInst(cast);
785
786 return V(result);
787 }
788
Nicolas Capens598f8d82016-09-26 15:09:10 -0400789 Value *Nucleus::createTrunc(Value *v, Type *destType)
790 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -0400791 return createCast(Ice::InstCast::Trunc, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400792 }
793
794 Value *Nucleus::createZExt(Value *v, Type *destType)
795 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -0400796 return createCast(Ice::InstCast::Zext, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400797 }
798
799 Value *Nucleus::createSExt(Value *v, Type *destType)
800 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -0400801 return createCast(Ice::InstCast::Sext, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400802 }
803
804 Value *Nucleus::createFPToSI(Value *v, Type *destType)
805 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -0400806 return createCast(Ice::InstCast::Fptosi, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400807 }
808
809 Value *Nucleus::createUIToFP(Value *v, Type *destType)
810 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -0400811 return createCast(Ice::InstCast::Uitofp, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400812 }
813
814 Value *Nucleus::createSIToFP(Value *v, Type *destType)
815 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -0400816 return createCast(Ice::InstCast::Sitofp, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400817 }
818
819 Value *Nucleus::createFPTrunc(Value *v, Type *destType)
820 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -0400821 return createCast(Ice::InstCast::Fptrunc, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400822 }
823
824 Value *Nucleus::createFPExt(Value *v, Type *destType)
825 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -0400826 return createCast(Ice::InstCast::Fpext, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400827 }
828
829 Value *Nucleus::createBitCast(Value *v, Type *destType)
830 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -0400831 return createCast(Ice::InstCast::Bitcast, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400832 }
833
Nicolas Capens43dc6292016-10-20 00:01:38 -0400834 static Value *createIntCompare(Ice::InstIcmp::ICond condition, Value *lhs, Value *rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400835 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400836 assert(lhs->getType() == rhs->getType());
837
Nicolas Capens43dc6292016-10-20 00:01:38 -0400838 auto result = ::function->makeVariable(Ice::isScalarIntegerType(lhs->getType()) ? Ice::IceType_i1 : lhs->getType());
839 auto cmp = Ice::InstIcmp::create(::function, condition, result, lhs, rhs);
Nicolas Capens611642a2016-09-28 16:45:04 -0400840 ::basicBlock->appendInst(cmp);
841
842 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400843 }
844
Nicolas Capens43dc6292016-10-20 00:01:38 -0400845 Value *Nucleus::createICmpEQ(Value *lhs, Value *rhs)
846 {
847 return createIntCompare(Ice::InstIcmp::Eq, lhs, rhs);
848 }
849
850 Value *Nucleus::createICmpNE(Value *lhs, Value *rhs)
851 {
852 return createIntCompare(Ice::InstIcmp::Ne, lhs, rhs);
853 }
854
855 Value *Nucleus::createICmpUGT(Value *lhs, Value *rhs)
856 {
857 return createIntCompare(Ice::InstIcmp::Ugt, lhs, rhs);
858 }
859
860 Value *Nucleus::createICmpUGE(Value *lhs, Value *rhs)
861 {
862 return createIntCompare(Ice::InstIcmp::Uge, lhs, rhs);
863 }
864
865 Value *Nucleus::createICmpULT(Value *lhs, Value *rhs)
866 {
867 return createIntCompare(Ice::InstIcmp::Ult, lhs, rhs);
868 }
869
870 Value *Nucleus::createICmpULE(Value *lhs, Value *rhs)
871 {
872 return createIntCompare(Ice::InstIcmp::Ule, lhs, rhs);
873 }
874
875 Value *Nucleus::createICmpSGT(Value *lhs, Value *rhs)
876 {
877 return createIntCompare(Ice::InstIcmp::Sgt, lhs, rhs);
878 }
879
880 Value *Nucleus::createICmpSGE(Value *lhs, Value *rhs)
881 {
882 return createIntCompare(Ice::InstIcmp::Sge, lhs, rhs);
883 }
884
885 Value *Nucleus::createICmpSLT(Value *lhs, Value *rhs)
886 {
887 return createIntCompare(Ice::InstIcmp::Slt, lhs, rhs);
888 }
889
Nicolas Capens598f8d82016-09-26 15:09:10 -0400890 Value *Nucleus::createICmpSLE(Value *lhs, Value *rhs)
891 {
Nicolas Capens43dc6292016-10-20 00:01:38 -0400892 return createIntCompare(Ice::InstIcmp::Sle, lhs, rhs);
893 }
894
895 static Value *createFloatCompare(Ice::InstFcmp::FCond condition, Value *lhs, Value *rhs)
896 {
897 assert(lhs->getType() == rhs->getType());
898 assert(Ice::isScalarFloatingType(lhs->getType()) || lhs->getType() == Ice::IceType_v4f32);
899
900 auto result = ::function->makeVariable(Ice::isScalarFloatingType(lhs->getType()) ? Ice::IceType_i1 : Ice::IceType_v4i32);
901 auto cmp = Ice::InstFcmp::create(::function, condition, result, lhs, rhs);
902 ::basicBlock->appendInst(cmp);
903
904 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400905 }
906
907 Value *Nucleus::createFCmpOEQ(Value *lhs, Value *rhs)
908 {
Nicolas Capens43dc6292016-10-20 00:01:38 -0400909 return createFloatCompare(Ice::InstFcmp::Oeq, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400910 }
911
912 Value *Nucleus::createFCmpOGT(Value *lhs, Value *rhs)
913 {
Nicolas Capens43dc6292016-10-20 00:01:38 -0400914 return createFloatCompare(Ice::InstFcmp::Ogt, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400915 }
916
917 Value *Nucleus::createFCmpOGE(Value *lhs, Value *rhs)
918 {
Nicolas Capens43dc6292016-10-20 00:01:38 -0400919 return createFloatCompare(Ice::InstFcmp::Oge, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400920 }
921
922 Value *Nucleus::createFCmpOLT(Value *lhs, Value *rhs)
923 {
Nicolas Capens43dc6292016-10-20 00:01:38 -0400924 return createFloatCompare(Ice::InstFcmp::Olt, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400925 }
926
927 Value *Nucleus::createFCmpOLE(Value *lhs, Value *rhs)
928 {
Nicolas Capens43dc6292016-10-20 00:01:38 -0400929 return createFloatCompare(Ice::InstFcmp::Ole, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400930 }
931
932 Value *Nucleus::createFCmpONE(Value *lhs, Value *rhs)
933 {
Nicolas Capens43dc6292016-10-20 00:01:38 -0400934 return createFloatCompare(Ice::InstFcmp::One, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400935 }
936
937 Value *Nucleus::createFCmpORD(Value *lhs, Value *rhs)
938 {
Nicolas Capens43dc6292016-10-20 00:01:38 -0400939 return createFloatCompare(Ice::InstFcmp::Ord, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400940 }
941
942 Value *Nucleus::createFCmpUNO(Value *lhs, Value *rhs)
943 {
Nicolas Capens43dc6292016-10-20 00:01:38 -0400944 return createFloatCompare(Ice::InstFcmp::Uno, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400945 }
946
947 Value *Nucleus::createFCmpUEQ(Value *lhs, Value *rhs)
948 {
Nicolas Capens43dc6292016-10-20 00:01:38 -0400949 return createFloatCompare(Ice::InstFcmp::Ueq, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400950 }
951
952 Value *Nucleus::createFCmpUGT(Value *lhs, Value *rhs)
953 {
Nicolas Capens43dc6292016-10-20 00:01:38 -0400954 return createFloatCompare(Ice::InstFcmp::Ugt, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400955 }
956
957 Value *Nucleus::createFCmpUGE(Value *lhs, Value *rhs)
958 {
Nicolas Capens43dc6292016-10-20 00:01:38 -0400959 return createFloatCompare(Ice::InstFcmp::Uge, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400960 }
961
962 Value *Nucleus::createFCmpULT(Value *lhs, Value *rhs)
963 {
Nicolas Capens43dc6292016-10-20 00:01:38 -0400964 return createFloatCompare(Ice::InstFcmp::Ult, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400965 }
966
967 Value *Nucleus::createFCmpULE(Value *lhs, Value *rhs)
968 {
Nicolas Capens43dc6292016-10-20 00:01:38 -0400969 return createFloatCompare(Ice::InstFcmp::Ule, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400970 }
971
972 Value *Nucleus::createFCmpUNE(Value *lhs, Value *rhs)
973 {
Nicolas Capens43dc6292016-10-20 00:01:38 -0400974 return createFloatCompare(Ice::InstFcmp::Une, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400975 }
976
Nicolas Capense95d5342016-09-30 11:37:28 -0400977 Value *Nucleus::createExtractElement(Value *vector, Type *type, int index)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400978 {
Nicolas Capens9709d4f2016-09-30 11:44:14 -0400979 auto result = ::function->makeVariable(T(type));
980 auto extract = Ice::InstExtractElement::create(::function, result, vector, ::context->getConstantInt32(index));
981 ::basicBlock->appendInst(extract);
982
983 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400984 }
985
986 Value *Nucleus::createInsertElement(Value *vector, Value *element, int index)
987 {
Nicolas Capens9709d4f2016-09-30 11:44:14 -0400988 auto result = ::function->makeVariable(vector->getType());
989 auto insert = Ice::InstInsertElement::create(::function, result, vector, element, ::context->getConstantInt32(index));
990 ::basicBlock->appendInst(insert);
991
992 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400993 }
994
Nicolas Capense89cd582016-09-30 14:23:47 -0400995 Value *Nucleus::createShuffleVector(Value *V1, Value *V2, const int *select)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400996 {
Nicolas Capens619c0ab2016-09-30 14:46:24 -0400997 assert(V1->getType() == V2->getType());
998
999 int size = Ice::typeNumElements(V1->getType());
1000 auto result = ::function->makeVariable(V1->getType());
1001 auto shuffle = Ice::InstShuffleVector::create(::function, result, V1, V2);
1002
1003 for(int i = 0; i < size; i++)
1004 {
1005 shuffle->addIndex(llvm::cast<Ice::ConstantInteger32>(::context->getConstantInt32(select[i])));
1006 }
1007
1008 ::basicBlock->appendInst(shuffle);
1009
1010 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001011 }
1012
1013 Value *Nucleus::createSelect(Value *C, Value *ifTrue, Value *ifFalse)
1014 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04001015 assert(ifTrue->getType() == ifFalse->getType());
1016
1017 auto result = ::function->makeVariable(ifTrue->getType());
1018 auto *select = Ice::InstSelect::create(::function, result, C, ifTrue, ifFalse);
1019 ::basicBlock->appendInst(select);
1020
1021 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001022 }
1023
1024 Value *Nucleus::createSwitch(Value *v, BasicBlock *Dest, unsigned NumCases)
1025 {
1026 assert(false && "UNIMPLEMENTED"); return nullptr;
1027 }
1028
1029 void Nucleus::addSwitchCase(Value *Switch, int Case, BasicBlock *Branch)
1030 {
1031 assert(false && "UNIMPLEMENTED"); return;
1032 }
1033
1034 void Nucleus::createUnreachable()
1035 {
Nicolas Capensfdcca2d2016-10-20 11:31:36 -04001036 Ice::InstUnreachable *unreachable = Ice::InstUnreachable::create(::function);
1037 ::basicBlock->appendInst(unreachable);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001038 }
1039
Nicolas Capense95d5342016-09-30 11:37:28 -04001040 static Value *createSwizzle4(Value *val, unsigned char select)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001041 {
Nicolas Capens619c0ab2016-09-30 14:46:24 -04001042 int swizzle[4] =
1043 {
1044 (select >> 0) & 0x03,
1045 (select >> 2) & 0x03,
1046 (select >> 4) & 0x03,
1047 (select >> 6) & 0x03,
1048 };
Nicolas Capens9709d4f2016-09-30 11:44:14 -04001049
Nicolas Capens619c0ab2016-09-30 14:46:24 -04001050 return Nucleus::createShuffleVector(val, val, swizzle);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001051 }
1052
Nicolas Capense95d5342016-09-30 11:37:28 -04001053 static Value *createMask4(Value *lhs, Value *rhs, unsigned char select)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001054 {
1055 assert(false && "UNIMPLEMENTED"); return nullptr;
1056 }
1057
Nicolas Capens73dd7a22016-10-20 13:20:34 -04001058 Value *Nucleus::createConstantPointer(const void *address, Type *Ty, unsigned int align)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001059 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001060 if(sizeof(void*) == 8)
1061 {
1062 return createAssign(::context->getConstantInt64(reinterpret_cast<intptr_t>(address)));
1063 }
1064 else
1065 {
1066 return createAssign(::context->getConstantInt32(reinterpret_cast<intptr_t>(address)));
1067 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04001068 }
1069
1070 Type *Nucleus::getPointerType(Type *ElementType)
1071 {
Nicolas Capense12780d2016-09-27 14:18:07 -04001072 if(sizeof(void*) == 8)
1073 {
1074 return T(Ice::IceType_i64);
1075 }
1076 else
1077 {
1078 return T(Ice::IceType_i32);
1079 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04001080 }
1081
Nicolas Capens13ac2322016-10-13 14:52:12 -04001082 Value *Nucleus::createNullValue(Type *Ty)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001083 {
Nicolas Capens73dd7a22016-10-20 13:20:34 -04001084 if(Ice::isVectorType(T(Ty)))
1085 {
1086 int64_t c[4] = {0, 0, 0, 0};
1087 return createConstantVector(c, Ty);
1088 }
1089 else
1090 {
1091 return createAssign(::context->getConstantZero(T(Ty)));
1092 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04001093 }
1094
Nicolas Capens13ac2322016-10-13 14:52:12 -04001095 Value *Nucleus::createConstantLong(int64_t i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001096 {
Nicolas Capens73dd7a22016-10-20 13:20:34 -04001097 return createAssign(::context->getConstantInt64(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001098 }
1099
Nicolas Capens13ac2322016-10-13 14:52:12 -04001100 Value *Nucleus::createConstantInt(int i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001101 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04001102 return createAssign(::context->getConstantInt32(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001103 }
1104
Nicolas Capens13ac2322016-10-13 14:52:12 -04001105 Value *Nucleus::createConstantInt(unsigned int i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001106 {
Nicolas Capens73dd7a22016-10-20 13:20:34 -04001107 return createAssign(::context->getConstantInt32(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001108 }
1109
Nicolas Capens13ac2322016-10-13 14:52:12 -04001110 Value *Nucleus::createConstantBool(bool b)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001111 {
Nicolas Capens73dd7a22016-10-20 13:20:34 -04001112 return createAssign(::context->getConstantInt1(b));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001113 }
1114
Nicolas Capens13ac2322016-10-13 14:52:12 -04001115 Value *Nucleus::createConstantByte(signed char i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001116 {
Nicolas Capens73dd7a22016-10-20 13:20:34 -04001117 return createAssign(::context->getConstantInt8(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001118 }
1119
Nicolas Capens13ac2322016-10-13 14:52:12 -04001120 Value *Nucleus::createConstantByte(unsigned char i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001121 {
Nicolas Capens73dd7a22016-10-20 13:20:34 -04001122 return createAssign(::context->getConstantInt8(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001123 }
1124
Nicolas Capens13ac2322016-10-13 14:52:12 -04001125 Value *Nucleus::createConstantShort(short i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001126 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001127 return createAssign(::context->getConstantInt16(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001128 }
1129
Nicolas Capens13ac2322016-10-13 14:52:12 -04001130 Value *Nucleus::createConstantShort(unsigned short i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001131 {
Nicolas Capens73dd7a22016-10-20 13:20:34 -04001132 return createAssign(::context->getConstantInt16(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001133 }
1134
Nicolas Capens13ac2322016-10-13 14:52:12 -04001135 Value *Nucleus::createConstantFloat(float x)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001136 {
Nicolas Capens73dd7a22016-10-20 13:20:34 -04001137 return createAssign(::context->getConstantFloat(x));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001138 }
1139
Nicolas Capens13ac2322016-10-13 14:52:12 -04001140 Value *Nucleus::createNullPointer(Type *Ty)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001141 {
Nicolas Capens73dd7a22016-10-20 13:20:34 -04001142 if(true)
1143 {
1144 return createNullValue(T(sizeof(void*) == 8 ? Ice::IceType_i64 : Ice::IceType_i32));
1145 }
1146 else
1147 {
1148 return createConstantPointer(nullptr, Ty);
1149 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04001150 }
1151
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001152 Value *Nucleus::createConstantVector(const int64_t *constants, Type *type)
Nicolas Capens13ac2322016-10-13 14:52:12 -04001153 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001154 const int vectorSize = 16;
1155 assert(Ice::typeWidthInBytes(T(type)) == vectorSize);
1156 const int alignment = vectorSize;
1157 auto globalPool = ::function->getGlobalPool();
1158
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001159 const int64_t *i = constants;
1160 const double *f = reinterpret_cast<const double*>(constants);
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001161 Ice::VariableDeclaration::DataInitializer *dataInitializer = nullptr;
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001162
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001163 switch((int)reinterpret_cast<intptr_t>(type))
1164 {
1165 case Ice::IceType_v4i32:
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001166 {
1167 const int initializer[4] = {(int)i[0], (int)i[1], (int)i[2], (int)i[3]};
1168 static_assert(sizeof(initializer) == vectorSize, "!");
1169 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1170 }
1171 break;
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001172 case Ice::IceType_v4f32:
1173 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001174 const float initializer[4] = {(float)f[0], (float)f[1], (float)f[2], (float)f[3]};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001175 static_assert(sizeof(initializer) == vectorSize, "!");
1176 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1177 }
1178 break;
1179 case Ice::IceType_v8i16:
1180 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001181 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]};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001182 static_assert(sizeof(initializer) == vectorSize, "!");
1183 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1184 }
1185 break;
1186 case Ice::IceType_v16i8:
1187 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001188 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]};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001189 static_assert(sizeof(initializer) == vectorSize, "!");
1190 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1191 }
1192 break;
1193 case Type_v2i32:
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001194 {
1195 const int initializer[4] = {(int)i[0], (int)i[1], (int)i[0], (int)i[1]};
1196 static_assert(sizeof(initializer) == vectorSize, "!");
1197 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1198 }
1199 break;
Nicolas Capens4cfd4572016-10-20 01:00:19 -04001200 case Type_v2f32:
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001201 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001202 const float initializer[4] = {(float)f[0], (float)f[1], (float)f[0], (float)f[1]};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001203 static_assert(sizeof(initializer) == vectorSize, "!");
1204 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1205 }
1206 break;
1207 case Type_v4i16:
1208 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001209 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]};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001210 static_assert(sizeof(initializer) == vectorSize, "!");
1211 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1212 }
1213 break;
1214 case Type_v8i8:
1215 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001216 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]};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001217 static_assert(sizeof(initializer) == vectorSize, "!");
1218 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1219 }
1220 break;
1221 case Type_v4i8:
1222 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001223 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]};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001224 static_assert(sizeof(initializer) == vectorSize, "!");
1225 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1226 }
1227 break;
1228 default:
1229 assert(false && "Unknown constant vector type" && type);
1230 }
1231
1232 auto name = Ice::GlobalString::createWithoutString(::context);
1233 auto *variableDeclaration = Ice::VariableDeclaration::create(globalPool);
1234 variableDeclaration->setName(name);
1235 variableDeclaration->setAlignment(alignment);
1236 variableDeclaration->setIsConstant(true);
1237 variableDeclaration->addInitializer(dataInitializer);
1238
1239 ::function->addGlobal(variableDeclaration);
1240
1241 constexpr int32_t offset = 0;
1242 Ice::Operand *ptr = ::context->getConstantSym(offset, name);
1243
1244 Ice::Variable *result = ::function->makeVariable(T(type));
1245 auto load = Ice::InstLoad::create(::function, result, ptr, alignment);
1246 ::basicBlock->appendInst(load);
1247
1248 return V(result);
Nicolas Capens13ac2322016-10-13 14:52:12 -04001249 }
1250
1251 Value *Nucleus::createConstantVector(const double *constants, Type *type)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001252 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001253 return createConstantVector((const int64_t*)constants, type);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001254 }
1255
1256 Type *Void::getType()
1257 {
1258 return T(Ice::IceType_void);
1259 }
1260
Nicolas Capens598f8d82016-09-26 15:09:10 -04001261 Bool::Bool(Argument<Bool> argument)
1262 {
1263 storeValue(argument.value);
1264 }
1265
1266 Bool::Bool()
1267 {
1268 }
1269
1270 Bool::Bool(bool x)
1271 {
1272 storeValue(Nucleus::createConstantBool(x));
1273 }
1274
1275 Bool::Bool(RValue<Bool> rhs)
1276 {
1277 storeValue(rhs.value);
1278 }
1279
1280 Bool::Bool(const Bool &rhs)
1281 {
1282 Value *value = rhs.loadValue();
1283 storeValue(value);
1284 }
1285
1286 Bool::Bool(const Reference<Bool> &rhs)
1287 {
1288 Value *value = rhs.loadValue();
1289 storeValue(value);
1290 }
1291
1292 RValue<Bool> Bool::operator=(RValue<Bool> rhs) const
1293 {
1294 storeValue(rhs.value);
1295
1296 return rhs;
1297 }
1298
1299 RValue<Bool> Bool::operator=(const Bool &rhs) const
1300 {
1301 Value *value = rhs.loadValue();
1302 storeValue(value);
1303
1304 return RValue<Bool>(value);
1305 }
1306
1307 RValue<Bool> Bool::operator=(const Reference<Bool> &rhs) const
1308 {
1309 Value *value = rhs.loadValue();
1310 storeValue(value);
1311
1312 return RValue<Bool>(value);
1313 }
1314
1315 RValue<Bool> operator!(RValue<Bool> val)
1316 {
1317 return RValue<Bool>(Nucleus::createNot(val.value));
1318 }
1319
1320 RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs)
1321 {
1322 return RValue<Bool>(Nucleus::createAnd(lhs.value, rhs.value));
1323 }
1324
1325 RValue<Bool> operator||(RValue<Bool> lhs, RValue<Bool> rhs)
1326 {
1327 return RValue<Bool>(Nucleus::createOr(lhs.value, rhs.value));
1328 }
1329
1330 Type *Bool::getType()
1331 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04001332 return T(Ice::IceType_i1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001333 }
1334
1335 Byte::Byte(Argument<Byte> argument)
1336 {
1337 storeValue(argument.value);
1338 }
1339
1340 Byte::Byte(RValue<Int> cast)
1341 {
1342 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
1343
1344 storeValue(integer);
1345 }
1346
1347 Byte::Byte(RValue<UInt> cast)
1348 {
1349 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
1350
1351 storeValue(integer);
1352 }
1353
1354 Byte::Byte(RValue<UShort> cast)
1355 {
1356 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
1357
1358 storeValue(integer);
1359 }
1360
1361 Byte::Byte()
1362 {
1363 }
1364
1365 Byte::Byte(int x)
1366 {
1367 storeValue(Nucleus::createConstantByte((unsigned char)x));
1368 }
1369
1370 Byte::Byte(unsigned char x)
1371 {
1372 storeValue(Nucleus::createConstantByte(x));
1373 }
1374
1375 Byte::Byte(RValue<Byte> rhs)
1376 {
1377 storeValue(rhs.value);
1378 }
1379
1380 Byte::Byte(const Byte &rhs)
1381 {
1382 Value *value = rhs.loadValue();
1383 storeValue(value);
1384 }
1385
1386 Byte::Byte(const Reference<Byte> &rhs)
1387 {
1388 Value *value = rhs.loadValue();
1389 storeValue(value);
1390 }
1391
1392 RValue<Byte> Byte::operator=(RValue<Byte> rhs) const
1393 {
1394 storeValue(rhs.value);
1395
1396 return rhs;
1397 }
1398
1399 RValue<Byte> Byte::operator=(const Byte &rhs) const
1400 {
1401 Value *value = rhs.loadValue();
1402 storeValue(value);
1403
1404 return RValue<Byte>(value);
1405 }
1406
1407 RValue<Byte> Byte::operator=(const Reference<Byte> &rhs) const
1408 {
1409 Value *value = rhs.loadValue();
1410 storeValue(value);
1411
1412 return RValue<Byte>(value);
1413 }
1414
1415 RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs)
1416 {
1417 return RValue<Byte>(Nucleus::createAdd(lhs.value, rhs.value));
1418 }
1419
1420 RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs)
1421 {
1422 return RValue<Byte>(Nucleus::createSub(lhs.value, rhs.value));
1423 }
1424
1425 RValue<Byte> operator*(RValue<Byte> lhs, RValue<Byte> rhs)
1426 {
1427 return RValue<Byte>(Nucleus::createMul(lhs.value, rhs.value));
1428 }
1429
1430 RValue<Byte> operator/(RValue<Byte> lhs, RValue<Byte> rhs)
1431 {
1432 return RValue<Byte>(Nucleus::createUDiv(lhs.value, rhs.value));
1433 }
1434
1435 RValue<Byte> operator%(RValue<Byte> lhs, RValue<Byte> rhs)
1436 {
1437 return RValue<Byte>(Nucleus::createURem(lhs.value, rhs.value));
1438 }
1439
1440 RValue<Byte> operator&(RValue<Byte> lhs, RValue<Byte> rhs)
1441 {
1442 return RValue<Byte>(Nucleus::createAnd(lhs.value, rhs.value));
1443 }
1444
1445 RValue<Byte> operator|(RValue<Byte> lhs, RValue<Byte> rhs)
1446 {
1447 return RValue<Byte>(Nucleus::createOr(lhs.value, rhs.value));
1448 }
1449
1450 RValue<Byte> operator^(RValue<Byte> lhs, RValue<Byte> rhs)
1451 {
1452 return RValue<Byte>(Nucleus::createXor(lhs.value, rhs.value));
1453 }
1454
1455 RValue<Byte> operator<<(RValue<Byte> lhs, RValue<Byte> rhs)
1456 {
1457 return RValue<Byte>(Nucleus::createShl(lhs.value, rhs.value));
1458 }
1459
1460 RValue<Byte> operator>>(RValue<Byte> lhs, RValue<Byte> rhs)
1461 {
1462 return RValue<Byte>(Nucleus::createLShr(lhs.value, rhs.value));
1463 }
1464
1465 RValue<Byte> operator+=(const Byte &lhs, RValue<Byte> rhs)
1466 {
1467 return lhs = lhs + rhs;
1468 }
1469
1470 RValue<Byte> operator-=(const Byte &lhs, RValue<Byte> rhs)
1471 {
1472 return lhs = lhs - rhs;
1473 }
1474
1475 RValue<Byte> operator*=(const Byte &lhs, RValue<Byte> rhs)
1476 {
1477 return lhs = lhs * rhs;
1478 }
1479
1480 RValue<Byte> operator/=(const Byte &lhs, RValue<Byte> rhs)
1481 {
1482 return lhs = lhs / rhs;
1483 }
1484
1485 RValue<Byte> operator%=(const Byte &lhs, RValue<Byte> rhs)
1486 {
1487 return lhs = lhs % rhs;
1488 }
1489
1490 RValue<Byte> operator&=(const Byte &lhs, RValue<Byte> rhs)
1491 {
1492 return lhs = lhs & rhs;
1493 }
1494
1495 RValue<Byte> operator|=(const Byte &lhs, RValue<Byte> rhs)
1496 {
1497 return lhs = lhs | rhs;
1498 }
1499
1500 RValue<Byte> operator^=(const Byte &lhs, RValue<Byte> rhs)
1501 {
1502 return lhs = lhs ^ rhs;
1503 }
1504
1505 RValue<Byte> operator<<=(const Byte &lhs, RValue<Byte> rhs)
1506 {
1507 return lhs = lhs << rhs;
1508 }
1509
1510 RValue<Byte> operator>>=(const Byte &lhs, RValue<Byte> rhs)
1511 {
1512 return lhs = lhs >> rhs;
1513 }
1514
1515 RValue<Byte> operator+(RValue<Byte> val)
1516 {
1517 return val;
1518 }
1519
1520 RValue<Byte> operator-(RValue<Byte> val)
1521 {
1522 return RValue<Byte>(Nucleus::createNeg(val.value));
1523 }
1524
1525 RValue<Byte> operator~(RValue<Byte> val)
1526 {
1527 return RValue<Byte>(Nucleus::createNot(val.value));
1528 }
1529
1530 RValue<Byte> operator++(const Byte &val, int) // Post-increment
1531 {
1532 RValue<Byte> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05001533 val += Byte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001534 return res;
1535 }
1536
1537 const Byte &operator++(const Byte &val) // Pre-increment
1538 {
Nicolas Capensd1229402016-11-07 16:05:22 -05001539 val += Byte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001540 return val;
1541 }
1542
1543 RValue<Byte> operator--(const Byte &val, int) // Post-decrement
1544 {
1545 RValue<Byte> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05001546 val -= Byte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001547 return res;
1548 }
1549
1550 const Byte &operator--(const Byte &val) // Pre-decrement
1551 {
Nicolas Capensd1229402016-11-07 16:05:22 -05001552 val -= Byte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001553 return val;
1554 }
1555
1556 RValue<Bool> operator<(RValue<Byte> lhs, RValue<Byte> rhs)
1557 {
1558 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1559 }
1560
1561 RValue<Bool> operator<=(RValue<Byte> lhs, RValue<Byte> rhs)
1562 {
1563 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1564 }
1565
1566 RValue<Bool> operator>(RValue<Byte> lhs, RValue<Byte> rhs)
1567 {
1568 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1569 }
1570
1571 RValue<Bool> operator>=(RValue<Byte> lhs, RValue<Byte> rhs)
1572 {
1573 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1574 }
1575
1576 RValue<Bool> operator!=(RValue<Byte> lhs, RValue<Byte> rhs)
1577 {
1578 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1579 }
1580
1581 RValue<Bool> operator==(RValue<Byte> lhs, RValue<Byte> rhs)
1582 {
1583 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1584 }
1585
1586 Type *Byte::getType()
1587 {
Nicolas Capens6d738712016-09-30 04:15:22 -04001588 return T(Ice::IceType_i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001589 }
1590
1591 SByte::SByte(Argument<SByte> argument)
1592 {
1593 storeValue(argument.value);
1594 }
1595
1596 SByte::SByte(RValue<Int> cast)
1597 {
1598 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1599
1600 storeValue(integer);
1601 }
1602
1603 SByte::SByte(RValue<Short> cast)
1604 {
1605 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1606
1607 storeValue(integer);
1608 }
1609
1610 SByte::SByte()
1611 {
1612 }
1613
1614 SByte::SByte(signed char x)
1615 {
1616 storeValue(Nucleus::createConstantByte(x));
1617 }
1618
1619 SByte::SByte(RValue<SByte> rhs)
1620 {
1621 storeValue(rhs.value);
1622 }
1623
1624 SByte::SByte(const SByte &rhs)
1625 {
1626 Value *value = rhs.loadValue();
1627 storeValue(value);
1628 }
1629
1630 SByte::SByte(const Reference<SByte> &rhs)
1631 {
1632 Value *value = rhs.loadValue();
1633 storeValue(value);
1634 }
1635
1636 RValue<SByte> SByte::operator=(RValue<SByte> rhs) const
1637 {
1638 storeValue(rhs.value);
1639
1640 return rhs;
1641 }
1642
1643 RValue<SByte> SByte::operator=(const SByte &rhs) const
1644 {
1645 Value *value = rhs.loadValue();
1646 storeValue(value);
1647
1648 return RValue<SByte>(value);
1649 }
1650
1651 RValue<SByte> SByte::operator=(const Reference<SByte> &rhs) const
1652 {
1653 Value *value = rhs.loadValue();
1654 storeValue(value);
1655
1656 return RValue<SByte>(value);
1657 }
1658
1659 RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs)
1660 {
1661 return RValue<SByte>(Nucleus::createAdd(lhs.value, rhs.value));
1662 }
1663
1664 RValue<SByte> operator-(RValue<SByte> lhs, RValue<SByte> rhs)
1665 {
1666 return RValue<SByte>(Nucleus::createSub(lhs.value, rhs.value));
1667 }
1668
1669 RValue<SByte> operator*(RValue<SByte> lhs, RValue<SByte> rhs)
1670 {
1671 return RValue<SByte>(Nucleus::createMul(lhs.value, rhs.value));
1672 }
1673
1674 RValue<SByte> operator/(RValue<SByte> lhs, RValue<SByte> rhs)
1675 {
1676 return RValue<SByte>(Nucleus::createSDiv(lhs.value, rhs.value));
1677 }
1678
1679 RValue<SByte> operator%(RValue<SByte> lhs, RValue<SByte> rhs)
1680 {
1681 return RValue<SByte>(Nucleus::createSRem(lhs.value, rhs.value));
1682 }
1683
1684 RValue<SByte> operator&(RValue<SByte> lhs, RValue<SByte> rhs)
1685 {
1686 return RValue<SByte>(Nucleus::createAnd(lhs.value, rhs.value));
1687 }
1688
1689 RValue<SByte> operator|(RValue<SByte> lhs, RValue<SByte> rhs)
1690 {
1691 return RValue<SByte>(Nucleus::createOr(lhs.value, rhs.value));
1692 }
1693
1694 RValue<SByte> operator^(RValue<SByte> lhs, RValue<SByte> rhs)
1695 {
1696 return RValue<SByte>(Nucleus::createXor(lhs.value, rhs.value));
1697 }
1698
1699 RValue<SByte> operator<<(RValue<SByte> lhs, RValue<SByte> rhs)
1700 {
1701 return RValue<SByte>(Nucleus::createShl(lhs.value, rhs.value));
1702 }
1703
1704 RValue<SByte> operator>>(RValue<SByte> lhs, RValue<SByte> rhs)
1705 {
1706 return RValue<SByte>(Nucleus::createAShr(lhs.value, rhs.value));
1707 }
1708
1709 RValue<SByte> operator+=(const SByte &lhs, RValue<SByte> rhs)
1710 {
1711 return lhs = lhs + rhs;
1712 }
1713
1714 RValue<SByte> operator-=(const SByte &lhs, RValue<SByte> rhs)
1715 {
1716 return lhs = lhs - rhs;
1717 }
1718
1719 RValue<SByte> operator*=(const SByte &lhs, RValue<SByte> rhs)
1720 {
1721 return lhs = lhs * rhs;
1722 }
1723
1724 RValue<SByte> operator/=(const SByte &lhs, RValue<SByte> rhs)
1725 {
1726 return lhs = lhs / rhs;
1727 }
1728
1729 RValue<SByte> operator%=(const SByte &lhs, RValue<SByte> rhs)
1730 {
1731 return lhs = lhs % rhs;
1732 }
1733
1734 RValue<SByte> operator&=(const SByte &lhs, RValue<SByte> rhs)
1735 {
1736 return lhs = lhs & rhs;
1737 }
1738
1739 RValue<SByte> operator|=(const SByte &lhs, RValue<SByte> rhs)
1740 {
1741 return lhs = lhs | rhs;
1742 }
1743
1744 RValue<SByte> operator^=(const SByte &lhs, RValue<SByte> rhs)
1745 {
1746 return lhs = lhs ^ rhs;
1747 }
1748
1749 RValue<SByte> operator<<=(const SByte &lhs, RValue<SByte> rhs)
1750 {
1751 return lhs = lhs << rhs;
1752 }
1753
1754 RValue<SByte> operator>>=(const SByte &lhs, RValue<SByte> rhs)
1755 {
1756 return lhs = lhs >> rhs;
1757 }
1758
1759 RValue<SByte> operator+(RValue<SByte> val)
1760 {
1761 return val;
1762 }
1763
1764 RValue<SByte> operator-(RValue<SByte> val)
1765 {
1766 return RValue<SByte>(Nucleus::createNeg(val.value));
1767 }
1768
1769 RValue<SByte> operator~(RValue<SByte> val)
1770 {
1771 return RValue<SByte>(Nucleus::createNot(val.value));
1772 }
1773
1774 RValue<SByte> operator++(const SByte &val, int) // Post-increment
1775 {
1776 RValue<SByte> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05001777 val += SByte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001778 return res;
1779 }
1780
1781 const SByte &operator++(const SByte &val) // Pre-increment
1782 {
Nicolas Capensd1229402016-11-07 16:05:22 -05001783 val += SByte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001784 return val;
1785 }
1786
1787 RValue<SByte> operator--(const SByte &val, int) // Post-decrement
1788 {
1789 RValue<SByte> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05001790 val -= SByte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001791 return res;
1792 }
1793
1794 const SByte &operator--(const SByte &val) // Pre-decrement
1795 {
Nicolas Capensd1229402016-11-07 16:05:22 -05001796 val -= SByte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001797 return val;
1798 }
1799
1800 RValue<Bool> operator<(RValue<SByte> lhs, RValue<SByte> rhs)
1801 {
1802 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
1803 }
1804
1805 RValue<Bool> operator<=(RValue<SByte> lhs, RValue<SByte> rhs)
1806 {
1807 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
1808 }
1809
1810 RValue<Bool> operator>(RValue<SByte> lhs, RValue<SByte> rhs)
1811 {
1812 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
1813 }
1814
1815 RValue<Bool> operator>=(RValue<SByte> lhs, RValue<SByte> rhs)
1816 {
1817 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
1818 }
1819
1820 RValue<Bool> operator!=(RValue<SByte> lhs, RValue<SByte> rhs)
1821 {
1822 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1823 }
1824
1825 RValue<Bool> operator==(RValue<SByte> lhs, RValue<SByte> rhs)
1826 {
1827 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1828 }
1829
1830 Type *SByte::getType()
1831 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04001832 return T(Ice::IceType_i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001833 }
1834
1835 Short::Short(Argument<Short> argument)
1836 {
1837 storeValue(argument.value);
1838 }
1839
1840 Short::Short(RValue<Int> cast)
1841 {
1842 Value *integer = Nucleus::createTrunc(cast.value, Short::getType());
1843
1844 storeValue(integer);
1845 }
1846
1847 Short::Short()
1848 {
1849 }
1850
1851 Short::Short(short x)
1852 {
1853 storeValue(Nucleus::createConstantShort(x));
1854 }
1855
1856 Short::Short(RValue<Short> rhs)
1857 {
1858 storeValue(rhs.value);
1859 }
1860
1861 Short::Short(const Short &rhs)
1862 {
1863 Value *value = rhs.loadValue();
1864 storeValue(value);
1865 }
1866
1867 Short::Short(const Reference<Short> &rhs)
1868 {
1869 Value *value = rhs.loadValue();
1870 storeValue(value);
1871 }
1872
1873 RValue<Short> Short::operator=(RValue<Short> rhs) const
1874 {
1875 storeValue(rhs.value);
1876
1877 return rhs;
1878 }
1879
1880 RValue<Short> Short::operator=(const Short &rhs) const
1881 {
1882 Value *value = rhs.loadValue();
1883 storeValue(value);
1884
1885 return RValue<Short>(value);
1886 }
1887
1888 RValue<Short> Short::operator=(const Reference<Short> &rhs) const
1889 {
1890 Value *value = rhs.loadValue();
1891 storeValue(value);
1892
1893 return RValue<Short>(value);
1894 }
1895
1896 RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs)
1897 {
1898 return RValue<Short>(Nucleus::createAdd(lhs.value, rhs.value));
1899 }
1900
1901 RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs)
1902 {
1903 return RValue<Short>(Nucleus::createSub(lhs.value, rhs.value));
1904 }
1905
1906 RValue<Short> operator*(RValue<Short> lhs, RValue<Short> rhs)
1907 {
1908 return RValue<Short>(Nucleus::createMul(lhs.value, rhs.value));
1909 }
1910
1911 RValue<Short> operator/(RValue<Short> lhs, RValue<Short> rhs)
1912 {
1913 return RValue<Short>(Nucleus::createSDiv(lhs.value, rhs.value));
1914 }
1915
1916 RValue<Short> operator%(RValue<Short> lhs, RValue<Short> rhs)
1917 {
1918 return RValue<Short>(Nucleus::createSRem(lhs.value, rhs.value));
1919 }
1920
1921 RValue<Short> operator&(RValue<Short> lhs, RValue<Short> rhs)
1922 {
1923 return RValue<Short>(Nucleus::createAnd(lhs.value, rhs.value));
1924 }
1925
1926 RValue<Short> operator|(RValue<Short> lhs, RValue<Short> rhs)
1927 {
1928 return RValue<Short>(Nucleus::createOr(lhs.value, rhs.value));
1929 }
1930
1931 RValue<Short> operator^(RValue<Short> lhs, RValue<Short> rhs)
1932 {
1933 return RValue<Short>(Nucleus::createXor(lhs.value, rhs.value));
1934 }
1935
1936 RValue<Short> operator<<(RValue<Short> lhs, RValue<Short> rhs)
1937 {
1938 return RValue<Short>(Nucleus::createShl(lhs.value, rhs.value));
1939 }
1940
1941 RValue<Short> operator>>(RValue<Short> lhs, RValue<Short> rhs)
1942 {
1943 return RValue<Short>(Nucleus::createAShr(lhs.value, rhs.value));
1944 }
1945
1946 RValue<Short> operator+=(const Short &lhs, RValue<Short> rhs)
1947 {
1948 return lhs = lhs + rhs;
1949 }
1950
1951 RValue<Short> operator-=(const Short &lhs, RValue<Short> rhs)
1952 {
1953 return lhs = lhs - rhs;
1954 }
1955
1956 RValue<Short> operator*=(const Short &lhs, RValue<Short> rhs)
1957 {
1958 return lhs = lhs * rhs;
1959 }
1960
1961 RValue<Short> operator/=(const Short &lhs, RValue<Short> rhs)
1962 {
1963 return lhs = lhs / rhs;
1964 }
1965
1966 RValue<Short> operator%=(const Short &lhs, RValue<Short> rhs)
1967 {
1968 return lhs = lhs % rhs;
1969 }
1970
1971 RValue<Short> operator&=(const Short &lhs, RValue<Short> rhs)
1972 {
1973 return lhs = lhs & rhs;
1974 }
1975
1976 RValue<Short> operator|=(const Short &lhs, RValue<Short> rhs)
1977 {
1978 return lhs = lhs | rhs;
1979 }
1980
1981 RValue<Short> operator^=(const Short &lhs, RValue<Short> rhs)
1982 {
1983 return lhs = lhs ^ rhs;
1984 }
1985
1986 RValue<Short> operator<<=(const Short &lhs, RValue<Short> rhs)
1987 {
1988 return lhs = lhs << rhs;
1989 }
1990
1991 RValue<Short> operator>>=(const Short &lhs, RValue<Short> rhs)
1992 {
1993 return lhs = lhs >> rhs;
1994 }
1995
1996 RValue<Short> operator+(RValue<Short> val)
1997 {
1998 return val;
1999 }
2000
2001 RValue<Short> operator-(RValue<Short> val)
2002 {
2003 return RValue<Short>(Nucleus::createNeg(val.value));
2004 }
2005
2006 RValue<Short> operator~(RValue<Short> val)
2007 {
2008 return RValue<Short>(Nucleus::createNot(val.value));
2009 }
2010
2011 RValue<Short> operator++(const Short &val, int) // Post-increment
2012 {
2013 RValue<Short> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002014 val += Short(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002015 return res;
2016 }
2017
2018 const Short &operator++(const Short &val) // Pre-increment
2019 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002020 val += Short(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002021 return val;
2022 }
2023
2024 RValue<Short> operator--(const Short &val, int) // Post-decrement
2025 {
2026 RValue<Short> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002027 val -= Short(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002028 return res;
2029 }
2030
2031 const Short &operator--(const Short &val) // Pre-decrement
2032 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002033 val -= Short(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002034 return val;
2035 }
2036
2037 RValue<Bool> operator<(RValue<Short> lhs, RValue<Short> rhs)
2038 {
2039 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
2040 }
2041
2042 RValue<Bool> operator<=(RValue<Short> lhs, RValue<Short> rhs)
2043 {
2044 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
2045 }
2046
2047 RValue<Bool> operator>(RValue<Short> lhs, RValue<Short> rhs)
2048 {
2049 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
2050 }
2051
2052 RValue<Bool> operator>=(RValue<Short> lhs, RValue<Short> rhs)
2053 {
2054 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
2055 }
2056
2057 RValue<Bool> operator!=(RValue<Short> lhs, RValue<Short> rhs)
2058 {
2059 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
2060 }
2061
2062 RValue<Bool> operator==(RValue<Short> lhs, RValue<Short> rhs)
2063 {
2064 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
2065 }
2066
2067 Type *Short::getType()
2068 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04002069 return T(Ice::IceType_i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002070 }
2071
2072 UShort::UShort(Argument<UShort> argument)
2073 {
2074 storeValue(argument.value);
2075 }
2076
2077 UShort::UShort(RValue<UInt> cast)
2078 {
2079 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
2080
2081 storeValue(integer);
2082 }
2083
2084 UShort::UShort(RValue<Int> cast)
2085 {
2086 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
2087
2088 storeValue(integer);
2089 }
2090
2091 UShort::UShort()
2092 {
2093 }
2094
2095 UShort::UShort(unsigned short x)
2096 {
2097 storeValue(Nucleus::createConstantShort(x));
2098 }
2099
2100 UShort::UShort(RValue<UShort> rhs)
2101 {
2102 storeValue(rhs.value);
2103 }
2104
2105 UShort::UShort(const UShort &rhs)
2106 {
2107 Value *value = rhs.loadValue();
2108 storeValue(value);
2109 }
2110
2111 UShort::UShort(const Reference<UShort> &rhs)
2112 {
2113 Value *value = rhs.loadValue();
2114 storeValue(value);
2115 }
2116
2117 RValue<UShort> UShort::operator=(RValue<UShort> rhs) const
2118 {
2119 storeValue(rhs.value);
2120
2121 return rhs;
2122 }
2123
2124 RValue<UShort> UShort::operator=(const UShort &rhs) const
2125 {
2126 Value *value = rhs.loadValue();
2127 storeValue(value);
2128
2129 return RValue<UShort>(value);
2130 }
2131
2132 RValue<UShort> UShort::operator=(const Reference<UShort> &rhs) const
2133 {
2134 Value *value = rhs.loadValue();
2135 storeValue(value);
2136
2137 return RValue<UShort>(value);
2138 }
2139
2140 RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs)
2141 {
2142 return RValue<UShort>(Nucleus::createAdd(lhs.value, rhs.value));
2143 }
2144
2145 RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs)
2146 {
2147 return RValue<UShort>(Nucleus::createSub(lhs.value, rhs.value));
2148 }
2149
2150 RValue<UShort> operator*(RValue<UShort> lhs, RValue<UShort> rhs)
2151 {
2152 return RValue<UShort>(Nucleus::createMul(lhs.value, rhs.value));
2153 }
2154
2155 RValue<UShort> operator/(RValue<UShort> lhs, RValue<UShort> rhs)
2156 {
2157 return RValue<UShort>(Nucleus::createUDiv(lhs.value, rhs.value));
2158 }
2159
2160 RValue<UShort> operator%(RValue<UShort> lhs, RValue<UShort> rhs)
2161 {
2162 return RValue<UShort>(Nucleus::createURem(lhs.value, rhs.value));
2163 }
2164
2165 RValue<UShort> operator&(RValue<UShort> lhs, RValue<UShort> rhs)
2166 {
2167 return RValue<UShort>(Nucleus::createAnd(lhs.value, rhs.value));
2168 }
2169
2170 RValue<UShort> operator|(RValue<UShort> lhs, RValue<UShort> rhs)
2171 {
2172 return RValue<UShort>(Nucleus::createOr(lhs.value, rhs.value));
2173 }
2174
2175 RValue<UShort> operator^(RValue<UShort> lhs, RValue<UShort> rhs)
2176 {
2177 return RValue<UShort>(Nucleus::createXor(lhs.value, rhs.value));
2178 }
2179
2180 RValue<UShort> operator<<(RValue<UShort> lhs, RValue<UShort> rhs)
2181 {
2182 return RValue<UShort>(Nucleus::createShl(lhs.value, rhs.value));
2183 }
2184
2185 RValue<UShort> operator>>(RValue<UShort> lhs, RValue<UShort> rhs)
2186 {
2187 return RValue<UShort>(Nucleus::createLShr(lhs.value, rhs.value));
2188 }
2189
2190 RValue<UShort> operator+=(const UShort &lhs, RValue<UShort> rhs)
2191 {
2192 return lhs = lhs + rhs;
2193 }
2194
2195 RValue<UShort> operator-=(const UShort &lhs, RValue<UShort> rhs)
2196 {
2197 return lhs = lhs - rhs;
2198 }
2199
2200 RValue<UShort> operator*=(const UShort &lhs, RValue<UShort> rhs)
2201 {
2202 return lhs = lhs * rhs;
2203 }
2204
2205 RValue<UShort> operator/=(const UShort &lhs, RValue<UShort> rhs)
2206 {
2207 return lhs = lhs / rhs;
2208 }
2209
2210 RValue<UShort> operator%=(const UShort &lhs, RValue<UShort> rhs)
2211 {
2212 return lhs = lhs % rhs;
2213 }
2214
2215 RValue<UShort> operator&=(const UShort &lhs, RValue<UShort> rhs)
2216 {
2217 return lhs = lhs & rhs;
2218 }
2219
2220 RValue<UShort> operator|=(const UShort &lhs, RValue<UShort> rhs)
2221 {
2222 return lhs = lhs | rhs;
2223 }
2224
2225 RValue<UShort> operator^=(const UShort &lhs, RValue<UShort> rhs)
2226 {
2227 return lhs = lhs ^ rhs;
2228 }
2229
2230 RValue<UShort> operator<<=(const UShort &lhs, RValue<UShort> rhs)
2231 {
2232 return lhs = lhs << rhs;
2233 }
2234
2235 RValue<UShort> operator>>=(const UShort &lhs, RValue<UShort> rhs)
2236 {
2237 return lhs = lhs >> rhs;
2238 }
2239
2240 RValue<UShort> operator+(RValue<UShort> val)
2241 {
2242 return val;
2243 }
2244
2245 RValue<UShort> operator-(RValue<UShort> val)
2246 {
2247 return RValue<UShort>(Nucleus::createNeg(val.value));
2248 }
2249
2250 RValue<UShort> operator~(RValue<UShort> val)
2251 {
2252 return RValue<UShort>(Nucleus::createNot(val.value));
2253 }
2254
2255 RValue<UShort> operator++(const UShort &val, int) // Post-increment
2256 {
2257 RValue<UShort> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002258 val += UShort(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002259 return res;
2260 }
2261
2262 const UShort &operator++(const UShort &val) // Pre-increment
2263 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002264 val += UShort(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002265 return val;
2266 }
2267
2268 RValue<UShort> operator--(const UShort &val, int) // Post-decrement
2269 {
2270 RValue<UShort> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002271 val -= UShort(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002272 return res;
2273 }
2274
2275 const UShort &operator--(const UShort &val) // Pre-decrement
2276 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002277 val -= UShort(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002278 return val;
2279 }
2280
2281 RValue<Bool> operator<(RValue<UShort> lhs, RValue<UShort> rhs)
2282 {
2283 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
2284 }
2285
2286 RValue<Bool> operator<=(RValue<UShort> lhs, RValue<UShort> rhs)
2287 {
2288 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
2289 }
2290
2291 RValue<Bool> operator>(RValue<UShort> lhs, RValue<UShort> rhs)
2292 {
2293 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
2294 }
2295
2296 RValue<Bool> operator>=(RValue<UShort> lhs, RValue<UShort> rhs)
2297 {
2298 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
2299 }
2300
2301 RValue<Bool> operator!=(RValue<UShort> lhs, RValue<UShort> rhs)
2302 {
2303 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
2304 }
2305
2306 RValue<Bool> operator==(RValue<UShort> lhs, RValue<UShort> rhs)
2307 {
2308 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
2309 }
2310
2311 Type *UShort::getType()
2312 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04002313 return T(Ice::IceType_i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002314 }
2315
Nicolas Capens16b5f152016-10-13 13:39:01 -04002316 Byte4::Byte4(RValue<Byte8> cast)
2317 {
2318 // xyzw.parent = this;
2319
2320 storeValue(Nucleus::createBitCast(cast.value, getType()));
2321 }
2322
2323 Byte4::Byte4(const Reference<Byte4> &rhs)
2324 {
2325 // xyzw.parent = this;
2326
Nicolas Capensd1229402016-11-07 16:05:22 -05002327 Value *value = rhs.loadValue();
2328 storeValue(value);
Nicolas Capens16b5f152016-10-13 13:39:01 -04002329 }
2330
Nicolas Capens598f8d82016-09-26 15:09:10 -04002331 Type *Byte4::getType()
2332 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04002333 return T(Type_v4i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002334 }
2335
2336 Type *SByte4::getType()
2337 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04002338 return T(Type_v4i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002339 }
2340
2341 Byte8::Byte8()
2342 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002343 }
2344
2345 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)
2346 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04002347 int64_t constantVector[8] = {x0, x1, x2, x3, x4, x5, x6, x7};
2348 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002349 }
2350
2351 Byte8::Byte8(RValue<Byte8> rhs)
2352 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002353 storeValue(rhs.value);
2354 }
2355
2356 Byte8::Byte8(const Byte8 &rhs)
2357 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002358 Value *value = rhs.loadValue();
2359 storeValue(value);
2360 }
2361
2362 Byte8::Byte8(const Reference<Byte8> &rhs)
2363 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002364 Value *value = rhs.loadValue();
2365 storeValue(value);
2366 }
2367
2368 RValue<Byte8> Byte8::operator=(RValue<Byte8> rhs) const
2369 {
2370 storeValue(rhs.value);
2371
2372 return rhs;
2373 }
2374
2375 RValue<Byte8> Byte8::operator=(const Byte8 &rhs) const
2376 {
2377 Value *value = rhs.loadValue();
2378 storeValue(value);
2379
2380 return RValue<Byte8>(value);
2381 }
2382
2383 RValue<Byte8> Byte8::operator=(const Reference<Byte8> &rhs) const
2384 {
2385 Value *value = rhs.loadValue();
2386 storeValue(value);
2387
2388 return RValue<Byte8>(value);
2389 }
2390
2391 RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs)
2392 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002393 return RValue<Byte8>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002394 }
2395
2396 RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs)
2397 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002398 return RValue<Byte8>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002399 }
2400
2401// RValue<Byte8> operator*(RValue<Byte8> lhs, RValue<Byte8> rhs)
2402// {
2403// return RValue<Byte8>(Nucleus::createMul(lhs.value, rhs.value));
2404// }
2405
2406// RValue<Byte8> operator/(RValue<Byte8> lhs, RValue<Byte8> rhs)
2407// {
2408// return RValue<Byte8>(Nucleus::createUDiv(lhs.value, rhs.value));
2409// }
2410
2411// RValue<Byte8> operator%(RValue<Byte8> lhs, RValue<Byte8> rhs)
2412// {
2413// return RValue<Byte8>(Nucleus::createURem(lhs.value, rhs.value));
2414// }
2415
2416 RValue<Byte8> operator&(RValue<Byte8> lhs, RValue<Byte8> rhs)
2417 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002418 return RValue<Byte8>(Nucleus::createAnd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002419 }
2420
2421 RValue<Byte8> operator|(RValue<Byte8> lhs, RValue<Byte8> rhs)
2422 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002423 return RValue<Byte8>(Nucleus::createOr(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002424 }
2425
2426 RValue<Byte8> operator^(RValue<Byte8> lhs, RValue<Byte8> rhs)
2427 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002428 return RValue<Byte8>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002429 }
2430
2431// RValue<Byte8> operator<<(RValue<Byte8> lhs, unsigned char rhs)
2432// {
Nicolas Capens327f1df2016-10-21 14:26:34 -04002433// return RValue<Byte8>(Nucleus::createShl(lhs.value, C(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002434// }
2435
2436// RValue<Byte8> operator>>(RValue<Byte8> lhs, unsigned char rhs)
2437// {
Nicolas Capens327f1df2016-10-21 14:26:34 -04002438// return RValue<Byte8>(Nucleus::createLShr(lhs.value, C(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002439// }
2440
2441 RValue<Byte8> operator+=(const Byte8 &lhs, RValue<Byte8> rhs)
2442 {
2443 return lhs = lhs + rhs;
2444 }
2445
2446 RValue<Byte8> operator-=(const Byte8 &lhs, RValue<Byte8> rhs)
2447 {
2448 return lhs = lhs - rhs;
2449 }
2450
2451// RValue<Byte8> operator*=(const Byte8 &lhs, RValue<Byte8> rhs)
2452// {
2453// return lhs = lhs * rhs;
2454// }
2455
2456// RValue<Byte8> operator/=(const Byte8 &lhs, RValue<Byte8> rhs)
2457// {
2458// return lhs = lhs / rhs;
2459// }
2460
2461// RValue<Byte8> operator%=(const Byte8 &lhs, RValue<Byte8> rhs)
2462// {
2463// return lhs = lhs % rhs;
2464// }
2465
2466 RValue<Byte8> operator&=(const Byte8 &lhs, RValue<Byte8> rhs)
2467 {
2468 return lhs = lhs & rhs;
2469 }
2470
2471 RValue<Byte8> operator|=(const Byte8 &lhs, RValue<Byte8> rhs)
2472 {
2473 return lhs = lhs | rhs;
2474 }
2475
2476 RValue<Byte8> operator^=(const Byte8 &lhs, RValue<Byte8> rhs)
2477 {
2478 return lhs = lhs ^ rhs;
2479 }
2480
2481// RValue<Byte8> operator<<=(const Byte8 &lhs, RValue<Byte8> rhs)
2482// {
2483// return lhs = lhs << rhs;
2484// }
2485
2486// RValue<Byte8> operator>>=(const Byte8 &lhs, RValue<Byte8> rhs)
2487// {
2488// return lhs = lhs >> rhs;
2489// }
2490
2491// RValue<Byte8> operator+(RValue<Byte8> val)
2492// {
2493// return val;
2494// }
2495
2496// RValue<Byte8> operator-(RValue<Byte8> val)
2497// {
2498// return RValue<Byte8>(Nucleus::createNeg(val.value));
2499// }
2500
2501 RValue<Byte8> operator~(RValue<Byte8> val)
2502 {
2503 return RValue<Byte8>(Nucleus::createNot(val.value));
2504 }
2505
2506 RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y)
2507 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05002508 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
2509 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2510 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2511 auto paddusb = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
2512 paddusb->addArg(x.value);
2513 paddusb->addArg(y.value);
2514 ::basicBlock->appendInst(paddusb);
2515
2516 return RValue<Byte8>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002517 }
2518
2519 RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y)
2520 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05002521 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
2522 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2523 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2524 auto psubusw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
2525 psubusw->addArg(x.value);
2526 psubusw->addArg(y.value);
2527 ::basicBlock->appendInst(psubusw);
2528
2529 return RValue<Byte8>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002530 }
2531
2532 RValue<Short4> Unpack(RValue<Byte4> x)
2533 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04002534 int shuffle[16] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7}; // Real type is v16i8
2535 return RValue<Short4>(Nucleus::createShuffleVector(x.value, x.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002536 }
2537
2538 RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y)
2539 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04002540 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
2541 return RValue<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002542 }
2543
2544 RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y)
2545 {
Nicolas Capens20e22c42016-10-25 17:32:37 -04002546 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
2547 auto lowHigh = RValue<Byte16>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
2548 return As<Short4>(Swizzle(As<Int4>(lowHigh), 0xEE));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002549 }
2550
2551 RValue<Int> SignMask(RValue<Byte8> x)
2552 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05002553 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
2554 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2555 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2556 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
2557 movmsk->addArg(x.value);
2558 ::basicBlock->appendInst(movmsk);
2559
2560 return RValue<Int>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002561 }
2562
2563// RValue<Byte8> CmpGT(RValue<Byte8> x, RValue<Byte8> y)
2564// {
Nicolas Capensc37252c2016-09-28 16:11:54 -04002565// assert(false && "UNIMPLEMENTED"); return RValue<Byte8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002566// }
2567
2568 RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y)
2569 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04002570 assert(false && "UNIMPLEMENTED"); return RValue<Byte8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002571 }
2572
2573 Type *Byte8::getType()
2574 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04002575 return T(Type_v8i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002576 }
2577
2578 SByte8::SByte8()
2579 {
2580 // xyzw.parent = this;
2581 }
2582
2583 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)
2584 {
2585 // xyzw.parent = this;
2586
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04002587 int64_t constantVector[8] = { x0, x1, x2, x3, x4, x5, x6, x7 };
2588 Value *vector = V(Nucleus::createConstantVector(constantVector, getType()));
2589
2590 storeValue(Nucleus::createBitCast(vector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002591 }
2592
Nicolas Capens598f8d82016-09-26 15:09:10 -04002593 SByte8::SByte8(RValue<SByte8> rhs)
2594 {
2595 // xyzw.parent = this;
2596
2597 storeValue(rhs.value);
2598 }
2599
2600 SByte8::SByte8(const SByte8 &rhs)
2601 {
2602 // xyzw.parent = this;
2603
2604 Value *value = rhs.loadValue();
2605 storeValue(value);
2606 }
2607
2608 SByte8::SByte8(const Reference<SByte8> &rhs)
2609 {
2610 // xyzw.parent = this;
2611
2612 Value *value = rhs.loadValue();
2613 storeValue(value);
2614 }
2615
2616 RValue<SByte8> SByte8::operator=(RValue<SByte8> rhs) const
2617 {
2618 storeValue(rhs.value);
2619
2620 return rhs;
2621 }
2622
2623 RValue<SByte8> SByte8::operator=(const SByte8 &rhs) const
2624 {
2625 Value *value = rhs.loadValue();
2626 storeValue(value);
2627
2628 return RValue<SByte8>(value);
2629 }
2630
2631 RValue<SByte8> SByte8::operator=(const Reference<SByte8> &rhs) const
2632 {
2633 Value *value = rhs.loadValue();
2634 storeValue(value);
2635
2636 return RValue<SByte8>(value);
2637 }
2638
2639 RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs)
2640 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002641 return RValue<SByte8>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002642 }
2643
2644 RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs)
2645 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002646 return RValue<SByte8>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002647 }
2648
2649// RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs)
2650// {
2651// return RValue<SByte8>(Nucleus::createMul(lhs.value, rhs.value));
2652// }
2653
2654// RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs)
2655// {
2656// return RValue<SByte8>(Nucleus::createSDiv(lhs.value, rhs.value));
2657// }
2658
2659// RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs)
2660// {
2661// return RValue<SByte8>(Nucleus::createSRem(lhs.value, rhs.value));
2662// }
2663
2664 RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs)
2665 {
2666 return RValue<SByte8>(Nucleus::createAnd(lhs.value, rhs.value));
2667 }
2668
2669 RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs)
2670 {
2671 return RValue<SByte8>(Nucleus::createOr(lhs.value, rhs.value));
2672 }
2673
2674 RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs)
2675 {
2676 return RValue<SByte8>(Nucleus::createXor(lhs.value, rhs.value));
2677 }
2678
2679// RValue<SByte8> operator<<(RValue<SByte8> lhs, unsigned char rhs)
2680// {
Nicolas Capens327f1df2016-10-21 14:26:34 -04002681// return RValue<SByte8>(Nucleus::createShl(lhs.value, C(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002682// }
2683
2684// RValue<SByte8> operator>>(RValue<SByte8> lhs, unsigned char rhs)
2685// {
Nicolas Capens327f1df2016-10-21 14:26:34 -04002686// return RValue<SByte8>(Nucleus::createAShr(lhs.value, C(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002687// }
2688
2689 RValue<SByte8> operator+=(const SByte8 &lhs, RValue<SByte8> rhs)
2690 {
2691 return lhs = lhs + rhs;
2692 }
2693
2694 RValue<SByte8> operator-=(const SByte8 &lhs, RValue<SByte8> rhs)
2695 {
2696 return lhs = lhs - rhs;
2697 }
2698
2699// RValue<SByte8> operator*=(const SByte8 &lhs, RValue<SByte8> rhs)
2700// {
2701// return lhs = lhs * rhs;
2702// }
2703
2704// RValue<SByte8> operator/=(const SByte8 &lhs, RValue<SByte8> rhs)
2705// {
2706// return lhs = lhs / rhs;
2707// }
2708
2709// RValue<SByte8> operator%=(const SByte8 &lhs, RValue<SByte8> rhs)
2710// {
2711// return lhs = lhs % rhs;
2712// }
2713
2714 RValue<SByte8> operator&=(const SByte8 &lhs, RValue<SByte8> rhs)
2715 {
2716 return lhs = lhs & rhs;
2717 }
2718
2719 RValue<SByte8> operator|=(const SByte8 &lhs, RValue<SByte8> rhs)
2720 {
2721 return lhs = lhs | rhs;
2722 }
2723
2724 RValue<SByte8> operator^=(const SByte8 &lhs, RValue<SByte8> rhs)
2725 {
2726 return lhs = lhs ^ rhs;
2727 }
2728
2729// RValue<SByte8> operator<<=(const SByte8 &lhs, RValue<SByte8> rhs)
2730// {
2731// return lhs = lhs << rhs;
2732// }
2733
2734// RValue<SByte8> operator>>=(const SByte8 &lhs, RValue<SByte8> rhs)
2735// {
2736// return lhs = lhs >> rhs;
2737// }
2738
2739// RValue<SByte8> operator+(RValue<SByte8> val)
2740// {
2741// return val;
2742// }
2743
2744// RValue<SByte8> operator-(RValue<SByte8> val)
2745// {
2746// return RValue<SByte8>(Nucleus::createNeg(val.value));
2747// }
2748
2749 RValue<SByte8> operator~(RValue<SByte8> val)
2750 {
2751 return RValue<SByte8>(Nucleus::createNot(val.value));
2752 }
2753
2754 RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y)
2755 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05002756 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
2757 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2758 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2759 auto paddsb = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
2760 paddsb->addArg(x.value);
2761 paddsb->addArg(y.value);
2762 ::basicBlock->appendInst(paddsb);
2763
2764 return RValue<SByte8>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002765 }
2766
2767 RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y)
2768 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05002769 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
2770 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2771 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2772 auto psubsb = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
2773 psubsb->addArg(x.value);
2774 psubsb->addArg(y.value);
2775 ::basicBlock->appendInst(psubsb);
2776
2777 return RValue<SByte8>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002778 }
2779
2780 RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y)
2781 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04002782 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
2783 return RValue<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002784 }
2785
2786 RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y)
2787 {
Nicolas Capens20e22c42016-10-25 17:32:37 -04002788 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
2789 auto lowHigh = RValue<Byte16>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
2790 return As<Short4>(Swizzle(As<Int4>(lowHigh), 0xEE));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002791 }
2792
2793 RValue<Int> SignMask(RValue<SByte8> x)
2794 {
Nicolas Capensf2cb9df2016-10-21 17:26:13 -04002795 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
2796 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2797 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2798 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
2799 movmsk->addArg(x.value);
2800 ::basicBlock->appendInst(movmsk);
2801
2802 return RValue<Int>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002803 }
2804
2805 RValue<Byte8> CmpGT(RValue<SByte8> x, RValue<SByte8> y)
2806 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04002807 assert(false && "UNIMPLEMENTED"); return RValue<Byte8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002808 }
2809
2810 RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y)
2811 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04002812 assert(false && "UNIMPLEMENTED"); return RValue<Byte8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002813 }
2814
2815 Type *SByte8::getType()
2816 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04002817 return T(Type_v8i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002818 }
2819
2820 Byte16::Byte16(RValue<Byte16> rhs)
2821 {
2822 // xyzw.parent = this;
2823
2824 storeValue(rhs.value);
2825 }
2826
2827 Byte16::Byte16(const Byte16 &rhs)
2828 {
2829 // xyzw.parent = this;
2830
2831 Value *value = rhs.loadValue();
2832 storeValue(value);
2833 }
2834
2835 Byte16::Byte16(const Reference<Byte16> &rhs)
2836 {
2837 // xyzw.parent = this;
2838
2839 Value *value = rhs.loadValue();
2840 storeValue(value);
2841 }
2842
2843 RValue<Byte16> Byte16::operator=(RValue<Byte16> rhs) const
2844 {
2845 storeValue(rhs.value);
2846
2847 return rhs;
2848 }
2849
2850 RValue<Byte16> Byte16::operator=(const Byte16 &rhs) const
2851 {
2852 Value *value = rhs.loadValue();
2853 storeValue(value);
2854
2855 return RValue<Byte16>(value);
2856 }
2857
2858 RValue<Byte16> Byte16::operator=(const Reference<Byte16> &rhs) const
2859 {
2860 Value *value = rhs.loadValue();
2861 storeValue(value);
2862
2863 return RValue<Byte16>(value);
2864 }
2865
2866 Type *Byte16::getType()
2867 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04002868 return T(Ice::IceType_v16i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002869 }
2870
2871 Type *SByte16::getType()
2872 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04002873 return T(Ice::IceType_v16i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002874 }
2875
Nicolas Capens16b5f152016-10-13 13:39:01 -04002876 Short2::Short2(RValue<Short4> cast)
2877 {
2878 assert(false && "UNIMPLEMENTED");
2879 }
2880
2881 Type *Short2::getType()
2882 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04002883 return T(Type_v2i16);
Nicolas Capens16b5f152016-10-13 13:39:01 -04002884 }
2885
2886 UShort2::UShort2(RValue<UShort4> cast)
2887 {
2888 assert(false && "UNIMPLEMENTED");
2889 }
2890
2891 Type *UShort2::getType()
2892 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04002893 return T(Type_v2i16);
Nicolas Capens16b5f152016-10-13 13:39:01 -04002894 }
2895
Nicolas Capens598f8d82016-09-26 15:09:10 -04002896 Short4::Short4(RValue<Int> cast)
2897 {
2898 Value *extend = Nucleus::createZExt(cast.value, Long::getType());
2899 Value *swizzle = Swizzle(RValue<Short4>(extend), 0x00).value;
2900
2901 storeValue(swizzle);
2902 }
2903
2904 Short4::Short4(RValue<Int4> cast)
2905 {
2906 assert(false && "UNIMPLEMENTED");
2907 }
2908
2909// Short4::Short4(RValue<Float> cast)
2910// {
2911// }
2912
2913 Short4::Short4(RValue<Float4> cast)
2914 {
2915 assert(false && "UNIMPLEMENTED");
2916 }
2917
2918 Short4::Short4()
2919 {
2920 // xyzw.parent = this;
2921 }
2922
2923 Short4::Short4(short xyzw)
2924 {
2925 // xyzw.parent = this;
2926
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04002927 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
2928 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002929 }
2930
2931 Short4::Short4(short x, short y, short z, short w)
2932 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04002933 // xyzw.parent = this;
Nicolas Capens598f8d82016-09-26 15:09:10 -04002934
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04002935 int64_t constantVector[4] = {x, y, z, w};
2936 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002937 }
2938
2939 Short4::Short4(RValue<Short4> rhs)
2940 {
2941 // xyzw.parent = this;
2942
2943 storeValue(rhs.value);
2944 }
2945
2946 Short4::Short4(const Short4 &rhs)
2947 {
2948 // xyzw.parent = this;
2949
2950 Value *value = rhs.loadValue();
2951 storeValue(value);
2952 }
2953
2954 Short4::Short4(const Reference<Short4> &rhs)
2955 {
2956 // xyzw.parent = this;
2957
2958 Value *value = rhs.loadValue();
2959 storeValue(value);
2960 }
2961
2962 Short4::Short4(RValue<UShort4> rhs)
2963 {
2964 // xyzw.parent = this;
2965
2966 storeValue(rhs.value);
2967 }
2968
2969 Short4::Short4(const UShort4 &rhs)
2970 {
2971 // xyzw.parent = this;
2972
2973 storeValue(rhs.loadValue());
2974 }
2975
2976 Short4::Short4(const Reference<UShort4> &rhs)
2977 {
2978 // xyzw.parent = this;
2979
2980 storeValue(rhs.loadValue());
2981 }
2982
2983 RValue<Short4> Short4::operator=(RValue<Short4> rhs) const
2984 {
2985 storeValue(rhs.value);
2986
2987 return rhs;
2988 }
2989
2990 RValue<Short4> Short4::operator=(const Short4 &rhs) const
2991 {
2992 Value *value = rhs.loadValue();
2993 storeValue(value);
2994
2995 return RValue<Short4>(value);
2996 }
2997
2998 RValue<Short4> Short4::operator=(const Reference<Short4> &rhs) const
2999 {
3000 Value *value = rhs.loadValue();
3001 storeValue(value);
3002
3003 return RValue<Short4>(value);
3004 }
3005
3006 RValue<Short4> Short4::operator=(RValue<UShort4> rhs) const
3007 {
3008 storeValue(rhs.value);
3009
3010 return RValue<Short4>(rhs);
3011 }
3012
3013 RValue<Short4> Short4::operator=(const UShort4 &rhs) const
3014 {
3015 Value *value = rhs.loadValue();
3016 storeValue(value);
3017
3018 return RValue<Short4>(value);
3019 }
3020
3021 RValue<Short4> Short4::operator=(const Reference<UShort4> &rhs) const
3022 {
3023 Value *value = rhs.loadValue();
3024 storeValue(value);
3025
3026 return RValue<Short4>(value);
3027 }
3028
3029 RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs)
3030 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003031 return RValue<Short4>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003032 }
3033
3034 RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs)
3035 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003036 return RValue<Short4>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003037 }
3038
3039 RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs)
3040 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003041 return RValue<Short4>(Nucleus::createMul(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003042 }
3043
3044// RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs)
3045// {
3046// return RValue<Short4>(Nucleus::createSDiv(lhs.value, rhs.value));
3047// }
3048
3049// RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs)
3050// {
3051// return RValue<Short4>(Nucleus::createSRem(lhs.value, rhs.value));
3052// }
3053
3054 RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs)
3055 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003056 return RValue<Short4>(Nucleus::createAnd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003057 }
3058
3059 RValue<Short4> operator|(RValue<Short4> lhs, RValue<Short4> rhs)
3060 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003061 return RValue<Short4>(Nucleus::createOr(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003062 }
3063
3064 RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs)
3065 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003066 return RValue<Short4>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003067 }
3068
3069 RValue<Short4> operator<<(RValue<Short4> lhs, unsigned char rhs)
3070 {
Nicolas Capens327f1df2016-10-21 14:26:34 -04003071 return RValue<Short4>(Nucleus::createShl(lhs.value, C(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003072 }
3073
3074 RValue<Short4> operator>>(RValue<Short4> lhs, unsigned char rhs)
3075 {
Nicolas Capens327f1df2016-10-21 14:26:34 -04003076 return RValue<Short4>(Nucleus::createAShr(lhs.value, C(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003077 }
3078
3079 RValue<Short4> operator<<(RValue<Short4> lhs, RValue<Long1> rhs)
3080 {
3081 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
3082
Nicolas Capensc37252c2016-09-28 16:11:54 -04003083 assert(false && "UNIMPLEMENTED"); return RValue<Short4>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003084 }
3085
3086 RValue<Short4> operator>>(RValue<Short4> lhs, RValue<Long1> rhs)
3087 {
3088 // return RValue<Short4>(Nucleus::createAShr(lhs.value, rhs.value));
3089
Nicolas Capensc37252c2016-09-28 16:11:54 -04003090 assert(false && "UNIMPLEMENTED"); return RValue<Short4>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003091 }
3092
3093 RValue<Short4> operator+=(const Short4 &lhs, RValue<Short4> rhs)
3094 {
3095 return lhs = lhs + rhs;
3096 }
3097
3098 RValue<Short4> operator-=(const Short4 &lhs, RValue<Short4> rhs)
3099 {
3100 return lhs = lhs - rhs;
3101 }
3102
3103 RValue<Short4> operator*=(const Short4 &lhs, RValue<Short4> rhs)
3104 {
3105 return lhs = lhs * rhs;
3106 }
3107
3108// RValue<Short4> operator/=(const Short4 &lhs, RValue<Short4> rhs)
3109// {
3110// return lhs = lhs / rhs;
3111// }
3112
3113// RValue<Short4> operator%=(const Short4 &lhs, RValue<Short4> rhs)
3114// {
3115// return lhs = lhs % rhs;
3116// }
3117
3118 RValue<Short4> operator&=(const Short4 &lhs, RValue<Short4> rhs)
3119 {
3120 return lhs = lhs & rhs;
3121 }
3122
3123 RValue<Short4> operator|=(const Short4 &lhs, RValue<Short4> rhs)
3124 {
3125 return lhs = lhs | rhs;
3126 }
3127
3128 RValue<Short4> operator^=(const Short4 &lhs, RValue<Short4> rhs)
3129 {
3130 return lhs = lhs ^ rhs;
3131 }
3132
3133 RValue<Short4> operator<<=(const Short4 &lhs, unsigned char rhs)
3134 {
3135 return lhs = lhs << rhs;
3136 }
3137
3138 RValue<Short4> operator>>=(const Short4 &lhs, unsigned char rhs)
3139 {
3140 return lhs = lhs >> rhs;
3141 }
3142
3143 RValue<Short4> operator<<=(const Short4 &lhs, RValue<Long1> rhs)
3144 {
3145 return lhs = lhs << rhs;
3146 }
3147
3148 RValue<Short4> operator>>=(const Short4 &lhs, RValue<Long1> rhs)
3149 {
3150 return lhs = lhs >> rhs;
3151 }
3152
3153// RValue<Short4> operator+(RValue<Short4> val)
3154// {
3155// return val;
3156// }
3157
3158 RValue<Short4> operator-(RValue<Short4> val)
3159 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003160 assert(false && "UNIMPLEMENTED"); return RValue<Short4>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003161 }
3162
3163 RValue<Short4> operator~(RValue<Short4> val)
3164 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003165 assert(false && "UNIMPLEMENTED"); return RValue<Short4>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003166 }
3167
3168 RValue<Short4> RoundShort4(RValue<Float4> cast)
3169 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003170 assert(false && "UNIMPLEMENTED"); return RValue<Short4>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003171 }
3172
3173 RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y)
3174 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04003175 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3176 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sle, condition, x.value, y.value);
3177 ::basicBlock->appendInst(cmp);
3178
3179 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3180 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3181 ::basicBlock->appendInst(select);
3182
3183 return RValue<Short4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003184 }
3185
3186 RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y)
3187 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04003188 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3189 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sgt, condition, x.value, y.value);
3190 ::basicBlock->appendInst(cmp);
3191
3192 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3193 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3194 ::basicBlock->appendInst(select);
3195
3196 return RValue<Short4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003197 }
3198
3199 RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y)
3200 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05003201 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3202 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3203 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3204 auto paddsw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3205 paddsw->addArg(x.value);
3206 paddsw->addArg(y.value);
3207 ::basicBlock->appendInst(paddsw);
3208
3209 return RValue<Short4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003210 }
3211
3212 RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y)
3213 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05003214 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3215 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3216 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3217 auto psubsw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3218 psubsw->addArg(x.value);
3219 psubsw->addArg(y.value);
3220 ::basicBlock->appendInst(psubsw);
3221
3222 return RValue<Short4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003223 }
3224
3225 RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y)
3226 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05003227 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3228 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::MultiplyHighSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3229 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3230 auto pmulhw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3231 pmulhw->addArg(x.value);
3232 pmulhw->addArg(y.value);
3233 ::basicBlock->appendInst(pmulhw);
3234
3235 return RValue<UShort4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003236 }
3237
3238 RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y)
3239 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05003240 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3241 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::MultiplyAddPairs, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3242 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3243 auto pmaddwd = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3244 pmaddwd->addArg(x.value);
3245 pmaddwd->addArg(y.value);
3246 ::basicBlock->appendInst(pmaddwd);
3247
3248 return RValue<Int2>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003249 }
3250
3251 RValue<SByte8> Pack(RValue<Short4> x, RValue<Short4> y)
3252 {
Nicolas Capensec54a172016-10-25 17:32:37 -04003253 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
3254 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3255 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3256 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3257 pack->addArg(x.value);
3258 pack->addArg(y.value);
3259 ::basicBlock->appendInst(pack);
3260
Nicolas Capens70dfff42016-10-27 10:20:28 -04003261 return As<SByte8>(Swizzle(As<Int4>(V(result)), 0x88));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003262 }
3263
3264 RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y)
3265 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04003266 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11}; // Real type is v8i16
3267 return RValue<Int2>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003268 }
3269
3270 RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y)
3271 {
Nicolas Capens20e22c42016-10-25 17:32:37 -04003272 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11}; // Real type is v8i16
3273 auto lowHigh = RValue<Short8>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
3274 return As<Int2>(Swizzle(As<Int4>(lowHigh), 0xEE));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003275 }
3276
3277 RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select)
3278 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04003279 // Real type is v8i16
3280 int shuffle[8] =
3281 {
3282 (select >> 0) & 0x03,
3283 (select >> 2) & 0x03,
3284 (select >> 4) & 0x03,
3285 (select >> 6) & 0x03,
3286 (select >> 0) & 0x03,
3287 (select >> 2) & 0x03,
3288 (select >> 4) & 0x03,
3289 (select >> 6) & 0x03,
3290 };
3291
3292 return RValue<Short4>(Nucleus::createShuffleVector(x.value, x.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003293 }
3294
3295 RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i)
3296 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003297 assert(false && "UNIMPLEMENTED"); return RValue<Short4>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003298 }
3299
3300 RValue<Short> Extract(RValue<Short4> val, int i)
3301 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003302 assert(false && "UNIMPLEMENTED"); return RValue<Short>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003303 }
3304
3305 RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y)
3306 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003307 assert(false && "UNIMPLEMENTED"); return RValue<Short4>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003308 }
3309
3310 RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y)
3311 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003312 assert(false && "UNIMPLEMENTED"); return RValue<Short4>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003313 }
3314
3315 Type *Short4::getType()
3316 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04003317 return T(Type_v4i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003318 }
3319
3320 UShort4::UShort4(RValue<Int4> cast)
3321 {
3322 *this = Short4(cast);
3323 }
3324
3325 UShort4::UShort4(RValue<Float4> cast, bool saturate)
3326 {
3327 assert(false && "UNIMPLEMENTED");
3328 }
3329
3330 UShort4::UShort4()
3331 {
3332 // xyzw.parent = this;
3333 }
3334
3335 UShort4::UShort4(unsigned short xyzw)
3336 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04003337 // xyzw.parent = this;
Nicolas Capens598f8d82016-09-26 15:09:10 -04003338
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04003339 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
3340 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003341 }
3342
3343 UShort4::UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w)
3344 {
3345 // xyzw.parent = this;
3346
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04003347 int64_t constantVector[4] = {x, y, z, w};
3348 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003349 }
3350
3351 UShort4::UShort4(RValue<UShort4> rhs)
3352 {
3353 // xyzw.parent = this;
3354
3355 storeValue(rhs.value);
3356 }
3357
3358 UShort4::UShort4(const UShort4 &rhs)
3359 {
3360 // xyzw.parent = this;
3361
3362 Value *value = rhs.loadValue();
3363 storeValue(value);
3364 }
3365
3366 UShort4::UShort4(const Reference<UShort4> &rhs)
3367 {
3368 // xyzw.parent = this;
3369
3370 Value *value = rhs.loadValue();
3371 storeValue(value);
3372 }
3373
3374 UShort4::UShort4(RValue<Short4> rhs)
3375 {
3376 // xyzw.parent = this;
3377
3378 storeValue(rhs.value);
3379 }
3380
3381 UShort4::UShort4(const Short4 &rhs)
3382 {
3383 // xyzw.parent = this;
3384
3385 Value *value = rhs.loadValue();
3386 storeValue(value);
3387 }
3388
3389 UShort4::UShort4(const Reference<Short4> &rhs)
3390 {
3391 // xyzw.parent = this;
3392
3393 Value *value = rhs.loadValue();
3394 storeValue(value);
3395 }
3396
3397 RValue<UShort4> UShort4::operator=(RValue<UShort4> rhs) const
3398 {
3399 storeValue(rhs.value);
3400
3401 return rhs;
3402 }
3403
3404 RValue<UShort4> UShort4::operator=(const UShort4 &rhs) const
3405 {
3406 Value *value = rhs.loadValue();
3407 storeValue(value);
3408
3409 return RValue<UShort4>(value);
3410 }
3411
3412 RValue<UShort4> UShort4::operator=(const Reference<UShort4> &rhs) const
3413 {
3414 Value *value = rhs.loadValue();
3415 storeValue(value);
3416
3417 return RValue<UShort4>(value);
3418 }
3419
3420 RValue<UShort4> UShort4::operator=(RValue<Short4> rhs) const
3421 {
3422 storeValue(rhs.value);
3423
3424 return RValue<UShort4>(rhs);
3425 }
3426
3427 RValue<UShort4> UShort4::operator=(const Short4 &rhs) const
3428 {
3429 Value *value = rhs.loadValue();
3430 storeValue(value);
3431
3432 return RValue<UShort4>(value);
3433 }
3434
3435 RValue<UShort4> UShort4::operator=(const Reference<Short4> &rhs) const
3436 {
3437 Value *value = rhs.loadValue();
3438 storeValue(value);
3439
3440 return RValue<UShort4>(value);
3441 }
3442
3443 RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs)
3444 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003445 return RValue<Short4>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003446 }
3447
3448 RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs)
3449 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003450 return RValue<UShort4>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003451 }
3452
3453 RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs)
3454 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003455 return RValue<UShort4>(Nucleus::createMul(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003456 }
3457
Nicolas Capens16b5f152016-10-13 13:39:01 -04003458 RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs)
3459 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003460 return RValue<UShort4>(Nucleus::createAnd(lhs.value, rhs.value));
Nicolas Capens16b5f152016-10-13 13:39:01 -04003461 }
3462
3463 RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs)
3464 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003465 return RValue<UShort4>(Nucleus::createOr(lhs.value, rhs.value));
Nicolas Capens16b5f152016-10-13 13:39:01 -04003466 }
3467
3468 RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs)
3469 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003470 return RValue<UShort4>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens16b5f152016-10-13 13:39:01 -04003471 }
3472
Nicolas Capens598f8d82016-09-26 15:09:10 -04003473 RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs)
3474 {
Nicolas Capens327f1df2016-10-21 14:26:34 -04003475 return RValue<UShort4>(Nucleus::createShl(lhs.value, C(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003476 }
3477
3478 RValue<UShort4> operator>>(RValue<UShort4> lhs, unsigned char rhs)
3479 {
Nicolas Capens327f1df2016-10-21 14:26:34 -04003480 return RValue<UShort4>(Nucleus::createLShr(lhs.value, C(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003481 }
3482
3483 RValue<UShort4> operator<<(RValue<UShort4> lhs, RValue<Long1> rhs)
3484 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003485 assert(false && "UNIMPLEMENTED"); return RValue<UShort4>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003486 }
3487
3488 RValue<UShort4> operator>>(RValue<UShort4> lhs, RValue<Long1> rhs)
3489 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003490 assert(false && "UNIMPLEMENTED"); return RValue<UShort4>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003491 }
3492
3493 RValue<UShort4> operator<<=(const UShort4 &lhs, unsigned char rhs)
3494 {
3495 return lhs = lhs << rhs;
3496 }
3497
3498 RValue<UShort4> operator>>=(const UShort4 &lhs, unsigned char rhs)
3499 {
3500 return lhs = lhs >> rhs;
3501 }
3502
3503 RValue<UShort4> operator<<=(const UShort4 &lhs, RValue<Long1> rhs)
3504 {
3505 return lhs = lhs << rhs;
3506 }
3507
3508 RValue<UShort4> operator>>=(const UShort4 &lhs, RValue<Long1> rhs)
3509 {
3510 return lhs = lhs >> rhs;
3511 }
3512
3513 RValue<UShort4> operator~(RValue<UShort4> val)
3514 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003515 assert(false && "UNIMPLEMENTED"); return RValue<UShort4>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003516 }
3517
3518 RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y)
3519 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04003520 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3521 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ule, condition, x.value, y.value);
3522 ::basicBlock->appendInst(cmp);
3523
3524 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3525 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3526 ::basicBlock->appendInst(select);
3527
3528 return RValue<UShort4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003529 }
3530
3531 RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y)
3532 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04003533 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3534 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ugt, condition, x.value, y.value);
3535 ::basicBlock->appendInst(cmp);
3536
3537 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3538 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3539 ::basicBlock->appendInst(select);
3540
3541 return RValue<UShort4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003542 }
3543
3544 RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y)
3545 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05003546 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3547 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3548 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3549 auto paddusw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3550 paddusw->addArg(x.value);
3551 paddusw->addArg(y.value);
3552 ::basicBlock->appendInst(paddusw);
3553
3554 return RValue<UShort4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003555 }
3556
3557 RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y)
3558 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05003559 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3560 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3561 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3562 auto psubusw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3563 psubusw->addArg(x.value);
3564 psubusw->addArg(y.value);
3565 ::basicBlock->appendInst(psubusw);
3566
3567 return RValue<UShort4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003568 }
3569
3570 RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y)
3571 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05003572 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3573 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::MultiplyHighUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3574 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3575 auto pmulhuw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3576 pmulhuw->addArg(x.value);
3577 pmulhuw->addArg(y.value);
3578 ::basicBlock->appendInst(pmulhuw);
3579
3580 return RValue<UShort4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003581 }
3582
3583 RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y)
3584 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003585 assert(false && "UNIMPLEMENTED"); return RValue<UShort4>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003586 }
3587
3588 RValue<Byte8> Pack(RValue<UShort4> x, RValue<UShort4> y)
3589 {
Nicolas Capensec54a172016-10-25 17:32:37 -04003590 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
3591 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3592 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3593 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3594 pack->addArg(x.value);
3595 pack->addArg(y.value);
3596 ::basicBlock->appendInst(pack);
3597
Nicolas Capens70dfff42016-10-27 10:20:28 -04003598 return As<Byte8>(Swizzle(As<Int4>(V(result)), 0x88));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003599 }
3600
3601 Type *UShort4::getType()
3602 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04003603 return T(Type_v4i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003604 }
3605
3606 Short8::Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7)
3607 {
3608 // xyzw.parent = this;
3609
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04003610 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
3611 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003612 }
3613
3614 Short8::Short8(RValue<Short8> rhs)
3615 {
3616 // xyzw.parent = this;
3617
3618 storeValue(rhs.value);
3619 }
3620
3621 Short8::Short8(const Reference<Short8> &rhs)
3622 {
3623 // xyzw.parent = this;
3624
3625 Value *value = rhs.loadValue();
3626 storeValue(value);
3627 }
3628
3629 Short8::Short8(RValue<Short4> lo, RValue<Short4> hi)
3630 {
3631 assert(false && "UNIMPLEMENTED");
3632 }
3633
3634 RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs)
3635 {
3636 return RValue<Short8>(Nucleus::createAdd(lhs.value, rhs.value));
3637 }
3638
3639 RValue<Short8> operator&(RValue<Short8> lhs, RValue<Short8> rhs)
3640 {
3641 return RValue<Short8>(Nucleus::createAnd(lhs.value, rhs.value));
3642 }
3643
3644 RValue<Short8> operator<<(RValue<Short8> lhs, unsigned char rhs)
3645 {
Nicolas Capens327f1df2016-10-21 14:26:34 -04003646 return RValue<Short8>(Nucleus::createShl(lhs.value, C(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003647 }
3648
3649 RValue<Short8> operator>>(RValue<Short8> lhs, unsigned char rhs)
3650 {
Nicolas Capens327f1df2016-10-21 14:26:34 -04003651 return RValue<Short8>(Nucleus::createAShr(lhs.value, C(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003652 }
3653
3654 RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y)
3655 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003656 assert(false && "UNIMPLEMENTED"); return RValue<Int4>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003657 }
3658
3659 RValue<Int4> Abs(RValue<Int4> x)
3660 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003661 assert(false && "UNIMPLEMENTED"); return RValue<Int4>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003662 }
3663
3664 RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y)
3665 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003666 assert(false && "UNIMPLEMENTED"); return RValue<Short8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003667 }
3668
3669 Type *Short8::getType()
3670 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04003671 return T(Ice::IceType_v8i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003672 }
3673
3674 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)
3675 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04003676 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
3677 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003678 }
3679
3680 UShort8::UShort8(RValue<UShort8> rhs)
3681 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003682 storeValue(rhs.value);
3683 }
3684
3685 UShort8::UShort8(const Reference<UShort8> &rhs)
3686 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003687 Value *value = rhs.loadValue();
3688 storeValue(value);
3689 }
3690
3691 UShort8::UShort8(RValue<UShort4> lo, RValue<UShort4> hi)
3692 {
3693 assert(false && "UNIMPLEMENTED");
3694 }
3695
3696 RValue<UShort8> UShort8::operator=(RValue<UShort8> rhs) const
3697 {
3698 storeValue(rhs.value);
3699
3700 return rhs;
3701 }
3702
3703 RValue<UShort8> UShort8::operator=(const UShort8 &rhs) const
3704 {
3705 Value *value = rhs.loadValue();
3706 storeValue(value);
3707
3708 return RValue<UShort8>(value);
3709 }
3710
3711 RValue<UShort8> UShort8::operator=(const Reference<UShort8> &rhs) const
3712 {
3713 Value *value = rhs.loadValue();
3714 storeValue(value);
3715
3716 return RValue<UShort8>(value);
3717 }
3718
3719 RValue<UShort8> operator&(RValue<UShort8> lhs, RValue<UShort8> rhs)
3720 {
3721 return RValue<UShort8>(Nucleus::createAnd(lhs.value, rhs.value));
3722 }
3723
3724 RValue<UShort8> operator<<(RValue<UShort8> lhs, unsigned char rhs)
3725 {
Nicolas Capens327f1df2016-10-21 14:26:34 -04003726 return RValue<UShort8>(Nucleus::createShl(lhs.value, C(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003727 }
3728
3729 RValue<UShort8> operator>>(RValue<UShort8> lhs, unsigned char rhs)
3730 {
Nicolas Capens327f1df2016-10-21 14:26:34 -04003731 return RValue<UShort8>(Nucleus::createLShr(lhs.value, C(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003732 }
3733
3734 RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs)
3735 {
3736 return RValue<UShort8>(Nucleus::createAdd(lhs.value, rhs.value));
3737 }
3738
3739 RValue<UShort8> operator*(RValue<UShort8> lhs, RValue<UShort8> rhs)
3740 {
3741 return RValue<UShort8>(Nucleus::createMul(lhs.value, rhs.value));
3742 }
3743
3744 RValue<UShort8> operator+=(const UShort8 &lhs, RValue<UShort8> rhs)
3745 {
3746 return lhs = lhs + rhs;
3747 }
3748
3749 RValue<UShort8> operator~(RValue<UShort8> val)
3750 {
3751 return RValue<UShort8>(Nucleus::createNot(val.value));
3752 }
3753
3754 RValue<UShort8> Swizzle(RValue<UShort8> x, char select0, char select1, char select2, char select3, char select4, char select5, char select6, char select7)
3755 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003756 assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003757 }
3758
3759 RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y)
3760 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003761 assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003762 }
3763
3764 // FIXME: Implement as Shuffle(x, y, Select(i0, ..., i16)) and Shuffle(x, y, SELECT_PACK_REPEAT(element))
3765// RValue<UShort8> PackRepeat(RValue<Byte16> x, RValue<Byte16> y, int element)
3766// {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003767// assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003768// }
3769
3770 Type *UShort8::getType()
3771 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04003772 return T(Ice::IceType_v8i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003773 }
3774
3775 Int::Int(Argument<Int> argument)
3776 {
3777 storeValue(argument.value);
3778 }
3779
3780 Int::Int(RValue<Byte> cast)
3781 {
3782 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3783
3784 storeValue(integer);
3785 }
3786
3787 Int::Int(RValue<SByte> cast)
3788 {
3789 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3790
3791 storeValue(integer);
3792 }
3793
3794 Int::Int(RValue<Short> cast)
3795 {
3796 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3797
3798 storeValue(integer);
3799 }
3800
3801 Int::Int(RValue<UShort> cast)
3802 {
3803 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3804
3805 storeValue(integer);
3806 }
3807
3808 Int::Int(RValue<Int2> cast)
3809 {
3810 *this = Extract(cast, 0);
3811 }
3812
3813 Int::Int(RValue<Long> cast)
3814 {
3815 Value *integer = Nucleus::createTrunc(cast.value, Int::getType());
3816
3817 storeValue(integer);
3818 }
3819
3820 Int::Int(RValue<Float> cast)
3821 {
3822 Value *integer = Nucleus::createFPToSI(cast.value, Int::getType());
3823
3824 storeValue(integer);
3825 }
3826
3827 Int::Int()
3828 {
3829 }
3830
3831 Int::Int(int x)
3832 {
3833 storeValue(Nucleus::createConstantInt(x));
3834 }
3835
3836 Int::Int(RValue<Int> rhs)
3837 {
3838 storeValue(rhs.value);
3839 }
3840
3841 Int::Int(RValue<UInt> rhs)
3842 {
3843 storeValue(rhs.value);
3844 }
3845
3846 Int::Int(const Int &rhs)
3847 {
3848 Value *value = rhs.loadValue();
3849 storeValue(value);
3850 }
3851
3852 Int::Int(const Reference<Int> &rhs)
3853 {
3854 Value *value = rhs.loadValue();
3855 storeValue(value);
3856 }
3857
3858 Int::Int(const UInt &rhs)
3859 {
3860 Value *value = rhs.loadValue();
3861 storeValue(value);
3862 }
3863
3864 Int::Int(const Reference<UInt> &rhs)
3865 {
3866 Value *value = rhs.loadValue();
3867 storeValue(value);
3868 }
3869
3870 RValue<Int> Int::operator=(int rhs) const
3871 {
3872 return RValue<Int>(storeValue(Nucleus::createConstantInt(rhs)));
3873 }
3874
3875 RValue<Int> Int::operator=(RValue<Int> rhs) const
3876 {
3877 storeValue(rhs.value);
3878
3879 return rhs;
3880 }
3881
3882 RValue<Int> Int::operator=(RValue<UInt> rhs) const
3883 {
3884 storeValue(rhs.value);
3885
3886 return RValue<Int>(rhs);
3887 }
3888
3889 RValue<Int> Int::operator=(const Int &rhs) const
3890 {
3891 Value *value = rhs.loadValue();
3892 storeValue(value);
3893
3894 return RValue<Int>(value);
3895 }
3896
3897 RValue<Int> Int::operator=(const Reference<Int> &rhs) const
3898 {
3899 Value *value = rhs.loadValue();
3900 storeValue(value);
3901
3902 return RValue<Int>(value);
3903 }
3904
3905 RValue<Int> Int::operator=(const UInt &rhs) const
3906 {
3907 Value *value = rhs.loadValue();
3908 storeValue(value);
3909
3910 return RValue<Int>(value);
3911 }
3912
3913 RValue<Int> Int::operator=(const Reference<UInt> &rhs) const
3914 {
3915 Value *value = rhs.loadValue();
3916 storeValue(value);
3917
3918 return RValue<Int>(value);
3919 }
3920
3921 RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs)
3922 {
3923 return RValue<Int>(Nucleus::createAdd(lhs.value, rhs.value));
3924 }
3925
3926 RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs)
3927 {
3928 return RValue<Int>(Nucleus::createSub(lhs.value, rhs.value));
3929 }
3930
3931 RValue<Int> operator*(RValue<Int> lhs, RValue<Int> rhs)
3932 {
3933 return RValue<Int>(Nucleus::createMul(lhs.value, rhs.value));
3934 }
3935
3936 RValue<Int> operator/(RValue<Int> lhs, RValue<Int> rhs)
3937 {
3938 return RValue<Int>(Nucleus::createSDiv(lhs.value, rhs.value));
3939 }
3940
3941 RValue<Int> operator%(RValue<Int> lhs, RValue<Int> rhs)
3942 {
3943 return RValue<Int>(Nucleus::createSRem(lhs.value, rhs.value));
3944 }
3945
3946 RValue<Int> operator&(RValue<Int> lhs, RValue<Int> rhs)
3947 {
3948 return RValue<Int>(Nucleus::createAnd(lhs.value, rhs.value));
3949 }
3950
3951 RValue<Int> operator|(RValue<Int> lhs, RValue<Int> rhs)
3952 {
3953 return RValue<Int>(Nucleus::createOr(lhs.value, rhs.value));
3954 }
3955
3956 RValue<Int> operator^(RValue<Int> lhs, RValue<Int> rhs)
3957 {
3958 return RValue<Int>(Nucleus::createXor(lhs.value, rhs.value));
3959 }
3960
3961 RValue<Int> operator<<(RValue<Int> lhs, RValue<Int> rhs)
3962 {
3963 return RValue<Int>(Nucleus::createShl(lhs.value, rhs.value));
3964 }
3965
3966 RValue<Int> operator>>(RValue<Int> lhs, RValue<Int> rhs)
3967 {
3968 return RValue<Int>(Nucleus::createAShr(lhs.value, rhs.value));
3969 }
3970
3971 RValue<Int> operator+=(const Int &lhs, RValue<Int> rhs)
3972 {
3973 return lhs = lhs + rhs;
3974 }
3975
3976 RValue<Int> operator-=(const Int &lhs, RValue<Int> rhs)
3977 {
3978 return lhs = lhs - rhs;
3979 }
3980
3981 RValue<Int> operator*=(const Int &lhs, RValue<Int> rhs)
3982 {
3983 return lhs = lhs * rhs;
3984 }
3985
3986 RValue<Int> operator/=(const Int &lhs, RValue<Int> rhs)
3987 {
3988 return lhs = lhs / rhs;
3989 }
3990
3991 RValue<Int> operator%=(const Int &lhs, RValue<Int> rhs)
3992 {
3993 return lhs = lhs % rhs;
3994 }
3995
3996 RValue<Int> operator&=(const Int &lhs, RValue<Int> rhs)
3997 {
3998 return lhs = lhs & rhs;
3999 }
4000
4001 RValue<Int> operator|=(const Int &lhs, RValue<Int> rhs)
4002 {
4003 return lhs = lhs | rhs;
4004 }
4005
4006 RValue<Int> operator^=(const Int &lhs, RValue<Int> rhs)
4007 {
4008 return lhs = lhs ^ rhs;
4009 }
4010
4011 RValue<Int> operator<<=(const Int &lhs, RValue<Int> rhs)
4012 {
4013 return lhs = lhs << rhs;
4014 }
4015
4016 RValue<Int> operator>>=(const Int &lhs, RValue<Int> rhs)
4017 {
4018 return lhs = lhs >> rhs;
4019 }
4020
4021 RValue<Int> operator+(RValue<Int> val)
4022 {
4023 return val;
4024 }
4025
4026 RValue<Int> operator-(RValue<Int> val)
4027 {
4028 return RValue<Int>(Nucleus::createNeg(val.value));
4029 }
4030
4031 RValue<Int> operator~(RValue<Int> val)
4032 {
4033 return RValue<Int>(Nucleus::createNot(val.value));
4034 }
4035
4036 RValue<Int> operator++(const Int &val, int) // Post-increment
4037 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004038 RValue<UInt> res = val;
4039 val += 1;
4040 return res;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004041 }
4042
4043 const Int &operator++(const Int &val) // Pre-increment
4044 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004045 val += 1;
4046 return val;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004047 }
4048
4049 RValue<Int> operator--(const Int &val, int) // Post-decrement
4050 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004051 RValue<Int> res = val;
4052 val -= 1;
4053 return res;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004054 }
4055
4056 const Int &operator--(const Int &val) // Pre-decrement
4057 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004058 val -= 1;
4059 return val;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004060 }
4061
4062 RValue<Bool> operator<(RValue<Int> lhs, RValue<Int> rhs)
4063 {
4064 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
4065 }
4066
4067 RValue<Bool> operator<=(RValue<Int> lhs, RValue<Int> rhs)
4068 {
4069 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
4070 }
4071
4072 RValue<Bool> operator>(RValue<Int> lhs, RValue<Int> rhs)
4073 {
4074 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
4075 }
4076
4077 RValue<Bool> operator>=(RValue<Int> lhs, RValue<Int> rhs)
4078 {
4079 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
4080 }
4081
4082 RValue<Bool> operator!=(RValue<Int> lhs, RValue<Int> rhs)
4083 {
4084 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
4085 }
4086
4087 RValue<Bool> operator==(RValue<Int> lhs, RValue<Int> rhs)
4088 {
4089 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
4090 }
4091
4092 RValue<Int> Max(RValue<Int> x, RValue<Int> y)
4093 {
4094 return IfThenElse(x > y, x, y);
4095 }
4096
4097 RValue<Int> Min(RValue<Int> x, RValue<Int> y)
4098 {
4099 return IfThenElse(x < y, x, y);
4100 }
4101
4102 RValue<Int> Clamp(RValue<Int> x, RValue<Int> min, RValue<Int> max)
4103 {
4104 return Min(Max(x, min), max);
4105 }
4106
4107 RValue<Int> RoundInt(RValue<Float> cast)
4108 {
Nicolas Capensa8086512016-11-07 17:32:17 -05004109 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
4110 auto round = Ice::InstCast::create(::function, Ice::InstCast::Fptosi, result, cast.value);
4111 ::basicBlock->appendInst(round);
4112
4113 return RValue<Int>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004114 }
4115
4116 Type *Int::getType()
4117 {
4118 return T(Ice::IceType_i32);
4119 }
4120
4121 Long::Long(RValue<Int> cast)
4122 {
4123 Value *integer = Nucleus::createSExt(cast.value, Long::getType());
4124
4125 storeValue(integer);
4126 }
4127
4128 Long::Long(RValue<UInt> cast)
4129 {
4130 Value *integer = Nucleus::createZExt(cast.value, Long::getType());
4131
4132 storeValue(integer);
4133 }
4134
4135 Long::Long()
4136 {
4137 }
4138
4139 Long::Long(RValue<Long> rhs)
4140 {
4141 storeValue(rhs.value);
4142 }
4143
4144 RValue<Long> Long::operator=(int64_t rhs) const
4145 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04004146 return RValue<Long>(storeValue(Nucleus::createConstantLong(rhs)));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004147 }
4148
4149 RValue<Long> Long::operator=(RValue<Long> rhs) const
4150 {
4151 storeValue(rhs.value);
4152
4153 return rhs;
4154 }
4155
4156 RValue<Long> Long::operator=(const Long &rhs) const
4157 {
4158 Value *value = rhs.loadValue();
4159 storeValue(value);
4160
4161 return RValue<Long>(value);
4162 }
4163
4164 RValue<Long> Long::operator=(const Reference<Long> &rhs) const
4165 {
4166 Value *value = rhs.loadValue();
4167 storeValue(value);
4168
4169 return RValue<Long>(value);
4170 }
4171
4172 RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs)
4173 {
4174 return RValue<Long>(Nucleus::createAdd(lhs.value, rhs.value));
4175 }
4176
4177 RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs)
4178 {
4179 return RValue<Long>(Nucleus::createSub(lhs.value, rhs.value));
4180 }
4181
4182 RValue<Long> operator+=(const Long &lhs, RValue<Long> rhs)
4183 {
4184 return lhs = lhs + rhs;
4185 }
4186
4187 RValue<Long> operator-=(const Long &lhs, RValue<Long> rhs)
4188 {
4189 return lhs = lhs - rhs;
4190 }
4191
4192 RValue<Long> AddAtomic(RValue<Pointer<Long> > x, RValue<Long> y)
4193 {
4194 return RValue<Long>(Nucleus::createAtomicAdd(x.value, y.value));
4195 }
4196
4197 Type *Long::getType()
4198 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04004199 return T(Ice::IceType_i64);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004200 }
4201
4202 Long1::Long1(const RValue<UInt> cast)
4203 {
4204 assert(false && "UNIMPLEMENTED");
4205 }
4206
4207 Long1::Long1(RValue<Long1> rhs)
4208 {
4209 storeValue(rhs.value);
4210 }
4211
4212 Type *Long1::getType()
4213 {
4214 assert(false && "UNIMPLEMENTED"); return nullptr;
4215 }
4216
Nicolas Capens598f8d82016-09-26 15:09:10 -04004217 UInt::UInt(Argument<UInt> argument)
4218 {
4219 storeValue(argument.value);
4220 }
4221
4222 UInt::UInt(RValue<UShort> cast)
4223 {
4224 Value *integer = Nucleus::createZExt(cast.value, UInt::getType());
4225
4226 storeValue(integer);
4227 }
4228
4229 UInt::UInt(RValue<Long> cast)
4230 {
4231 Value *integer = Nucleus::createTrunc(cast.value, UInt::getType());
4232
4233 storeValue(integer);
4234 }
4235
4236 UInt::UInt(RValue<Float> cast)
4237 {
4238 assert(false && "UNIMPLEMENTED");
4239 }
4240
4241 UInt::UInt()
4242 {
4243 }
4244
4245 UInt::UInt(int x)
4246 {
4247 storeValue(Nucleus::createConstantInt(x));
4248 }
4249
4250 UInt::UInt(unsigned int x)
4251 {
4252 storeValue(Nucleus::createConstantInt(x));
4253 }
4254
4255 UInt::UInt(RValue<UInt> rhs)
4256 {
4257 storeValue(rhs.value);
4258 }
4259
4260 UInt::UInt(RValue<Int> rhs)
4261 {
4262 storeValue(rhs.value);
4263 }
4264
4265 UInt::UInt(const UInt &rhs)
4266 {
4267 Value *value = rhs.loadValue();
4268 storeValue(value);
4269 }
4270
4271 UInt::UInt(const Reference<UInt> &rhs)
4272 {
4273 Value *value = rhs.loadValue();
4274 storeValue(value);
4275 }
4276
4277 UInt::UInt(const Int &rhs)
4278 {
4279 Value *value = rhs.loadValue();
4280 storeValue(value);
4281 }
4282
4283 UInt::UInt(const Reference<Int> &rhs)
4284 {
4285 Value *value = rhs.loadValue();
4286 storeValue(value);
4287 }
4288
4289 RValue<UInt> UInt::operator=(unsigned int rhs) const
4290 {
4291 return RValue<UInt>(storeValue(Nucleus::createConstantInt(rhs)));
4292 }
4293
4294 RValue<UInt> UInt::operator=(RValue<UInt> rhs) const
4295 {
4296 storeValue(rhs.value);
4297
4298 return rhs;
4299 }
4300
4301 RValue<UInt> UInt::operator=(RValue<Int> rhs) const
4302 {
4303 storeValue(rhs.value);
4304
4305 return RValue<UInt>(rhs);
4306 }
4307
4308 RValue<UInt> UInt::operator=(const UInt &rhs) const
4309 {
4310 Value *value = rhs.loadValue();
4311 storeValue(value);
4312
4313 return RValue<UInt>(value);
4314 }
4315
4316 RValue<UInt> UInt::operator=(const Reference<UInt> &rhs) const
4317 {
4318 Value *value = rhs.loadValue();
4319 storeValue(value);
4320
4321 return RValue<UInt>(value);
4322 }
4323
4324 RValue<UInt> UInt::operator=(const Int &rhs) const
4325 {
4326 Value *value = rhs.loadValue();
4327 storeValue(value);
4328
4329 return RValue<UInt>(value);
4330 }
4331
4332 RValue<UInt> UInt::operator=(const Reference<Int> &rhs) const
4333 {
4334 Value *value = rhs.loadValue();
4335 storeValue(value);
4336
4337 return RValue<UInt>(value);
4338 }
4339
4340 RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs)
4341 {
4342 return RValue<UInt>(Nucleus::createAdd(lhs.value, rhs.value));
4343 }
4344
4345 RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs)
4346 {
4347 return RValue<UInt>(Nucleus::createSub(lhs.value, rhs.value));
4348 }
4349
4350 RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs)
4351 {
4352 return RValue<UInt>(Nucleus::createMul(lhs.value, rhs.value));
4353 }
4354
4355 RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs)
4356 {
4357 return RValue<UInt>(Nucleus::createUDiv(lhs.value, rhs.value));
4358 }
4359
4360 RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs)
4361 {
4362 return RValue<UInt>(Nucleus::createURem(lhs.value, rhs.value));
4363 }
4364
4365 RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs)
4366 {
4367 return RValue<UInt>(Nucleus::createAnd(lhs.value, rhs.value));
4368 }
4369
4370 RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs)
4371 {
4372 return RValue<UInt>(Nucleus::createOr(lhs.value, rhs.value));
4373 }
4374
4375 RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs)
4376 {
4377 return RValue<UInt>(Nucleus::createXor(lhs.value, rhs.value));
4378 }
4379
4380 RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs)
4381 {
4382 return RValue<UInt>(Nucleus::createShl(lhs.value, rhs.value));
4383 }
4384
4385 RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs)
4386 {
4387 return RValue<UInt>(Nucleus::createLShr(lhs.value, rhs.value));
4388 }
4389
4390 RValue<UInt> operator+=(const UInt &lhs, RValue<UInt> rhs)
4391 {
4392 return lhs = lhs + rhs;
4393 }
4394
4395 RValue<UInt> operator-=(const UInt &lhs, RValue<UInt> rhs)
4396 {
4397 return lhs = lhs - rhs;
4398 }
4399
4400 RValue<UInt> operator*=(const UInt &lhs, RValue<UInt> rhs)
4401 {
4402 return lhs = lhs * rhs;
4403 }
4404
4405 RValue<UInt> operator/=(const UInt &lhs, RValue<UInt> rhs)
4406 {
4407 return lhs = lhs / rhs;
4408 }
4409
4410 RValue<UInt> operator%=(const UInt &lhs, RValue<UInt> rhs)
4411 {
4412 return lhs = lhs % rhs;
4413 }
4414
4415 RValue<UInt> operator&=(const UInt &lhs, RValue<UInt> rhs)
4416 {
4417 return lhs = lhs & rhs;
4418 }
4419
4420 RValue<UInt> operator|=(const UInt &lhs, RValue<UInt> rhs)
4421 {
4422 return lhs = lhs | rhs;
4423 }
4424
4425 RValue<UInt> operator^=(const UInt &lhs, RValue<UInt> rhs)
4426 {
4427 return lhs = lhs ^ rhs;
4428 }
4429
4430 RValue<UInt> operator<<=(const UInt &lhs, RValue<UInt> rhs)
4431 {
4432 return lhs = lhs << rhs;
4433 }
4434
4435 RValue<UInt> operator>>=(const UInt &lhs, RValue<UInt> rhs)
4436 {
4437 return lhs = lhs >> rhs;
4438 }
4439
4440 RValue<UInt> operator+(RValue<UInt> val)
4441 {
4442 return val;
4443 }
4444
4445 RValue<UInt> operator-(RValue<UInt> val)
4446 {
4447 return RValue<UInt>(Nucleus::createNeg(val.value));
4448 }
4449
4450 RValue<UInt> operator~(RValue<UInt> val)
4451 {
4452 return RValue<UInt>(Nucleus::createNot(val.value));
4453 }
4454
4455 RValue<UInt> operator++(const UInt &val, int) // Post-increment
4456 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004457 RValue<UInt> res = val;
4458 val += 1;
4459 return res;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004460 }
4461
4462 const UInt &operator++(const UInt &val) // Pre-increment
4463 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004464 val += 1;
4465 return val;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004466 }
4467
4468 RValue<UInt> operator--(const UInt &val, int) // Post-decrement
4469 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004470 RValue<UInt> res = val;
4471 val -= 1;
4472 return res;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004473 }
4474
4475 const UInt &operator--(const UInt &val) // Pre-decrement
4476 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004477 val -= 1;
4478 return val;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004479 }
4480
4481 RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y)
4482 {
4483 return IfThenElse(x > y, x, y);
4484 }
4485
4486 RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y)
4487 {
4488 return IfThenElse(x < y, x, y);
4489 }
4490
4491 RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max)
4492 {
4493 return Min(Max(x, min), max);
4494 }
4495
4496 RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs)
4497 {
4498 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
4499 }
4500
4501 RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs)
4502 {
4503 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
4504 }
4505
4506 RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs)
4507 {
4508 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
4509 }
4510
4511 RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs)
4512 {
4513 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
4514 }
4515
4516 RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs)
4517 {
4518 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
4519 }
4520
4521 RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs)
4522 {
4523 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
4524 }
4525
4526// RValue<UInt> RoundUInt(RValue<Float> cast)
4527// {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004528// assert(false && "UNIMPLEMENTED"); return RValue<UInt>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004529// }
4530
4531 Type *UInt::getType()
4532 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04004533 return T(Ice::IceType_i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004534 }
4535
4536// Int2::Int2(RValue<Int> cast)
4537// {
4538// Value *extend = Nucleus::createZExt(cast.value, Long::getType());
4539// Value *vector = Nucleus::createBitCast(extend, Int2::getType());
4540//
4541// Constant *shuffle[2];
4542// shuffle[0] = Nucleus::createConstantInt(0);
4543// shuffle[1] = Nucleus::createConstantInt(0);
4544//
4545// Value *replicate = Nucleus::createShuffleVector(vector, UndefValue::get(Int2::getType()), Nucleus::createConstantVector(shuffle, 2));
4546//
4547// storeValue(replicate);
4548// }
4549
4550 Int2::Int2(RValue<Int4> cast)
4551 {
Nicolas Capens22008782016-10-20 01:11:47 -04004552 storeValue(Nucleus::createBitCast(cast.value, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004553 }
4554
4555 Int2::Int2()
4556 {
4557 // xy.parent = this;
4558 }
4559
4560 Int2::Int2(int x, int y)
4561 {
4562 // xy.parent = this;
4563
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04004564 int64_t constantVector[2] = {x, y};
4565 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004566 }
4567
4568 Int2::Int2(RValue<Int2> rhs)
4569 {
4570 // xy.parent = this;
4571
4572 storeValue(rhs.value);
4573 }
4574
4575 Int2::Int2(const Int2 &rhs)
4576 {
4577 // xy.parent = this;
4578
4579 Value *value = rhs.loadValue();
4580 storeValue(value);
4581 }
4582
4583 Int2::Int2(const Reference<Int2> &rhs)
4584 {
4585 // xy.parent = this;
4586
4587 Value *value = rhs.loadValue();
4588 storeValue(value);
4589 }
4590
4591 Int2::Int2(RValue<Int> lo, RValue<Int> hi)
4592 {
4593 assert(false && "UNIMPLEMENTED");
4594 }
4595
4596 RValue<Int2> Int2::operator=(RValue<Int2> rhs) const
4597 {
4598 storeValue(rhs.value);
4599
4600 return rhs;
4601 }
4602
4603 RValue<Int2> Int2::operator=(const Int2 &rhs) const
4604 {
4605 Value *value = rhs.loadValue();
4606 storeValue(value);
4607
4608 return RValue<Int2>(value);
4609 }
4610
4611 RValue<Int2> Int2::operator=(const Reference<Int2> &rhs) const
4612 {
4613 Value *value = rhs.loadValue();
4614 storeValue(value);
4615
4616 return RValue<Int2>(value);
4617 }
4618
4619 RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs)
4620 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004621 return RValue<Int2>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004622 }
4623
4624 RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs)
4625 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004626 return RValue<Int2>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004627 }
4628
4629// RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs)
4630// {
4631// return RValue<Int2>(Nucleus::createMul(lhs.value, rhs.value));
4632// }
4633
4634// RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs)
4635// {
4636// return RValue<Int2>(Nucleus::createSDiv(lhs.value, rhs.value));
4637// }
4638
4639// RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs)
4640// {
4641// return RValue<Int2>(Nucleus::createSRem(lhs.value, rhs.value));
4642// }
4643
4644 RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs)
4645 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004646 return RValue<Int2>(Nucleus::createAnd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004647 }
4648
4649 RValue<Int2> operator|(RValue<Int2> lhs, RValue<Int2> rhs)
4650 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004651 return RValue<Int2>(Nucleus::createOr(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004652 }
4653
4654 RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs)
4655 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004656 return RValue<Int2>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004657 }
4658
4659 RValue<Int2> operator<<(RValue<Int2> lhs, unsigned char rhs)
4660 {
Nicolas Capens327f1df2016-10-21 14:26:34 -04004661 return RValue<Int2>(Nucleus::createShl(lhs.value, C(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004662 }
4663
4664 RValue<Int2> operator>>(RValue<Int2> lhs, unsigned char rhs)
4665 {
Nicolas Capens327f1df2016-10-21 14:26:34 -04004666 return RValue<Int2>(Nucleus::createAShr(lhs.value, C(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004667 }
4668
4669 RValue<Int2> operator<<(RValue<Int2> lhs, RValue<Long1> rhs)
4670 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004671 assert(false && "UNIMPLEMENTED"); return RValue<Int2>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004672 }
4673
4674 RValue<Int2> operator>>(RValue<Int2> lhs, RValue<Long1> rhs)
4675 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004676 assert(false && "UNIMPLEMENTED"); return RValue<Int2>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004677 }
4678
4679 RValue<Int2> operator+=(const Int2 &lhs, RValue<Int2> rhs)
4680 {
4681 return lhs = lhs + rhs;
4682 }
4683
4684 RValue<Int2> operator-=(const Int2 &lhs, RValue<Int2> rhs)
4685 {
4686 return lhs = lhs - rhs;
4687 }
4688
4689// RValue<Int2> operator*=(const Int2 &lhs, RValue<Int2> rhs)
4690// {
4691// return lhs = lhs * rhs;
4692// }
4693
4694// RValue<Int2> operator/=(const Int2 &lhs, RValue<Int2> rhs)
4695// {
4696// return lhs = lhs / rhs;
4697// }
4698
4699// RValue<Int2> operator%=(const Int2 &lhs, RValue<Int2> rhs)
4700// {
4701// return lhs = lhs % rhs;
4702// }
4703
4704 RValue<Int2> operator&=(const Int2 &lhs, RValue<Int2> rhs)
4705 {
4706 return lhs = lhs & rhs;
4707 }
4708
4709 RValue<Int2> operator|=(const Int2 &lhs, RValue<Int2> rhs)
4710 {
4711 return lhs = lhs | rhs;
4712 }
4713
4714 RValue<Int2> operator^=(const Int2 &lhs, RValue<Int2> rhs)
4715 {
4716 return lhs = lhs ^ rhs;
4717 }
4718
4719 RValue<Int2> operator<<=(const Int2 &lhs, unsigned char rhs)
4720 {
4721 return lhs = lhs << rhs;
4722 }
4723
4724 RValue<Int2> operator>>=(const Int2 &lhs, unsigned char rhs)
4725 {
4726 return lhs = lhs >> rhs;
4727 }
4728
4729 RValue<Int2> operator<<=(const Int2 &lhs, RValue<Long1> rhs)
4730 {
4731 return lhs = lhs << rhs;
4732 }
4733
4734 RValue<Int2> operator>>=(const Int2 &lhs, RValue<Long1> rhs)
4735 {
4736 return lhs = lhs >> rhs;
4737 }
4738
4739// RValue<Int2> operator+(RValue<Int2> val)
4740// {
4741// return val;
4742// }
4743
4744// RValue<Int2> operator-(RValue<Int2> val)
4745// {
4746// return RValue<Int2>(Nucleus::createNeg(val.value));
4747// }
4748
4749 RValue<Int2> operator~(RValue<Int2> val)
4750 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004751 assert(false && "UNIMPLEMENTED"); return RValue<Int2>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004752 }
4753
4754 RValue<Long1> UnpackLow(RValue<Int2> x, RValue<Int2> y)
4755 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004756 assert(false && "UNIMPLEMENTED"); return RValue<Long1>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004757 }
4758
4759 RValue<Long1> UnpackHigh(RValue<Int2> x, RValue<Int2> y)
4760 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004761 assert(false && "UNIMPLEMENTED"); return RValue<Long1>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004762 }
4763
4764 RValue<Int> Extract(RValue<Int2> val, int i)
4765 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004766 assert(false && "UNIMPLEMENTED"); return RValue<Int>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004767 }
4768
4769 RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i)
4770 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004771 assert(false && "UNIMPLEMENTED"); return RValue<Int2>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004772 }
4773
4774 Type *Int2::getType()
4775 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04004776 return T(Type_v2i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004777 }
4778
4779 UInt2::UInt2()
4780 {
4781 // xy.parent = this;
4782 }
4783
4784 UInt2::UInt2(unsigned int x, unsigned int y)
4785 {
4786 // xy.parent = this;
4787
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04004788 int64_t constantVector[2] = {x, y};
4789 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004790 }
4791
4792 UInt2::UInt2(RValue<UInt2> rhs)
4793 {
4794 // xy.parent = this;
4795
4796 storeValue(rhs.value);
4797 }
4798
4799 UInt2::UInt2(const UInt2 &rhs)
4800 {
4801 // xy.parent = this;
4802
4803 Value *value = rhs.loadValue();
4804 storeValue(value);
4805 }
4806
4807 UInt2::UInt2(const Reference<UInt2> &rhs)
4808 {
4809 // xy.parent = this;
4810
4811 Value *value = rhs.loadValue();
4812 storeValue(value);
4813 }
4814
4815 RValue<UInt2> UInt2::operator=(RValue<UInt2> rhs) const
4816 {
4817 storeValue(rhs.value);
4818
4819 return rhs;
4820 }
4821
4822 RValue<UInt2> UInt2::operator=(const UInt2 &rhs) const
4823 {
4824 Value *value = rhs.loadValue();
4825 storeValue(value);
4826
4827 return RValue<UInt2>(value);
4828 }
4829
4830 RValue<UInt2> UInt2::operator=(const Reference<UInt2> &rhs) const
4831 {
4832 Value *value = rhs.loadValue();
4833 storeValue(value);
4834
4835 return RValue<UInt2>(value);
4836 }
4837
4838 RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs)
4839 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004840 return RValue<UInt2>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004841 }
4842
4843 RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs)
4844 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004845 return RValue<UInt2>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004846 }
4847
4848// RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs)
4849// {
4850// return RValue<UInt2>(Nucleus::createMul(lhs.value, rhs.value));
4851// }
4852
4853// RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs)
4854// {
4855// return RValue<UInt2>(Nucleus::createUDiv(lhs.value, rhs.value));
4856// }
4857
4858// RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs)
4859// {
4860// return RValue<UInt2>(Nucleus::createURem(lhs.value, rhs.value));
4861// }
4862
4863 RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs)
4864 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004865 return RValue<UInt2>(Nucleus::createAnd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004866 }
4867
4868 RValue<UInt2> operator|(RValue<UInt2> lhs, RValue<UInt2> rhs)
4869 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004870 return RValue<UInt2>(Nucleus::createOr(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004871 }
4872
4873 RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs)
4874 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004875 return RValue<UInt2>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004876 }
4877
4878 RValue<UInt2> operator<<(RValue<UInt2> lhs, unsigned char rhs)
4879 {
Nicolas Capens327f1df2016-10-21 14:26:34 -04004880 return RValue<UInt2>(Nucleus::createShl(lhs.value, C(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004881 }
4882
4883 RValue<UInt2> operator>>(RValue<UInt2> lhs, unsigned char rhs)
4884 {
Nicolas Capens327f1df2016-10-21 14:26:34 -04004885 return RValue<UInt2>(Nucleus::createLShr(lhs.value, C(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004886 }
4887
4888 RValue<UInt2> operator<<(RValue<UInt2> lhs, RValue<Long1> rhs)
4889 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004890 assert(false && "UNIMPLEMENTED"); return RValue<UInt2>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004891 }
4892
4893 RValue<UInt2> operator>>(RValue<UInt2> lhs, RValue<Long1> rhs)
4894 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004895 assert(false && "UNIMPLEMENTED"); return RValue<UInt2>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004896 }
4897
4898 RValue<UInt2> operator+=(const UInt2 &lhs, RValue<UInt2> rhs)
4899 {
4900 return lhs = lhs + rhs;
4901 }
4902
4903 RValue<UInt2> operator-=(const UInt2 &lhs, RValue<UInt2> rhs)
4904 {
4905 return lhs = lhs - rhs;
4906 }
4907
4908// RValue<UInt2> operator*=(const UInt2 &lhs, RValue<UInt2> rhs)
4909// {
4910// return lhs = lhs * rhs;
4911// }
4912
4913// RValue<UInt2> operator/=(const UInt2 &lhs, RValue<UInt2> rhs)
4914// {
4915// return lhs = lhs / rhs;
4916// }
4917
4918// RValue<UInt2> operator%=(const UInt2 &lhs, RValue<UInt2> rhs)
4919// {
4920// return lhs = lhs % rhs;
4921// }
4922
4923 RValue<UInt2> operator&=(const UInt2 &lhs, RValue<UInt2> rhs)
4924 {
4925 return lhs = lhs & rhs;
4926 }
4927
4928 RValue<UInt2> operator|=(const UInt2 &lhs, RValue<UInt2> rhs)
4929 {
4930 return lhs = lhs | rhs;
4931 }
4932
4933 RValue<UInt2> operator^=(const UInt2 &lhs, RValue<UInt2> rhs)
4934 {
4935 return lhs = lhs ^ rhs;
4936 }
4937
4938 RValue<UInt2> operator<<=(const UInt2 &lhs, unsigned char rhs)
4939 {
4940 return lhs = lhs << rhs;
4941 }
4942
4943 RValue<UInt2> operator>>=(const UInt2 &lhs, unsigned char rhs)
4944 {
4945 return lhs = lhs >> rhs;
4946 }
4947
4948 RValue<UInt2> operator<<=(const UInt2 &lhs, RValue<Long1> rhs)
4949 {
4950 return lhs = lhs << rhs;
4951 }
4952
4953 RValue<UInt2> operator>>=(const UInt2 &lhs, RValue<Long1> rhs)
4954 {
4955 return lhs = lhs >> rhs;
4956 }
4957
4958// RValue<UInt2> operator+(RValue<UInt2> val)
4959// {
4960// return val;
4961// }
4962
4963// RValue<UInt2> operator-(RValue<UInt2> val)
4964// {
4965// return RValue<UInt2>(Nucleus::createNeg(val.value));
4966// }
4967
4968 RValue<UInt2> operator~(RValue<UInt2> val)
4969 {
4970 return RValue<UInt2>(Nucleus::createNot(val.value));
4971 }
4972
4973 Type *UInt2::getType()
4974 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04004975 return T(Type_v2i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004976 }
4977
4978 Int4::Int4(RValue<Byte4> cast)
4979 {
4980 assert(false && "UNIMPLEMENTED");
4981 }
4982
4983 Int4::Int4(RValue<SByte4> cast)
4984 {
4985 assert(false && "UNIMPLEMENTED");
4986 }
4987
4988 Int4::Int4(RValue<Float4> cast)
4989 {
4990 // xyzw.parent = this;
4991
4992 Value *xyzw = Nucleus::createFPToSI(cast.value, Int4::getType());
4993
4994 storeValue(xyzw);
4995 }
4996
4997 Int4::Int4(RValue<Short4> cast)
4998 {
4999 assert(false && "UNIMPLEMENTED");
5000 }
5001
5002 Int4::Int4(RValue<UShort4> cast)
5003 {
5004 assert(false && "UNIMPLEMENTED");
5005 }
5006
5007 Int4::Int4()
5008 {
5009 // xyzw.parent = this;
5010 }
5011
5012 Int4::Int4(int xyzw)
5013 {
5014 constant(xyzw, xyzw, xyzw, xyzw);
5015 }
5016
5017 Int4::Int4(int x, int yzw)
5018 {
5019 constant(x, yzw, yzw, yzw);
5020 }
5021
5022 Int4::Int4(int x, int y, int zw)
5023 {
5024 constant(x, y, zw, zw);
5025 }
5026
5027 Int4::Int4(int x, int y, int z, int w)
5028 {
5029 constant(x, y, z, w);
5030 }
5031
5032 void Int4::constant(int x, int y, int z, int w)
5033 {
5034 // xyzw.parent = this;
5035
Nicolas Capens13ac2322016-10-13 14:52:12 -04005036 int64_t constantVector[4] = {x, y, z, w};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04005037 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005038 }
5039
5040 Int4::Int4(RValue<Int4> rhs)
5041 {
5042 // xyzw.parent = this;
5043
5044 storeValue(rhs.value);
5045 }
5046
5047 Int4::Int4(const Int4 &rhs)
5048 {
5049 // xyzw.parent = this;
5050
5051 Value *value = rhs.loadValue();
5052 storeValue(value);
5053 }
5054
5055 Int4::Int4(const Reference<Int4> &rhs)
5056 {
5057 // xyzw.parent = this;
5058
5059 Value *value = rhs.loadValue();
5060 storeValue(value);
5061 }
5062
5063 Int4::Int4(RValue<UInt4> rhs)
5064 {
5065 // xyzw.parent = this;
5066
5067 storeValue(rhs.value);
5068 }
5069
5070 Int4::Int4(const UInt4 &rhs)
5071 {
5072 // xyzw.parent = this;
5073
5074 Value *value = rhs.loadValue();
5075 storeValue(value);
5076 }
5077
5078 Int4::Int4(const Reference<UInt4> &rhs)
5079 {
5080 // xyzw.parent = this;
5081
5082 Value *value = rhs.loadValue();
5083 storeValue(value);
5084 }
5085
5086 Int4::Int4(RValue<Int2> lo, RValue<Int2> hi)
5087 {
5088 assert(false && "UNIMPLEMENTED");
5089 }
5090
5091 Int4::Int4(RValue<Int> rhs)
5092 {
5093 // xyzw.parent = this;
5094
5095 assert(false && "UNIMPLEMENTED");
5096 }
5097
5098 Int4::Int4(const Int &rhs)
5099 {
5100 // xyzw.parent = this;
5101
5102 *this = RValue<Int>(rhs.loadValue());
5103 }
5104
5105 Int4::Int4(const Reference<Int> &rhs)
5106 {
5107 // xyzw.parent = this;
5108
5109 *this = RValue<Int>(rhs.loadValue());
5110 }
5111
5112 RValue<Int4> Int4::operator=(RValue<Int4> rhs) const
5113 {
5114 storeValue(rhs.value);
5115
5116 return rhs;
5117 }
5118
5119 RValue<Int4> Int4::operator=(const Int4 &rhs) const
5120 {
5121 Value *value = rhs.loadValue();
5122 storeValue(value);
5123
5124 return RValue<Int4>(value);
5125 }
5126
5127 RValue<Int4> Int4::operator=(const Reference<Int4> &rhs) const
5128 {
5129 Value *value = rhs.loadValue();
5130 storeValue(value);
5131
5132 return RValue<Int4>(value);
5133 }
5134
5135 RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs)
5136 {
5137 return RValue<Int4>(Nucleus::createAdd(lhs.value, rhs.value));
5138 }
5139
5140 RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs)
5141 {
5142 return RValue<Int4>(Nucleus::createSub(lhs.value, rhs.value));
5143 }
5144
5145 RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs)
5146 {
5147 return RValue<Int4>(Nucleus::createMul(lhs.value, rhs.value));
5148 }
5149
5150 RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs)
5151 {
5152 return RValue<Int4>(Nucleus::createSDiv(lhs.value, rhs.value));
5153 }
5154
5155 RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs)
5156 {
5157 return RValue<Int4>(Nucleus::createSRem(lhs.value, rhs.value));
5158 }
5159
5160 RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs)
5161 {
5162 return RValue<Int4>(Nucleus::createAnd(lhs.value, rhs.value));
5163 }
5164
5165 RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs)
5166 {
5167 return RValue<Int4>(Nucleus::createOr(lhs.value, rhs.value));
5168 }
5169
5170 RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs)
5171 {
5172 return RValue<Int4>(Nucleus::createXor(lhs.value, rhs.value));
5173 }
5174
5175 RValue<Int4> operator<<(RValue<Int4> lhs, unsigned char rhs)
5176 {
Nicolas Capens327f1df2016-10-21 14:26:34 -04005177 return RValue<Int4>(Nucleus::createShl(lhs.value, C(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005178 }
5179
5180 RValue<Int4> operator>>(RValue<Int4> lhs, unsigned char rhs)
5181 {
Nicolas Capens327f1df2016-10-21 14:26:34 -04005182 return RValue<Int4>(Nucleus::createAShr(lhs.value, C(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005183 }
5184
5185 RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs)
5186 {
5187 return RValue<Int4>(Nucleus::createShl(lhs.value, rhs.value));
5188 }
5189
5190 RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs)
5191 {
5192 return RValue<Int4>(Nucleus::createAShr(lhs.value, rhs.value));
5193 }
5194
5195 RValue<Int4> operator+=(const Int4 &lhs, RValue<Int4> rhs)
5196 {
5197 return lhs = lhs + rhs;
5198 }
5199
5200 RValue<Int4> operator-=(const Int4 &lhs, RValue<Int4> rhs)
5201 {
5202 return lhs = lhs - rhs;
5203 }
5204
5205 RValue<Int4> operator*=(const Int4 &lhs, RValue<Int4> rhs)
5206 {
5207 return lhs = lhs * rhs;
5208 }
5209
5210// RValue<Int4> operator/=(const Int4 &lhs, RValue<Int4> rhs)
5211// {
5212// return lhs = lhs / rhs;
5213// }
5214
5215// RValue<Int4> operator%=(const Int4 &lhs, RValue<Int4> rhs)
5216// {
5217// return lhs = lhs % rhs;
5218// }
5219
5220 RValue<Int4> operator&=(const Int4 &lhs, RValue<Int4> rhs)
5221 {
5222 return lhs = lhs & rhs;
5223 }
5224
5225 RValue<Int4> operator|=(const Int4 &lhs, RValue<Int4> rhs)
5226 {
5227 return lhs = lhs | rhs;
5228 }
5229
5230 RValue<Int4> operator^=(const Int4 &lhs, RValue<Int4> rhs)
5231 {
5232 return lhs = lhs ^ rhs;
5233 }
5234
5235 RValue<Int4> operator<<=(const Int4 &lhs, unsigned char rhs)
5236 {
5237 return lhs = lhs << rhs;
5238 }
5239
5240 RValue<Int4> operator>>=(const Int4 &lhs, unsigned char rhs)
5241 {
5242 return lhs = lhs >> rhs;
5243 }
5244
5245 RValue<Int4> operator+(RValue<Int4> val)
5246 {
5247 return val;
5248 }
5249
5250 RValue<Int4> operator-(RValue<Int4> val)
5251 {
5252 return RValue<Int4>(Nucleus::createNeg(val.value));
5253 }
5254
5255 RValue<Int4> operator~(RValue<Int4> val)
5256 {
5257 return RValue<Int4>(Nucleus::createNot(val.value));
5258 }
5259
5260 RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y)
5261 {
5262 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
5263 }
5264
5265 RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y)
5266 {
5267 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLT(x.value, y.value), Int4::getType()));
5268 }
5269
5270 RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y)
5271 {
5272 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLE(x.value, y.value), Int4::getType()));
5273 }
5274
5275 RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y)
5276 {
5277 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
5278 }
5279
5280 RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y)
5281 {
5282 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGE(x.value, y.value), Int4::getType()));
5283 }
5284
5285 RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y)
5286 {
5287 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGT(x.value, y.value), Int4::getType()));
5288 }
5289
5290 RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y)
5291 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04005292 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
5293 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sle, condition, x.value, y.value);
5294 ::basicBlock->appendInst(cmp);
5295
5296 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5297 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
5298 ::basicBlock->appendInst(select);
5299
5300 return RValue<Int4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005301 }
5302
5303 RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y)
5304 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04005305 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
5306 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sgt, condition, x.value, y.value);
5307 ::basicBlock->appendInst(cmp);
5308
5309 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5310 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
5311 ::basicBlock->appendInst(select);
5312
5313 return RValue<Int4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005314 }
5315
5316 RValue<Int4> RoundInt(RValue<Float4> cast)
5317 {
Nicolas Capensa8086512016-11-07 17:32:17 -05005318 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5319 auto round = Ice::InstCast::create(::function, Ice::InstCast::Fptosi, result, cast.value);
5320 ::basicBlock->appendInst(round);
5321
5322 return RValue<Int4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005323 }
5324
5325 RValue<Short8> Pack(RValue<Int4> x, RValue<Int4> y)
5326 {
Nicolas Capensec54a172016-10-25 17:32:37 -04005327 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
5328 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5329 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5330 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
5331 pack->addArg(x.value);
5332 pack->addArg(y.value);
5333 ::basicBlock->appendInst(pack);
5334
5335 return RValue<Short8>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005336 }
5337
5338 RValue<Int> Extract(RValue<Int4> x, int i)
5339 {
Nicolas Capense95d5342016-09-30 11:37:28 -04005340 return RValue<Int>(Nucleus::createExtractElement(x.value, Int::getType(), i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005341 }
5342
5343 RValue<Int4> Insert(RValue<Int4> x, RValue<Int> element, int i)
5344 {
5345 return RValue<Int4>(Nucleus::createInsertElement(x.value, element.value, i));
5346 }
5347
5348 RValue<Int> SignMask(RValue<Int4> x)
5349 {
Nicolas Capensf2cb9df2016-10-21 17:26:13 -04005350 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
5351 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5352 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5353 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
5354 movmsk->addArg(x.value);
5355 ::basicBlock->appendInst(movmsk);
5356
5357 return RValue<Int>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005358 }
5359
5360 RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select)
5361 {
Nicolas Capense95d5342016-09-30 11:37:28 -04005362 return RValue<Int4>(createSwizzle4(x.value, select));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005363 }
5364
5365 Type *Int4::getType()
5366 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04005367 return T(Ice::IceType_v4i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005368 }
5369
5370 UInt4::UInt4(RValue<Float4> cast)
5371 {
5372 // xyzw.parent = this;
5373
5374 assert(false && "UNIMPLEMENTED");
5375 }
5376
5377 UInt4::UInt4()
5378 {
5379 // xyzw.parent = this;
5380 }
5381
5382 UInt4::UInt4(int xyzw)
5383 {
5384 constant(xyzw, xyzw, xyzw, xyzw);
5385 }
5386
5387 UInt4::UInt4(int x, int yzw)
5388 {
5389 constant(x, yzw, yzw, yzw);
5390 }
5391
5392 UInt4::UInt4(int x, int y, int zw)
5393 {
5394 constant(x, y, zw, zw);
5395 }
5396
5397 UInt4::UInt4(int x, int y, int z, int w)
5398 {
5399 constant(x, y, z, w);
5400 }
5401
5402 void UInt4::constant(int x, int y, int z, int w)
5403 {
5404 // xyzw.parent = this;
5405
Nicolas Capens13ac2322016-10-13 14:52:12 -04005406 int64_t constantVector[4] = {x, y, z, w};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04005407 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005408 }
5409
5410 UInt4::UInt4(RValue<UInt4> rhs)
5411 {
5412 // xyzw.parent = this;
5413
5414 storeValue(rhs.value);
5415 }
5416
5417 UInt4::UInt4(const UInt4 &rhs)
5418 {
5419 // xyzw.parent = this;
5420
5421 Value *value = rhs.loadValue();
5422 storeValue(value);
5423 }
5424
5425 UInt4::UInt4(const Reference<UInt4> &rhs)
5426 {
5427 // xyzw.parent = this;
5428
5429 Value *value = rhs.loadValue();
5430 storeValue(value);
5431 }
5432
5433 UInt4::UInt4(RValue<Int4> rhs)
5434 {
5435 // xyzw.parent = this;
5436
5437 storeValue(rhs.value);
5438 }
5439
5440 UInt4::UInt4(const Int4 &rhs)
5441 {
5442 // xyzw.parent = this;
5443
5444 Value *value = rhs.loadValue();
5445 storeValue(value);
5446 }
5447
5448 UInt4::UInt4(const Reference<Int4> &rhs)
5449 {
5450 // xyzw.parent = this;
5451
5452 Value *value = rhs.loadValue();
5453 storeValue(value);
5454 }
5455
5456 UInt4::UInt4(RValue<UInt2> lo, RValue<UInt2> hi)
5457 {
5458 assert(false && "UNIMPLEMENTED");
5459 }
5460
5461 RValue<UInt4> UInt4::operator=(RValue<UInt4> rhs) const
5462 {
5463 storeValue(rhs.value);
5464
5465 return rhs;
5466 }
5467
5468 RValue<UInt4> UInt4::operator=(const UInt4 &rhs) const
5469 {
5470 Value *value = rhs.loadValue();
5471 storeValue(value);
5472
5473 return RValue<UInt4>(value);
5474 }
5475
5476 RValue<UInt4> UInt4::operator=(const Reference<UInt4> &rhs) const
5477 {
5478 Value *value = rhs.loadValue();
5479 storeValue(value);
5480
5481 return RValue<UInt4>(value);
5482 }
5483
5484 RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs)
5485 {
5486 return RValue<UInt4>(Nucleus::createAdd(lhs.value, rhs.value));
5487 }
5488
5489 RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs)
5490 {
5491 return RValue<UInt4>(Nucleus::createSub(lhs.value, rhs.value));
5492 }
5493
5494 RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs)
5495 {
5496 return RValue<UInt4>(Nucleus::createMul(lhs.value, rhs.value));
5497 }
5498
5499 RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs)
5500 {
5501 return RValue<UInt4>(Nucleus::createUDiv(lhs.value, rhs.value));
5502 }
5503
5504 RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs)
5505 {
5506 return RValue<UInt4>(Nucleus::createURem(lhs.value, rhs.value));
5507 }
5508
5509 RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs)
5510 {
5511 return RValue<UInt4>(Nucleus::createAnd(lhs.value, rhs.value));
5512 }
5513
5514 RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs)
5515 {
5516 return RValue<UInt4>(Nucleus::createOr(lhs.value, rhs.value));
5517 }
5518
5519 RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs)
5520 {
5521 return RValue<UInt4>(Nucleus::createXor(lhs.value, rhs.value));
5522 }
5523
5524 RValue<UInt4> operator<<(RValue<UInt4> lhs, unsigned char rhs)
5525 {
Nicolas Capens327f1df2016-10-21 14:26:34 -04005526 return RValue<UInt4>(Nucleus::createShl(lhs.value, C(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005527 }
5528
5529 RValue<UInt4> operator>>(RValue<UInt4> lhs, unsigned char rhs)
5530 {
Nicolas Capens327f1df2016-10-21 14:26:34 -04005531 return RValue<UInt4>(Nucleus::createLShr(lhs.value, C(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005532 }
5533
5534 RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs)
5535 {
5536 return RValue<UInt4>(Nucleus::createShl(lhs.value, rhs.value));
5537 }
5538
5539 RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs)
5540 {
5541 return RValue<UInt4>(Nucleus::createLShr(lhs.value, rhs.value));
5542 }
5543
5544 RValue<UInt4> operator+=(const UInt4 &lhs, RValue<UInt4> rhs)
5545 {
5546 return lhs = lhs + rhs;
5547 }
5548
5549 RValue<UInt4> operator-=(const UInt4 &lhs, RValue<UInt4> rhs)
5550 {
5551 return lhs = lhs - rhs;
5552 }
5553
5554 RValue<UInt4> operator*=(const UInt4 &lhs, RValue<UInt4> rhs)
5555 {
5556 return lhs = lhs * rhs;
5557 }
5558
5559// RValue<UInt4> operator/=(const UInt4 &lhs, RValue<UInt4> rhs)
5560// {
5561// return lhs = lhs / rhs;
5562// }
5563
5564// RValue<UInt4> operator%=(const UInt4 &lhs, RValue<UInt4> rhs)
5565// {
5566// return lhs = lhs % rhs;
5567// }
5568
5569 RValue<UInt4> operator&=(const UInt4 &lhs, RValue<UInt4> rhs)
5570 {
5571 return lhs = lhs & rhs;
5572 }
5573
5574 RValue<UInt4> operator|=(const UInt4 &lhs, RValue<UInt4> rhs)
5575 {
5576 return lhs = lhs | rhs;
5577 }
5578
5579 RValue<UInt4> operator^=(const UInt4 &lhs, RValue<UInt4> rhs)
5580 {
5581 return lhs = lhs ^ rhs;
5582 }
5583
5584 RValue<UInt4> operator<<=(const UInt4 &lhs, unsigned char rhs)
5585 {
5586 return lhs = lhs << rhs;
5587 }
5588
5589 RValue<UInt4> operator>>=(const UInt4 &lhs, unsigned char rhs)
5590 {
5591 return lhs = lhs >> rhs;
5592 }
5593
5594 RValue<UInt4> operator+(RValue<UInt4> val)
5595 {
5596 return val;
5597 }
5598
5599 RValue<UInt4> operator-(RValue<UInt4> val)
5600 {
5601 return RValue<UInt4>(Nucleus::createNeg(val.value));
5602 }
5603
5604 RValue<UInt4> operator~(RValue<UInt4> val)
5605 {
5606 return RValue<UInt4>(Nucleus::createNot(val.value));
5607 }
5608
5609 RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y)
5610 {
5611 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
5612 }
5613
5614 RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y)
5615 {
5616 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULT(x.value, y.value), Int4::getType()));
5617 }
5618
5619 RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y)
5620 {
5621 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULE(x.value, y.value), Int4::getType()));
5622 }
5623
5624 RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y)
5625 {
5626 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
5627 }
5628
5629 RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y)
5630 {
5631 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGE(x.value, y.value), Int4::getType()));
5632 }
5633
5634 RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y)
5635 {
5636 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGT(x.value, y.value), Int4::getType()));
5637 }
5638
5639 RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y)
5640 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04005641 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
5642 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ule, condition, x.value, y.value);
5643 ::basicBlock->appendInst(cmp);
5644
5645 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5646 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
5647 ::basicBlock->appendInst(select);
5648
5649 return RValue<UInt4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005650 }
5651
5652 RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y)
5653 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04005654 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
5655 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ugt, condition, x.value, y.value);
5656 ::basicBlock->appendInst(cmp);
5657
5658 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5659 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
5660 ::basicBlock->appendInst(select);
5661
5662 return RValue<UInt4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005663 }
5664
5665 RValue<UShort8> Pack(RValue<UInt4> x, RValue<UInt4> y)
5666 {
Nicolas Capensec54a172016-10-25 17:32:37 -04005667 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
5668 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5669 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5670 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
5671 pack->addArg(x.value);
5672 pack->addArg(y.value);
5673 ::basicBlock->appendInst(pack);
5674
5675 return RValue<UShort8>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005676 }
5677
5678 Type *UInt4::getType()
5679 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04005680 return T(Ice::IceType_v4i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005681 }
5682
5683 Float::Float(RValue<Int> cast)
5684 {
5685 Value *integer = Nucleus::createSIToFP(cast.value, Float::getType());
5686
5687 storeValue(integer);
5688 }
5689
5690 Float::Float()
5691 {
5692 }
5693
5694 Float::Float(float x)
5695 {
5696 storeValue(Nucleus::createConstantFloat(x));
5697 }
5698
5699 Float::Float(RValue<Float> rhs)
5700 {
5701 storeValue(rhs.value);
5702 }
5703
5704 Float::Float(const Float &rhs)
5705 {
5706 Value *value = rhs.loadValue();
5707 storeValue(value);
5708 }
5709
5710 Float::Float(const Reference<Float> &rhs)
5711 {
5712 Value *value = rhs.loadValue();
5713 storeValue(value);
5714 }
5715
5716 RValue<Float> Float::operator=(RValue<Float> rhs) const
5717 {
5718 storeValue(rhs.value);
5719
5720 return rhs;
5721 }
5722
5723 RValue<Float> Float::operator=(const Float &rhs) const
5724 {
5725 Value *value = rhs.loadValue();
5726 storeValue(value);
5727
5728 return RValue<Float>(value);
5729 }
5730
5731 RValue<Float> Float::operator=(const Reference<Float> &rhs) const
5732 {
5733 Value *value = rhs.loadValue();
5734 storeValue(value);
5735
5736 return RValue<Float>(value);
5737 }
5738
5739 RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs)
5740 {
5741 return RValue<Float>(Nucleus::createFAdd(lhs.value, rhs.value));
5742 }
5743
5744 RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs)
5745 {
5746 return RValue<Float>(Nucleus::createFSub(lhs.value, rhs.value));
5747 }
5748
5749 RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs)
5750 {
5751 return RValue<Float>(Nucleus::createFMul(lhs.value, rhs.value));
5752 }
5753
5754 RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs)
5755 {
5756 return RValue<Float>(Nucleus::createFDiv(lhs.value, rhs.value));
5757 }
5758
5759 RValue<Float> operator+=(const Float &lhs, RValue<Float> rhs)
5760 {
5761 return lhs = lhs + rhs;
5762 }
5763
5764 RValue<Float> operator-=(const Float &lhs, RValue<Float> rhs)
5765 {
5766 return lhs = lhs - rhs;
5767 }
5768
5769 RValue<Float> operator*=(const Float &lhs, RValue<Float> rhs)
5770 {
5771 return lhs = lhs * rhs;
5772 }
5773
5774 RValue<Float> operator/=(const Float &lhs, RValue<Float> rhs)
5775 {
5776 return lhs = lhs / rhs;
5777 }
5778
5779 RValue<Float> operator+(RValue<Float> val)
5780 {
5781 return val;
5782 }
5783
5784 RValue<Float> operator-(RValue<Float> val)
5785 {
5786 return RValue<Float>(Nucleus::createFNeg(val.value));
5787 }
5788
5789 RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs)
5790 {
5791 return RValue<Bool>(Nucleus::createFCmpOLT(lhs.value, rhs.value));
5792 }
5793
5794 RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs)
5795 {
5796 return RValue<Bool>(Nucleus::createFCmpOLE(lhs.value, rhs.value));
5797 }
5798
5799 RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs)
5800 {
5801 return RValue<Bool>(Nucleus::createFCmpOGT(lhs.value, rhs.value));
5802 }
5803
5804 RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs)
5805 {
5806 return RValue<Bool>(Nucleus::createFCmpOGE(lhs.value, rhs.value));
5807 }
5808
5809 RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs)
5810 {
5811 return RValue<Bool>(Nucleus::createFCmpONE(lhs.value, rhs.value));
5812 }
5813
5814 RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs)
5815 {
5816 return RValue<Bool>(Nucleus::createFCmpOEQ(lhs.value, rhs.value));
5817 }
5818
5819 RValue<Float> Abs(RValue<Float> x)
5820 {
5821 return IfThenElse(x > 0.0f, x, -x);
5822 }
5823
5824 RValue<Float> Max(RValue<Float> x, RValue<Float> y)
5825 {
5826 return IfThenElse(x > y, x, y);
5827 }
5828
5829 RValue<Float> Min(RValue<Float> x, RValue<Float> y)
5830 {
5831 return IfThenElse(x < y, x, y);
5832 }
5833
5834 RValue<Float> Rcp_pp(RValue<Float> x, bool exactAtPow2)
5835 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04005836 return 1.0f / x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005837 }
5838
5839 RValue<Float> RcpSqrt_pp(RValue<Float> x)
5840 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04005841 return Rcp_pp(Sqrt(x));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005842 }
5843
5844 RValue<Float> Sqrt(RValue<Float> x)
5845 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04005846 Ice::Variable *result = ::function->makeVariable(Ice::IceType_f32);
5847 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Sqrt, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5848 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5849 auto sqrt = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
5850 sqrt->addArg(x.value);
5851 ::basicBlock->appendInst(sqrt);
5852
5853 return RValue<Float>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005854 }
5855
5856 RValue<Float> Round(RValue<Float> x)
5857 {
Nicolas Capensa8086512016-11-07 17:32:17 -05005858 return Float4(Round(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005859 }
5860
5861 RValue<Float> Trunc(RValue<Float> x)
5862 {
Nicolas Capensa8086512016-11-07 17:32:17 -05005863 return Float4(Trunc(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005864 }
5865
5866 RValue<Float> Frac(RValue<Float> x)
5867 {
Nicolas Capensa8086512016-11-07 17:32:17 -05005868 return Float4(Frac(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005869 }
5870
5871 RValue<Float> Floor(RValue<Float> x)
5872 {
Nicolas Capensa8086512016-11-07 17:32:17 -05005873 return Float4(Floor(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005874 }
5875
5876 RValue<Float> Ceil(RValue<Float> x)
5877 {
Nicolas Capensa8086512016-11-07 17:32:17 -05005878 return Float4(Ceil(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005879 }
5880
5881 Type *Float::getType()
5882 {
Nicolas Capens9709d4f2016-09-30 11:44:14 -04005883 return T(Ice::IceType_f32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005884 }
5885
5886 Float2::Float2(RValue<Float4> cast)
5887 {
Nicolas Capens22008782016-10-20 01:11:47 -04005888 storeValue(Nucleus::createBitCast(cast.value, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005889 }
5890
5891 Type *Float2::getType()
5892 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04005893 return T(Type_v2f32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005894 }
5895
5896 Float4::Float4(RValue<Byte4> cast)
5897 {
5898 xyzw.parent = this;
5899
5900 assert(false && "UNIMPLEMENTED");
5901 }
5902
5903 Float4::Float4(RValue<SByte4> cast)
5904 {
5905 xyzw.parent = this;
5906
5907 assert(false && "UNIMPLEMENTED");
5908 }
5909
5910 Float4::Float4(RValue<Short4> cast)
5911 {
5912 xyzw.parent = this;
5913
5914 Int4 c(cast);
5915 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
5916 }
5917
5918 Float4::Float4(RValue<UShort4> cast)
5919 {
5920 xyzw.parent = this;
5921
5922 Int4 c(cast);
5923 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
5924 }
5925
5926 Float4::Float4(RValue<Int4> cast)
5927 {
5928 xyzw.parent = this;
5929
5930 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType());
5931
5932 storeValue(xyzw);
5933 }
5934
5935 Float4::Float4(RValue<UInt4> cast)
5936 {
5937 xyzw.parent = this;
5938
5939 Value *xyzw = Nucleus::createUIToFP(cast.value, Float4::getType());
5940
5941 storeValue(xyzw);
5942 }
5943
5944 Float4::Float4()
5945 {
5946 xyzw.parent = this;
5947 }
5948
5949 Float4::Float4(float xyzw)
5950 {
5951 constant(xyzw, xyzw, xyzw, xyzw);
5952 }
5953
5954 Float4::Float4(float x, float yzw)
5955 {
5956 constant(x, yzw, yzw, yzw);
5957 }
5958
5959 Float4::Float4(float x, float y, float zw)
5960 {
5961 constant(x, y, zw, zw);
5962 }
5963
5964 Float4::Float4(float x, float y, float z, float w)
5965 {
5966 constant(x, y, z, w);
5967 }
5968
5969 void Float4::constant(float x, float y, float z, float w)
5970 {
5971 xyzw.parent = this;
5972
Nicolas Capens13ac2322016-10-13 14:52:12 -04005973 double constantVector[4] = {x, y, z, w};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04005974 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005975 }
5976
5977 Float4::Float4(RValue<Float4> rhs)
5978 {
5979 xyzw.parent = this;
5980
5981 storeValue(rhs.value);
5982 }
5983
5984 Float4::Float4(const Float4 &rhs)
5985 {
5986 xyzw.parent = this;
5987
5988 Value *value = rhs.loadValue();
5989 storeValue(value);
5990 }
5991
5992 Float4::Float4(const Reference<Float4> &rhs)
5993 {
5994 xyzw.parent = this;
5995
5996 Value *value = rhs.loadValue();
5997 storeValue(value);
5998 }
5999
6000 Float4::Float4(RValue<Float> rhs)
6001 {
6002 xyzw.parent = this;
6003
6004 assert(false && "UNIMPLEMENTED");
6005 }
6006
6007 Float4::Float4(const Float &rhs)
6008 {
6009 xyzw.parent = this;
6010
6011 *this = RValue<Float>(rhs.loadValue());
6012 }
6013
6014 Float4::Float4(const Reference<Float> &rhs)
6015 {
6016 xyzw.parent = this;
6017
6018 *this = RValue<Float>(rhs.loadValue());
6019 }
6020
6021 RValue<Float4> Float4::operator=(float x) const
6022 {
6023 return *this = Float4(x, x, x, x);
6024 }
6025
6026 RValue<Float4> Float4::operator=(RValue<Float4> rhs) const
6027 {
6028 storeValue(rhs.value);
6029
6030 return rhs;
6031 }
6032
6033 RValue<Float4> Float4::operator=(const Float4 &rhs) const
6034 {
6035 Value *value = rhs.loadValue();
6036 storeValue(value);
6037
6038 return RValue<Float4>(value);
6039 }
6040
6041 RValue<Float4> Float4::operator=(const Reference<Float4> &rhs) const
6042 {
6043 Value *value = rhs.loadValue();
6044 storeValue(value);
6045
6046 return RValue<Float4>(value);
6047 }
6048
6049 RValue<Float4> Float4::operator=(RValue<Float> rhs) const
6050 {
6051 return *this = Float4(rhs);
6052 }
6053
6054 RValue<Float4> Float4::operator=(const Float &rhs) const
6055 {
6056 return *this = Float4(rhs);
6057 }
6058
6059 RValue<Float4> Float4::operator=(const Reference<Float> &rhs) const
6060 {
6061 return *this = Float4(rhs);
6062 }
6063
6064 RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs)
6065 {
6066 return RValue<Float4>(Nucleus::createFAdd(lhs.value, rhs.value));
6067 }
6068
6069 RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs)
6070 {
6071 return RValue<Float4>(Nucleus::createFSub(lhs.value, rhs.value));
6072 }
6073
6074 RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs)
6075 {
6076 return RValue<Float4>(Nucleus::createFMul(lhs.value, rhs.value));
6077 }
6078
6079 RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs)
6080 {
6081 return RValue<Float4>(Nucleus::createFDiv(lhs.value, rhs.value));
6082 }
6083
6084 RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs)
6085 {
6086 return RValue<Float4>(Nucleus::createFRem(lhs.value, rhs.value));
6087 }
6088
6089 RValue<Float4> operator+=(const Float4 &lhs, RValue<Float4> rhs)
6090 {
6091 return lhs = lhs + rhs;
6092 }
6093
6094 RValue<Float4> operator-=(const Float4 &lhs, RValue<Float4> rhs)
6095 {
6096 return lhs = lhs - rhs;
6097 }
6098
6099 RValue<Float4> operator*=(const Float4 &lhs, RValue<Float4> rhs)
6100 {
6101 return lhs = lhs * rhs;
6102 }
6103
6104 RValue<Float4> operator/=(const Float4 &lhs, RValue<Float4> rhs)
6105 {
6106 return lhs = lhs / rhs;
6107 }
6108
6109 RValue<Float4> operator%=(const Float4 &lhs, RValue<Float4> rhs)
6110 {
6111 return lhs = lhs % rhs;
6112 }
6113
6114 RValue<Float4> operator+(RValue<Float4> val)
6115 {
6116 return val;
6117 }
6118
6119 RValue<Float4> operator-(RValue<Float4> val)
6120 {
6121 return RValue<Float4>(Nucleus::createFNeg(val.value));
6122 }
6123
6124 RValue<Float4> Abs(RValue<Float4> x)
6125 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04006126 assert(false && "UNIMPLEMENTED"); return RValue<Float4>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006127 }
6128
6129 RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y)
6130 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006131 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
6132 auto cmp = Ice::InstFcmp::create(::function, Ice::InstFcmp::Ule, condition, x.value, y.value);
6133 ::basicBlock->appendInst(cmp);
6134
6135 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6136 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
6137 ::basicBlock->appendInst(select);
6138
6139 return RValue<Float4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006140 }
6141
6142 RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y)
6143 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006144 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
6145 auto cmp = Ice::InstFcmp::create(::function, Ice::InstFcmp::Ugt, condition, x.value, y.value);
6146 ::basicBlock->appendInst(cmp);
6147
6148 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6149 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
6150 ::basicBlock->appendInst(select);
6151
6152 return RValue<Float4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006153 }
6154
6155 RValue<Float4> Rcp_pp(RValue<Float4> x, bool exactAtPow2)
6156 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04006157 return Float4(1.0f) / x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04006158 }
6159
6160 RValue<Float4> RcpSqrt_pp(RValue<Float4> x)
6161 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04006162 return Rcp_pp(Sqrt(x));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006163 }
6164
6165 RValue<Float4> Sqrt(RValue<Float4> x)
6166 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04006167 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6168 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Sqrt, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6169 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6170 auto sqrt = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
6171 sqrt->addArg(x.value);
6172 ::basicBlock->appendInst(sqrt);
6173
6174 return RValue<Float4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006175 }
6176
6177 RValue<Float4> Insert(const Float4 &val, RValue<Float> element, int i)
6178 {
6179 Value *value = val.loadValue();
6180 Value *insert = Nucleus::createInsertElement(value, element.value, i);
6181
6182 val = RValue<Float4>(insert);
6183
6184 return val;
6185 }
6186
6187 RValue<Float> Extract(RValue<Float4> x, int i)
6188 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006189 return RValue<Float>(Nucleus::createExtractElement(x.value, Float::getType(), i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006190 }
6191
6192 RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select)
6193 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006194 return RValue<Float4>(createSwizzle4(x.value, select));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006195 }
6196
6197 RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
6198 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04006199 int shuffle[4] =
6200 {
6201 ((imm >> 0) & 0x03) + 0,
6202 ((imm >> 2) & 0x03) + 0,
6203 ((imm >> 4) & 0x03) + 4,
6204 ((imm >> 6) & 0x03) + 4,
6205 };
6206
6207 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006208 }
6209
6210 RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y)
6211 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04006212 int shuffle[4] = {0, 4, 1, 5};
6213 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006214 }
6215
6216 RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y)
6217 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04006218 int shuffle[4] = {2, 6, 3, 7};
6219 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006220 }
6221
6222 RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select)
6223 {
6224 Value *vector = lhs.loadValue();
Nicolas Capense95d5342016-09-30 11:37:28 -04006225 Value *shuffle = createMask4(vector, rhs.value, select);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006226 lhs.storeValue(shuffle);
6227
6228 return RValue<Float4>(shuffle);
6229 }
6230
6231 RValue<Int> SignMask(RValue<Float4> x)
6232 {
Nicolas Capensf2cb9df2016-10-21 17:26:13 -04006233 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
6234 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6235 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6236 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
6237 movmsk->addArg(x.value);
6238 ::basicBlock->appendInst(movmsk);
6239
6240 return RValue<Int>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006241 }
6242
6243 RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y)
6244 {
6245 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOEQ(x.value, y.value), Int4::getType()));
6246 }
6247
6248 RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y)
6249 {
6250 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOLT(x.value, y.value), Int4::getType()));
6251 }
6252
6253 RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y)
6254 {
6255 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOLE(x.value, y.value), Int4::getType()));
6256 }
6257
6258 RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y)
6259 {
6260 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpONE(x.value, y.value), Int4::getType()));
6261 }
6262
6263 RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y)
6264 {
6265 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOGE(x.value, y.value), Int4::getType()));
6266 }
6267
6268 RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y)
6269 {
6270 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOGT(x.value, y.value), Int4::getType()));
6271 }
6272
6273 RValue<Float4> Round(RValue<Float4> x)
6274 {
Nicolas Capensa8086512016-11-07 17:32:17 -05006275 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6276 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6277 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6278 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
6279 round->addArg(x.value);
6280 round->addArg(::context->getConstantInt32(0));
6281 ::basicBlock->appendInst(round);
6282
6283 return RValue<Float4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006284 }
6285
6286 RValue<Float4> Trunc(RValue<Float4> x)
6287 {
Nicolas Capensa8086512016-11-07 17:32:17 -05006288 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6289 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6290 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6291 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
6292 round->addArg(x.value);
6293 round->addArg(::context->getConstantInt32(3));
6294 ::basicBlock->appendInst(round);
6295
6296 return RValue<Float4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006297 }
6298
6299 RValue<Float4> Frac(RValue<Float4> x)
6300 {
Nicolas Capensa8086512016-11-07 17:32:17 -05006301 return x - Floor(x);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006302 }
6303
6304 RValue<Float4> Floor(RValue<Float4> x)
6305 {
Nicolas Capensa8086512016-11-07 17:32:17 -05006306 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6307 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6308 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6309 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
6310 round->addArg(x.value);
6311 round->addArg(::context->getConstantInt32(1));
6312 ::basicBlock->appendInst(round);
6313
6314 return RValue<Float4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006315 }
6316
6317 RValue<Float4> Ceil(RValue<Float4> x)
6318 {
Nicolas Capensa8086512016-11-07 17:32:17 -05006319 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6320 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6321 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6322 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
6323 round->addArg(x.value);
6324 round->addArg(::context->getConstantInt32(2));
6325 ::basicBlock->appendInst(round);
6326
6327 return RValue<Float4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006328 }
6329
6330 Type *Float4::getType()
6331 {
Nicolas Capens9709d4f2016-09-30 11:44:14 -04006332 return T(Ice::IceType_v4f32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006333 }
6334
6335 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset)
6336 {
Nicolas Capens8820f642016-09-30 04:42:43 -04006337 return lhs + RValue<Int>(Nucleus::createConstantInt(offset));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006338 }
6339
6340 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
6341 {
Nicolas Capens6d738712016-09-30 04:15:22 -04006342 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006343 }
6344
6345 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
6346 {
Nicolas Capens6d738712016-09-30 04:15:22 -04006347 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006348 }
6349
6350 RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, int offset)
6351 {
6352 return lhs = lhs + offset;
6353 }
6354
6355 RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, RValue<Int> offset)
6356 {
6357 return lhs = lhs + offset;
6358 }
6359
6360 RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, RValue<UInt> offset)
6361 {
6362 return lhs = lhs + offset;
6363 }
6364
6365 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset)
6366 {
6367 return lhs + -offset;
6368 }
6369
6370 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
6371 {
6372 return lhs + -offset;
6373 }
6374
6375 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
6376 {
6377 return lhs + -offset;
6378 }
6379
6380 RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, int offset)
6381 {
6382 return lhs = lhs - offset;
6383 }
6384
6385 RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, RValue<Int> offset)
6386 {
6387 return lhs = lhs - offset;
6388 }
6389
6390 RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, RValue<UInt> offset)
6391 {
6392 return lhs = lhs - offset;
6393 }
6394
6395 void Return()
6396 {
6397 Nucleus::createRetVoid();
6398 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
6399 Nucleus::createUnreachable();
6400 }
6401
6402 void Return(bool ret)
6403 {
Nicolas Capensfdcca2d2016-10-20 11:31:36 -04006404 Nucleus::createRet(Nucleus::createConstantInt(ret));
6405 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
6406 Nucleus::createUnreachable();
Nicolas Capens598f8d82016-09-26 15:09:10 -04006407 }
6408
6409 void Return(const Int &ret)
6410 {
Nicolas Capensfdcca2d2016-10-20 11:31:36 -04006411 Nucleus::createRet(ret.loadValue());
6412 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
6413 Nucleus::createUnreachable();
Nicolas Capens598f8d82016-09-26 15:09:10 -04006414 }
6415
Nicolas Capens598f8d82016-09-26 15:09:10 -04006416 bool branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB)
6417 {
6418 Nucleus::createCondBr(cmp.value, bodyBB, endBB);
6419 Nucleus::setInsertBlock(bodyBB);
6420
6421 return true;
6422 }
6423
Nicolas Capens9ed1a182016-10-24 09:52:23 -04006424 void endIf(BasicBlock *falseBB)
6425 {
6426 ::falseBB = falseBB;
6427 }
6428
Nicolas Capens598f8d82016-09-26 15:09:10 -04006429 bool elseBlock(BasicBlock *falseBB)
6430 {
Nicolas Capens9ed1a182016-10-24 09:52:23 -04006431 assert(falseBB && "Else not preceded by If");
6432 falseBB->getInsts().back().setDeleted();
Nicolas Capens598f8d82016-09-26 15:09:10 -04006433 Nucleus::setInsertBlock(falseBB);
6434
6435 return true;
6436 }
6437
Nicolas Capens9ed1a182016-10-24 09:52:23 -04006438 BasicBlock *beginElse()
6439 {
6440 BasicBlock *falseBB = ::falseBB;
6441 ::falseBB = nullptr;
6442
6443 return falseBB;
6444 }
6445
Nicolas Capens598f8d82016-09-26 15:09:10 -04006446 RValue<Long> Ticks()
6447 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04006448 assert(false && "UNIMPLEMENTED"); return RValue<Long>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006449 }
6450}
6451