blob: 21298f8e3bbe90f254316faae828e8eed097b584 [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
Nicolas Capens2ae9d742016-11-24 14:43:05 -050020#include "Optimizer.hpp"
21
Nicolas Capens598f8d82016-09-26 15:09:10 -040022#include "src/IceTypes.h"
23#include "src/IceCfg.h"
24#include "src/IceELFStreamer.h"
25#include "src/IceGlobalContext.h"
26#include "src/IceCfgNode.h"
27#include "src/IceELFObjectWriter.h"
Nicolas Capens8dfd9a72016-10-13 17:44:51 -040028#include "src/IceGlobalInits.h"
Nicolas Capens598f8d82016-09-26 15:09:10 -040029
30#include "llvm/Support/FileSystem.h"
31#include "llvm/Support/raw_os_ostream.h"
32
Nicolas Capensbd65da92017-01-05 16:31:06 -050033#if defined(_WIN32)
Alexis Hetu113e33a2017-01-19 10:49:19 -050034#ifndef WIN32_LEAN_AND_MEAN
Nicolas Capens598f8d82016-09-26 15:09:10 -040035#define WIN32_LEAN_AND_MEAN
Alexis Hetu113e33a2017-01-19 10:49:19 -050036#endif // !WIN32_LEAN_AND_MEAN
37#ifndef NOMINMAX
Nicolas Capens598f8d82016-09-26 15:09:10 -040038#define NOMINMAX
Alexis Hetu113e33a2017-01-19 10:49:19 -050039#endif // !NOMINMAX
Nicolas Capens598f8d82016-09-26 15:09:10 -040040#include <Windows.h>
Nicolas Capensbd65da92017-01-05 16:31:06 -050041#else
42#include <sys/mman.h>
Nicolas Capens8b275742017-01-20 17:11:41 -050043#if !defined(MAP_ANONYMOUS)
44#define MAP_ANONYMOUS MAP_ANON
45#endif
Nicolas Capensbd65da92017-01-05 16:31:06 -050046#endif
Nicolas Capens598f8d82016-09-26 15:09:10 -040047
48#include <mutex>
49#include <limits>
50#include <iostream>
51#include <cassert>
52
53namespace
54{
55 Ice::GlobalContext *context = nullptr;
56 Ice::Cfg *function = nullptr;
57 Ice::CfgNode *basicBlock = nullptr;
58 Ice::CfgLocalAllocatorScope *allocator = nullptr;
59 sw::Routine *routine = nullptr;
60
61 std::mutex codegenMutex;
62
63 Ice::ELFFileStreamer *elfFile = nullptr;
64 Ice::Fdstream *out = nullptr;
65}
66
Nicolas Capensccd5ecb2017-01-14 12:52:55 -050067namespace
68{
69 class CPUID
70 {
71 public:
72 const static bool SSE4_1;
73
74 private:
75 static void cpuid(int registers[4], int info)
76 {
77 #if defined(_WIN32)
78 __cpuid(registers, info);
79 #else
80 __asm volatile("cpuid": "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]): "a" (info));
81 #endif
82 }
83
84 static bool detectSSE4_1()
85 {
86 int registers[4];
87 cpuid(registers, 1);
88 return (registers[2] & 0x00080000) != 0;
89 }
90 };
91
92 const bool CPUID::SSE4_1 = CPUID::detectSSE4_1();
93}
94
Nicolas Capens598f8d82016-09-26 15:09:10 -040095namespace sw
96{
Nicolas Capens23d99a42016-09-30 14:57:16 -040097 enum EmulatedType
98 {
99 EmulatedShift = 16,
100 EmulatedV2 = 2 << EmulatedShift,
101 EmulatedV4 = 4 << EmulatedShift,
102 EmulatedV8 = 8 << EmulatedShift,
103 EmulatedBits = EmulatedV2 | EmulatedV4 | EmulatedV8,
104
105 Type_v2i32 = Ice::IceType_v4i32 | EmulatedV2,
106 Type_v4i16 = Ice::IceType_v8i16 | EmulatedV4,
107 Type_v2i16 = Ice::IceType_v8i16 | EmulatedV2,
108 Type_v8i8 = Ice::IceType_v16i8 | EmulatedV8,
109 Type_v4i8 = Ice::IceType_v16i8 | EmulatedV4,
Nicolas Capens4cfd4572016-10-20 01:00:19 -0400110 Type_v2f32 = Ice::IceType_v4f32 | EmulatedV2,
Nicolas Capens23d99a42016-09-30 14:57:16 -0400111 };
112
Nicolas Capens15060bb2016-12-05 22:17:19 -0500113 class Value : public Ice::Operand {};
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500114 class SwitchCases : public Ice::InstSwitch {};
Nicolas Capens598f8d82016-09-26 15:09:10 -0400115 class BasicBlock : public Ice::CfgNode {};
116
117 Ice::Type T(Type *t)
118 {
Alexis Hetu113e33a2017-01-19 10:49:19 -0500119 static_assert(static_cast<unsigned int>(Ice::IceType_NUM) < static_cast<unsigned int>(EmulatedBits), "Ice::Type overlaps with our emulated types!");
Nicolas Capens23d99a42016-09-30 14:57:16 -0400120 return (Ice::Type)(reinterpret_cast<std::intptr_t>(t) & ~EmulatedBits);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400121 }
122
123 Type *T(Ice::Type t)
124 {
125 return reinterpret_cast<Type*>(t);
126 }
127
Nicolas Capens23d99a42016-09-30 14:57:16 -0400128 Type *T(EmulatedType t)
129 {
130 return reinterpret_cast<Type*>(t);
131 }
132
Nicolas Capens15060bb2016-12-05 22:17:19 -0500133 Value *V(Ice::Operand *v)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400134 {
135 return reinterpret_cast<Value*>(v);
136 }
137
Nicolas Capens611642a2016-09-28 16:45:04 -0400138 BasicBlock *B(Ice::CfgNode *b)
139 {
140 return reinterpret_cast<BasicBlock*>(b);
141 }
142
Nicolas Capens598f8d82016-09-26 15:09:10 -0400143 Optimization optimization[10] = {InstructionCombining, Disabled};
144
Nicolas Capens66478362016-10-13 15:36:36 -0400145 using ElfHeader = std::conditional<sizeof(void*) == 8, Elf64_Ehdr, Elf32_Ehdr>::type;
146 using SectionHeader = std::conditional<sizeof(void*) == 8, Elf64_Shdr, Elf32_Shdr>::type;
147
148 inline const SectionHeader *sectionHeader(const ElfHeader *elfHeader)
149 {
150 return reinterpret_cast<const SectionHeader*>((intptr_t)elfHeader + elfHeader->e_shoff);
151 }
Nicolas Capens87852e12016-11-24 14:45:06 -0500152
Nicolas Capens66478362016-10-13 15:36:36 -0400153 inline const SectionHeader *elfSection(const ElfHeader *elfHeader, int index)
154 {
155 return &sectionHeader(elfHeader)[index];
156 }
157
158 static void *relocateSymbol(const ElfHeader *elfHeader, const Elf32_Rel &relocation, const SectionHeader &relocationTable)
159 {
160 const SectionHeader *target = elfSection(elfHeader, relocationTable.sh_info);
Nicolas Capens87852e12016-11-24 14:45:06 -0500161
Nicolas Capens66478362016-10-13 15:36:36 -0400162 intptr_t address = (intptr_t)elfHeader + target->sh_offset;
163 int32_t *patchSite = (int*)(address + relocation.r_offset);
164 uint32_t index = relocation.getSymbol();
165 int table = relocationTable.sh_link;
166 void *symbolValue = nullptr;
Nicolas Capens87852e12016-11-24 14:45:06 -0500167
Nicolas Capens66478362016-10-13 15:36:36 -0400168 if(index != SHN_UNDEF)
169 {
170 if(table == SHN_UNDEF) return nullptr;
171 const SectionHeader *symbolTable = elfSection(elfHeader, table);
Nicolas Capens87852e12016-11-24 14:45:06 -0500172
Nicolas Capens66478362016-10-13 15:36:36 -0400173 uint32_t symtab_entries = symbolTable->sh_size / symbolTable->sh_entsize;
174 if(index >= symtab_entries)
175 {
176 assert(index < symtab_entries && "Symbol Index out of range");
177 return nullptr;
178 }
Nicolas Capens87852e12016-11-24 14:45:06 -0500179
Nicolas Capens66478362016-10-13 15:36:36 -0400180 intptr_t symbolAddress = (intptr_t)elfHeader + symbolTable->sh_offset;
181 Elf32_Sym &symbol = ((Elf32_Sym*)symbolAddress)[index];
182 uint16_t section = symbol.st_shndx;
183
184 if(section != SHN_UNDEF && section < SHN_LORESERVE)
185 {
186 const SectionHeader *target = elfSection(elfHeader, symbol.st_shndx);
187 symbolValue = reinterpret_cast<void*>((intptr_t)elfHeader + symbol.st_value + target->sh_offset);
188 }
189 else
190 {
191 return nullptr;
192 }
193 }
194
195 switch(relocation.getType())
196 {
197 case R_386_NONE:
198 // No relocation
199 break;
200 case R_386_32:
201 *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite);
202 break;
203 // case R_386_PC32:
204 // *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite - (intptr_t)patchSite);
205 // break;
206 default:
207 assert(false && "Unsupported relocation type");
208 return nullptr;
209 }
210
211 return symbolValue;
212 }
213
214 static void *relocateSymbol(const ElfHeader *elfHeader, const Elf64_Rela &relocation, const SectionHeader &relocationTable)
215 {
216 const SectionHeader *target = elfSection(elfHeader, relocationTable.sh_info);
Nicolas Capens87852e12016-11-24 14:45:06 -0500217
Nicolas Capens66478362016-10-13 15:36:36 -0400218 intptr_t address = (intptr_t)elfHeader + target->sh_offset;
219 int32_t *patchSite = (int*)(address + relocation.r_offset);
220 uint32_t index = relocation.getSymbol();
221 int table = relocationTable.sh_link;
222 void *symbolValue = nullptr;
223
224 if(index != SHN_UNDEF)
225 {
226 if(table == SHN_UNDEF) return nullptr;
227 const SectionHeader *symbolTable = elfSection(elfHeader, table);
Nicolas Capens87852e12016-11-24 14:45:06 -0500228
Nicolas Capens66478362016-10-13 15:36:36 -0400229 uint32_t symtab_entries = symbolTable->sh_size / symbolTable->sh_entsize;
230 if(index >= symtab_entries)
231 {
232 assert(index < symtab_entries && "Symbol Index out of range");
233 return nullptr;
234 }
Nicolas Capens87852e12016-11-24 14:45:06 -0500235
Nicolas Capens66478362016-10-13 15:36:36 -0400236 intptr_t symbolAddress = (intptr_t)elfHeader + symbolTable->sh_offset;
237 Elf64_Sym &symbol = ((Elf64_Sym*)symbolAddress)[index];
238 uint16_t section = symbol.st_shndx;
239
240 if(section != SHN_UNDEF && section < SHN_LORESERVE)
241 {
242 const SectionHeader *target = elfSection(elfHeader, symbol.st_shndx);
243 symbolValue = reinterpret_cast<void*>((intptr_t)elfHeader + symbol.st_value + target->sh_offset);
244 }
245 else
246 {
247 return nullptr;
248 }
249 }
250
251 switch(relocation.getType())
252 {
253 case R_X86_64_NONE:
254 // No relocation
255 break;
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500256 case R_X86_64_64:
257 *(int64_t*)patchSite = (int64_t)((intptr_t)symbolValue + *(int64_t*)patchSite) + relocation.r_addend;
258 break;
Nicolas Capens66478362016-10-13 15:36:36 -0400259 case R_X86_64_PC32:
260 *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite - (intptr_t)patchSite) + relocation.r_addend;
261 break;
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500262 case R_X86_64_32S:
263 *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite) + relocation.r_addend;
264 break;
Nicolas Capens66478362016-10-13 15:36:36 -0400265 default:
266 assert(false && "Unsupported relocation type");
267 return nullptr;
268 }
269
270 return symbolValue;
271 }
272
Nicolas Capens598f8d82016-09-26 15:09:10 -0400273 void *loadImage(uint8_t *const elfImage)
274 {
Nicolas Capens598f8d82016-09-26 15:09:10 -0400275 ElfHeader *elfHeader = (ElfHeader*)elfImage;
276
277 if(!elfHeader->checkMagic())
278 {
279 return nullptr;
280 }
281
Nicolas Capens66478362016-10-13 15:36:36 -0400282 // Expect ELF bitness to match platform
Nicolas Capens65047112016-11-07 13:01:07 -0500283 assert(sizeof(void*) == 8 ? elfHeader->getFileClass() == ELFCLASS64 : elfHeader->getFileClass() == ELFCLASS32);
Nicolas Capens66478362016-10-13 15:36:36 -0400284 assert(sizeof(void*) == 8 ? elfHeader->e_machine == EM_X86_64 : elfHeader->e_machine == EM_386);
285
Nicolas Capens598f8d82016-09-26 15:09:10 -0400286 SectionHeader *sectionHeader = (SectionHeader*)(elfImage + elfHeader->e_shoff);
287 void *entry = nullptr;
288
289 for(int i = 0; i < elfHeader->e_shnum; i++)
290 {
Nicolas Capens66478362016-10-13 15:36:36 -0400291 if(sectionHeader[i].sh_type == SHT_PROGBITS)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400292 {
Nicolas Capens66478362016-10-13 15:36:36 -0400293 if(sectionHeader[i].sh_flags & SHF_EXECINSTR)
294 {
295 entry = elfImage + sectionHeader[i].sh_offset;
296 }
297 }
298 else if(sectionHeader[i].sh_type == SHT_REL)
299 {
300 assert(sizeof(void*) == 4 && "UNIMPLEMENTED"); // Only expected/implemented for 32-bit code
301
Alexis Hetu113e33a2017-01-19 10:49:19 -0500302 for(Elf32_Word index = 0; index < sectionHeader[i].sh_size / sectionHeader[i].sh_entsize; index++)
Nicolas Capens66478362016-10-13 15:36:36 -0400303 {
304 const Elf32_Rel &relocation = ((const Elf32_Rel*)(elfImage + sectionHeader[i].sh_offset))[index];
Alexis Hetu113e33a2017-01-19 10:49:19 -0500305 relocateSymbol(elfHeader, relocation, sectionHeader[i]);
Nicolas Capens66478362016-10-13 15:36:36 -0400306 }
307 }
308 else if(sectionHeader[i].sh_type == SHT_RELA)
309 {
310 assert(sizeof(void*) == 8 && "UNIMPLEMENTED"); // Only expected/implemented for 64-bit code
311
Alexis Hetu113e33a2017-01-19 10:49:19 -0500312 for(Elf32_Word index = 0; index < sectionHeader[i].sh_size / sectionHeader[i].sh_entsize; index++)
Nicolas Capens66478362016-10-13 15:36:36 -0400313 {
314 const Elf64_Rela &relocation = ((const Elf64_Rela*)(elfImage + sectionHeader[i].sh_offset))[index];
Alexis Hetu113e33a2017-01-19 10:49:19 -0500315 relocateSymbol(elfHeader, relocation, sectionHeader[i]);
Nicolas Capens66478362016-10-13 15:36:36 -0400316 }
Nicolas Capens598f8d82016-09-26 15:09:10 -0400317 }
318 }
319
320 return entry;
321 }
322
323 template<typename T>
324 struct ExecutableAllocator
325 {
326 ExecutableAllocator() {};
327 template<class U> ExecutableAllocator(const ExecutableAllocator<U> &other) {};
328
329 using value_type = T;
330 using size_type = std::size_t;
331
332 T *allocate(size_type n)
333 {
Nicolas Capensbd65da92017-01-05 16:31:06 -0500334 #if defined(_WIN32)
335 return (T*)VirtualAlloc(NULL, sizeof(T) * n, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
336 #else
337 return (T*)mmap(nullptr, sizeof(T) * n, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
338 #endif
Nicolas Capens598f8d82016-09-26 15:09:10 -0400339 }
340
341 void deallocate(T *p, size_type n)
342 {
Nicolas Capensbd65da92017-01-05 16:31:06 -0500343 #if defined(_WIN32)
344 VirtualFree(p, 0, MEM_RELEASE);
345 #else
346 munmap(p, sizeof(T) * n);
347 #endif
Nicolas Capens598f8d82016-09-26 15:09:10 -0400348 }
349 };
350
351 class ELFMemoryStreamer : public Ice::ELFStreamer, public Routine
352 {
353 ELFMemoryStreamer(const ELFMemoryStreamer &) = delete;
354 ELFMemoryStreamer &operator=(const ELFMemoryStreamer &) = delete;
355
356 public:
Nicolas Capens58274b52016-10-19 23:45:19 -0400357 ELFMemoryStreamer() : Routine(), entry(nullptr)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400358 {
359 position = 0;
360 buffer.reserve(0x1000);
361 }
362
363 virtual ~ELFMemoryStreamer()
364 {
Nicolas Capensbd65da92017-01-05 16:31:06 -0500365 #if defined(_WIN32)
366 if(buffer.size() != 0)
367 {
368 DWORD exeProtection;
369 VirtualProtect(&buffer[0], buffer.size(), oldProtection, &exeProtection);
370 }
371 #endif
Nicolas Capens598f8d82016-09-26 15:09:10 -0400372 }
373
374 void write8(uint8_t Value) override
375 {
376 if(position == (uint64_t)buffer.size())
377 {
378 buffer.push_back(Value);
379 position++;
380 }
381 else if(position < (uint64_t)buffer.size())
382 {
383 buffer[position] = Value;
384 position++;
385 }
386 else assert(false && "UNIMPLEMENTED");
387 }
388
389 void writeBytes(llvm::StringRef Bytes) override
390 {
391 std::size_t oldSize = buffer.size();
392 buffer.resize(oldSize + Bytes.size());
393 memcpy(&buffer[oldSize], Bytes.begin(), Bytes.size());
394 position += Bytes.size();
395 }
396
397 uint64_t tell() const override { return position; }
398
399 void seek(uint64_t Off) override { position = Off; }
400
401 const void *getEntry() override
402 {
Nicolas Capens58274b52016-10-19 23:45:19 -0400403 if(!entry)
404 {
Nicolas Capensbd65da92017-01-05 16:31:06 -0500405 #if defined(_WIN32)
406 VirtualProtect(&buffer[0], buffer.size(), PAGE_EXECUTE_READWRITE, &oldProtection);
407 #else
408 mprotect(&buffer[0], buffer.size(), PROT_READ | PROT_WRITE | PROT_EXEC);
409 #endif
410
411 position = std::numeric_limits<std::size_t>::max(); // Can't stream more data after this
Nicolas Capens598f8d82016-09-26 15:09:10 -0400412
Nicolas Capens58274b52016-10-19 23:45:19 -0400413 entry = loadImage(&buffer[0]);
414 }
415
416 return entry;
Nicolas Capens598f8d82016-09-26 15:09:10 -0400417 }
418
419 private:
Nicolas Capens58274b52016-10-19 23:45:19 -0400420 void *entry;
Nicolas Capens598f8d82016-09-26 15:09:10 -0400421 std::vector<uint8_t, ExecutableAllocator<uint8_t>> buffer;
422 std::size_t position;
Nicolas Capensbd65da92017-01-05 16:31:06 -0500423
424 #if defined(_WIN32)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400425 DWORD oldProtection;
Nicolas Capensbd65da92017-01-05 16:31:06 -0500426 #endif
Nicolas Capens598f8d82016-09-26 15:09:10 -0400427 };
428
429 Nucleus::Nucleus()
430 {
431 ::codegenMutex.lock(); // Reactor is currently not thread safe
432
Nicolas Capens66478362016-10-13 15:36:36 -0400433 Ice::ClFlags &Flags = Ice::ClFlags::Flags;
434 Ice::ClFlags::getParsedClFlags(Flags);
435
436 Flags.setTargetArch(sizeof(void*) == 8 ? Ice::Target_X8664 : Ice::Target_X8632);
437 Flags.setOutFileType(Ice::FT_Elf);
438 Flags.setOptLevel(Ice::Opt_2);
439 Flags.setApplicationBinaryInterface(Ice::ABI_Platform);
Nicolas Capensccd5ecb2017-01-14 12:52:55 -0500440 Flags.setTargetInstructionSet(CPUID::SSE4_1 ? Ice::X86InstructionSet_SSE4_1 : Ice::X86InstructionSet_SSE2);
Nicolas Capens65047112016-11-07 13:01:07 -0500441 Flags.setVerbose(false ? Ice::IceV_All : Ice::IceV_None);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400442
Nicolas Capens65047112016-11-07 13:01:07 -0500443 static llvm::raw_os_ostream cout(std::cout);
444 static llvm::raw_os_ostream cerr(std::cerr);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400445
446 if(false) // Write out to a file
447 {
448 std::error_code errorCode;
449 ::out = new Ice::Fdstream("out.o", errorCode, llvm::sys::fs::F_None);
450 ::elfFile = new Ice::ELFFileStreamer(*out);
Nicolas Capens65047112016-11-07 13:01:07 -0500451 ::context = new Ice::GlobalContext(&cout, &cout, &cerr, elfFile);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400452 }
453 else
454 {
455 ELFMemoryStreamer *elfMemory = new ELFMemoryStreamer();
Nicolas Capens65047112016-11-07 13:01:07 -0500456 ::context = new Ice::GlobalContext(&cout, &cout, &cerr, elfMemory);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400457 ::routine = elfMemory;
458 }
459 }
460
461 Nucleus::~Nucleus()
462 {
463 delete ::allocator;
464 delete ::function;
465 delete ::context;
466
467 delete ::elfFile;
468 delete ::out;
469
470 ::codegenMutex.unlock();
471 }
472
473 Routine *Nucleus::acquireRoutine(const wchar_t *name, bool runOptimizations)
474 {
475 if(basicBlock->getInsts().empty() || basicBlock->getInsts().back().getKind() != Ice::Inst::Ret)
476 {
477 createRetVoid();
478 }
479
480 std::wstring wideName(name);
481 std::string asciiName(wideName.begin(), wideName.end());
482 ::function->setFunctionName(Ice::GlobalString::createWithString(::context, asciiName));
483
Nicolas Capens2ae9d742016-11-24 14:43:05 -0500484 optimize();
485
Nicolas Capens598f8d82016-09-26 15:09:10 -0400486 ::function->translate();
Nicolas Capensde19f392016-10-19 10:29:49 -0400487 assert(!::function->hasError());
488
Nicolas Capens66478362016-10-13 15:36:36 -0400489 auto *globals = ::function->getGlobalInits().release();
490
491 if(globals && !globals->empty())
492 {
493 ::context->getGlobals()->merge(globals);
494 }
Nicolas Capens598f8d82016-09-26 15:09:10 -0400495
496 ::context->emitFileHeader();
497 ::function->emitIAS();
498 auto assembler = ::function->releaseAssembler();
Nicolas Capens66478362016-10-13 15:36:36 -0400499 auto objectWriter = ::context->getObjectWriter();
500 assembler->alignFunction();
501 objectWriter->writeFunctionCode(::function->getFunctionName(), false, assembler.get());
502 ::context->lowerGlobals("last");
Nicolas Capens73dd7a22016-10-20 13:20:34 -0400503 ::context->lowerConstants();
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500504 ::context->lowerJumpTables();
Nicolas Capens66478362016-10-13 15:36:36 -0400505 objectWriter->setUndefinedSyms(::context->getConstantExternSyms());
506 objectWriter->writeNonUserSections();
Nicolas Capens598f8d82016-09-26 15:09:10 -0400507
508 return ::routine;
509 }
510
511 void Nucleus::optimize()
512 {
Nicolas Capens2ae9d742016-11-24 14:43:05 -0500513 sw::optimize(::function);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400514 }
515
516 Value *Nucleus::allocateStackVariable(Type *t, int arraySize)
517 {
518 Ice::Type type = T(t);
Nicolas Capensa8f98632016-10-20 11:25:55 -0400519 int typeSize = Ice::typeWidthInBytes(type);
520 int totalSize = typeSize * (arraySize ? arraySize : 1);
Nicolas Capense12780d2016-09-27 14:18:07 -0400521
Nicolas Capensa8f98632016-10-20 11:25:55 -0400522 auto bytes = Ice::ConstantInteger32::create(::context, type, totalSize);
Nicolas Capense12780d2016-09-27 14:18:07 -0400523 auto address = ::function->makeVariable(T(getPointerType(t)));
Nicolas Capensa8f98632016-10-20 11:25:55 -0400524 auto alloca = Ice::InstAlloca::create(::function, address, bytes, typeSize);
Nicolas Capense12780d2016-09-27 14:18:07 -0400525 ::function->getEntryNode()->getInsts().push_front(alloca);
526
527 return V(address);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400528 }
529
530 BasicBlock *Nucleus::createBasicBlock()
531 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400532 return B(::function->makeNode());
Nicolas Capens598f8d82016-09-26 15:09:10 -0400533 }
534
535 BasicBlock *Nucleus::getInsertBlock()
536 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400537 return B(::basicBlock);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400538 }
539
540 void Nucleus::setInsertBlock(BasicBlock *basicBlock)
541 {
Nicolas Capens9ed1a182016-10-24 09:52:23 -0400542 // assert(::basicBlock->getInsts().back().getTerminatorEdges().size() >= 0 && "Previous basic block must have a terminator");
Nicolas Capens611642a2016-09-28 16:45:04 -0400543 ::basicBlock = basicBlock;
Nicolas Capens598f8d82016-09-26 15:09:10 -0400544 }
545
Nicolas Capens598f8d82016-09-26 15:09:10 -0400546 void Nucleus::createFunction(Type *ReturnType, std::vector<Type*> &Params)
547 {
548 uint32_t sequenceNumber = 0;
549 ::function = Ice::Cfg::create(::context, sequenceNumber).release();
550 ::allocator = new Ice::CfgLocalAllocatorScope(::function);
551
552 for(Type *type : Params)
553 {
554 Ice::Variable *arg = ::function->makeVariable(T(type));
555 ::function->addArg(arg);
556 }
557
558 Ice::CfgNode *node = ::function->makeNode();
559 ::function->setEntryNode(node);
560 ::basicBlock = node;
561 }
562
563 Value *Nucleus::getArgument(unsigned int index)
564 {
565 return V(::function->getArgs()[index]);
566 }
567
568 void Nucleus::createRetVoid()
569 {
Nicolas Capensfdcca2d2016-10-20 11:31:36 -0400570 Ice::InstRet *ret = Ice::InstRet::create(::function);
571 ::basicBlock->appendInst(ret);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400572 }
573
574 void Nucleus::createRet(Value *v)
575 {
Nicolas Capensfdcca2d2016-10-20 11:31:36 -0400576 Ice::InstRet *ret = Ice::InstRet::create(::function, v);
577 ::basicBlock->appendInst(ret);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400578 }
579
580 void Nucleus::createBr(BasicBlock *dest)
581 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400582 auto br = Ice::InstBr::create(::function, dest);
583 ::basicBlock->appendInst(br);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400584 }
585
586 void Nucleus::createCondBr(Value *cond, BasicBlock *ifTrue, BasicBlock *ifFalse)
587 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400588 auto br = Ice::InstBr::create(::function, cond, ifTrue, ifFalse);
589 ::basicBlock->appendInst(br);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400590 }
591
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400592 static Value *createArithmetic(Ice::InstArithmetic::OpKind op, Value *lhs, Value *rhs)
593 {
Nicolas Capens327f1df2016-10-21 14:26:34 -0400594 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 -0400595
596 Ice::Variable *result = ::function->makeVariable(lhs->getType());
597 Ice::InstArithmetic *arithmetic = Ice::InstArithmetic::create(::function, op, result, lhs, rhs);
598 ::basicBlock->appendInst(arithmetic);
599
600 return V(result);
601 }
602
Nicolas Capens598f8d82016-09-26 15:09:10 -0400603 Value *Nucleus::createAdd(Value *lhs, Value *rhs)
604 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400605 return createArithmetic(Ice::InstArithmetic::Add, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400606 }
607
608 Value *Nucleus::createSub(Value *lhs, Value *rhs)
609 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400610 return createArithmetic(Ice::InstArithmetic::Sub, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400611 }
612
613 Value *Nucleus::createMul(Value *lhs, Value *rhs)
614 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400615 return createArithmetic(Ice::InstArithmetic::Mul, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400616 }
617
618 Value *Nucleus::createUDiv(Value *lhs, Value *rhs)
619 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400620 return createArithmetic(Ice::InstArithmetic::Udiv, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400621 }
622
623 Value *Nucleus::createSDiv(Value *lhs, Value *rhs)
624 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400625 return createArithmetic(Ice::InstArithmetic::Sdiv, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400626 }
627
628 Value *Nucleus::createFAdd(Value *lhs, Value *rhs)
629 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400630 return createArithmetic(Ice::InstArithmetic::Fadd, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400631 }
632
633 Value *Nucleus::createFSub(Value *lhs, Value *rhs)
634 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400635 return createArithmetic(Ice::InstArithmetic::Fsub, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400636 }
637
638 Value *Nucleus::createFMul(Value *lhs, Value *rhs)
639 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400640 return createArithmetic(Ice::InstArithmetic::Fmul, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400641 }
642
643 Value *Nucleus::createFDiv(Value *lhs, Value *rhs)
644 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400645 return createArithmetic(Ice::InstArithmetic::Fdiv, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400646 }
647
648 Value *Nucleus::createURem(Value *lhs, Value *rhs)
649 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400650 return createArithmetic(Ice::InstArithmetic::Urem, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400651 }
652
653 Value *Nucleus::createSRem(Value *lhs, Value *rhs)
654 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400655 return createArithmetic(Ice::InstArithmetic::Srem, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400656 }
657
658 Value *Nucleus::createFRem(Value *lhs, Value *rhs)
659 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400660 return createArithmetic(Ice::InstArithmetic::Frem, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400661 }
662
663 Value *Nucleus::createShl(Value *lhs, Value *rhs)
664 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400665 return createArithmetic(Ice::InstArithmetic::Shl, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400666 }
667
668 Value *Nucleus::createLShr(Value *lhs, Value *rhs)
669 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400670 return createArithmetic(Ice::InstArithmetic::Lshr, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400671 }
672
673 Value *Nucleus::createAShr(Value *lhs, Value *rhs)
674 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400675 return createArithmetic(Ice::InstArithmetic::Ashr, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400676 }
677
678 Value *Nucleus::createAnd(Value *lhs, Value *rhs)
679 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400680 return createArithmetic(Ice::InstArithmetic::And, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400681 }
682
683 Value *Nucleus::createOr(Value *lhs, Value *rhs)
684 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400685 return createArithmetic(Ice::InstArithmetic::Or, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400686 }
687
688 Value *Nucleus::createXor(Value *lhs, Value *rhs)
689 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400690 return createArithmetic(Ice::InstArithmetic::Xor, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400691 }
692
693 Value *Nucleus::createNeg(Value *v)
694 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500695 return createSub(createNullValue(T(v->getType())), v);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400696 }
697
698 Value *Nucleus::createFNeg(Value *v)
699 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500700 double c[4] = {-0.0, -0.0, -0.0, -0.0};
701 Value *negativeZero = Ice::isVectorType(v->getType()) ?
702 createConstantVector(c, T(v->getType())) :
Nicolas Capens15060bb2016-12-05 22:17:19 -0500703 V(::context->getConstantFloat(-0.0f));
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500704
705 return createFSub(negativeZero, v);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400706 }
707
708 Value *Nucleus::createNot(Value *v)
709 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500710 if(Ice::isScalarIntegerType(v->getType()))
711 {
Nicolas Capens15060bb2016-12-05 22:17:19 -0500712 return createXor(v, V(::context->getConstantInt(v->getType(), -1)));
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500713 }
714 else // Vector
715 {
716 int64_t c[4] = {-1, -1, -1, -1};
717 return createXor(v, createConstantVector(c, T(v->getType())));
718 }
Nicolas Capens598f8d82016-09-26 15:09:10 -0400719 }
720
Nicolas Capense12780d2016-09-27 14:18:07 -0400721 Value *Nucleus::createLoad(Value *ptr, Type *type, bool isVolatile, unsigned int align)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400722 {
Nicolas Capens23d99a42016-09-30 14:57:16 -0400723 int valueType = (int)reinterpret_cast<intptr_t>(type);
724 Ice::Variable *result = ::function->makeVariable(T(type));
725
726 if(valueType & EmulatedBits)
727 {
728 switch(valueType)
729 {
730 case Type_v4i8:
731 case Type_v2i16:
732 {
733 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::LoadSubVector, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
734 auto target = ::context->getConstantUndef(Ice::IceType_i32);
735 auto load = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
Nicolas Capens23d99a42016-09-30 14:57:16 -0400736 load->addArg(ptr);
Nicolas Capens87852e12016-11-24 14:45:06 -0500737 load->addArg(::context->getConstantInt32(4));
Nicolas Capens23d99a42016-09-30 14:57:16 -0400738 ::basicBlock->appendInst(load);
739 }
740 break;
741 case Type_v2i32:
742 case Type_v8i8:
743 case Type_v4i16:
Nicolas Capens4cfd4572016-10-20 01:00:19 -0400744 case Type_v2f32:
Nicolas Capens23d99a42016-09-30 14:57:16 -0400745 {
746 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::LoadSubVector, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
747 auto target = ::context->getConstantUndef(Ice::IceType_i32);
748 auto load = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
Nicolas Capens23d99a42016-09-30 14:57:16 -0400749 load->addArg(ptr);
Nicolas Capens87852e12016-11-24 14:45:06 -0500750 load->addArg(::context->getConstantInt32(8));
Nicolas Capens23d99a42016-09-30 14:57:16 -0400751 ::basicBlock->appendInst(load);
752 }
753 break;
754 default: assert(false && "UNIMPLEMENTED");
755 }
756 }
757 else
758 {
759 auto load = Ice::InstLoad::create(::function, result, ptr, align);
760 ::basicBlock->appendInst(load);
761 }
762
763 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400764 }
765
Nicolas Capens6d738712016-09-30 04:15:22 -0400766 Value *Nucleus::createStore(Value *value, Value *ptr, Type *type, bool isVolatile, unsigned int align)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400767 {
Nicolas Capens23d99a42016-09-30 14:57:16 -0400768 int valueType = (int)reinterpret_cast<intptr_t>(type);
769
770 if(valueType & EmulatedBits)
771 {
772 switch(valueType)
773 {
774 case Type_v4i8:
775 case Type_v2i16:
776 {
777 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::StoreSubVector, Ice::Intrinsics::SideEffects_T, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_T};
778 auto target = ::context->getConstantUndef(Ice::IceType_i32);
779 auto store = Ice::InstIntrinsicCall::create(::function, 3, nullptr, target, intrinsic);
Nicolas Capens23d99a42016-09-30 14:57:16 -0400780 store->addArg(value);
781 store->addArg(ptr);
Nicolas Capens87852e12016-11-24 14:45:06 -0500782 store->addArg(::context->getConstantInt32(4));
Nicolas Capens23d99a42016-09-30 14:57:16 -0400783 ::basicBlock->appendInst(store);
784 }
785 break;
786 case Type_v2i32:
787 case Type_v8i8:
788 case Type_v4i16:
Nicolas Capens4cfd4572016-10-20 01:00:19 -0400789 case Type_v2f32:
Nicolas Capens23d99a42016-09-30 14:57:16 -0400790 {
791 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::StoreSubVector, Ice::Intrinsics::SideEffects_T, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_T};
792 auto target = ::context->getConstantUndef(Ice::IceType_i32);
793 auto store = Ice::InstIntrinsicCall::create(::function, 3, nullptr, target, intrinsic);
Nicolas Capens23d99a42016-09-30 14:57:16 -0400794 store->addArg(value);
795 store->addArg(ptr);
Nicolas Capens87852e12016-11-24 14:45:06 -0500796 store->addArg(::context->getConstantInt32(8));
Nicolas Capens23d99a42016-09-30 14:57:16 -0400797 ::basicBlock->appendInst(store);
798 }
799 break;
800 default: assert(false && "UNIMPLEMENTED");
801 }
802 }
803 else
804 {
805 assert(T(value->getType()) == type);
806
807 auto store = Ice::InstStore::create(::function, value, ptr, align);
808 ::basicBlock->appendInst(store);
809 }
810
Nicolas Capens598f8d82016-09-26 15:09:10 -0400811 return value;
812 }
813
Nicolas Capens6d738712016-09-30 04:15:22 -0400814 Value *Nucleus::createGEP(Value *ptr, Type *type, Value *index)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400815 {
Nicolas Capens8820f642016-09-30 04:42:43 -0400816 assert(index->getType() == Ice::IceType_i32);
817
Nicolas Capens15060bb2016-12-05 22:17:19 -0500818 if(auto *constant = llvm::dyn_cast<Ice::ConstantInteger32>(index))
819 {
820 int32_t offset = constant->getValue() * (int)Ice::typeWidthInBytes(T(type));
821
822 if(offset == 0)
823 {
824 return ptr;
825 }
826
827 return createAdd(ptr, createConstantInt(offset));
828 }
829
Nicolas Capens8820f642016-09-30 04:42:43 -0400830 if(!Ice::isByteSizedType(T(type)))
831 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400832 index = createMul(index, createConstantInt((int)Ice::typeWidthInBytes(T(type))));
Nicolas Capens8820f642016-09-30 04:42:43 -0400833 }
834
835 if(sizeof(void*) == 8)
836 {
837 index = createSExt(index, T(Ice::IceType_i64));
838 }
839
840 return createAdd(ptr, index);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400841 }
842
843 Value *Nucleus::createAtomicAdd(Value *ptr, Value *value)
844 {
845 assert(false && "UNIMPLEMENTED"); return nullptr;
846 }
847
Nicolas Capensa0c2fc52016-09-30 05:04:21 -0400848 static Value *createCast(Ice::InstCast::OpKind op, Value *v, Type *destType)
849 {
Nicolas Capens23d99a42016-09-30 14:57:16 -0400850 if(v->getType() == T(destType))
Nicolas Capensa0c2fc52016-09-30 05:04:21 -0400851 {
852 return v;
853 }
854
855 Ice::Variable *result = ::function->makeVariable(T(destType));
856 Ice::InstCast *cast = Ice::InstCast::create(::function, op, result, v);
857 ::basicBlock->appendInst(cast);
858
859 return V(result);
860 }
861
Nicolas Capens598f8d82016-09-26 15:09:10 -0400862 Value *Nucleus::createTrunc(Value *v, Type *destType)
863 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -0400864 return createCast(Ice::InstCast::Trunc, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400865 }
866
867 Value *Nucleus::createZExt(Value *v, Type *destType)
868 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -0400869 return createCast(Ice::InstCast::Zext, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400870 }
871
872 Value *Nucleus::createSExt(Value *v, Type *destType)
873 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -0400874 return createCast(Ice::InstCast::Sext, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400875 }
876
877 Value *Nucleus::createFPToSI(Value *v, Type *destType)
878 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -0400879 return createCast(Ice::InstCast::Fptosi, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400880 }
881
Nicolas Capens598f8d82016-09-26 15:09:10 -0400882 Value *Nucleus::createSIToFP(Value *v, Type *destType)
883 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -0400884 return createCast(Ice::InstCast::Sitofp, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400885 }
886
887 Value *Nucleus::createFPTrunc(Value *v, Type *destType)
888 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -0400889 return createCast(Ice::InstCast::Fptrunc, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400890 }
891
892 Value *Nucleus::createFPExt(Value *v, Type *destType)
893 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -0400894 return createCast(Ice::InstCast::Fpext, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400895 }
896
897 Value *Nucleus::createBitCast(Value *v, Type *destType)
898 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -0400899 return createCast(Ice::InstCast::Bitcast, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400900 }
901
Nicolas Capens43dc6292016-10-20 00:01:38 -0400902 static Value *createIntCompare(Ice::InstIcmp::ICond condition, Value *lhs, Value *rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400903 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400904 assert(lhs->getType() == rhs->getType());
905
Nicolas Capens43dc6292016-10-20 00:01:38 -0400906 auto result = ::function->makeVariable(Ice::isScalarIntegerType(lhs->getType()) ? Ice::IceType_i1 : lhs->getType());
907 auto cmp = Ice::InstIcmp::create(::function, condition, result, lhs, rhs);
Nicolas Capens611642a2016-09-28 16:45:04 -0400908 ::basicBlock->appendInst(cmp);
909
910 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400911 }
912
Nicolas Capens43dc6292016-10-20 00:01:38 -0400913 Value *Nucleus::createICmpEQ(Value *lhs, Value *rhs)
914 {
915 return createIntCompare(Ice::InstIcmp::Eq, lhs, rhs);
916 }
917
918 Value *Nucleus::createICmpNE(Value *lhs, Value *rhs)
919 {
920 return createIntCompare(Ice::InstIcmp::Ne, lhs, rhs);
921 }
922
923 Value *Nucleus::createICmpUGT(Value *lhs, Value *rhs)
924 {
925 return createIntCompare(Ice::InstIcmp::Ugt, lhs, rhs);
926 }
927
928 Value *Nucleus::createICmpUGE(Value *lhs, Value *rhs)
929 {
930 return createIntCompare(Ice::InstIcmp::Uge, lhs, rhs);
931 }
932
933 Value *Nucleus::createICmpULT(Value *lhs, Value *rhs)
934 {
935 return createIntCompare(Ice::InstIcmp::Ult, lhs, rhs);
936 }
937
938 Value *Nucleus::createICmpULE(Value *lhs, Value *rhs)
939 {
940 return createIntCompare(Ice::InstIcmp::Ule, lhs, rhs);
941 }
942
943 Value *Nucleus::createICmpSGT(Value *lhs, Value *rhs)
944 {
945 return createIntCompare(Ice::InstIcmp::Sgt, lhs, rhs);
946 }
947
948 Value *Nucleus::createICmpSGE(Value *lhs, Value *rhs)
949 {
950 return createIntCompare(Ice::InstIcmp::Sge, lhs, rhs);
951 }
952
953 Value *Nucleus::createICmpSLT(Value *lhs, Value *rhs)
954 {
955 return createIntCompare(Ice::InstIcmp::Slt, lhs, rhs);
956 }
957
Nicolas Capens598f8d82016-09-26 15:09:10 -0400958 Value *Nucleus::createICmpSLE(Value *lhs, Value *rhs)
959 {
Nicolas Capens43dc6292016-10-20 00:01:38 -0400960 return createIntCompare(Ice::InstIcmp::Sle, lhs, rhs);
961 }
962
963 static Value *createFloatCompare(Ice::InstFcmp::FCond condition, Value *lhs, Value *rhs)
964 {
965 assert(lhs->getType() == rhs->getType());
966 assert(Ice::isScalarFloatingType(lhs->getType()) || lhs->getType() == Ice::IceType_v4f32);
967
968 auto result = ::function->makeVariable(Ice::isScalarFloatingType(lhs->getType()) ? Ice::IceType_i1 : Ice::IceType_v4i32);
969 auto cmp = Ice::InstFcmp::create(::function, condition, result, lhs, rhs);
970 ::basicBlock->appendInst(cmp);
971
972 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400973 }
974
975 Value *Nucleus::createFCmpOEQ(Value *lhs, Value *rhs)
976 {
Nicolas Capens43dc6292016-10-20 00:01:38 -0400977 return createFloatCompare(Ice::InstFcmp::Oeq, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400978 }
979
980 Value *Nucleus::createFCmpOGT(Value *lhs, Value *rhs)
981 {
Nicolas Capens43dc6292016-10-20 00:01:38 -0400982 return createFloatCompare(Ice::InstFcmp::Ogt, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400983 }
984
985 Value *Nucleus::createFCmpOGE(Value *lhs, Value *rhs)
986 {
Nicolas Capens43dc6292016-10-20 00:01:38 -0400987 return createFloatCompare(Ice::InstFcmp::Oge, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400988 }
989
990 Value *Nucleus::createFCmpOLT(Value *lhs, Value *rhs)
991 {
Nicolas Capens43dc6292016-10-20 00:01:38 -0400992 return createFloatCompare(Ice::InstFcmp::Olt, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400993 }
994
995 Value *Nucleus::createFCmpOLE(Value *lhs, Value *rhs)
996 {
Nicolas Capens43dc6292016-10-20 00:01:38 -0400997 return createFloatCompare(Ice::InstFcmp::Ole, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400998 }
999
1000 Value *Nucleus::createFCmpONE(Value *lhs, Value *rhs)
1001 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001002 return createFloatCompare(Ice::InstFcmp::One, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001003 }
1004
1005 Value *Nucleus::createFCmpORD(Value *lhs, Value *rhs)
1006 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001007 return createFloatCompare(Ice::InstFcmp::Ord, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001008 }
1009
1010 Value *Nucleus::createFCmpUNO(Value *lhs, Value *rhs)
1011 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001012 return createFloatCompare(Ice::InstFcmp::Uno, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001013 }
1014
1015 Value *Nucleus::createFCmpUEQ(Value *lhs, Value *rhs)
1016 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001017 return createFloatCompare(Ice::InstFcmp::Ueq, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001018 }
1019
1020 Value *Nucleus::createFCmpUGT(Value *lhs, Value *rhs)
1021 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001022 return createFloatCompare(Ice::InstFcmp::Ugt, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001023 }
1024
1025 Value *Nucleus::createFCmpUGE(Value *lhs, Value *rhs)
1026 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001027 return createFloatCompare(Ice::InstFcmp::Uge, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001028 }
1029
1030 Value *Nucleus::createFCmpULT(Value *lhs, Value *rhs)
1031 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001032 return createFloatCompare(Ice::InstFcmp::Ult, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001033 }
1034
1035 Value *Nucleus::createFCmpULE(Value *lhs, Value *rhs)
1036 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001037 return createFloatCompare(Ice::InstFcmp::Ule, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001038 }
1039
1040 Value *Nucleus::createFCmpUNE(Value *lhs, Value *rhs)
1041 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001042 return createFloatCompare(Ice::InstFcmp::Une, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001043 }
1044
Nicolas Capense95d5342016-09-30 11:37:28 -04001045 Value *Nucleus::createExtractElement(Value *vector, Type *type, int index)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001046 {
Nicolas Capens9709d4f2016-09-30 11:44:14 -04001047 auto result = ::function->makeVariable(T(type));
1048 auto extract = Ice::InstExtractElement::create(::function, result, vector, ::context->getConstantInt32(index));
1049 ::basicBlock->appendInst(extract);
1050
1051 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001052 }
1053
1054 Value *Nucleus::createInsertElement(Value *vector, Value *element, int index)
1055 {
Nicolas Capens9709d4f2016-09-30 11:44:14 -04001056 auto result = ::function->makeVariable(vector->getType());
1057 auto insert = Ice::InstInsertElement::create(::function, result, vector, element, ::context->getConstantInt32(index));
1058 ::basicBlock->appendInst(insert);
1059
1060 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001061 }
1062
Nicolas Capense89cd582016-09-30 14:23:47 -04001063 Value *Nucleus::createShuffleVector(Value *V1, Value *V2, const int *select)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001064 {
Nicolas Capens619c0ab2016-09-30 14:46:24 -04001065 assert(V1->getType() == V2->getType());
1066
1067 int size = Ice::typeNumElements(V1->getType());
1068 auto result = ::function->makeVariable(V1->getType());
1069 auto shuffle = Ice::InstShuffleVector::create(::function, result, V1, V2);
1070
1071 for(int i = 0; i < size; i++)
1072 {
1073 shuffle->addIndex(llvm::cast<Ice::ConstantInteger32>(::context->getConstantInt32(select[i])));
1074 }
1075
1076 ::basicBlock->appendInst(shuffle);
1077
1078 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001079 }
1080
1081 Value *Nucleus::createSelect(Value *C, Value *ifTrue, Value *ifFalse)
1082 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04001083 assert(ifTrue->getType() == ifFalse->getType());
1084
1085 auto result = ::function->makeVariable(ifTrue->getType());
1086 auto *select = Ice::InstSelect::create(::function, result, C, ifTrue, ifFalse);
1087 ::basicBlock->appendInst(select);
1088
1089 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001090 }
1091
Nicolas Capensb98fe5c2016-11-09 12:24:06 -05001092 SwitchCases *Nucleus::createSwitch(Value *control, BasicBlock *defaultBranch, unsigned numCases)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001093 {
Nicolas Capensb98fe5c2016-11-09 12:24:06 -05001094 auto switchInst = Ice::InstSwitch::create(::function, numCases, control, defaultBranch);
1095 ::basicBlock->appendInst(switchInst);
1096
1097 return reinterpret_cast<SwitchCases*>(switchInst);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001098 }
1099
Nicolas Capensb98fe5c2016-11-09 12:24:06 -05001100 void Nucleus::addSwitchCase(SwitchCases *switchCases, int label, BasicBlock *branch)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001101 {
Nicolas Capensb98fe5c2016-11-09 12:24:06 -05001102 switchCases->addBranch(label, label, branch);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001103 }
1104
1105 void Nucleus::createUnreachable()
1106 {
Nicolas Capensfdcca2d2016-10-20 11:31:36 -04001107 Ice::InstUnreachable *unreachable = Ice::InstUnreachable::create(::function);
1108 ::basicBlock->appendInst(unreachable);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001109 }
1110
Nicolas Capense95d5342016-09-30 11:37:28 -04001111 static Value *createSwizzle4(Value *val, unsigned char select)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001112 {
Nicolas Capens619c0ab2016-09-30 14:46:24 -04001113 int swizzle[4] =
1114 {
1115 (select >> 0) & 0x03,
1116 (select >> 2) & 0x03,
1117 (select >> 4) & 0x03,
1118 (select >> 6) & 0x03,
1119 };
Nicolas Capens9709d4f2016-09-30 11:44:14 -04001120
Nicolas Capens619c0ab2016-09-30 14:46:24 -04001121 return Nucleus::createShuffleVector(val, val, swizzle);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001122 }
1123
Nicolas Capense95d5342016-09-30 11:37:28 -04001124 static Value *createMask4(Value *lhs, Value *rhs, unsigned char select)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001125 {
Nicolas Capensa4c30b02016-11-08 15:43:17 -05001126 int64_t mask[4] = {0, 0, 0, 0};
1127
1128 mask[(select >> 0) & 0x03] = -1;
1129 mask[(select >> 2) & 0x03] = -1;
1130 mask[(select >> 4) & 0x03] = -1;
1131 mask[(select >> 6) & 0x03] = -1;
1132
1133 Value *condition = Nucleus::createConstantVector(mask, T(Ice::IceType_v4i1));
1134 Value *result = Nucleus::createSelect(condition, rhs, lhs);
1135
1136 return result;
Nicolas Capens598f8d82016-09-26 15:09:10 -04001137 }
1138
Nicolas Capens598f8d82016-09-26 15:09:10 -04001139 Type *Nucleus::getPointerType(Type *ElementType)
1140 {
Nicolas Capense12780d2016-09-27 14:18:07 -04001141 if(sizeof(void*) == 8)
1142 {
1143 return T(Ice::IceType_i64);
1144 }
1145 else
1146 {
1147 return T(Ice::IceType_i32);
1148 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04001149 }
1150
Nicolas Capens13ac2322016-10-13 14:52:12 -04001151 Value *Nucleus::createNullValue(Type *Ty)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001152 {
Nicolas Capens73dd7a22016-10-20 13:20:34 -04001153 if(Ice::isVectorType(T(Ty)))
1154 {
1155 int64_t c[4] = {0, 0, 0, 0};
1156 return createConstantVector(c, Ty);
1157 }
1158 else
1159 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001160 return V(::context->getConstantZero(T(Ty)));
Nicolas Capens73dd7a22016-10-20 13:20:34 -04001161 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04001162 }
1163
Nicolas Capens13ac2322016-10-13 14:52:12 -04001164 Value *Nucleus::createConstantLong(int64_t i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001165 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001166 return V(::context->getConstantInt64(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001167 }
1168
Nicolas Capens13ac2322016-10-13 14:52:12 -04001169 Value *Nucleus::createConstantInt(int i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001170 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001171 return V(::context->getConstantInt32(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001172 }
1173
Nicolas Capens13ac2322016-10-13 14:52:12 -04001174 Value *Nucleus::createConstantInt(unsigned int i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001175 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001176 return V(::context->getConstantInt32(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001177 }
1178
Nicolas Capens13ac2322016-10-13 14:52:12 -04001179 Value *Nucleus::createConstantBool(bool b)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001180 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001181 return V(::context->getConstantInt1(b));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001182 }
1183
Nicolas Capens13ac2322016-10-13 14:52:12 -04001184 Value *Nucleus::createConstantByte(signed char i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001185 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001186 return V(::context->getConstantInt8(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001187 }
1188
Nicolas Capens13ac2322016-10-13 14:52:12 -04001189 Value *Nucleus::createConstantByte(unsigned char i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001190 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001191 return V(::context->getConstantInt8(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001192 }
1193
Nicolas Capens13ac2322016-10-13 14:52:12 -04001194 Value *Nucleus::createConstantShort(short i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001195 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001196 return V(::context->getConstantInt16(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001197 }
1198
Nicolas Capens13ac2322016-10-13 14:52:12 -04001199 Value *Nucleus::createConstantShort(unsigned short i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001200 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001201 return V(::context->getConstantInt16(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001202 }
1203
Nicolas Capens13ac2322016-10-13 14:52:12 -04001204 Value *Nucleus::createConstantFloat(float x)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001205 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001206 return V(::context->getConstantFloat(x));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001207 }
1208
Nicolas Capens13ac2322016-10-13 14:52:12 -04001209 Value *Nucleus::createNullPointer(Type *Ty)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001210 {
Nicolas Capensa29d6532016-12-05 21:38:09 -05001211 return createNullValue(T(sizeof(void*) == 8 ? Ice::IceType_i64 : Ice::IceType_i32));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001212 }
1213
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001214 Value *Nucleus::createConstantVector(const int64_t *constants, Type *type)
Nicolas Capens13ac2322016-10-13 14:52:12 -04001215 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001216 const int vectorSize = 16;
1217 assert(Ice::typeWidthInBytes(T(type)) == vectorSize);
1218 const int alignment = vectorSize;
1219 auto globalPool = ::function->getGlobalPool();
1220
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001221 const int64_t *i = constants;
1222 const double *f = reinterpret_cast<const double*>(constants);
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001223 Ice::VariableDeclaration::DataInitializer *dataInitializer = nullptr;
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001224
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001225 switch((int)reinterpret_cast<intptr_t>(type))
1226 {
1227 case Ice::IceType_v4i32:
Nicolas Capensa4c30b02016-11-08 15:43:17 -05001228 case Ice::IceType_v4i1:
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001229 {
1230 const int initializer[4] = {(int)i[0], (int)i[1], (int)i[2], (int)i[3]};
1231 static_assert(sizeof(initializer) == vectorSize, "!");
1232 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1233 }
1234 break;
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001235 case Ice::IceType_v4f32:
1236 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001237 const float initializer[4] = {(float)f[0], (float)f[1], (float)f[2], (float)f[3]};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001238 static_assert(sizeof(initializer) == vectorSize, "!");
1239 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1240 }
1241 break;
1242 case Ice::IceType_v8i16:
Nicolas Capensa4c30b02016-11-08 15:43:17 -05001243 case Ice::IceType_v8i1:
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001244 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001245 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 -04001246 static_assert(sizeof(initializer) == vectorSize, "!");
1247 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1248 }
1249 break;
1250 case Ice::IceType_v16i8:
Nicolas Capensa4c30b02016-11-08 15:43:17 -05001251 case Ice::IceType_v16i1:
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001252 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001253 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 -04001254 static_assert(sizeof(initializer) == vectorSize, "!");
1255 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1256 }
1257 break;
1258 case Type_v2i32:
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001259 {
1260 const int initializer[4] = {(int)i[0], (int)i[1], (int)i[0], (int)i[1]};
1261 static_assert(sizeof(initializer) == vectorSize, "!");
1262 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1263 }
1264 break;
Nicolas Capens4cfd4572016-10-20 01:00:19 -04001265 case Type_v2f32:
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001266 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001267 const float initializer[4] = {(float)f[0], (float)f[1], (float)f[0], (float)f[1]};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001268 static_assert(sizeof(initializer) == vectorSize, "!");
1269 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1270 }
1271 break;
1272 case Type_v4i16:
1273 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001274 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 -04001275 static_assert(sizeof(initializer) == vectorSize, "!");
1276 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1277 }
1278 break;
1279 case Type_v8i8:
1280 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001281 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 -04001282 static_assert(sizeof(initializer) == vectorSize, "!");
1283 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1284 }
1285 break;
1286 case Type_v4i8:
1287 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001288 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 -04001289 static_assert(sizeof(initializer) == vectorSize, "!");
1290 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1291 }
1292 break;
1293 default:
1294 assert(false && "Unknown constant vector type" && type);
1295 }
1296
1297 auto name = Ice::GlobalString::createWithoutString(::context);
1298 auto *variableDeclaration = Ice::VariableDeclaration::create(globalPool);
1299 variableDeclaration->setName(name);
1300 variableDeclaration->setAlignment(alignment);
1301 variableDeclaration->setIsConstant(true);
1302 variableDeclaration->addInitializer(dataInitializer);
Nicolas Capens87852e12016-11-24 14:45:06 -05001303
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001304 ::function->addGlobal(variableDeclaration);
1305
1306 constexpr int32_t offset = 0;
1307 Ice::Operand *ptr = ::context->getConstantSym(offset, name);
1308
1309 Ice::Variable *result = ::function->makeVariable(T(type));
1310 auto load = Ice::InstLoad::create(::function, result, ptr, alignment);
1311 ::basicBlock->appendInst(load);
1312
1313 return V(result);
Nicolas Capens13ac2322016-10-13 14:52:12 -04001314 }
1315
1316 Value *Nucleus::createConstantVector(const double *constants, Type *type)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001317 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001318 return createConstantVector((const int64_t*)constants, type);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001319 }
1320
1321 Type *Void::getType()
1322 {
1323 return T(Ice::IceType_void);
1324 }
1325
Nicolas Capens598f8d82016-09-26 15:09:10 -04001326 Bool::Bool(Argument<Bool> argument)
1327 {
1328 storeValue(argument.value);
1329 }
1330
Nicolas Capens598f8d82016-09-26 15:09:10 -04001331 Bool::Bool(bool x)
1332 {
1333 storeValue(Nucleus::createConstantBool(x));
1334 }
1335
1336 Bool::Bool(RValue<Bool> rhs)
1337 {
1338 storeValue(rhs.value);
1339 }
1340
1341 Bool::Bool(const Bool &rhs)
1342 {
1343 Value *value = rhs.loadValue();
1344 storeValue(value);
1345 }
1346
1347 Bool::Bool(const Reference<Bool> &rhs)
1348 {
1349 Value *value = rhs.loadValue();
1350 storeValue(value);
1351 }
1352
Nicolas Capens96d4e092016-11-18 14:22:38 -05001353 RValue<Bool> Bool::operator=(RValue<Bool> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001354 {
1355 storeValue(rhs.value);
1356
1357 return rhs;
1358 }
1359
Nicolas Capens96d4e092016-11-18 14:22:38 -05001360 RValue<Bool> Bool::operator=(const Bool &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001361 {
1362 Value *value = rhs.loadValue();
1363 storeValue(value);
1364
1365 return RValue<Bool>(value);
1366 }
1367
Nicolas Capens96d4e092016-11-18 14:22:38 -05001368 RValue<Bool> Bool::operator=(const Reference<Bool> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001369 {
1370 Value *value = rhs.loadValue();
1371 storeValue(value);
1372
1373 return RValue<Bool>(value);
1374 }
1375
1376 RValue<Bool> operator!(RValue<Bool> val)
1377 {
1378 return RValue<Bool>(Nucleus::createNot(val.value));
1379 }
1380
1381 RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs)
1382 {
1383 return RValue<Bool>(Nucleus::createAnd(lhs.value, rhs.value));
1384 }
1385
1386 RValue<Bool> operator||(RValue<Bool> lhs, RValue<Bool> rhs)
1387 {
1388 return RValue<Bool>(Nucleus::createOr(lhs.value, rhs.value));
1389 }
1390
1391 Type *Bool::getType()
1392 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04001393 return T(Ice::IceType_i1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001394 }
1395
1396 Byte::Byte(Argument<Byte> argument)
1397 {
1398 storeValue(argument.value);
1399 }
1400
1401 Byte::Byte(RValue<Int> cast)
1402 {
1403 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
1404
1405 storeValue(integer);
1406 }
1407
1408 Byte::Byte(RValue<UInt> cast)
1409 {
1410 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
1411
1412 storeValue(integer);
1413 }
1414
1415 Byte::Byte(RValue<UShort> cast)
1416 {
1417 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
1418
1419 storeValue(integer);
1420 }
1421
Nicolas Capens598f8d82016-09-26 15:09:10 -04001422 Byte::Byte(int x)
1423 {
1424 storeValue(Nucleus::createConstantByte((unsigned char)x));
1425 }
1426
1427 Byte::Byte(unsigned char x)
1428 {
1429 storeValue(Nucleus::createConstantByte(x));
1430 }
1431
1432 Byte::Byte(RValue<Byte> rhs)
1433 {
1434 storeValue(rhs.value);
1435 }
1436
1437 Byte::Byte(const Byte &rhs)
1438 {
1439 Value *value = rhs.loadValue();
1440 storeValue(value);
1441 }
1442
1443 Byte::Byte(const Reference<Byte> &rhs)
1444 {
1445 Value *value = rhs.loadValue();
1446 storeValue(value);
1447 }
1448
Nicolas Capens96d4e092016-11-18 14:22:38 -05001449 RValue<Byte> Byte::operator=(RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001450 {
1451 storeValue(rhs.value);
1452
1453 return rhs;
1454 }
1455
Nicolas Capens96d4e092016-11-18 14:22:38 -05001456 RValue<Byte> Byte::operator=(const Byte &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001457 {
1458 Value *value = rhs.loadValue();
1459 storeValue(value);
1460
1461 return RValue<Byte>(value);
1462 }
1463
Nicolas Capens96d4e092016-11-18 14:22:38 -05001464 RValue<Byte> Byte::operator=(const Reference<Byte> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001465 {
1466 Value *value = rhs.loadValue();
1467 storeValue(value);
1468
1469 return RValue<Byte>(value);
1470 }
1471
1472 RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs)
1473 {
1474 return RValue<Byte>(Nucleus::createAdd(lhs.value, rhs.value));
1475 }
1476
1477 RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs)
1478 {
1479 return RValue<Byte>(Nucleus::createSub(lhs.value, rhs.value));
1480 }
1481
1482 RValue<Byte> operator*(RValue<Byte> lhs, RValue<Byte> rhs)
1483 {
1484 return RValue<Byte>(Nucleus::createMul(lhs.value, rhs.value));
1485 }
1486
1487 RValue<Byte> operator/(RValue<Byte> lhs, RValue<Byte> rhs)
1488 {
1489 return RValue<Byte>(Nucleus::createUDiv(lhs.value, rhs.value));
1490 }
1491
1492 RValue<Byte> operator%(RValue<Byte> lhs, RValue<Byte> rhs)
1493 {
1494 return RValue<Byte>(Nucleus::createURem(lhs.value, rhs.value));
1495 }
1496
1497 RValue<Byte> operator&(RValue<Byte> lhs, RValue<Byte> rhs)
1498 {
1499 return RValue<Byte>(Nucleus::createAnd(lhs.value, rhs.value));
1500 }
1501
1502 RValue<Byte> operator|(RValue<Byte> lhs, RValue<Byte> rhs)
1503 {
1504 return RValue<Byte>(Nucleus::createOr(lhs.value, rhs.value));
1505 }
1506
1507 RValue<Byte> operator^(RValue<Byte> lhs, RValue<Byte> rhs)
1508 {
1509 return RValue<Byte>(Nucleus::createXor(lhs.value, rhs.value));
1510 }
1511
1512 RValue<Byte> operator<<(RValue<Byte> lhs, RValue<Byte> rhs)
1513 {
1514 return RValue<Byte>(Nucleus::createShl(lhs.value, rhs.value));
1515 }
1516
1517 RValue<Byte> operator>>(RValue<Byte> lhs, RValue<Byte> rhs)
1518 {
1519 return RValue<Byte>(Nucleus::createLShr(lhs.value, rhs.value));
1520 }
1521
Nicolas Capens96d4e092016-11-18 14:22:38 -05001522 RValue<Byte> operator+=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001523 {
1524 return lhs = lhs + rhs;
1525 }
1526
Nicolas Capens96d4e092016-11-18 14:22:38 -05001527 RValue<Byte> operator-=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001528 {
1529 return lhs = lhs - rhs;
1530 }
1531
Nicolas Capens96d4e092016-11-18 14:22:38 -05001532 RValue<Byte> operator*=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001533 {
1534 return lhs = lhs * rhs;
1535 }
1536
Nicolas Capens96d4e092016-11-18 14:22:38 -05001537 RValue<Byte> operator/=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001538 {
1539 return lhs = lhs / rhs;
1540 }
1541
Nicolas Capens96d4e092016-11-18 14:22:38 -05001542 RValue<Byte> operator%=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001543 {
1544 return lhs = lhs % rhs;
1545 }
1546
Nicolas Capens96d4e092016-11-18 14:22:38 -05001547 RValue<Byte> operator&=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001548 {
1549 return lhs = lhs & rhs;
1550 }
1551
Nicolas Capens96d4e092016-11-18 14:22:38 -05001552 RValue<Byte> operator|=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001553 {
1554 return lhs = lhs | rhs;
1555 }
1556
Nicolas Capens96d4e092016-11-18 14:22:38 -05001557 RValue<Byte> operator^=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001558 {
1559 return lhs = lhs ^ rhs;
1560 }
1561
Nicolas Capens96d4e092016-11-18 14:22:38 -05001562 RValue<Byte> operator<<=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001563 {
1564 return lhs = lhs << rhs;
1565 }
1566
Nicolas Capens96d4e092016-11-18 14:22:38 -05001567 RValue<Byte> operator>>=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001568 {
1569 return lhs = lhs >> rhs;
1570 }
1571
1572 RValue<Byte> operator+(RValue<Byte> val)
1573 {
1574 return val;
1575 }
1576
1577 RValue<Byte> operator-(RValue<Byte> val)
1578 {
1579 return RValue<Byte>(Nucleus::createNeg(val.value));
1580 }
1581
1582 RValue<Byte> operator~(RValue<Byte> val)
1583 {
1584 return RValue<Byte>(Nucleus::createNot(val.value));
1585 }
1586
Nicolas Capens96d4e092016-11-18 14:22:38 -05001587 RValue<Byte> operator++(Byte &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04001588 {
1589 RValue<Byte> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05001590 val += Byte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001591 return res;
1592 }
1593
Nicolas Capens96d4e092016-11-18 14:22:38 -05001594 const Byte &operator++(Byte &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04001595 {
Nicolas Capensd1229402016-11-07 16:05:22 -05001596 val += Byte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001597 return val;
1598 }
1599
Nicolas Capens96d4e092016-11-18 14:22:38 -05001600 RValue<Byte> operator--(Byte &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04001601 {
1602 RValue<Byte> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05001603 val -= Byte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001604 return res;
1605 }
1606
Nicolas Capens96d4e092016-11-18 14:22:38 -05001607 const Byte &operator--(Byte &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04001608 {
Nicolas Capensd1229402016-11-07 16:05:22 -05001609 val -= Byte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001610 return val;
1611 }
1612
1613 RValue<Bool> operator<(RValue<Byte> lhs, RValue<Byte> rhs)
1614 {
1615 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1616 }
1617
1618 RValue<Bool> operator<=(RValue<Byte> lhs, RValue<Byte> rhs)
1619 {
1620 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1621 }
1622
1623 RValue<Bool> operator>(RValue<Byte> lhs, RValue<Byte> rhs)
1624 {
1625 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1626 }
1627
1628 RValue<Bool> operator>=(RValue<Byte> lhs, RValue<Byte> rhs)
1629 {
1630 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1631 }
1632
1633 RValue<Bool> operator!=(RValue<Byte> lhs, RValue<Byte> rhs)
1634 {
1635 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1636 }
1637
1638 RValue<Bool> operator==(RValue<Byte> lhs, RValue<Byte> rhs)
1639 {
1640 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1641 }
1642
1643 Type *Byte::getType()
1644 {
Nicolas Capens6d738712016-09-30 04:15:22 -04001645 return T(Ice::IceType_i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001646 }
1647
1648 SByte::SByte(Argument<SByte> argument)
1649 {
1650 storeValue(argument.value);
1651 }
1652
1653 SByte::SByte(RValue<Int> cast)
1654 {
1655 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1656
1657 storeValue(integer);
1658 }
1659
1660 SByte::SByte(RValue<Short> cast)
1661 {
1662 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1663
1664 storeValue(integer);
1665 }
1666
Nicolas Capens598f8d82016-09-26 15:09:10 -04001667 SByte::SByte(signed char x)
1668 {
1669 storeValue(Nucleus::createConstantByte(x));
1670 }
1671
1672 SByte::SByte(RValue<SByte> rhs)
1673 {
1674 storeValue(rhs.value);
1675 }
1676
1677 SByte::SByte(const SByte &rhs)
1678 {
1679 Value *value = rhs.loadValue();
1680 storeValue(value);
1681 }
1682
1683 SByte::SByte(const Reference<SByte> &rhs)
1684 {
1685 Value *value = rhs.loadValue();
1686 storeValue(value);
1687 }
1688
Nicolas Capens96d4e092016-11-18 14:22:38 -05001689 RValue<SByte> SByte::operator=(RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001690 {
1691 storeValue(rhs.value);
1692
1693 return rhs;
1694 }
1695
Nicolas Capens96d4e092016-11-18 14:22:38 -05001696 RValue<SByte> SByte::operator=(const SByte &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001697 {
1698 Value *value = rhs.loadValue();
1699 storeValue(value);
1700
1701 return RValue<SByte>(value);
1702 }
1703
Nicolas Capens96d4e092016-11-18 14:22:38 -05001704 RValue<SByte> SByte::operator=(const Reference<SByte> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001705 {
1706 Value *value = rhs.loadValue();
1707 storeValue(value);
1708
1709 return RValue<SByte>(value);
1710 }
1711
1712 RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs)
1713 {
1714 return RValue<SByte>(Nucleus::createAdd(lhs.value, rhs.value));
1715 }
1716
1717 RValue<SByte> operator-(RValue<SByte> lhs, RValue<SByte> rhs)
1718 {
1719 return RValue<SByte>(Nucleus::createSub(lhs.value, rhs.value));
1720 }
1721
1722 RValue<SByte> operator*(RValue<SByte> lhs, RValue<SByte> rhs)
1723 {
1724 return RValue<SByte>(Nucleus::createMul(lhs.value, rhs.value));
1725 }
1726
1727 RValue<SByte> operator/(RValue<SByte> lhs, RValue<SByte> rhs)
1728 {
1729 return RValue<SByte>(Nucleus::createSDiv(lhs.value, rhs.value));
1730 }
1731
1732 RValue<SByte> operator%(RValue<SByte> lhs, RValue<SByte> rhs)
1733 {
1734 return RValue<SByte>(Nucleus::createSRem(lhs.value, rhs.value));
1735 }
1736
1737 RValue<SByte> operator&(RValue<SByte> lhs, RValue<SByte> rhs)
1738 {
1739 return RValue<SByte>(Nucleus::createAnd(lhs.value, rhs.value));
1740 }
1741
1742 RValue<SByte> operator|(RValue<SByte> lhs, RValue<SByte> rhs)
1743 {
1744 return RValue<SByte>(Nucleus::createOr(lhs.value, rhs.value));
1745 }
1746
1747 RValue<SByte> operator^(RValue<SByte> lhs, RValue<SByte> rhs)
1748 {
1749 return RValue<SByte>(Nucleus::createXor(lhs.value, rhs.value));
1750 }
1751
1752 RValue<SByte> operator<<(RValue<SByte> lhs, RValue<SByte> rhs)
1753 {
1754 return RValue<SByte>(Nucleus::createShl(lhs.value, rhs.value));
1755 }
1756
1757 RValue<SByte> operator>>(RValue<SByte> lhs, RValue<SByte> rhs)
1758 {
1759 return RValue<SByte>(Nucleus::createAShr(lhs.value, rhs.value));
1760 }
1761
Nicolas Capens96d4e092016-11-18 14:22:38 -05001762 RValue<SByte> operator+=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001763 {
1764 return lhs = lhs + rhs;
1765 }
1766
Nicolas Capens96d4e092016-11-18 14:22:38 -05001767 RValue<SByte> operator-=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001768 {
1769 return lhs = lhs - rhs;
1770 }
1771
Nicolas Capens96d4e092016-11-18 14:22:38 -05001772 RValue<SByte> operator*=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001773 {
1774 return lhs = lhs * rhs;
1775 }
1776
Nicolas Capens96d4e092016-11-18 14:22:38 -05001777 RValue<SByte> operator/=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001778 {
1779 return lhs = lhs / rhs;
1780 }
1781
Nicolas Capens96d4e092016-11-18 14:22:38 -05001782 RValue<SByte> operator%=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001783 {
1784 return lhs = lhs % rhs;
1785 }
1786
Nicolas Capens96d4e092016-11-18 14:22:38 -05001787 RValue<SByte> operator&=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001788 {
1789 return lhs = lhs & rhs;
1790 }
1791
Nicolas Capens96d4e092016-11-18 14:22:38 -05001792 RValue<SByte> operator|=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001793 {
1794 return lhs = lhs | rhs;
1795 }
1796
Nicolas Capens96d4e092016-11-18 14:22:38 -05001797 RValue<SByte> operator^=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001798 {
1799 return lhs = lhs ^ rhs;
1800 }
1801
Nicolas Capens96d4e092016-11-18 14:22:38 -05001802 RValue<SByte> operator<<=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001803 {
1804 return lhs = lhs << rhs;
1805 }
1806
Nicolas Capens96d4e092016-11-18 14:22:38 -05001807 RValue<SByte> operator>>=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001808 {
1809 return lhs = lhs >> rhs;
1810 }
1811
1812 RValue<SByte> operator+(RValue<SByte> val)
1813 {
1814 return val;
1815 }
1816
1817 RValue<SByte> operator-(RValue<SByte> val)
1818 {
1819 return RValue<SByte>(Nucleus::createNeg(val.value));
1820 }
1821
1822 RValue<SByte> operator~(RValue<SByte> val)
1823 {
1824 return RValue<SByte>(Nucleus::createNot(val.value));
1825 }
1826
Nicolas Capens96d4e092016-11-18 14:22:38 -05001827 RValue<SByte> operator++(SByte &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04001828 {
1829 RValue<SByte> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05001830 val += SByte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001831 return res;
1832 }
1833
Nicolas Capens96d4e092016-11-18 14:22:38 -05001834 const SByte &operator++(SByte &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04001835 {
Nicolas Capensd1229402016-11-07 16:05:22 -05001836 val += SByte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001837 return val;
1838 }
1839
Nicolas Capens96d4e092016-11-18 14:22:38 -05001840 RValue<SByte> operator--(SByte &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04001841 {
1842 RValue<SByte> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05001843 val -= SByte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001844 return res;
1845 }
1846
Nicolas Capens96d4e092016-11-18 14:22:38 -05001847 const SByte &operator--(SByte &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04001848 {
Nicolas Capensd1229402016-11-07 16:05:22 -05001849 val -= SByte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001850 return val;
1851 }
1852
1853 RValue<Bool> operator<(RValue<SByte> lhs, RValue<SByte> rhs)
1854 {
1855 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
1856 }
1857
1858 RValue<Bool> operator<=(RValue<SByte> lhs, RValue<SByte> rhs)
1859 {
1860 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
1861 }
1862
1863 RValue<Bool> operator>(RValue<SByte> lhs, RValue<SByte> rhs)
1864 {
1865 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
1866 }
1867
1868 RValue<Bool> operator>=(RValue<SByte> lhs, RValue<SByte> rhs)
1869 {
1870 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
1871 }
1872
1873 RValue<Bool> operator!=(RValue<SByte> lhs, RValue<SByte> rhs)
1874 {
1875 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1876 }
1877
1878 RValue<Bool> operator==(RValue<SByte> lhs, RValue<SByte> rhs)
1879 {
1880 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1881 }
1882
1883 Type *SByte::getType()
1884 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04001885 return T(Ice::IceType_i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001886 }
1887
1888 Short::Short(Argument<Short> argument)
1889 {
1890 storeValue(argument.value);
1891 }
1892
1893 Short::Short(RValue<Int> cast)
1894 {
1895 Value *integer = Nucleus::createTrunc(cast.value, Short::getType());
1896
1897 storeValue(integer);
1898 }
1899
Nicolas Capens598f8d82016-09-26 15:09:10 -04001900 Short::Short(short x)
1901 {
1902 storeValue(Nucleus::createConstantShort(x));
1903 }
1904
1905 Short::Short(RValue<Short> rhs)
1906 {
1907 storeValue(rhs.value);
1908 }
1909
1910 Short::Short(const Short &rhs)
1911 {
1912 Value *value = rhs.loadValue();
1913 storeValue(value);
1914 }
1915
1916 Short::Short(const Reference<Short> &rhs)
1917 {
1918 Value *value = rhs.loadValue();
1919 storeValue(value);
1920 }
1921
Nicolas Capens96d4e092016-11-18 14:22:38 -05001922 RValue<Short> Short::operator=(RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001923 {
1924 storeValue(rhs.value);
1925
1926 return rhs;
1927 }
1928
Nicolas Capens96d4e092016-11-18 14:22:38 -05001929 RValue<Short> Short::operator=(const Short &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001930 {
1931 Value *value = rhs.loadValue();
1932 storeValue(value);
1933
1934 return RValue<Short>(value);
1935 }
1936
Nicolas Capens96d4e092016-11-18 14:22:38 -05001937 RValue<Short> Short::operator=(const Reference<Short> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001938 {
1939 Value *value = rhs.loadValue();
1940 storeValue(value);
1941
1942 return RValue<Short>(value);
1943 }
1944
1945 RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs)
1946 {
1947 return RValue<Short>(Nucleus::createAdd(lhs.value, rhs.value));
1948 }
1949
1950 RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs)
1951 {
1952 return RValue<Short>(Nucleus::createSub(lhs.value, rhs.value));
1953 }
1954
1955 RValue<Short> operator*(RValue<Short> lhs, RValue<Short> rhs)
1956 {
1957 return RValue<Short>(Nucleus::createMul(lhs.value, rhs.value));
1958 }
1959
1960 RValue<Short> operator/(RValue<Short> lhs, RValue<Short> rhs)
1961 {
1962 return RValue<Short>(Nucleus::createSDiv(lhs.value, rhs.value));
1963 }
1964
1965 RValue<Short> operator%(RValue<Short> lhs, RValue<Short> rhs)
1966 {
1967 return RValue<Short>(Nucleus::createSRem(lhs.value, rhs.value));
1968 }
1969
1970 RValue<Short> operator&(RValue<Short> lhs, RValue<Short> rhs)
1971 {
1972 return RValue<Short>(Nucleus::createAnd(lhs.value, rhs.value));
1973 }
1974
1975 RValue<Short> operator|(RValue<Short> lhs, RValue<Short> rhs)
1976 {
1977 return RValue<Short>(Nucleus::createOr(lhs.value, rhs.value));
1978 }
1979
1980 RValue<Short> operator^(RValue<Short> lhs, RValue<Short> rhs)
1981 {
1982 return RValue<Short>(Nucleus::createXor(lhs.value, rhs.value));
1983 }
1984
1985 RValue<Short> operator<<(RValue<Short> lhs, RValue<Short> rhs)
1986 {
1987 return RValue<Short>(Nucleus::createShl(lhs.value, rhs.value));
1988 }
1989
1990 RValue<Short> operator>>(RValue<Short> lhs, RValue<Short> rhs)
1991 {
1992 return RValue<Short>(Nucleus::createAShr(lhs.value, rhs.value));
1993 }
1994
Nicolas Capens96d4e092016-11-18 14:22:38 -05001995 RValue<Short> operator+=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001996 {
1997 return lhs = lhs + rhs;
1998 }
1999
Nicolas Capens96d4e092016-11-18 14:22:38 -05002000 RValue<Short> operator-=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002001 {
2002 return lhs = lhs - rhs;
2003 }
2004
Nicolas Capens96d4e092016-11-18 14:22:38 -05002005 RValue<Short> operator*=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002006 {
2007 return lhs = lhs * rhs;
2008 }
2009
Nicolas Capens96d4e092016-11-18 14:22:38 -05002010 RValue<Short> operator/=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002011 {
2012 return lhs = lhs / rhs;
2013 }
2014
Nicolas Capens96d4e092016-11-18 14:22:38 -05002015 RValue<Short> operator%=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002016 {
2017 return lhs = lhs % rhs;
2018 }
2019
Nicolas Capens96d4e092016-11-18 14:22:38 -05002020 RValue<Short> operator&=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002021 {
2022 return lhs = lhs & rhs;
2023 }
2024
Nicolas Capens96d4e092016-11-18 14:22:38 -05002025 RValue<Short> operator|=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002026 {
2027 return lhs = lhs | rhs;
2028 }
2029
Nicolas Capens96d4e092016-11-18 14:22:38 -05002030 RValue<Short> operator^=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002031 {
2032 return lhs = lhs ^ rhs;
2033 }
2034
Nicolas Capens96d4e092016-11-18 14:22:38 -05002035 RValue<Short> operator<<=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002036 {
2037 return lhs = lhs << rhs;
2038 }
2039
Nicolas Capens96d4e092016-11-18 14:22:38 -05002040 RValue<Short> operator>>=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002041 {
2042 return lhs = lhs >> rhs;
2043 }
2044
2045 RValue<Short> operator+(RValue<Short> val)
2046 {
2047 return val;
2048 }
2049
2050 RValue<Short> operator-(RValue<Short> val)
2051 {
2052 return RValue<Short>(Nucleus::createNeg(val.value));
2053 }
2054
2055 RValue<Short> operator~(RValue<Short> val)
2056 {
2057 return RValue<Short>(Nucleus::createNot(val.value));
2058 }
2059
Nicolas Capens96d4e092016-11-18 14:22:38 -05002060 RValue<Short> operator++(Short &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04002061 {
2062 RValue<Short> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002063 val += Short(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002064 return res;
2065 }
2066
Nicolas Capens96d4e092016-11-18 14:22:38 -05002067 const Short &operator++(Short &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04002068 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002069 val += Short(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002070 return val;
2071 }
2072
Nicolas Capens96d4e092016-11-18 14:22:38 -05002073 RValue<Short> operator--(Short &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04002074 {
2075 RValue<Short> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002076 val -= Short(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002077 return res;
2078 }
2079
Nicolas Capens96d4e092016-11-18 14:22:38 -05002080 const Short &operator--(Short &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04002081 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002082 val -= Short(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002083 return val;
2084 }
2085
2086 RValue<Bool> operator<(RValue<Short> lhs, RValue<Short> rhs)
2087 {
2088 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
2089 }
2090
2091 RValue<Bool> operator<=(RValue<Short> lhs, RValue<Short> rhs)
2092 {
2093 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
2094 }
2095
2096 RValue<Bool> operator>(RValue<Short> lhs, RValue<Short> rhs)
2097 {
2098 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
2099 }
2100
2101 RValue<Bool> operator>=(RValue<Short> lhs, RValue<Short> rhs)
2102 {
2103 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
2104 }
2105
2106 RValue<Bool> operator!=(RValue<Short> lhs, RValue<Short> rhs)
2107 {
2108 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
2109 }
2110
2111 RValue<Bool> operator==(RValue<Short> lhs, RValue<Short> rhs)
2112 {
2113 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
2114 }
2115
2116 Type *Short::getType()
2117 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04002118 return T(Ice::IceType_i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002119 }
2120
2121 UShort::UShort(Argument<UShort> argument)
2122 {
2123 storeValue(argument.value);
2124 }
2125
2126 UShort::UShort(RValue<UInt> cast)
2127 {
2128 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
2129
2130 storeValue(integer);
2131 }
2132
2133 UShort::UShort(RValue<Int> cast)
2134 {
2135 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
2136
2137 storeValue(integer);
2138 }
2139
Nicolas Capens598f8d82016-09-26 15:09:10 -04002140 UShort::UShort(unsigned short x)
2141 {
2142 storeValue(Nucleus::createConstantShort(x));
2143 }
2144
2145 UShort::UShort(RValue<UShort> rhs)
2146 {
2147 storeValue(rhs.value);
2148 }
2149
2150 UShort::UShort(const UShort &rhs)
2151 {
2152 Value *value = rhs.loadValue();
2153 storeValue(value);
2154 }
2155
2156 UShort::UShort(const Reference<UShort> &rhs)
2157 {
2158 Value *value = rhs.loadValue();
2159 storeValue(value);
2160 }
2161
Nicolas Capens96d4e092016-11-18 14:22:38 -05002162 RValue<UShort> UShort::operator=(RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002163 {
2164 storeValue(rhs.value);
2165
2166 return rhs;
2167 }
2168
Nicolas Capens96d4e092016-11-18 14:22:38 -05002169 RValue<UShort> UShort::operator=(const UShort &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002170 {
2171 Value *value = rhs.loadValue();
2172 storeValue(value);
2173
2174 return RValue<UShort>(value);
2175 }
2176
Nicolas Capens96d4e092016-11-18 14:22:38 -05002177 RValue<UShort> UShort::operator=(const Reference<UShort> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002178 {
2179 Value *value = rhs.loadValue();
2180 storeValue(value);
2181
2182 return RValue<UShort>(value);
2183 }
2184
2185 RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs)
2186 {
2187 return RValue<UShort>(Nucleus::createAdd(lhs.value, rhs.value));
2188 }
2189
2190 RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs)
2191 {
2192 return RValue<UShort>(Nucleus::createSub(lhs.value, rhs.value));
2193 }
2194
2195 RValue<UShort> operator*(RValue<UShort> lhs, RValue<UShort> rhs)
2196 {
2197 return RValue<UShort>(Nucleus::createMul(lhs.value, rhs.value));
2198 }
2199
2200 RValue<UShort> operator/(RValue<UShort> lhs, RValue<UShort> rhs)
2201 {
2202 return RValue<UShort>(Nucleus::createUDiv(lhs.value, rhs.value));
2203 }
2204
2205 RValue<UShort> operator%(RValue<UShort> lhs, RValue<UShort> rhs)
2206 {
2207 return RValue<UShort>(Nucleus::createURem(lhs.value, rhs.value));
2208 }
2209
2210 RValue<UShort> operator&(RValue<UShort> lhs, RValue<UShort> rhs)
2211 {
2212 return RValue<UShort>(Nucleus::createAnd(lhs.value, rhs.value));
2213 }
2214
2215 RValue<UShort> operator|(RValue<UShort> lhs, RValue<UShort> rhs)
2216 {
2217 return RValue<UShort>(Nucleus::createOr(lhs.value, rhs.value));
2218 }
2219
2220 RValue<UShort> operator^(RValue<UShort> lhs, RValue<UShort> rhs)
2221 {
2222 return RValue<UShort>(Nucleus::createXor(lhs.value, rhs.value));
2223 }
2224
2225 RValue<UShort> operator<<(RValue<UShort> lhs, RValue<UShort> rhs)
2226 {
2227 return RValue<UShort>(Nucleus::createShl(lhs.value, rhs.value));
2228 }
2229
2230 RValue<UShort> operator>>(RValue<UShort> lhs, RValue<UShort> rhs)
2231 {
2232 return RValue<UShort>(Nucleus::createLShr(lhs.value, rhs.value));
2233 }
2234
Nicolas Capens96d4e092016-11-18 14:22:38 -05002235 RValue<UShort> operator+=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002236 {
2237 return lhs = lhs + rhs;
2238 }
2239
Nicolas Capens96d4e092016-11-18 14:22:38 -05002240 RValue<UShort> operator-=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002241 {
2242 return lhs = lhs - rhs;
2243 }
2244
Nicolas Capens96d4e092016-11-18 14:22:38 -05002245 RValue<UShort> operator*=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002246 {
2247 return lhs = lhs * rhs;
2248 }
2249
Nicolas Capens96d4e092016-11-18 14:22:38 -05002250 RValue<UShort> operator/=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002251 {
2252 return lhs = lhs / rhs;
2253 }
2254
Nicolas Capens96d4e092016-11-18 14:22:38 -05002255 RValue<UShort> operator%=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002256 {
2257 return lhs = lhs % rhs;
2258 }
2259
Nicolas Capens96d4e092016-11-18 14:22:38 -05002260 RValue<UShort> operator&=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002261 {
2262 return lhs = lhs & rhs;
2263 }
2264
Nicolas Capens96d4e092016-11-18 14:22:38 -05002265 RValue<UShort> operator|=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002266 {
2267 return lhs = lhs | rhs;
2268 }
2269
Nicolas Capens96d4e092016-11-18 14:22:38 -05002270 RValue<UShort> operator^=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002271 {
2272 return lhs = lhs ^ rhs;
2273 }
2274
Nicolas Capens96d4e092016-11-18 14:22:38 -05002275 RValue<UShort> operator<<=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002276 {
2277 return lhs = lhs << rhs;
2278 }
2279
Nicolas Capens96d4e092016-11-18 14:22:38 -05002280 RValue<UShort> operator>>=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002281 {
2282 return lhs = lhs >> rhs;
2283 }
2284
2285 RValue<UShort> operator+(RValue<UShort> val)
2286 {
2287 return val;
2288 }
2289
2290 RValue<UShort> operator-(RValue<UShort> val)
2291 {
2292 return RValue<UShort>(Nucleus::createNeg(val.value));
2293 }
2294
2295 RValue<UShort> operator~(RValue<UShort> val)
2296 {
2297 return RValue<UShort>(Nucleus::createNot(val.value));
2298 }
2299
Nicolas Capens96d4e092016-11-18 14:22:38 -05002300 RValue<UShort> operator++(UShort &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04002301 {
2302 RValue<UShort> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002303 val += UShort(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002304 return res;
2305 }
2306
Nicolas Capens96d4e092016-11-18 14:22:38 -05002307 const UShort &operator++(UShort &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04002308 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002309 val += UShort(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002310 return val;
2311 }
2312
Nicolas Capens96d4e092016-11-18 14:22:38 -05002313 RValue<UShort> operator--(UShort &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04002314 {
2315 RValue<UShort> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002316 val -= UShort(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002317 return res;
2318 }
2319
Nicolas Capens96d4e092016-11-18 14:22:38 -05002320 const UShort &operator--(UShort &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04002321 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002322 val -= UShort(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002323 return val;
2324 }
2325
2326 RValue<Bool> operator<(RValue<UShort> lhs, RValue<UShort> rhs)
2327 {
2328 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
2329 }
2330
2331 RValue<Bool> operator<=(RValue<UShort> lhs, RValue<UShort> rhs)
2332 {
2333 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
2334 }
2335
2336 RValue<Bool> operator>(RValue<UShort> lhs, RValue<UShort> rhs)
2337 {
2338 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
2339 }
2340
2341 RValue<Bool> operator>=(RValue<UShort> lhs, RValue<UShort> rhs)
2342 {
2343 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
2344 }
2345
2346 RValue<Bool> operator!=(RValue<UShort> lhs, RValue<UShort> rhs)
2347 {
2348 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
2349 }
2350
2351 RValue<Bool> operator==(RValue<UShort> lhs, RValue<UShort> rhs)
2352 {
2353 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
2354 }
2355
2356 Type *UShort::getType()
2357 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04002358 return T(Ice::IceType_i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002359 }
2360
Nicolas Capens16b5f152016-10-13 13:39:01 -04002361 Byte4::Byte4(RValue<Byte8> cast)
2362 {
Nicolas Capens16b5f152016-10-13 13:39:01 -04002363 storeValue(Nucleus::createBitCast(cast.value, getType()));
2364 }
2365
2366 Byte4::Byte4(const Reference<Byte4> &rhs)
2367 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002368 Value *value = rhs.loadValue();
2369 storeValue(value);
Nicolas Capens16b5f152016-10-13 13:39:01 -04002370 }
2371
Nicolas Capens598f8d82016-09-26 15:09:10 -04002372 Type *Byte4::getType()
2373 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04002374 return T(Type_v4i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002375 }
2376
2377 Type *SByte4::getType()
2378 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04002379 return T(Type_v4i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002380 }
2381
Nicolas Capens598f8d82016-09-26 15:09:10 -04002382 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)
2383 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04002384 int64_t constantVector[8] = {x0, x1, x2, x3, x4, x5, x6, x7};
2385 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002386 }
2387
2388 Byte8::Byte8(RValue<Byte8> rhs)
2389 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002390 storeValue(rhs.value);
2391 }
2392
2393 Byte8::Byte8(const Byte8 &rhs)
2394 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002395 Value *value = rhs.loadValue();
2396 storeValue(value);
2397 }
2398
2399 Byte8::Byte8(const Reference<Byte8> &rhs)
2400 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002401 Value *value = rhs.loadValue();
2402 storeValue(value);
2403 }
2404
Nicolas Capens96d4e092016-11-18 14:22:38 -05002405 RValue<Byte8> Byte8::operator=(RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002406 {
2407 storeValue(rhs.value);
2408
2409 return rhs;
2410 }
2411
Nicolas Capens96d4e092016-11-18 14:22:38 -05002412 RValue<Byte8> Byte8::operator=(const Byte8 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002413 {
2414 Value *value = rhs.loadValue();
2415 storeValue(value);
2416
2417 return RValue<Byte8>(value);
2418 }
2419
Nicolas Capens96d4e092016-11-18 14:22:38 -05002420 RValue<Byte8> Byte8::operator=(const Reference<Byte8> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002421 {
2422 Value *value = rhs.loadValue();
2423 storeValue(value);
2424
2425 return RValue<Byte8>(value);
2426 }
2427
2428 RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs)
2429 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002430 return RValue<Byte8>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002431 }
2432
2433 RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs)
2434 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002435 return RValue<Byte8>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002436 }
2437
2438// RValue<Byte8> operator*(RValue<Byte8> lhs, RValue<Byte8> rhs)
2439// {
2440// return RValue<Byte8>(Nucleus::createMul(lhs.value, rhs.value));
2441// }
2442
2443// RValue<Byte8> operator/(RValue<Byte8> lhs, RValue<Byte8> rhs)
2444// {
2445// return RValue<Byte8>(Nucleus::createUDiv(lhs.value, rhs.value));
2446// }
2447
2448// RValue<Byte8> operator%(RValue<Byte8> lhs, RValue<Byte8> rhs)
2449// {
2450// return RValue<Byte8>(Nucleus::createURem(lhs.value, rhs.value));
2451// }
2452
2453 RValue<Byte8> operator&(RValue<Byte8> lhs, RValue<Byte8> rhs)
2454 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002455 return RValue<Byte8>(Nucleus::createAnd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002456 }
2457
2458 RValue<Byte8> operator|(RValue<Byte8> lhs, RValue<Byte8> rhs)
2459 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002460 return RValue<Byte8>(Nucleus::createOr(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002461 }
2462
2463 RValue<Byte8> operator^(RValue<Byte8> lhs, RValue<Byte8> rhs)
2464 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002465 return RValue<Byte8>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002466 }
2467
2468// RValue<Byte8> operator<<(RValue<Byte8> lhs, unsigned char rhs)
2469// {
Nicolas Capens15060bb2016-12-05 22:17:19 -05002470// return RValue<Byte8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002471// }
2472
2473// RValue<Byte8> operator>>(RValue<Byte8> lhs, unsigned char rhs)
2474// {
Nicolas Capens15060bb2016-12-05 22:17:19 -05002475// return RValue<Byte8>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002476// }
2477
Nicolas Capens96d4e092016-11-18 14:22:38 -05002478 RValue<Byte8> operator+=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002479 {
2480 return lhs = lhs + rhs;
2481 }
2482
Nicolas Capens96d4e092016-11-18 14:22:38 -05002483 RValue<Byte8> operator-=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002484 {
2485 return lhs = lhs - rhs;
2486 }
2487
Nicolas Capens96d4e092016-11-18 14:22:38 -05002488// RValue<Byte8> operator*=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002489// {
2490// return lhs = lhs * rhs;
2491// }
2492
Nicolas Capens96d4e092016-11-18 14:22:38 -05002493// RValue<Byte8> operator/=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002494// {
2495// return lhs = lhs / rhs;
2496// }
2497
Nicolas Capens96d4e092016-11-18 14:22:38 -05002498// RValue<Byte8> operator%=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002499// {
2500// return lhs = lhs % rhs;
2501// }
2502
Nicolas Capens96d4e092016-11-18 14:22:38 -05002503 RValue<Byte8> operator&=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002504 {
2505 return lhs = lhs & rhs;
2506 }
2507
Nicolas Capens96d4e092016-11-18 14:22:38 -05002508 RValue<Byte8> operator|=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002509 {
2510 return lhs = lhs | rhs;
2511 }
2512
Nicolas Capens96d4e092016-11-18 14:22:38 -05002513 RValue<Byte8> operator^=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002514 {
2515 return lhs = lhs ^ rhs;
2516 }
2517
Nicolas Capens96d4e092016-11-18 14:22:38 -05002518// RValue<Byte8> operator<<=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002519// {
2520// return lhs = lhs << rhs;
2521// }
2522
Nicolas Capens96d4e092016-11-18 14:22:38 -05002523// RValue<Byte8> operator>>=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002524// {
2525// return lhs = lhs >> rhs;
2526// }
2527
2528// RValue<Byte8> operator+(RValue<Byte8> val)
2529// {
2530// return val;
2531// }
2532
2533// RValue<Byte8> operator-(RValue<Byte8> val)
2534// {
2535// return RValue<Byte8>(Nucleus::createNeg(val.value));
2536// }
2537
2538 RValue<Byte8> operator~(RValue<Byte8> val)
2539 {
2540 return RValue<Byte8>(Nucleus::createNot(val.value));
2541 }
2542
2543 RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y)
2544 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05002545 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
2546 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2547 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2548 auto paddusb = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
2549 paddusb->addArg(x.value);
2550 paddusb->addArg(y.value);
2551 ::basicBlock->appendInst(paddusb);
2552
2553 return RValue<Byte8>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002554 }
2555
2556 RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y)
2557 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05002558 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
2559 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2560 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2561 auto psubusw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
2562 psubusw->addArg(x.value);
2563 psubusw->addArg(y.value);
2564 ::basicBlock->appendInst(psubusw);
2565
2566 return RValue<Byte8>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002567 }
2568
2569 RValue<Short4> Unpack(RValue<Byte4> x)
2570 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04002571 int shuffle[16] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7}; // Real type is v16i8
2572 return RValue<Short4>(Nucleus::createShuffleVector(x.value, x.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002573 }
2574
2575 RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y)
2576 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04002577 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
2578 return RValue<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002579 }
2580
2581 RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y)
2582 {
Nicolas Capens20e22c42016-10-25 17:32:37 -04002583 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
2584 auto lowHigh = RValue<Byte16>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
2585 return As<Short4>(Swizzle(As<Int4>(lowHigh), 0xEE));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002586 }
2587
2588 RValue<Int> SignMask(RValue<Byte8> x)
2589 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05002590 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
2591 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2592 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2593 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
2594 movmsk->addArg(x.value);
2595 ::basicBlock->appendInst(movmsk);
2596
2597 return RValue<Int>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002598 }
2599
2600// RValue<Byte8> CmpGT(RValue<Byte8> x, RValue<Byte8> y)
2601// {
Nicolas Capens2f970b62016-11-08 14:28:59 -05002602// return RValue<Byte8>(createIntCompare(Ice::InstIcmp::Ugt, x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002603// }
2604
2605 RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y)
2606 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05002607 return RValue<Byte8>(Nucleus::createICmpEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002608 }
2609
2610 Type *Byte8::getType()
2611 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04002612 return T(Type_v8i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002613 }
2614
Nicolas Capens598f8d82016-09-26 15:09:10 -04002615 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)
2616 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04002617 int64_t constantVector[8] = { x0, x1, x2, x3, x4, x5, x6, x7 };
2618 Value *vector = V(Nucleus::createConstantVector(constantVector, getType()));
2619
2620 storeValue(Nucleus::createBitCast(vector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002621 }
2622
Nicolas Capens598f8d82016-09-26 15:09:10 -04002623 SByte8::SByte8(RValue<SByte8> rhs)
2624 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002625 storeValue(rhs.value);
2626 }
2627
2628 SByte8::SByte8(const SByte8 &rhs)
2629 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002630 Value *value = rhs.loadValue();
2631 storeValue(value);
2632 }
2633
2634 SByte8::SByte8(const Reference<SByte8> &rhs)
2635 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002636 Value *value = rhs.loadValue();
2637 storeValue(value);
2638 }
2639
Nicolas Capens96d4e092016-11-18 14:22:38 -05002640 RValue<SByte8> SByte8::operator=(RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002641 {
2642 storeValue(rhs.value);
2643
2644 return rhs;
2645 }
2646
Nicolas Capens96d4e092016-11-18 14:22:38 -05002647 RValue<SByte8> SByte8::operator=(const SByte8 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002648 {
2649 Value *value = rhs.loadValue();
2650 storeValue(value);
2651
2652 return RValue<SByte8>(value);
2653 }
2654
Nicolas Capens96d4e092016-11-18 14:22:38 -05002655 RValue<SByte8> SByte8::operator=(const Reference<SByte8> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002656 {
2657 Value *value = rhs.loadValue();
2658 storeValue(value);
2659
2660 return RValue<SByte8>(value);
2661 }
2662
2663 RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs)
2664 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002665 return RValue<SByte8>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002666 }
2667
2668 RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs)
2669 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002670 return RValue<SByte8>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002671 }
2672
2673// RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs)
2674// {
2675// return RValue<SByte8>(Nucleus::createMul(lhs.value, rhs.value));
2676// }
2677
2678// RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs)
2679// {
2680// return RValue<SByte8>(Nucleus::createSDiv(lhs.value, rhs.value));
2681// }
2682
2683// RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs)
2684// {
2685// return RValue<SByte8>(Nucleus::createSRem(lhs.value, rhs.value));
2686// }
2687
2688 RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs)
2689 {
2690 return RValue<SByte8>(Nucleus::createAnd(lhs.value, rhs.value));
2691 }
2692
2693 RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs)
2694 {
2695 return RValue<SByte8>(Nucleus::createOr(lhs.value, rhs.value));
2696 }
2697
2698 RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs)
2699 {
2700 return RValue<SByte8>(Nucleus::createXor(lhs.value, rhs.value));
2701 }
2702
2703// RValue<SByte8> operator<<(RValue<SByte8> lhs, unsigned char rhs)
2704// {
Nicolas Capens15060bb2016-12-05 22:17:19 -05002705// return RValue<SByte8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002706// }
2707
2708// RValue<SByte8> operator>>(RValue<SByte8> lhs, unsigned char rhs)
2709// {
Nicolas Capens15060bb2016-12-05 22:17:19 -05002710// return RValue<SByte8>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002711// }
2712
Nicolas Capens96d4e092016-11-18 14:22:38 -05002713 RValue<SByte8> operator+=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002714 {
2715 return lhs = lhs + rhs;
2716 }
2717
Nicolas Capens96d4e092016-11-18 14:22:38 -05002718 RValue<SByte8> operator-=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002719 {
2720 return lhs = lhs - rhs;
2721 }
2722
Nicolas Capens96d4e092016-11-18 14:22:38 -05002723// RValue<SByte8> operator*=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002724// {
2725// return lhs = lhs * rhs;
2726// }
2727
Nicolas Capens96d4e092016-11-18 14:22:38 -05002728// RValue<SByte8> operator/=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002729// {
2730// return lhs = lhs / rhs;
2731// }
2732
Nicolas Capens96d4e092016-11-18 14:22:38 -05002733// RValue<SByte8> operator%=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002734// {
2735// return lhs = lhs % rhs;
2736// }
2737
Nicolas Capens96d4e092016-11-18 14:22:38 -05002738 RValue<SByte8> operator&=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002739 {
2740 return lhs = lhs & rhs;
2741 }
2742
Nicolas Capens96d4e092016-11-18 14:22:38 -05002743 RValue<SByte8> operator|=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002744 {
2745 return lhs = lhs | rhs;
2746 }
2747
Nicolas Capens96d4e092016-11-18 14:22:38 -05002748 RValue<SByte8> operator^=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002749 {
2750 return lhs = lhs ^ rhs;
2751 }
2752
Nicolas Capens96d4e092016-11-18 14:22:38 -05002753// RValue<SByte8> operator<<=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002754// {
2755// return lhs = lhs << rhs;
2756// }
2757
Nicolas Capens96d4e092016-11-18 14:22:38 -05002758// RValue<SByte8> operator>>=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002759// {
2760// return lhs = lhs >> rhs;
2761// }
2762
2763// RValue<SByte8> operator+(RValue<SByte8> val)
2764// {
2765// return val;
2766// }
2767
2768// RValue<SByte8> operator-(RValue<SByte8> val)
2769// {
2770// return RValue<SByte8>(Nucleus::createNeg(val.value));
2771// }
2772
2773 RValue<SByte8> operator~(RValue<SByte8> val)
2774 {
2775 return RValue<SByte8>(Nucleus::createNot(val.value));
2776 }
2777
2778 RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y)
2779 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05002780 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
2781 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2782 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2783 auto paddsb = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
2784 paddsb->addArg(x.value);
2785 paddsb->addArg(y.value);
2786 ::basicBlock->appendInst(paddsb);
2787
2788 return RValue<SByte8>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002789 }
2790
2791 RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y)
2792 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05002793 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
2794 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2795 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2796 auto psubsb = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
2797 psubsb->addArg(x.value);
2798 psubsb->addArg(y.value);
2799 ::basicBlock->appendInst(psubsb);
2800
2801 return RValue<SByte8>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002802 }
2803
2804 RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y)
2805 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04002806 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
2807 return RValue<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002808 }
2809
2810 RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y)
2811 {
Nicolas Capens20e22c42016-10-25 17:32:37 -04002812 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
2813 auto lowHigh = RValue<Byte16>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
2814 return As<Short4>(Swizzle(As<Int4>(lowHigh), 0xEE));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002815 }
2816
2817 RValue<Int> SignMask(RValue<SByte8> x)
2818 {
Nicolas Capensf2cb9df2016-10-21 17:26:13 -04002819 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
2820 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2821 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2822 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
2823 movmsk->addArg(x.value);
2824 ::basicBlock->appendInst(movmsk);
2825
2826 return RValue<Int>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002827 }
2828
2829 RValue<Byte8> CmpGT(RValue<SByte8> x, RValue<SByte8> y)
2830 {
Nicolas Capens2f970b62016-11-08 14:28:59 -05002831 return RValue<Byte8>(createIntCompare(Ice::InstIcmp::Sgt, x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002832 }
2833
2834 RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y)
2835 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05002836 return RValue<Byte8>(Nucleus::createICmpEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002837 }
2838
2839 Type *SByte8::getType()
2840 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04002841 return T(Type_v8i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002842 }
2843
2844 Byte16::Byte16(RValue<Byte16> rhs)
2845 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002846 storeValue(rhs.value);
2847 }
2848
2849 Byte16::Byte16(const Byte16 &rhs)
2850 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002851 Value *value = rhs.loadValue();
2852 storeValue(value);
2853 }
2854
2855 Byte16::Byte16(const Reference<Byte16> &rhs)
2856 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002857 Value *value = rhs.loadValue();
2858 storeValue(value);
2859 }
2860
Nicolas Capens96d4e092016-11-18 14:22:38 -05002861 RValue<Byte16> Byte16::operator=(RValue<Byte16> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002862 {
2863 storeValue(rhs.value);
2864
2865 return rhs;
2866 }
2867
Nicolas Capens96d4e092016-11-18 14:22:38 -05002868 RValue<Byte16> Byte16::operator=(const Byte16 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002869 {
2870 Value *value = rhs.loadValue();
2871 storeValue(value);
2872
2873 return RValue<Byte16>(value);
2874 }
2875
Nicolas Capens96d4e092016-11-18 14:22:38 -05002876 RValue<Byte16> Byte16::operator=(const Reference<Byte16> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002877 {
2878 Value *value = rhs.loadValue();
2879 storeValue(value);
2880
2881 return RValue<Byte16>(value);
2882 }
2883
2884 Type *Byte16::getType()
2885 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04002886 return T(Ice::IceType_v16i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002887 }
2888
2889 Type *SByte16::getType()
2890 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04002891 return T(Ice::IceType_v16i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002892 }
2893
Nicolas Capens16b5f152016-10-13 13:39:01 -04002894 Short2::Short2(RValue<Short4> cast)
2895 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05002896 storeValue(Nucleus::createBitCast(cast.value, getType()));
Nicolas Capens16b5f152016-10-13 13:39:01 -04002897 }
2898
2899 Type *Short2::getType()
2900 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04002901 return T(Type_v2i16);
Nicolas Capens16b5f152016-10-13 13:39:01 -04002902 }
2903
2904 UShort2::UShort2(RValue<UShort4> cast)
2905 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05002906 storeValue(Nucleus::createBitCast(cast.value, getType()));
Nicolas Capens16b5f152016-10-13 13:39:01 -04002907 }
2908
2909 Type *UShort2::getType()
2910 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04002911 return T(Type_v2i16);
Nicolas Capens16b5f152016-10-13 13:39:01 -04002912 }
2913
Nicolas Capens598f8d82016-09-26 15:09:10 -04002914 Short4::Short4(RValue<Int> cast)
2915 {
Nicolas Capensd4227962016-11-09 14:24:25 -05002916 Value *vector = loadValue();
Nicolas Capensbf22bbf2017-01-13 17:37:45 -05002917 Value *element = Nucleus::createTrunc(cast.value, Short::getType());
2918 Value *insert = Nucleus::createInsertElement(vector, element, 0);
Nicolas Capensd4227962016-11-09 14:24:25 -05002919 Value *swizzle = Swizzle(RValue<Short4>(insert), 0x00).value;
Nicolas Capens598f8d82016-09-26 15:09:10 -04002920
2921 storeValue(swizzle);
2922 }
2923
2924 Short4::Short4(RValue<Int4> cast)
2925 {
Nicolas Capensd4227962016-11-09 14:24:25 -05002926 int pshufb[16] = {0, 1, 4, 5, 8, 9, 12, 13, 0, 1, 4, 5, 8, 9, 12, 13};
2927 Value *byte16 = Nucleus::createBitCast(cast.value, Byte16::getType());
2928 Value *packed = Nucleus::createShuffleVector(byte16, byte16, pshufb);
2929
2930 Value *int2 = RValue<Int2>(Int2(RValue<Int4>(packed))).value;
2931 Value *short4 = Nucleus::createBitCast(int2, Short4::getType());
2932
2933 storeValue(short4);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002934 }
2935
2936// Short4::Short4(RValue<Float> cast)
2937// {
2938// }
2939
2940 Short4::Short4(RValue<Float4> cast)
2941 {
2942 assert(false && "UNIMPLEMENTED");
2943 }
2944
Nicolas Capens598f8d82016-09-26 15:09:10 -04002945 Short4::Short4(short xyzw)
2946 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04002947 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
2948 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002949 }
2950
2951 Short4::Short4(short x, short y, short z, short w)
2952 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04002953 int64_t constantVector[4] = {x, y, z, w};
2954 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002955 }
2956
2957 Short4::Short4(RValue<Short4> rhs)
2958 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002959 storeValue(rhs.value);
2960 }
2961
2962 Short4::Short4(const Short4 &rhs)
2963 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002964 Value *value = rhs.loadValue();
2965 storeValue(value);
2966 }
2967
2968 Short4::Short4(const Reference<Short4> &rhs)
2969 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002970 Value *value = rhs.loadValue();
2971 storeValue(value);
2972 }
2973
2974 Short4::Short4(RValue<UShort4> rhs)
2975 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002976 storeValue(rhs.value);
2977 }
2978
2979 Short4::Short4(const UShort4 &rhs)
2980 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002981 storeValue(rhs.loadValue());
2982 }
2983
2984 Short4::Short4(const Reference<UShort4> &rhs)
2985 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002986 storeValue(rhs.loadValue());
2987 }
2988
Nicolas Capens96d4e092016-11-18 14:22:38 -05002989 RValue<Short4> Short4::operator=(RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002990 {
2991 storeValue(rhs.value);
2992
2993 return rhs;
2994 }
2995
Nicolas Capens96d4e092016-11-18 14:22:38 -05002996 RValue<Short4> Short4::operator=(const Short4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002997 {
2998 Value *value = rhs.loadValue();
2999 storeValue(value);
3000
3001 return RValue<Short4>(value);
3002 }
3003
Nicolas Capens96d4e092016-11-18 14:22:38 -05003004 RValue<Short4> Short4::operator=(const Reference<Short4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003005 {
3006 Value *value = rhs.loadValue();
3007 storeValue(value);
3008
3009 return RValue<Short4>(value);
3010 }
3011
Nicolas Capens96d4e092016-11-18 14:22:38 -05003012 RValue<Short4> Short4::operator=(RValue<UShort4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003013 {
3014 storeValue(rhs.value);
3015
3016 return RValue<Short4>(rhs);
3017 }
3018
Nicolas Capens96d4e092016-11-18 14:22:38 -05003019 RValue<Short4> Short4::operator=(const UShort4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003020 {
3021 Value *value = rhs.loadValue();
3022 storeValue(value);
3023
3024 return RValue<Short4>(value);
3025 }
3026
Nicolas Capens96d4e092016-11-18 14:22:38 -05003027 RValue<Short4> Short4::operator=(const Reference<UShort4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003028 {
3029 Value *value = rhs.loadValue();
3030 storeValue(value);
3031
3032 return RValue<Short4>(value);
3033 }
3034
3035 RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs)
3036 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003037 return RValue<Short4>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003038 }
3039
3040 RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs)
3041 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003042 return RValue<Short4>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003043 }
3044
3045 RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs)
3046 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003047 return RValue<Short4>(Nucleus::createMul(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003048 }
3049
3050// RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs)
3051// {
3052// return RValue<Short4>(Nucleus::createSDiv(lhs.value, rhs.value));
3053// }
3054
3055// RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs)
3056// {
3057// return RValue<Short4>(Nucleus::createSRem(lhs.value, rhs.value));
3058// }
3059
3060 RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs)
3061 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003062 return RValue<Short4>(Nucleus::createAnd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003063 }
3064
3065 RValue<Short4> operator|(RValue<Short4> lhs, RValue<Short4> rhs)
3066 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003067 return RValue<Short4>(Nucleus::createOr(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003068 }
3069
3070 RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs)
3071 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003072 return RValue<Short4>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003073 }
3074
3075 RValue<Short4> operator<<(RValue<Short4> lhs, unsigned char rhs)
3076 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05003077 return RValue<Short4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003078 }
3079
3080 RValue<Short4> operator>>(RValue<Short4> lhs, unsigned char rhs)
3081 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05003082 return RValue<Short4>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003083 }
3084
Nicolas Capens96d4e092016-11-18 14:22:38 -05003085 RValue<Short4> operator+=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003086 {
3087 return lhs = lhs + rhs;
3088 }
3089
Nicolas Capens96d4e092016-11-18 14:22:38 -05003090 RValue<Short4> operator-=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003091 {
3092 return lhs = lhs - rhs;
3093 }
3094
Nicolas Capens96d4e092016-11-18 14:22:38 -05003095 RValue<Short4> operator*=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003096 {
3097 return lhs = lhs * rhs;
3098 }
3099
Nicolas Capens96d4e092016-11-18 14:22:38 -05003100// RValue<Short4> operator/=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003101// {
3102// return lhs = lhs / rhs;
3103// }
3104
Nicolas Capens96d4e092016-11-18 14:22:38 -05003105// RValue<Short4> operator%=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003106// {
3107// return lhs = lhs % rhs;
3108// }
3109
Nicolas Capens96d4e092016-11-18 14:22:38 -05003110 RValue<Short4> operator&=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003111 {
3112 return lhs = lhs & rhs;
3113 }
3114
Nicolas Capens96d4e092016-11-18 14:22:38 -05003115 RValue<Short4> operator|=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003116 {
3117 return lhs = lhs | rhs;
3118 }
3119
Nicolas Capens96d4e092016-11-18 14:22:38 -05003120 RValue<Short4> operator^=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003121 {
3122 return lhs = lhs ^ rhs;
3123 }
3124
Nicolas Capens96d4e092016-11-18 14:22:38 -05003125 RValue<Short4> operator<<=(Short4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003126 {
3127 return lhs = lhs << rhs;
3128 }
3129
Nicolas Capens96d4e092016-11-18 14:22:38 -05003130 RValue<Short4> operator>>=(Short4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003131 {
3132 return lhs = lhs >> rhs;
3133 }
3134
Nicolas Capens598f8d82016-09-26 15:09:10 -04003135// RValue<Short4> operator+(RValue<Short4> val)
3136// {
3137// return val;
3138// }
3139
3140 RValue<Short4> operator-(RValue<Short4> val)
3141 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -05003142 return RValue<Short4>(Nucleus::createNeg(val.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003143 }
3144
3145 RValue<Short4> operator~(RValue<Short4> val)
3146 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -05003147 return RValue<Short4>(Nucleus::createNot(val.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003148 }
3149
3150 RValue<Short4> RoundShort4(RValue<Float4> cast)
3151 {
Nicolas Capensd4227962016-11-09 14:24:25 -05003152 RValue<Int4> int4 = RoundInt(cast);
3153 return As<Short4>(Pack(int4, int4));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003154 }
3155
3156 RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y)
3157 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04003158 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3159 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sle, condition, x.value, y.value);
3160 ::basicBlock->appendInst(cmp);
3161
3162 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3163 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3164 ::basicBlock->appendInst(select);
3165
3166 return RValue<Short4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003167 }
3168
3169 RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y)
3170 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04003171 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3172 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sgt, condition, x.value, y.value);
3173 ::basicBlock->appendInst(cmp);
3174
3175 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3176 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3177 ::basicBlock->appendInst(select);
3178
3179 return RValue<Short4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003180 }
3181
3182 RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y)
3183 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05003184 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3185 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3186 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3187 auto paddsw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3188 paddsw->addArg(x.value);
3189 paddsw->addArg(y.value);
3190 ::basicBlock->appendInst(paddsw);
3191
3192 return RValue<Short4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003193 }
3194
3195 RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y)
3196 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05003197 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3198 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3199 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3200 auto psubsw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3201 psubsw->addArg(x.value);
3202 psubsw->addArg(y.value);
3203 ::basicBlock->appendInst(psubsw);
3204
3205 return RValue<Short4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003206 }
3207
3208 RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y)
3209 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05003210 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3211 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::MultiplyHighSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3212 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3213 auto pmulhw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3214 pmulhw->addArg(x.value);
3215 pmulhw->addArg(y.value);
3216 ::basicBlock->appendInst(pmulhw);
3217
Nicolas Capens5b41ba32016-12-08 14:34:00 -05003218 return RValue<Short4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003219 }
3220
3221 RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y)
3222 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05003223 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3224 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::MultiplyAddPairs, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3225 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3226 auto pmaddwd = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3227 pmaddwd->addArg(x.value);
3228 pmaddwd->addArg(y.value);
3229 ::basicBlock->appendInst(pmaddwd);
3230
3231 return RValue<Int2>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003232 }
3233
3234 RValue<SByte8> Pack(RValue<Short4> x, RValue<Short4> y)
3235 {
Nicolas Capensec54a172016-10-25 17:32:37 -04003236 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
3237 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3238 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3239 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3240 pack->addArg(x.value);
3241 pack->addArg(y.value);
3242 ::basicBlock->appendInst(pack);
3243
Nicolas Capens70dfff42016-10-27 10:20:28 -04003244 return As<SByte8>(Swizzle(As<Int4>(V(result)), 0x88));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003245 }
3246
3247 RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y)
3248 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04003249 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11}; // Real type is v8i16
3250 return RValue<Int2>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003251 }
3252
3253 RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y)
3254 {
Nicolas Capens20e22c42016-10-25 17:32:37 -04003255 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11}; // Real type is v8i16
3256 auto lowHigh = RValue<Short8>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
3257 return As<Int2>(Swizzle(As<Int4>(lowHigh), 0xEE));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003258 }
3259
3260 RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select)
3261 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04003262 // Real type is v8i16
3263 int shuffle[8] =
3264 {
3265 (select >> 0) & 0x03,
3266 (select >> 2) & 0x03,
3267 (select >> 4) & 0x03,
3268 (select >> 6) & 0x03,
3269 (select >> 0) & 0x03,
3270 (select >> 2) & 0x03,
3271 (select >> 4) & 0x03,
3272 (select >> 6) & 0x03,
3273 };
3274
3275 return RValue<Short4>(Nucleus::createShuffleVector(x.value, x.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003276 }
3277
3278 RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i)
3279 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05003280 return RValue<Short4>(Nucleus::createInsertElement(val.value, element.value, i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003281 }
3282
3283 RValue<Short> Extract(RValue<Short4> val, int i)
3284 {
Nicolas Capens0133d0f2017-01-16 16:25:08 -05003285 return RValue<Short>(Nucleus::createExtractElement(val.value, Short::getType(), i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003286 }
3287
3288 RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y)
3289 {
Nicolas Capens2f970b62016-11-08 14:28:59 -05003290 return RValue<Short4>(createIntCompare(Ice::InstIcmp::Sgt, x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003291 }
3292
3293 RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y)
3294 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05003295 return RValue<Short4>(Nucleus::createICmpEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003296 }
3297
3298 Type *Short4::getType()
3299 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04003300 return T(Type_v4i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003301 }
3302
3303 UShort4::UShort4(RValue<Int4> cast)
3304 {
3305 *this = Short4(cast);
3306 }
3307
3308 UShort4::UShort4(RValue<Float4> cast, bool saturate)
3309 {
Nicolas Capensd4227962016-11-09 14:24:25 -05003310 if(saturate)
3311 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05003312 if(CPUID::SSE4_1)
Nicolas Capensd4227962016-11-09 14:24:25 -05003313 {
3314 Int4 int4(Min(cast, Float4(0xFFFF))); // packusdw takes care of 0x0000 saturation
3315 *this = As<Short4>(Pack(As<UInt4>(int4), As<UInt4>(int4)));
3316 }
3317 else
3318 {
3319 *this = Short4(Int4(Max(Min(cast, Float4(0xFFFF)), Float4(0x0000))));
3320 }
3321 }
3322 else
3323 {
3324 *this = Short4(Int4(cast));
3325 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003326 }
3327
Nicolas Capens598f8d82016-09-26 15:09:10 -04003328 UShort4::UShort4(unsigned short xyzw)
3329 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04003330 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
3331 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003332 }
3333
3334 UShort4::UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w)
3335 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04003336 int64_t constantVector[4] = {x, y, z, w};
3337 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003338 }
3339
3340 UShort4::UShort4(RValue<UShort4> rhs)
3341 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003342 storeValue(rhs.value);
3343 }
3344
3345 UShort4::UShort4(const UShort4 &rhs)
3346 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003347 Value *value = rhs.loadValue();
3348 storeValue(value);
3349 }
3350
3351 UShort4::UShort4(const Reference<UShort4> &rhs)
3352 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003353 Value *value = rhs.loadValue();
3354 storeValue(value);
3355 }
3356
3357 UShort4::UShort4(RValue<Short4> rhs)
3358 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003359 storeValue(rhs.value);
3360 }
3361
3362 UShort4::UShort4(const Short4 &rhs)
3363 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003364 Value *value = rhs.loadValue();
3365 storeValue(value);
3366 }
3367
3368 UShort4::UShort4(const Reference<Short4> &rhs)
3369 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003370 Value *value = rhs.loadValue();
3371 storeValue(value);
3372 }
3373
Nicolas Capens96d4e092016-11-18 14:22:38 -05003374 RValue<UShort4> UShort4::operator=(RValue<UShort4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003375 {
3376 storeValue(rhs.value);
3377
3378 return rhs;
3379 }
3380
Nicolas Capens96d4e092016-11-18 14:22:38 -05003381 RValue<UShort4> UShort4::operator=(const UShort4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003382 {
3383 Value *value = rhs.loadValue();
3384 storeValue(value);
3385
3386 return RValue<UShort4>(value);
3387 }
3388
Nicolas Capens96d4e092016-11-18 14:22:38 -05003389 RValue<UShort4> UShort4::operator=(const Reference<UShort4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003390 {
3391 Value *value = rhs.loadValue();
3392 storeValue(value);
3393
3394 return RValue<UShort4>(value);
3395 }
3396
Nicolas Capens96d4e092016-11-18 14:22:38 -05003397 RValue<UShort4> UShort4::operator=(RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003398 {
3399 storeValue(rhs.value);
3400
3401 return RValue<UShort4>(rhs);
3402 }
3403
Nicolas Capens96d4e092016-11-18 14:22:38 -05003404 RValue<UShort4> UShort4::operator=(const Short4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003405 {
3406 Value *value = rhs.loadValue();
3407 storeValue(value);
3408
3409 return RValue<UShort4>(value);
3410 }
3411
Nicolas Capens96d4e092016-11-18 14:22:38 -05003412 RValue<UShort4> UShort4::operator=(const Reference<Short4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003413 {
3414 Value *value = rhs.loadValue();
3415 storeValue(value);
3416
3417 return RValue<UShort4>(value);
3418 }
3419
3420 RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs)
3421 {
Nicolas Capens5b41ba32016-12-08 14:34:00 -05003422 return RValue<UShort4>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003423 }
3424
3425 RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs)
3426 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003427 return RValue<UShort4>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003428 }
3429
3430 RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs)
3431 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003432 return RValue<UShort4>(Nucleus::createMul(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003433 }
3434
Nicolas Capens16b5f152016-10-13 13:39:01 -04003435 RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs)
3436 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003437 return RValue<UShort4>(Nucleus::createAnd(lhs.value, rhs.value));
Nicolas Capens16b5f152016-10-13 13:39:01 -04003438 }
3439
3440 RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs)
3441 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003442 return RValue<UShort4>(Nucleus::createOr(lhs.value, rhs.value));
Nicolas Capens16b5f152016-10-13 13:39:01 -04003443 }
3444
3445 RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs)
3446 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003447 return RValue<UShort4>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens16b5f152016-10-13 13:39:01 -04003448 }
3449
Nicolas Capens598f8d82016-09-26 15:09:10 -04003450 RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs)
3451 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05003452 return RValue<UShort4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003453 }
3454
3455 RValue<UShort4> operator>>(RValue<UShort4> lhs, unsigned char rhs)
3456 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05003457 return RValue<UShort4>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003458 }
3459
Nicolas Capens96d4e092016-11-18 14:22:38 -05003460 RValue<UShort4> operator<<=(UShort4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003461 {
3462 return lhs = lhs << rhs;
3463 }
3464
Nicolas Capens96d4e092016-11-18 14:22:38 -05003465 RValue<UShort4> operator>>=(UShort4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003466 {
3467 return lhs = lhs >> rhs;
3468 }
3469
Nicolas Capens598f8d82016-09-26 15:09:10 -04003470 RValue<UShort4> operator~(RValue<UShort4> val)
3471 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -05003472 return RValue<UShort4>(Nucleus::createNot(val.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003473 }
3474
3475 RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y)
3476 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04003477 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3478 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ule, condition, x.value, y.value);
3479 ::basicBlock->appendInst(cmp);
3480
3481 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3482 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3483 ::basicBlock->appendInst(select);
3484
3485 return RValue<UShort4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003486 }
3487
3488 RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y)
3489 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04003490 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3491 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ugt, condition, x.value, y.value);
3492 ::basicBlock->appendInst(cmp);
3493
3494 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3495 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3496 ::basicBlock->appendInst(select);
3497
3498 return RValue<UShort4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003499 }
3500
3501 RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y)
3502 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05003503 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3504 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3505 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3506 auto paddusw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3507 paddusw->addArg(x.value);
3508 paddusw->addArg(y.value);
3509 ::basicBlock->appendInst(paddusw);
3510
3511 return RValue<UShort4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003512 }
3513
3514 RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y)
3515 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05003516 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3517 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3518 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3519 auto psubusw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3520 psubusw->addArg(x.value);
3521 psubusw->addArg(y.value);
3522 ::basicBlock->appendInst(psubusw);
3523
3524 return RValue<UShort4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003525 }
3526
3527 RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y)
3528 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05003529 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3530 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::MultiplyHighUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3531 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3532 auto pmulhuw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3533 pmulhuw->addArg(x.value);
3534 pmulhuw->addArg(y.value);
3535 ::basicBlock->appendInst(pmulhuw);
3536
3537 return RValue<UShort4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003538 }
3539
3540 RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y)
3541 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003542 assert(false && "UNIMPLEMENTED"); return RValue<UShort4>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003543 }
3544
3545 RValue<Byte8> Pack(RValue<UShort4> x, RValue<UShort4> y)
3546 {
Nicolas Capensec54a172016-10-25 17:32:37 -04003547 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
3548 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3549 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3550 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3551 pack->addArg(x.value);
3552 pack->addArg(y.value);
3553 ::basicBlock->appendInst(pack);
3554
Nicolas Capens70dfff42016-10-27 10:20:28 -04003555 return As<Byte8>(Swizzle(As<Int4>(V(result)), 0x88));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003556 }
3557
3558 Type *UShort4::getType()
3559 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04003560 return T(Type_v4i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003561 }
3562
Nicolas Capens3e7062b2017-01-17 14:01:33 -05003563 Short8::Short8(short c)
3564 {
3565 int64_t constantVector[8] = {c, c, c, c, c, c, c, c};
3566 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3567 }
3568
Nicolas Capens598f8d82016-09-26 15:09:10 -04003569 Short8::Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7)
3570 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04003571 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
3572 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003573 }
3574
3575 Short8::Short8(RValue<Short8> rhs)
3576 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003577 storeValue(rhs.value);
3578 }
3579
3580 Short8::Short8(const Reference<Short8> &rhs)
3581 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003582 Value *value = rhs.loadValue();
3583 storeValue(value);
3584 }
3585
3586 Short8::Short8(RValue<Short4> lo, RValue<Short4> hi)
3587 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05003588 int shuffle[8] = {0, 1, 2, 3, 8, 9, 10, 11}; // Real type is v8i16
3589 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
3590
3591 storeValue(packed);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003592 }
3593
3594 RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs)
3595 {
3596 return RValue<Short8>(Nucleus::createAdd(lhs.value, rhs.value));
3597 }
3598
3599 RValue<Short8> operator&(RValue<Short8> lhs, RValue<Short8> rhs)
3600 {
3601 return RValue<Short8>(Nucleus::createAnd(lhs.value, rhs.value));
3602 }
3603
3604 RValue<Short8> operator<<(RValue<Short8> lhs, unsigned char rhs)
3605 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05003606 return RValue<Short8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003607 }
3608
3609 RValue<Short8> operator>>(RValue<Short8> lhs, unsigned char rhs)
3610 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05003611 return RValue<Short8>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003612 }
3613
3614 RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y)
3615 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003616 assert(false && "UNIMPLEMENTED"); return RValue<Int4>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003617 }
3618
3619 RValue<Int4> Abs(RValue<Int4> x)
3620 {
Nicolas Capens84272242016-11-09 13:31:06 -05003621 auto negative = x >> 31;
3622 return (x ^ negative) - negative;
Nicolas Capens598f8d82016-09-26 15:09:10 -04003623 }
3624
3625 RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y)
3626 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003627 assert(false && "UNIMPLEMENTED"); return RValue<Short8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003628 }
3629
3630 Type *Short8::getType()
3631 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04003632 return T(Ice::IceType_v8i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003633 }
3634
Nicolas Capens3e7062b2017-01-17 14:01:33 -05003635 UShort8::UShort8(unsigned short c)
3636 {
3637 int64_t constantVector[8] = {c, c, c, c, c, c, c, c};
3638 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3639 }
3640
Nicolas Capens598f8d82016-09-26 15:09:10 -04003641 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)
3642 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04003643 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
3644 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003645 }
3646
3647 UShort8::UShort8(RValue<UShort8> rhs)
3648 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003649 storeValue(rhs.value);
3650 }
3651
3652 UShort8::UShort8(const Reference<UShort8> &rhs)
3653 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003654 Value *value = rhs.loadValue();
3655 storeValue(value);
3656 }
3657
3658 UShort8::UShort8(RValue<UShort4> lo, RValue<UShort4> hi)
3659 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05003660 int shuffle[8] = {0, 1, 2, 3, 8, 9, 10, 11}; // Real type is v8i16
3661 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
3662
3663 storeValue(packed);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003664 }
3665
Nicolas Capens96d4e092016-11-18 14:22:38 -05003666 RValue<UShort8> UShort8::operator=(RValue<UShort8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003667 {
3668 storeValue(rhs.value);
3669
3670 return rhs;
3671 }
3672
Nicolas Capens96d4e092016-11-18 14:22:38 -05003673 RValue<UShort8> UShort8::operator=(const UShort8 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003674 {
3675 Value *value = rhs.loadValue();
3676 storeValue(value);
3677
3678 return RValue<UShort8>(value);
3679 }
3680
Nicolas Capens96d4e092016-11-18 14:22:38 -05003681 RValue<UShort8> UShort8::operator=(const Reference<UShort8> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003682 {
3683 Value *value = rhs.loadValue();
3684 storeValue(value);
3685
3686 return RValue<UShort8>(value);
3687 }
3688
3689 RValue<UShort8> operator&(RValue<UShort8> lhs, RValue<UShort8> rhs)
3690 {
3691 return RValue<UShort8>(Nucleus::createAnd(lhs.value, rhs.value));
3692 }
3693
3694 RValue<UShort8> operator<<(RValue<UShort8> lhs, unsigned char rhs)
3695 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05003696 return RValue<UShort8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003697 }
3698
3699 RValue<UShort8> operator>>(RValue<UShort8> lhs, unsigned char rhs)
3700 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05003701 return RValue<UShort8>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003702 }
3703
3704 RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs)
3705 {
3706 return RValue<UShort8>(Nucleus::createAdd(lhs.value, rhs.value));
3707 }
3708
3709 RValue<UShort8> operator*(RValue<UShort8> lhs, RValue<UShort8> rhs)
3710 {
3711 return RValue<UShort8>(Nucleus::createMul(lhs.value, rhs.value));
3712 }
3713
Nicolas Capens96d4e092016-11-18 14:22:38 -05003714 RValue<UShort8> operator+=(UShort8 &lhs, RValue<UShort8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003715 {
3716 return lhs = lhs + rhs;
3717 }
3718
3719 RValue<UShort8> operator~(RValue<UShort8> val)
3720 {
3721 return RValue<UShort8>(Nucleus::createNot(val.value));
3722 }
3723
3724 RValue<UShort8> Swizzle(RValue<UShort8> x, char select0, char select1, char select2, char select3, char select4, char select5, char select6, char select7)
3725 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003726 assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003727 }
3728
3729 RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y)
3730 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003731 assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003732 }
3733
3734 // FIXME: Implement as Shuffle(x, y, Select(i0, ..., i16)) and Shuffle(x, y, SELECT_PACK_REPEAT(element))
3735// RValue<UShort8> PackRepeat(RValue<Byte16> x, RValue<Byte16> y, int element)
3736// {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003737// assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003738// }
3739
3740 Type *UShort8::getType()
3741 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04003742 return T(Ice::IceType_v8i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003743 }
3744
3745 Int::Int(Argument<Int> argument)
3746 {
3747 storeValue(argument.value);
3748 }
3749
3750 Int::Int(RValue<Byte> cast)
3751 {
3752 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3753
3754 storeValue(integer);
3755 }
3756
3757 Int::Int(RValue<SByte> cast)
3758 {
3759 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3760
3761 storeValue(integer);
3762 }
3763
3764 Int::Int(RValue<Short> cast)
3765 {
3766 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3767
3768 storeValue(integer);
3769 }
3770
3771 Int::Int(RValue<UShort> cast)
3772 {
3773 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3774
3775 storeValue(integer);
3776 }
3777
3778 Int::Int(RValue<Int2> cast)
3779 {
3780 *this = Extract(cast, 0);
3781 }
3782
3783 Int::Int(RValue<Long> cast)
3784 {
3785 Value *integer = Nucleus::createTrunc(cast.value, Int::getType());
3786
3787 storeValue(integer);
3788 }
3789
3790 Int::Int(RValue<Float> cast)
3791 {
3792 Value *integer = Nucleus::createFPToSI(cast.value, Int::getType());
3793
3794 storeValue(integer);
3795 }
3796
Nicolas Capens598f8d82016-09-26 15:09:10 -04003797 Int::Int(int x)
3798 {
3799 storeValue(Nucleus::createConstantInt(x));
3800 }
3801
3802 Int::Int(RValue<Int> rhs)
3803 {
3804 storeValue(rhs.value);
3805 }
3806
3807 Int::Int(RValue<UInt> rhs)
3808 {
3809 storeValue(rhs.value);
3810 }
3811
3812 Int::Int(const Int &rhs)
3813 {
3814 Value *value = rhs.loadValue();
3815 storeValue(value);
3816 }
3817
3818 Int::Int(const Reference<Int> &rhs)
3819 {
3820 Value *value = rhs.loadValue();
3821 storeValue(value);
3822 }
3823
3824 Int::Int(const UInt &rhs)
3825 {
3826 Value *value = rhs.loadValue();
3827 storeValue(value);
3828 }
3829
3830 Int::Int(const Reference<UInt> &rhs)
3831 {
3832 Value *value = rhs.loadValue();
3833 storeValue(value);
3834 }
3835
Nicolas Capens96d4e092016-11-18 14:22:38 -05003836 RValue<Int> Int::operator=(int rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003837 {
3838 return RValue<Int>(storeValue(Nucleus::createConstantInt(rhs)));
3839 }
3840
Nicolas Capens96d4e092016-11-18 14:22:38 -05003841 RValue<Int> Int::operator=(RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003842 {
3843 storeValue(rhs.value);
3844
3845 return rhs;
3846 }
3847
Nicolas Capens96d4e092016-11-18 14:22:38 -05003848 RValue<Int> Int::operator=(RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003849 {
3850 storeValue(rhs.value);
3851
3852 return RValue<Int>(rhs);
3853 }
3854
Nicolas Capens96d4e092016-11-18 14:22:38 -05003855 RValue<Int> Int::operator=(const Int &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003856 {
3857 Value *value = rhs.loadValue();
3858 storeValue(value);
3859
3860 return RValue<Int>(value);
3861 }
3862
Nicolas Capens96d4e092016-11-18 14:22:38 -05003863 RValue<Int> Int::operator=(const Reference<Int> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003864 {
3865 Value *value = rhs.loadValue();
3866 storeValue(value);
3867
3868 return RValue<Int>(value);
3869 }
3870
Nicolas Capens96d4e092016-11-18 14:22:38 -05003871 RValue<Int> Int::operator=(const UInt &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003872 {
3873 Value *value = rhs.loadValue();
3874 storeValue(value);
3875
3876 return RValue<Int>(value);
3877 }
3878
Nicolas Capens96d4e092016-11-18 14:22:38 -05003879 RValue<Int> Int::operator=(const Reference<UInt> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003880 {
3881 Value *value = rhs.loadValue();
3882 storeValue(value);
3883
3884 return RValue<Int>(value);
3885 }
3886
3887 RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs)
3888 {
3889 return RValue<Int>(Nucleus::createAdd(lhs.value, rhs.value));
3890 }
3891
3892 RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs)
3893 {
3894 return RValue<Int>(Nucleus::createSub(lhs.value, rhs.value));
3895 }
3896
3897 RValue<Int> operator*(RValue<Int> lhs, RValue<Int> rhs)
3898 {
3899 return RValue<Int>(Nucleus::createMul(lhs.value, rhs.value));
3900 }
3901
3902 RValue<Int> operator/(RValue<Int> lhs, RValue<Int> rhs)
3903 {
3904 return RValue<Int>(Nucleus::createSDiv(lhs.value, rhs.value));
3905 }
3906
3907 RValue<Int> operator%(RValue<Int> lhs, RValue<Int> rhs)
3908 {
3909 return RValue<Int>(Nucleus::createSRem(lhs.value, rhs.value));
3910 }
3911
3912 RValue<Int> operator&(RValue<Int> lhs, RValue<Int> rhs)
3913 {
3914 return RValue<Int>(Nucleus::createAnd(lhs.value, rhs.value));
3915 }
3916
3917 RValue<Int> operator|(RValue<Int> lhs, RValue<Int> rhs)
3918 {
3919 return RValue<Int>(Nucleus::createOr(lhs.value, rhs.value));
3920 }
3921
3922 RValue<Int> operator^(RValue<Int> lhs, RValue<Int> rhs)
3923 {
3924 return RValue<Int>(Nucleus::createXor(lhs.value, rhs.value));
3925 }
3926
3927 RValue<Int> operator<<(RValue<Int> lhs, RValue<Int> rhs)
3928 {
3929 return RValue<Int>(Nucleus::createShl(lhs.value, rhs.value));
3930 }
3931
3932 RValue<Int> operator>>(RValue<Int> lhs, RValue<Int> rhs)
3933 {
3934 return RValue<Int>(Nucleus::createAShr(lhs.value, rhs.value));
3935 }
3936
Nicolas Capens96d4e092016-11-18 14:22:38 -05003937 RValue<Int> operator+=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003938 {
3939 return lhs = lhs + rhs;
3940 }
3941
Nicolas Capens96d4e092016-11-18 14:22:38 -05003942 RValue<Int> operator-=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003943 {
3944 return lhs = lhs - rhs;
3945 }
3946
Nicolas Capens96d4e092016-11-18 14:22:38 -05003947 RValue<Int> operator*=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003948 {
3949 return lhs = lhs * rhs;
3950 }
3951
Nicolas Capens96d4e092016-11-18 14:22:38 -05003952 RValue<Int> operator/=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003953 {
3954 return lhs = lhs / rhs;
3955 }
3956
Nicolas Capens96d4e092016-11-18 14:22:38 -05003957 RValue<Int> operator%=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003958 {
3959 return lhs = lhs % rhs;
3960 }
3961
Nicolas Capens96d4e092016-11-18 14:22:38 -05003962 RValue<Int> operator&=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003963 {
3964 return lhs = lhs & rhs;
3965 }
3966
Nicolas Capens96d4e092016-11-18 14:22:38 -05003967 RValue<Int> operator|=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003968 {
3969 return lhs = lhs | rhs;
3970 }
3971
Nicolas Capens96d4e092016-11-18 14:22:38 -05003972 RValue<Int> operator^=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003973 {
3974 return lhs = lhs ^ rhs;
3975 }
3976
Nicolas Capens96d4e092016-11-18 14:22:38 -05003977 RValue<Int> operator<<=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003978 {
3979 return lhs = lhs << rhs;
3980 }
3981
Nicolas Capens96d4e092016-11-18 14:22:38 -05003982 RValue<Int> operator>>=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003983 {
3984 return lhs = lhs >> rhs;
3985 }
3986
3987 RValue<Int> operator+(RValue<Int> val)
3988 {
3989 return val;
3990 }
3991
3992 RValue<Int> operator-(RValue<Int> val)
3993 {
3994 return RValue<Int>(Nucleus::createNeg(val.value));
3995 }
3996
3997 RValue<Int> operator~(RValue<Int> val)
3998 {
3999 return RValue<Int>(Nucleus::createNot(val.value));
4000 }
4001
Nicolas Capens96d4e092016-11-18 14:22:38 -05004002 RValue<Int> operator++(Int &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04004003 {
Nicolas Capens5b41ba32016-12-08 14:34:00 -05004004 RValue<Int> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05004005 val += 1;
4006 return res;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004007 }
4008
Nicolas Capens96d4e092016-11-18 14:22:38 -05004009 const Int &operator++(Int &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04004010 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004011 val += 1;
4012 return val;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004013 }
4014
Nicolas Capens96d4e092016-11-18 14:22:38 -05004015 RValue<Int> operator--(Int &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04004016 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004017 RValue<Int> res = val;
4018 val -= 1;
4019 return res;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004020 }
4021
Nicolas Capens96d4e092016-11-18 14:22:38 -05004022 const Int &operator--(Int &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04004023 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004024 val -= 1;
4025 return val;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004026 }
4027
4028 RValue<Bool> operator<(RValue<Int> lhs, RValue<Int> rhs)
4029 {
4030 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
4031 }
4032
4033 RValue<Bool> operator<=(RValue<Int> lhs, RValue<Int> rhs)
4034 {
4035 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
4036 }
4037
4038 RValue<Bool> operator>(RValue<Int> lhs, RValue<Int> rhs)
4039 {
4040 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
4041 }
4042
4043 RValue<Bool> operator>=(RValue<Int> lhs, RValue<Int> rhs)
4044 {
4045 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
4046 }
4047
4048 RValue<Bool> operator!=(RValue<Int> lhs, RValue<Int> rhs)
4049 {
4050 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
4051 }
4052
4053 RValue<Bool> operator==(RValue<Int> lhs, RValue<Int> rhs)
4054 {
4055 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
4056 }
4057
4058 RValue<Int> Max(RValue<Int> x, RValue<Int> y)
4059 {
4060 return IfThenElse(x > y, x, y);
4061 }
4062
4063 RValue<Int> Min(RValue<Int> x, RValue<Int> y)
4064 {
4065 return IfThenElse(x < y, x, y);
4066 }
4067
4068 RValue<Int> Clamp(RValue<Int> x, RValue<Int> min, RValue<Int> max)
4069 {
4070 return Min(Max(x, min), max);
4071 }
4072
4073 RValue<Int> RoundInt(RValue<Float> cast)
4074 {
Nicolas Capensa8086512016-11-07 17:32:17 -05004075 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
Nicolas Capens9ca48d52017-01-14 12:52:55 -05004076 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Nearbyint, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
4077 auto target = ::context->getConstantUndef(Ice::IceType_i32);
4078 auto nearbyint = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
4079 nearbyint->addArg(cast.value);
4080 ::basicBlock->appendInst(nearbyint);
Nicolas Capensa8086512016-11-07 17:32:17 -05004081
4082 return RValue<Int>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004083 }
4084
4085 Type *Int::getType()
4086 {
4087 return T(Ice::IceType_i32);
4088 }
4089
4090 Long::Long(RValue<Int> cast)
4091 {
4092 Value *integer = Nucleus::createSExt(cast.value, Long::getType());
4093
4094 storeValue(integer);
4095 }
4096
4097 Long::Long(RValue<UInt> cast)
4098 {
4099 Value *integer = Nucleus::createZExt(cast.value, Long::getType());
4100
4101 storeValue(integer);
4102 }
4103
Nicolas Capens598f8d82016-09-26 15:09:10 -04004104 Long::Long(RValue<Long> rhs)
4105 {
4106 storeValue(rhs.value);
4107 }
4108
Nicolas Capens96d4e092016-11-18 14:22:38 -05004109 RValue<Long> Long::operator=(int64_t rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004110 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04004111 return RValue<Long>(storeValue(Nucleus::createConstantLong(rhs)));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004112 }
4113
Nicolas Capens96d4e092016-11-18 14:22:38 -05004114 RValue<Long> Long::operator=(RValue<Long> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004115 {
4116 storeValue(rhs.value);
4117
4118 return rhs;
4119 }
4120
Nicolas Capens96d4e092016-11-18 14:22:38 -05004121 RValue<Long> Long::operator=(const Long &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004122 {
4123 Value *value = rhs.loadValue();
4124 storeValue(value);
4125
4126 return RValue<Long>(value);
4127 }
4128
Nicolas Capens96d4e092016-11-18 14:22:38 -05004129 RValue<Long> Long::operator=(const Reference<Long> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004130 {
4131 Value *value = rhs.loadValue();
4132 storeValue(value);
4133
4134 return RValue<Long>(value);
4135 }
4136
4137 RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs)
4138 {
4139 return RValue<Long>(Nucleus::createAdd(lhs.value, rhs.value));
4140 }
4141
4142 RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs)
4143 {
4144 return RValue<Long>(Nucleus::createSub(lhs.value, rhs.value));
4145 }
4146
Nicolas Capens96d4e092016-11-18 14:22:38 -05004147 RValue<Long> operator+=(Long &lhs, RValue<Long> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004148 {
4149 return lhs = lhs + rhs;
4150 }
4151
Nicolas Capens96d4e092016-11-18 14:22:38 -05004152 RValue<Long> operator-=(Long &lhs, RValue<Long> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004153 {
4154 return lhs = lhs - rhs;
4155 }
4156
4157 RValue<Long> AddAtomic(RValue<Pointer<Long> > x, RValue<Long> y)
4158 {
4159 return RValue<Long>(Nucleus::createAtomicAdd(x.value, y.value));
4160 }
4161
4162 Type *Long::getType()
4163 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04004164 return T(Ice::IceType_i64);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004165 }
4166
Nicolas Capens598f8d82016-09-26 15:09:10 -04004167 UInt::UInt(Argument<UInt> argument)
4168 {
4169 storeValue(argument.value);
4170 }
4171
4172 UInt::UInt(RValue<UShort> cast)
4173 {
4174 Value *integer = Nucleus::createZExt(cast.value, UInt::getType());
4175
4176 storeValue(integer);
4177 }
4178
4179 UInt::UInt(RValue<Long> cast)
4180 {
4181 Value *integer = Nucleus::createTrunc(cast.value, UInt::getType());
4182
4183 storeValue(integer);
4184 }
4185
4186 UInt::UInt(RValue<Float> cast)
4187 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05004188 // Smallest positive value representable in UInt, but not in Int
4189 const unsigned int ustart = 0x80000000u;
4190 const float ustartf = float(ustart);
4191
4192 // If the value is negative, store 0, otherwise store the result of the conversion
4193 storeValue((~(As<Int>(cast) >> 31) &
4194 // Check if the value can be represented as an Int
4195 IfThenElse(cast >= ustartf,
4196 // If the value is too large, subtract ustart and re-add it after conversion.
4197 As<Int>(As<UInt>(Int(cast - Float(ustartf))) + UInt(ustart)),
4198 // Otherwise, just convert normally
4199 Int(cast))).value);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004200 }
4201
Nicolas Capens598f8d82016-09-26 15:09:10 -04004202 UInt::UInt(int x)
4203 {
4204 storeValue(Nucleus::createConstantInt(x));
4205 }
4206
4207 UInt::UInt(unsigned int x)
4208 {
4209 storeValue(Nucleus::createConstantInt(x));
4210 }
4211
4212 UInt::UInt(RValue<UInt> rhs)
4213 {
4214 storeValue(rhs.value);
4215 }
4216
4217 UInt::UInt(RValue<Int> rhs)
4218 {
4219 storeValue(rhs.value);
4220 }
4221
4222 UInt::UInt(const UInt &rhs)
4223 {
4224 Value *value = rhs.loadValue();
4225 storeValue(value);
4226 }
4227
4228 UInt::UInt(const Reference<UInt> &rhs)
4229 {
4230 Value *value = rhs.loadValue();
4231 storeValue(value);
4232 }
4233
4234 UInt::UInt(const Int &rhs)
4235 {
4236 Value *value = rhs.loadValue();
4237 storeValue(value);
4238 }
4239
4240 UInt::UInt(const Reference<Int> &rhs)
4241 {
4242 Value *value = rhs.loadValue();
4243 storeValue(value);
4244 }
4245
Nicolas Capens96d4e092016-11-18 14:22:38 -05004246 RValue<UInt> UInt::operator=(unsigned int rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004247 {
4248 return RValue<UInt>(storeValue(Nucleus::createConstantInt(rhs)));
4249 }
4250
Nicolas Capens96d4e092016-11-18 14:22:38 -05004251 RValue<UInt> UInt::operator=(RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004252 {
4253 storeValue(rhs.value);
4254
4255 return rhs;
4256 }
4257
Nicolas Capens96d4e092016-11-18 14:22:38 -05004258 RValue<UInt> UInt::operator=(RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004259 {
4260 storeValue(rhs.value);
4261
4262 return RValue<UInt>(rhs);
4263 }
4264
Nicolas Capens96d4e092016-11-18 14:22:38 -05004265 RValue<UInt> UInt::operator=(const UInt &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004266 {
4267 Value *value = rhs.loadValue();
4268 storeValue(value);
4269
4270 return RValue<UInt>(value);
4271 }
4272
Nicolas Capens96d4e092016-11-18 14:22:38 -05004273 RValue<UInt> UInt::operator=(const Reference<UInt> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004274 {
4275 Value *value = rhs.loadValue();
4276 storeValue(value);
4277
4278 return RValue<UInt>(value);
4279 }
4280
Nicolas Capens96d4e092016-11-18 14:22:38 -05004281 RValue<UInt> UInt::operator=(const Int &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004282 {
4283 Value *value = rhs.loadValue();
4284 storeValue(value);
4285
4286 return RValue<UInt>(value);
4287 }
4288
Nicolas Capens96d4e092016-11-18 14:22:38 -05004289 RValue<UInt> UInt::operator=(const Reference<Int> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004290 {
4291 Value *value = rhs.loadValue();
4292 storeValue(value);
4293
4294 return RValue<UInt>(value);
4295 }
4296
4297 RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs)
4298 {
4299 return RValue<UInt>(Nucleus::createAdd(lhs.value, rhs.value));
4300 }
4301
4302 RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs)
4303 {
4304 return RValue<UInt>(Nucleus::createSub(lhs.value, rhs.value));
4305 }
4306
4307 RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs)
4308 {
4309 return RValue<UInt>(Nucleus::createMul(lhs.value, rhs.value));
4310 }
4311
4312 RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs)
4313 {
4314 return RValue<UInt>(Nucleus::createUDiv(lhs.value, rhs.value));
4315 }
4316
4317 RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs)
4318 {
4319 return RValue<UInt>(Nucleus::createURem(lhs.value, rhs.value));
4320 }
4321
4322 RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs)
4323 {
4324 return RValue<UInt>(Nucleus::createAnd(lhs.value, rhs.value));
4325 }
4326
4327 RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs)
4328 {
4329 return RValue<UInt>(Nucleus::createOr(lhs.value, rhs.value));
4330 }
4331
4332 RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs)
4333 {
4334 return RValue<UInt>(Nucleus::createXor(lhs.value, rhs.value));
4335 }
4336
4337 RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs)
4338 {
4339 return RValue<UInt>(Nucleus::createShl(lhs.value, rhs.value));
4340 }
4341
4342 RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs)
4343 {
4344 return RValue<UInt>(Nucleus::createLShr(lhs.value, rhs.value));
4345 }
4346
Nicolas Capens96d4e092016-11-18 14:22:38 -05004347 RValue<UInt> operator+=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004348 {
4349 return lhs = lhs + rhs;
4350 }
4351
Nicolas Capens96d4e092016-11-18 14:22:38 -05004352 RValue<UInt> operator-=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004353 {
4354 return lhs = lhs - rhs;
4355 }
4356
Nicolas Capens96d4e092016-11-18 14:22:38 -05004357 RValue<UInt> operator*=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004358 {
4359 return lhs = lhs * rhs;
4360 }
4361
Nicolas Capens96d4e092016-11-18 14:22:38 -05004362 RValue<UInt> operator/=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004363 {
4364 return lhs = lhs / rhs;
4365 }
4366
Nicolas Capens96d4e092016-11-18 14:22:38 -05004367 RValue<UInt> operator%=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004368 {
4369 return lhs = lhs % rhs;
4370 }
4371
Nicolas Capens96d4e092016-11-18 14:22:38 -05004372 RValue<UInt> operator&=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004373 {
4374 return lhs = lhs & rhs;
4375 }
4376
Nicolas Capens96d4e092016-11-18 14:22:38 -05004377 RValue<UInt> operator|=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004378 {
4379 return lhs = lhs | rhs;
4380 }
4381
Nicolas Capens96d4e092016-11-18 14:22:38 -05004382 RValue<UInt> operator^=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004383 {
4384 return lhs = lhs ^ rhs;
4385 }
4386
Nicolas Capens96d4e092016-11-18 14:22:38 -05004387 RValue<UInt> operator<<=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004388 {
4389 return lhs = lhs << rhs;
4390 }
4391
Nicolas Capens96d4e092016-11-18 14:22:38 -05004392 RValue<UInt> operator>>=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004393 {
4394 return lhs = lhs >> rhs;
4395 }
4396
4397 RValue<UInt> operator+(RValue<UInt> val)
4398 {
4399 return val;
4400 }
4401
4402 RValue<UInt> operator-(RValue<UInt> val)
4403 {
4404 return RValue<UInt>(Nucleus::createNeg(val.value));
4405 }
4406
4407 RValue<UInt> operator~(RValue<UInt> val)
4408 {
4409 return RValue<UInt>(Nucleus::createNot(val.value));
4410 }
4411
Nicolas Capens96d4e092016-11-18 14:22:38 -05004412 RValue<UInt> operator++(UInt &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04004413 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004414 RValue<UInt> res = val;
4415 val += 1;
4416 return res;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004417 }
4418
Nicolas Capens96d4e092016-11-18 14:22:38 -05004419 const UInt &operator++(UInt &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04004420 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004421 val += 1;
4422 return val;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004423 }
4424
Nicolas Capens96d4e092016-11-18 14:22:38 -05004425 RValue<UInt> operator--(UInt &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04004426 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004427 RValue<UInt> res = val;
4428 val -= 1;
4429 return res;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004430 }
4431
Nicolas Capens96d4e092016-11-18 14:22:38 -05004432 const UInt &operator--(UInt &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04004433 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004434 val -= 1;
4435 return val;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004436 }
4437
4438 RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y)
4439 {
4440 return IfThenElse(x > y, x, y);
4441 }
4442
4443 RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y)
4444 {
4445 return IfThenElse(x < y, x, y);
4446 }
4447
4448 RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max)
4449 {
4450 return Min(Max(x, min), max);
4451 }
4452
4453 RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs)
4454 {
4455 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
4456 }
4457
4458 RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs)
4459 {
4460 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
4461 }
4462
4463 RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs)
4464 {
4465 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
4466 }
4467
4468 RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs)
4469 {
4470 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
4471 }
4472
4473 RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs)
4474 {
4475 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
4476 }
4477
4478 RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs)
4479 {
4480 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
4481 }
4482
4483// RValue<UInt> RoundUInt(RValue<Float> cast)
4484// {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004485// assert(false && "UNIMPLEMENTED"); return RValue<UInt>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004486// }
4487
4488 Type *UInt::getType()
4489 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04004490 return T(Ice::IceType_i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004491 }
4492
4493// Int2::Int2(RValue<Int> cast)
4494// {
4495// Value *extend = Nucleus::createZExt(cast.value, Long::getType());
4496// Value *vector = Nucleus::createBitCast(extend, Int2::getType());
4497//
4498// Constant *shuffle[2];
4499// shuffle[0] = Nucleus::createConstantInt(0);
4500// shuffle[1] = Nucleus::createConstantInt(0);
4501//
4502// Value *replicate = Nucleus::createShuffleVector(vector, UndefValue::get(Int2::getType()), Nucleus::createConstantVector(shuffle, 2));
4503//
4504// storeValue(replicate);
4505// }
4506
4507 Int2::Int2(RValue<Int4> cast)
4508 {
Nicolas Capens22008782016-10-20 01:11:47 -04004509 storeValue(Nucleus::createBitCast(cast.value, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004510 }
4511
Nicolas Capens598f8d82016-09-26 15:09:10 -04004512 Int2::Int2(int x, int y)
4513 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04004514 int64_t constantVector[2] = {x, y};
4515 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004516 }
4517
4518 Int2::Int2(RValue<Int2> rhs)
4519 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004520 storeValue(rhs.value);
4521 }
4522
4523 Int2::Int2(const Int2 &rhs)
4524 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004525 Value *value = rhs.loadValue();
4526 storeValue(value);
4527 }
4528
4529 Int2::Int2(const Reference<Int2> &rhs)
4530 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004531 Value *value = rhs.loadValue();
4532 storeValue(value);
4533 }
4534
4535 Int2::Int2(RValue<Int> lo, RValue<Int> hi)
4536 {
Nicolas Capensd4227962016-11-09 14:24:25 -05004537 int shuffle[4] = {0, 4, 1, 5};
4538 Value *packed = Nucleus::createShuffleVector(Int4(lo).loadValue(), Int4(hi).loadValue(), shuffle);
4539
4540 storeValue(Nucleus::createBitCast(packed, Int2::getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004541 }
4542
Nicolas Capens96d4e092016-11-18 14:22:38 -05004543 RValue<Int2> Int2::operator=(RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004544 {
4545 storeValue(rhs.value);
4546
4547 return rhs;
4548 }
4549
Nicolas Capens96d4e092016-11-18 14:22:38 -05004550 RValue<Int2> Int2::operator=(const Int2 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004551 {
4552 Value *value = rhs.loadValue();
4553 storeValue(value);
4554
4555 return RValue<Int2>(value);
4556 }
4557
Nicolas Capens96d4e092016-11-18 14:22:38 -05004558 RValue<Int2> Int2::operator=(const Reference<Int2> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004559 {
4560 Value *value = rhs.loadValue();
4561 storeValue(value);
4562
4563 return RValue<Int2>(value);
4564 }
4565
4566 RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs)
4567 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004568 return RValue<Int2>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004569 }
4570
4571 RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs)
4572 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004573 return RValue<Int2>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004574 }
4575
4576// RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs)
4577// {
4578// return RValue<Int2>(Nucleus::createMul(lhs.value, rhs.value));
4579// }
4580
4581// RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs)
4582// {
4583// return RValue<Int2>(Nucleus::createSDiv(lhs.value, rhs.value));
4584// }
4585
4586// RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs)
4587// {
4588// return RValue<Int2>(Nucleus::createSRem(lhs.value, rhs.value));
4589// }
4590
4591 RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs)
4592 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004593 return RValue<Int2>(Nucleus::createAnd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004594 }
4595
4596 RValue<Int2> operator|(RValue<Int2> lhs, RValue<Int2> rhs)
4597 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004598 return RValue<Int2>(Nucleus::createOr(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004599 }
4600
4601 RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs)
4602 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004603 return RValue<Int2>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004604 }
4605
4606 RValue<Int2> operator<<(RValue<Int2> lhs, unsigned char rhs)
4607 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05004608 return RValue<Int2>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004609 }
4610
4611 RValue<Int2> operator>>(RValue<Int2> lhs, unsigned char rhs)
4612 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05004613 return RValue<Int2>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004614 }
4615
Nicolas Capens96d4e092016-11-18 14:22:38 -05004616 RValue<Int2> operator+=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004617 {
4618 return lhs = lhs + rhs;
4619 }
4620
Nicolas Capens96d4e092016-11-18 14:22:38 -05004621 RValue<Int2> operator-=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004622 {
4623 return lhs = lhs - rhs;
4624 }
4625
Nicolas Capens96d4e092016-11-18 14:22:38 -05004626// RValue<Int2> operator*=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004627// {
4628// return lhs = lhs * rhs;
4629// }
4630
Nicolas Capens96d4e092016-11-18 14:22:38 -05004631// RValue<Int2> operator/=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004632// {
4633// return lhs = lhs / rhs;
4634// }
4635
Nicolas Capens96d4e092016-11-18 14:22:38 -05004636// RValue<Int2> operator%=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004637// {
4638// return lhs = lhs % rhs;
4639// }
4640
Nicolas Capens96d4e092016-11-18 14:22:38 -05004641 RValue<Int2> operator&=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004642 {
4643 return lhs = lhs & rhs;
4644 }
4645
Nicolas Capens96d4e092016-11-18 14:22:38 -05004646 RValue<Int2> operator|=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004647 {
4648 return lhs = lhs | rhs;
4649 }
4650
Nicolas Capens96d4e092016-11-18 14:22:38 -05004651 RValue<Int2> operator^=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004652 {
4653 return lhs = lhs ^ rhs;
4654 }
4655
Nicolas Capens96d4e092016-11-18 14:22:38 -05004656 RValue<Int2> operator<<=(Int2 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004657 {
4658 return lhs = lhs << rhs;
4659 }
4660
Nicolas Capens96d4e092016-11-18 14:22:38 -05004661 RValue<Int2> operator>>=(Int2 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004662 {
4663 return lhs = lhs >> rhs;
4664 }
4665
Nicolas Capens598f8d82016-09-26 15:09:10 -04004666// RValue<Int2> operator+(RValue<Int2> val)
4667// {
4668// return val;
4669// }
4670
4671// RValue<Int2> operator-(RValue<Int2> val)
4672// {
4673// return RValue<Int2>(Nucleus::createNeg(val.value));
4674// }
4675
4676 RValue<Int2> operator~(RValue<Int2> val)
4677 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -05004678 return RValue<Int2>(Nucleus::createNot(val.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004679 }
4680
Nicolas Capens45f187a2016-12-02 15:30:56 -05004681 RValue<Short4> UnpackLow(RValue<Int2> x, RValue<Int2> y)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004682 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05004683 int shuffle[4] = {0, 4, 1, 5}; // Real type is v4i32
4684 return As<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004685 }
4686
Nicolas Capens45f187a2016-12-02 15:30:56 -05004687 RValue<Short4> UnpackHigh(RValue<Int2> x, RValue<Int2> y)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004688 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05004689 int shuffle[16] = {0, 4, 1, 5}; // Real type is v4i32
4690 auto lowHigh = RValue<Int4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
4691 return As<Short4>(Swizzle(lowHigh, 0xEE));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004692 }
4693
4694 RValue<Int> Extract(RValue<Int2> val, int i)
4695 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05004696 return RValue<Int>(Nucleus::createExtractElement(val.value, Int::getType(), i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004697 }
4698
4699 RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i)
4700 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05004701 return RValue<Int2>(Nucleus::createInsertElement(val.value, element.value, i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004702 }
4703
4704 Type *Int2::getType()
4705 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04004706 return T(Type_v2i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004707 }
4708
Nicolas Capens598f8d82016-09-26 15:09:10 -04004709 UInt2::UInt2(unsigned int x, unsigned int y)
4710 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04004711 int64_t constantVector[2] = {x, y};
4712 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004713 }
4714
4715 UInt2::UInt2(RValue<UInt2> rhs)
4716 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004717 storeValue(rhs.value);
4718 }
4719
4720 UInt2::UInt2(const UInt2 &rhs)
4721 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004722 Value *value = rhs.loadValue();
4723 storeValue(value);
4724 }
4725
4726 UInt2::UInt2(const Reference<UInt2> &rhs)
4727 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004728 Value *value = rhs.loadValue();
4729 storeValue(value);
4730 }
4731
Nicolas Capens96d4e092016-11-18 14:22:38 -05004732 RValue<UInt2> UInt2::operator=(RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004733 {
4734 storeValue(rhs.value);
4735
4736 return rhs;
4737 }
4738
Nicolas Capens96d4e092016-11-18 14:22:38 -05004739 RValue<UInt2> UInt2::operator=(const UInt2 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004740 {
4741 Value *value = rhs.loadValue();
4742 storeValue(value);
4743
4744 return RValue<UInt2>(value);
4745 }
4746
Nicolas Capens96d4e092016-11-18 14:22:38 -05004747 RValue<UInt2> UInt2::operator=(const Reference<UInt2> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004748 {
4749 Value *value = rhs.loadValue();
4750 storeValue(value);
4751
4752 return RValue<UInt2>(value);
4753 }
4754
4755 RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs)
4756 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004757 return RValue<UInt2>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004758 }
4759
4760 RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs)
4761 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004762 return RValue<UInt2>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004763 }
4764
4765// RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs)
4766// {
4767// return RValue<UInt2>(Nucleus::createMul(lhs.value, rhs.value));
4768// }
4769
4770// RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs)
4771// {
4772// return RValue<UInt2>(Nucleus::createUDiv(lhs.value, rhs.value));
4773// }
4774
4775// RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs)
4776// {
4777// return RValue<UInt2>(Nucleus::createURem(lhs.value, rhs.value));
4778// }
4779
4780 RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs)
4781 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004782 return RValue<UInt2>(Nucleus::createAnd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004783 }
4784
4785 RValue<UInt2> operator|(RValue<UInt2> lhs, RValue<UInt2> rhs)
4786 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004787 return RValue<UInt2>(Nucleus::createOr(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004788 }
4789
4790 RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs)
4791 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004792 return RValue<UInt2>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004793 }
4794
4795 RValue<UInt2> operator<<(RValue<UInt2> lhs, unsigned char rhs)
4796 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05004797 return RValue<UInt2>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004798 }
4799
4800 RValue<UInt2> operator>>(RValue<UInt2> lhs, unsigned char rhs)
4801 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05004802 return RValue<UInt2>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004803 }
4804
Nicolas Capens96d4e092016-11-18 14:22:38 -05004805 RValue<UInt2> operator+=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004806 {
4807 return lhs = lhs + rhs;
4808 }
4809
Nicolas Capens96d4e092016-11-18 14:22:38 -05004810 RValue<UInt2> operator-=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004811 {
4812 return lhs = lhs - rhs;
4813 }
4814
Nicolas Capens96d4e092016-11-18 14:22:38 -05004815// RValue<UInt2> operator*=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004816// {
4817// return lhs = lhs * rhs;
4818// }
4819
Nicolas Capens96d4e092016-11-18 14:22:38 -05004820// RValue<UInt2> operator/=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004821// {
4822// return lhs = lhs / rhs;
4823// }
4824
Nicolas Capens96d4e092016-11-18 14:22:38 -05004825// RValue<UInt2> operator%=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004826// {
4827// return lhs = lhs % rhs;
4828// }
4829
Nicolas Capens96d4e092016-11-18 14:22:38 -05004830 RValue<UInt2> operator&=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004831 {
4832 return lhs = lhs & rhs;
4833 }
4834
Nicolas Capens96d4e092016-11-18 14:22:38 -05004835 RValue<UInt2> operator|=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004836 {
4837 return lhs = lhs | rhs;
4838 }
4839
Nicolas Capens96d4e092016-11-18 14:22:38 -05004840 RValue<UInt2> operator^=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004841 {
4842 return lhs = lhs ^ rhs;
4843 }
4844
Nicolas Capens96d4e092016-11-18 14:22:38 -05004845 RValue<UInt2> operator<<=(UInt2 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004846 {
4847 return lhs = lhs << rhs;
4848 }
4849
Nicolas Capens96d4e092016-11-18 14:22:38 -05004850 RValue<UInt2> operator>>=(UInt2 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004851 {
4852 return lhs = lhs >> rhs;
4853 }
4854
Nicolas Capens598f8d82016-09-26 15:09:10 -04004855// RValue<UInt2> operator+(RValue<UInt2> val)
4856// {
4857// return val;
4858// }
4859
4860// RValue<UInt2> operator-(RValue<UInt2> val)
4861// {
4862// return RValue<UInt2>(Nucleus::createNeg(val.value));
4863// }
4864
4865 RValue<UInt2> operator~(RValue<UInt2> val)
4866 {
4867 return RValue<UInt2>(Nucleus::createNot(val.value));
4868 }
4869
4870 Type *UInt2::getType()
4871 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04004872 return T(Type_v2i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004873 }
4874
4875 Int4::Int4(RValue<Byte4> cast)
4876 {
Nicolas Capensd4227962016-11-09 14:24:25 -05004877 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
4878 Value *a = Nucleus::createInsertElement(loadValue(), x, 0);
4879
4880 Value *e;
4881 int swizzle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23};
4882 Value *b = Nucleus::createBitCast(a, Byte16::getType());
4883 Value *c = Nucleus::createShuffleVector(b, V(Nucleus::createNullValue(Byte16::getType())), swizzle);
4884
4885 int swizzle2[8] = {0, 8, 1, 9, 2, 10, 3, 11};
4886 Value *d = Nucleus::createBitCast(c, Short8::getType());
4887 e = Nucleus::createShuffleVector(d, V(Nucleus::createNullValue(Short8::getType())), swizzle2);
4888
4889 Value *f = Nucleus::createBitCast(e, Int4::getType());
4890 storeValue(f);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004891 }
4892
4893 Int4::Int4(RValue<SByte4> cast)
4894 {
Nicolas Capensd4227962016-11-09 14:24:25 -05004895 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
4896 Value *a = Nucleus::createInsertElement(loadValue(), x, 0);
4897
4898 Value *e;
4899 int swizzle[16] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7};
4900 Value *b = Nucleus::createBitCast(a, Byte16::getType());
4901 Value *c = Nucleus::createShuffleVector(b, b, swizzle);
4902
4903 int swizzle2[8] = {0, 0, 1, 1, 2, 2, 3, 3};
4904 Value *d = Nucleus::createBitCast(c, Short8::getType());
4905 e = Nucleus::createShuffleVector(d, d, swizzle2);
4906
4907 Value *f = Nucleus::createBitCast(e, Int4::getType());
Nicolas Capens15060bb2016-12-05 22:17:19 -05004908 Value *g = Nucleus::createAShr(f, V(::context->getConstantInt32(24)));
Nicolas Capensd4227962016-11-09 14:24:25 -05004909 storeValue(g);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004910 }
4911
4912 Int4::Int4(RValue<Float4> cast)
4913 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004914 Value *xyzw = Nucleus::createFPToSI(cast.value, Int4::getType());
4915
4916 storeValue(xyzw);
4917 }
4918
4919 Int4::Int4(RValue<Short4> cast)
4920 {
Nicolas Capensd4227962016-11-09 14:24:25 -05004921 int swizzle[8] = {0, 0, 1, 1, 2, 2, 3, 3};
4922 Value *c = Nucleus::createShuffleVector(cast.value, cast.value, swizzle);
4923 Value *d = Nucleus::createBitCast(c, Int4::getType());
Nicolas Capens15060bb2016-12-05 22:17:19 -05004924 Value *e = Nucleus::createAShr(d, V(::context->getConstantInt32(16)));
Nicolas Capensd4227962016-11-09 14:24:25 -05004925 storeValue(e);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004926 }
4927
4928 Int4::Int4(RValue<UShort4> cast)
4929 {
Nicolas Capensd4227962016-11-09 14:24:25 -05004930 int swizzle[8] = {0, 8, 1, 9, 2, 10, 3, 11};
4931 Value *c = Nucleus::createShuffleVector(cast.value, Short8(0, 0, 0, 0, 0, 0, 0, 0).loadValue(), swizzle);
4932 Value *d = Nucleus::createBitCast(c, Int4::getType());
4933 storeValue(d);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004934 }
4935
Nicolas Capens598f8d82016-09-26 15:09:10 -04004936 Int4::Int4(int xyzw)
4937 {
4938 constant(xyzw, xyzw, xyzw, xyzw);
4939 }
4940
4941 Int4::Int4(int x, int yzw)
4942 {
4943 constant(x, yzw, yzw, yzw);
4944 }
4945
4946 Int4::Int4(int x, int y, int zw)
4947 {
4948 constant(x, y, zw, zw);
4949 }
4950
4951 Int4::Int4(int x, int y, int z, int w)
4952 {
4953 constant(x, y, z, w);
4954 }
4955
4956 void Int4::constant(int x, int y, int z, int w)
4957 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04004958 int64_t constantVector[4] = {x, y, z, w};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04004959 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004960 }
4961
4962 Int4::Int4(RValue<Int4> rhs)
4963 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004964 storeValue(rhs.value);
4965 }
4966
4967 Int4::Int4(const Int4 &rhs)
4968 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004969 Value *value = rhs.loadValue();
4970 storeValue(value);
4971 }
4972
4973 Int4::Int4(const Reference<Int4> &rhs)
4974 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004975 Value *value = rhs.loadValue();
4976 storeValue(value);
4977 }
4978
4979 Int4::Int4(RValue<UInt4> rhs)
4980 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004981 storeValue(rhs.value);
4982 }
4983
4984 Int4::Int4(const UInt4 &rhs)
4985 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004986 Value *value = rhs.loadValue();
4987 storeValue(value);
4988 }
4989
4990 Int4::Int4(const Reference<UInt4> &rhs)
4991 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004992 Value *value = rhs.loadValue();
4993 storeValue(value);
4994 }
4995
4996 Int4::Int4(RValue<Int2> lo, RValue<Int2> hi)
4997 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05004998 int shuffle[4] = {0, 1, 4, 5}; // Real type is v4i32
4999 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
5000
5001 storeValue(packed);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005002 }
5003
5004 Int4::Int4(RValue<Int> rhs)
5005 {
Nicolas Capensd4227962016-11-09 14:24:25 -05005006 Value *vector = loadValue();
5007 Value *insert = Nucleus::createInsertElement(vector, rhs.value, 0);
5008
5009 int swizzle[4] = {0, 0, 0, 0};
5010 Value *replicate = Nucleus::createShuffleVector(insert, insert, swizzle);
5011
5012 storeValue(replicate);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005013 }
5014
5015 Int4::Int4(const Int &rhs)
5016 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005017 *this = RValue<Int>(rhs.loadValue());
5018 }
5019
5020 Int4::Int4(const Reference<Int> &rhs)
5021 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005022 *this = RValue<Int>(rhs.loadValue());
5023 }
5024
Nicolas Capens96d4e092016-11-18 14:22:38 -05005025 RValue<Int4> Int4::operator=(RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005026 {
5027 storeValue(rhs.value);
5028
5029 return rhs;
5030 }
5031
Nicolas Capens96d4e092016-11-18 14:22:38 -05005032 RValue<Int4> Int4::operator=(const Int4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005033 {
5034 Value *value = rhs.loadValue();
5035 storeValue(value);
5036
5037 return RValue<Int4>(value);
5038 }
5039
Nicolas Capens96d4e092016-11-18 14:22:38 -05005040 RValue<Int4> Int4::operator=(const Reference<Int4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005041 {
5042 Value *value = rhs.loadValue();
5043 storeValue(value);
5044
5045 return RValue<Int4>(value);
5046 }
5047
5048 RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs)
5049 {
5050 return RValue<Int4>(Nucleus::createAdd(lhs.value, rhs.value));
5051 }
5052
5053 RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs)
5054 {
5055 return RValue<Int4>(Nucleus::createSub(lhs.value, rhs.value));
5056 }
5057
5058 RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs)
5059 {
5060 return RValue<Int4>(Nucleus::createMul(lhs.value, rhs.value));
5061 }
5062
5063 RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs)
5064 {
5065 return RValue<Int4>(Nucleus::createSDiv(lhs.value, rhs.value));
5066 }
5067
5068 RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs)
5069 {
5070 return RValue<Int4>(Nucleus::createSRem(lhs.value, rhs.value));
5071 }
5072
5073 RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs)
5074 {
5075 return RValue<Int4>(Nucleus::createAnd(lhs.value, rhs.value));
5076 }
5077
5078 RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs)
5079 {
5080 return RValue<Int4>(Nucleus::createOr(lhs.value, rhs.value));
5081 }
5082
5083 RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs)
5084 {
5085 return RValue<Int4>(Nucleus::createXor(lhs.value, rhs.value));
5086 }
5087
5088 RValue<Int4> operator<<(RValue<Int4> lhs, unsigned char rhs)
5089 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05005090 return RValue<Int4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005091 }
5092
5093 RValue<Int4> operator>>(RValue<Int4> lhs, unsigned char rhs)
5094 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05005095 return RValue<Int4>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005096 }
5097
5098 RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs)
5099 {
5100 return RValue<Int4>(Nucleus::createShl(lhs.value, rhs.value));
5101 }
5102
5103 RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs)
5104 {
5105 return RValue<Int4>(Nucleus::createAShr(lhs.value, rhs.value));
5106 }
5107
Nicolas Capens96d4e092016-11-18 14:22:38 -05005108 RValue<Int4> operator+=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005109 {
5110 return lhs = lhs + rhs;
5111 }
5112
Nicolas Capens96d4e092016-11-18 14:22:38 -05005113 RValue<Int4> operator-=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005114 {
5115 return lhs = lhs - rhs;
5116 }
5117
Nicolas Capens96d4e092016-11-18 14:22:38 -05005118 RValue<Int4> operator*=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005119 {
5120 return lhs = lhs * rhs;
5121 }
5122
Nicolas Capens96d4e092016-11-18 14:22:38 -05005123// RValue<Int4> operator/=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005124// {
5125// return lhs = lhs / rhs;
5126// }
5127
Nicolas Capens96d4e092016-11-18 14:22:38 -05005128// RValue<Int4> operator%=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005129// {
5130// return lhs = lhs % rhs;
5131// }
5132
Nicolas Capens96d4e092016-11-18 14:22:38 -05005133 RValue<Int4> operator&=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005134 {
5135 return lhs = lhs & rhs;
5136 }
5137
Nicolas Capens96d4e092016-11-18 14:22:38 -05005138 RValue<Int4> operator|=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005139 {
5140 return lhs = lhs | rhs;
5141 }
5142
Nicolas Capens96d4e092016-11-18 14:22:38 -05005143 RValue<Int4> operator^=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005144 {
5145 return lhs = lhs ^ rhs;
5146 }
5147
Nicolas Capens96d4e092016-11-18 14:22:38 -05005148 RValue<Int4> operator<<=(Int4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005149 {
5150 return lhs = lhs << rhs;
5151 }
5152
Nicolas Capens96d4e092016-11-18 14:22:38 -05005153 RValue<Int4> operator>>=(Int4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005154 {
5155 return lhs = lhs >> rhs;
5156 }
5157
5158 RValue<Int4> operator+(RValue<Int4> val)
5159 {
5160 return val;
5161 }
5162
5163 RValue<Int4> operator-(RValue<Int4> val)
5164 {
5165 return RValue<Int4>(Nucleus::createNeg(val.value));
5166 }
5167
5168 RValue<Int4> operator~(RValue<Int4> val)
5169 {
5170 return RValue<Int4>(Nucleus::createNot(val.value));
5171 }
5172
5173 RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y)
5174 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005175 return RValue<Int4>(Nucleus::createICmpEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005176 }
5177
5178 RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y)
5179 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005180 return RValue<Int4>(Nucleus::createICmpSLT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005181 }
5182
5183 RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y)
5184 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005185 return RValue<Int4>(Nucleus::createICmpSLE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005186 }
5187
5188 RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y)
5189 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005190 return RValue<Int4>(Nucleus::createICmpNE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005191 }
5192
5193 RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y)
5194 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005195 return RValue<Int4>(Nucleus::createICmpSGE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005196 }
5197
5198 RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y)
5199 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005200 return RValue<Int4>(Nucleus::createICmpSGT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005201 }
5202
5203 RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y)
5204 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04005205 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
5206 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sle, condition, x.value, y.value);
5207 ::basicBlock->appendInst(cmp);
5208
5209 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5210 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
5211 ::basicBlock->appendInst(select);
5212
5213 return RValue<Int4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005214 }
5215
5216 RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y)
5217 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04005218 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
5219 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sgt, condition, x.value, y.value);
5220 ::basicBlock->appendInst(cmp);
5221
5222 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5223 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
5224 ::basicBlock->appendInst(select);
5225
5226 return RValue<Int4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005227 }
5228
5229 RValue<Int4> RoundInt(RValue<Float4> cast)
5230 {
Nicolas Capensa8086512016-11-07 17:32:17 -05005231 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
Nicolas Capens9ca48d52017-01-14 12:52:55 -05005232 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Nearbyint, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5233 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5234 auto nearbyint = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
5235 nearbyint->addArg(cast.value);
5236 ::basicBlock->appendInst(nearbyint);
Nicolas Capensa8086512016-11-07 17:32:17 -05005237
5238 return RValue<Int4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005239 }
5240
5241 RValue<Short8> Pack(RValue<Int4> x, RValue<Int4> y)
5242 {
Nicolas Capensec54a172016-10-25 17:32:37 -04005243 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
5244 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5245 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5246 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
5247 pack->addArg(x.value);
5248 pack->addArg(y.value);
5249 ::basicBlock->appendInst(pack);
5250
5251 return RValue<Short8>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005252 }
5253
5254 RValue<Int> Extract(RValue<Int4> x, int i)
5255 {
Nicolas Capense95d5342016-09-30 11:37:28 -04005256 return RValue<Int>(Nucleus::createExtractElement(x.value, Int::getType(), i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005257 }
5258
5259 RValue<Int4> Insert(RValue<Int4> x, RValue<Int> element, int i)
5260 {
5261 return RValue<Int4>(Nucleus::createInsertElement(x.value, element.value, i));
5262 }
5263
5264 RValue<Int> SignMask(RValue<Int4> x)
5265 {
Nicolas Capensf2cb9df2016-10-21 17:26:13 -04005266 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
5267 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5268 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5269 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
5270 movmsk->addArg(x.value);
5271 ::basicBlock->appendInst(movmsk);
5272
5273 return RValue<Int>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005274 }
5275
5276 RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select)
5277 {
Nicolas Capense95d5342016-09-30 11:37:28 -04005278 return RValue<Int4>(createSwizzle4(x.value, select));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005279 }
5280
5281 Type *Int4::getType()
5282 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04005283 return T(Ice::IceType_v4i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005284 }
5285
5286 UInt4::UInt4(RValue<Float4> cast)
5287 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05005288 // Smallest positive value representable in UInt, but not in Int
5289 const unsigned int ustart = 0x80000000u;
5290 const float ustartf = float(ustart);
5291
5292 // Check if the value can be represented as an Int
5293 Int4 uiValue = CmpNLT(cast, Float4(ustartf));
5294 // If the value is too large, subtract ustart and re-add it after conversion.
5295 uiValue = (uiValue & As<Int4>(As<UInt4>(Int4(cast - Float4(ustartf))) + UInt4(ustart))) |
5296 // Otherwise, just convert normally
5297 (~uiValue & Int4(cast));
5298 // If the value is negative, store 0, otherwise store the result of the conversion
5299 storeValue((~(As<Int4>(cast) >> 31) & uiValue).value);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005300 }
5301
Nicolas Capens598f8d82016-09-26 15:09:10 -04005302 UInt4::UInt4(int xyzw)
5303 {
5304 constant(xyzw, xyzw, xyzw, xyzw);
5305 }
5306
5307 UInt4::UInt4(int x, int yzw)
5308 {
5309 constant(x, yzw, yzw, yzw);
5310 }
5311
5312 UInt4::UInt4(int x, int y, int zw)
5313 {
5314 constant(x, y, zw, zw);
5315 }
5316
5317 UInt4::UInt4(int x, int y, int z, int w)
5318 {
5319 constant(x, y, z, w);
5320 }
5321
5322 void UInt4::constant(int x, int y, int z, int w)
5323 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04005324 int64_t constantVector[4] = {x, y, z, w};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04005325 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005326 }
5327
5328 UInt4::UInt4(RValue<UInt4> rhs)
5329 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005330 storeValue(rhs.value);
5331 }
5332
5333 UInt4::UInt4(const UInt4 &rhs)
5334 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005335 Value *value = rhs.loadValue();
5336 storeValue(value);
5337 }
5338
5339 UInt4::UInt4(const Reference<UInt4> &rhs)
5340 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005341 Value *value = rhs.loadValue();
5342 storeValue(value);
5343 }
5344
5345 UInt4::UInt4(RValue<Int4> rhs)
5346 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005347 storeValue(rhs.value);
5348 }
5349
5350 UInt4::UInt4(const Int4 &rhs)
5351 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005352 Value *value = rhs.loadValue();
5353 storeValue(value);
5354 }
5355
5356 UInt4::UInt4(const Reference<Int4> &rhs)
5357 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005358 Value *value = rhs.loadValue();
5359 storeValue(value);
5360 }
5361
5362 UInt4::UInt4(RValue<UInt2> lo, RValue<UInt2> hi)
5363 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05005364 int shuffle[4] = {0, 1, 4, 5}; // Real type is v4i32
5365 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
5366
5367 storeValue(packed);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005368 }
5369
Nicolas Capens96d4e092016-11-18 14:22:38 -05005370 RValue<UInt4> UInt4::operator=(RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005371 {
5372 storeValue(rhs.value);
5373
5374 return rhs;
5375 }
5376
Nicolas Capens96d4e092016-11-18 14:22:38 -05005377 RValue<UInt4> UInt4::operator=(const UInt4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005378 {
5379 Value *value = rhs.loadValue();
5380 storeValue(value);
5381
5382 return RValue<UInt4>(value);
5383 }
5384
Nicolas Capens96d4e092016-11-18 14:22:38 -05005385 RValue<UInt4> UInt4::operator=(const Reference<UInt4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005386 {
5387 Value *value = rhs.loadValue();
5388 storeValue(value);
5389
5390 return RValue<UInt4>(value);
5391 }
5392
5393 RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs)
5394 {
5395 return RValue<UInt4>(Nucleus::createAdd(lhs.value, rhs.value));
5396 }
5397
5398 RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs)
5399 {
5400 return RValue<UInt4>(Nucleus::createSub(lhs.value, rhs.value));
5401 }
5402
5403 RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs)
5404 {
5405 return RValue<UInt4>(Nucleus::createMul(lhs.value, rhs.value));
5406 }
5407
5408 RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs)
5409 {
5410 return RValue<UInt4>(Nucleus::createUDiv(lhs.value, rhs.value));
5411 }
5412
5413 RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs)
5414 {
5415 return RValue<UInt4>(Nucleus::createURem(lhs.value, rhs.value));
5416 }
5417
5418 RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs)
5419 {
5420 return RValue<UInt4>(Nucleus::createAnd(lhs.value, rhs.value));
5421 }
5422
5423 RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs)
5424 {
5425 return RValue<UInt4>(Nucleus::createOr(lhs.value, rhs.value));
5426 }
5427
5428 RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs)
5429 {
5430 return RValue<UInt4>(Nucleus::createXor(lhs.value, rhs.value));
5431 }
5432
5433 RValue<UInt4> operator<<(RValue<UInt4> lhs, unsigned char rhs)
5434 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05005435 return RValue<UInt4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005436 }
5437
5438 RValue<UInt4> operator>>(RValue<UInt4> lhs, unsigned char rhs)
5439 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05005440 return RValue<UInt4>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005441 }
5442
5443 RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs)
5444 {
5445 return RValue<UInt4>(Nucleus::createShl(lhs.value, rhs.value));
5446 }
5447
5448 RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs)
5449 {
5450 return RValue<UInt4>(Nucleus::createLShr(lhs.value, rhs.value));
5451 }
5452
Nicolas Capens96d4e092016-11-18 14:22:38 -05005453 RValue<UInt4> operator+=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005454 {
5455 return lhs = lhs + rhs;
5456 }
5457
Nicolas Capens96d4e092016-11-18 14:22:38 -05005458 RValue<UInt4> operator-=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005459 {
5460 return lhs = lhs - rhs;
5461 }
5462
Nicolas Capens96d4e092016-11-18 14:22:38 -05005463 RValue<UInt4> operator*=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005464 {
5465 return lhs = lhs * rhs;
5466 }
5467
Nicolas Capens96d4e092016-11-18 14:22:38 -05005468// RValue<UInt4> operator/=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005469// {
5470// return lhs = lhs / rhs;
5471// }
5472
Nicolas Capens96d4e092016-11-18 14:22:38 -05005473// RValue<UInt4> operator%=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005474// {
5475// return lhs = lhs % rhs;
5476// }
5477
Nicolas Capens96d4e092016-11-18 14:22:38 -05005478 RValue<UInt4> operator&=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005479 {
5480 return lhs = lhs & rhs;
5481 }
5482
Nicolas Capens96d4e092016-11-18 14:22:38 -05005483 RValue<UInt4> operator|=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005484 {
5485 return lhs = lhs | rhs;
5486 }
5487
Nicolas Capens96d4e092016-11-18 14:22:38 -05005488 RValue<UInt4> operator^=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005489 {
5490 return lhs = lhs ^ rhs;
5491 }
5492
Nicolas Capens96d4e092016-11-18 14:22:38 -05005493 RValue<UInt4> operator<<=(UInt4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005494 {
5495 return lhs = lhs << rhs;
5496 }
5497
Nicolas Capens96d4e092016-11-18 14:22:38 -05005498 RValue<UInt4> operator>>=(UInt4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005499 {
5500 return lhs = lhs >> rhs;
5501 }
5502
5503 RValue<UInt4> operator+(RValue<UInt4> val)
5504 {
5505 return val;
5506 }
5507
5508 RValue<UInt4> operator-(RValue<UInt4> val)
5509 {
5510 return RValue<UInt4>(Nucleus::createNeg(val.value));
5511 }
5512
5513 RValue<UInt4> operator~(RValue<UInt4> val)
5514 {
5515 return RValue<UInt4>(Nucleus::createNot(val.value));
5516 }
5517
5518 RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y)
5519 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005520 return RValue<UInt4>(Nucleus::createICmpEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005521 }
5522
5523 RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y)
5524 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005525 return RValue<UInt4>(Nucleus::createICmpULT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005526 }
5527
5528 RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y)
5529 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005530 return RValue<UInt4>(Nucleus::createICmpULE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005531 }
5532
5533 RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y)
5534 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005535 return RValue<UInt4>(Nucleus::createICmpNE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005536 }
5537
5538 RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y)
5539 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005540 return RValue<UInt4>(Nucleus::createICmpUGE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005541 }
5542
5543 RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y)
5544 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005545 return RValue<UInt4>(Nucleus::createICmpUGT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005546 }
5547
5548 RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y)
5549 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04005550 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
5551 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ule, condition, x.value, y.value);
5552 ::basicBlock->appendInst(cmp);
5553
5554 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5555 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
5556 ::basicBlock->appendInst(select);
5557
5558 return RValue<UInt4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005559 }
5560
5561 RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y)
5562 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04005563 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
5564 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ugt, condition, x.value, y.value);
5565 ::basicBlock->appendInst(cmp);
5566
5567 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5568 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
5569 ::basicBlock->appendInst(select);
5570
5571 return RValue<UInt4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005572 }
5573
5574 RValue<UShort8> Pack(RValue<UInt4> x, RValue<UInt4> y)
5575 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05005576 if(CPUID::SSE4_1)
5577 {
5578 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
5579 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5580 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5581 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
5582 pack->addArg(x.value);
5583 pack->addArg(y.value);
5584 ::basicBlock->appendInst(pack);
Nicolas Capensec54a172016-10-25 17:32:37 -04005585
Nicolas Capens9ca48d52017-01-14 12:52:55 -05005586 return RValue<UShort8>(V(result));
5587 }
5588 else
5589 {
5590 RValue<Int4> sx = As<Int4>(x);
5591 RValue<Int4> bx = (sx & ~(sx >> 31)) - Int4(0x8000);
5592
5593 RValue<Int4> sy = As<Int4>(y);
5594 RValue<Int4> by = (sy & ~(sy >> 31)) - Int4(0x8000);
5595
5596 return As<UShort8>(Pack(bx, by) + Short8(0x8000u));
5597 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005598 }
5599
5600 Type *UInt4::getType()
5601 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04005602 return T(Ice::IceType_v4i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005603 }
5604
5605 Float::Float(RValue<Int> cast)
5606 {
5607 Value *integer = Nucleus::createSIToFP(cast.value, Float::getType());
5608
5609 storeValue(integer);
5610 }
5611
Nicolas Capens598f8d82016-09-26 15:09:10 -04005612 Float::Float(float x)
5613 {
5614 storeValue(Nucleus::createConstantFloat(x));
5615 }
5616
5617 Float::Float(RValue<Float> rhs)
5618 {
5619 storeValue(rhs.value);
5620 }
5621
5622 Float::Float(const Float &rhs)
5623 {
5624 Value *value = rhs.loadValue();
5625 storeValue(value);
5626 }
5627
5628 Float::Float(const Reference<Float> &rhs)
5629 {
5630 Value *value = rhs.loadValue();
5631 storeValue(value);
5632 }
5633
Nicolas Capens96d4e092016-11-18 14:22:38 -05005634 RValue<Float> Float::operator=(RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005635 {
5636 storeValue(rhs.value);
5637
5638 return rhs;
5639 }
5640
Nicolas Capens96d4e092016-11-18 14:22:38 -05005641 RValue<Float> Float::operator=(const Float &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005642 {
5643 Value *value = rhs.loadValue();
5644 storeValue(value);
5645
5646 return RValue<Float>(value);
5647 }
5648
Nicolas Capens96d4e092016-11-18 14:22:38 -05005649 RValue<Float> Float::operator=(const Reference<Float> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005650 {
5651 Value *value = rhs.loadValue();
5652 storeValue(value);
5653
5654 return RValue<Float>(value);
5655 }
5656
5657 RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs)
5658 {
5659 return RValue<Float>(Nucleus::createFAdd(lhs.value, rhs.value));
5660 }
5661
5662 RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs)
5663 {
5664 return RValue<Float>(Nucleus::createFSub(lhs.value, rhs.value));
5665 }
5666
5667 RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs)
5668 {
5669 return RValue<Float>(Nucleus::createFMul(lhs.value, rhs.value));
5670 }
5671
5672 RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs)
5673 {
5674 return RValue<Float>(Nucleus::createFDiv(lhs.value, rhs.value));
5675 }
5676
Nicolas Capens96d4e092016-11-18 14:22:38 -05005677 RValue<Float> operator+=(Float &lhs, RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005678 {
5679 return lhs = lhs + rhs;
5680 }
5681
Nicolas Capens96d4e092016-11-18 14:22:38 -05005682 RValue<Float> operator-=(Float &lhs, RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005683 {
5684 return lhs = lhs - rhs;
5685 }
5686
Nicolas Capens96d4e092016-11-18 14:22:38 -05005687 RValue<Float> operator*=(Float &lhs, RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005688 {
5689 return lhs = lhs * rhs;
5690 }
5691
Nicolas Capens96d4e092016-11-18 14:22:38 -05005692 RValue<Float> operator/=(Float &lhs, RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005693 {
5694 return lhs = lhs / rhs;
5695 }
5696
5697 RValue<Float> operator+(RValue<Float> val)
5698 {
5699 return val;
5700 }
5701
5702 RValue<Float> operator-(RValue<Float> val)
5703 {
5704 return RValue<Float>(Nucleus::createFNeg(val.value));
5705 }
5706
5707 RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs)
5708 {
5709 return RValue<Bool>(Nucleus::createFCmpOLT(lhs.value, rhs.value));
5710 }
5711
5712 RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs)
5713 {
5714 return RValue<Bool>(Nucleus::createFCmpOLE(lhs.value, rhs.value));
5715 }
5716
5717 RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs)
5718 {
5719 return RValue<Bool>(Nucleus::createFCmpOGT(lhs.value, rhs.value));
5720 }
5721
5722 RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs)
5723 {
5724 return RValue<Bool>(Nucleus::createFCmpOGE(lhs.value, rhs.value));
5725 }
5726
5727 RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs)
5728 {
5729 return RValue<Bool>(Nucleus::createFCmpONE(lhs.value, rhs.value));
5730 }
5731
5732 RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs)
5733 {
5734 return RValue<Bool>(Nucleus::createFCmpOEQ(lhs.value, rhs.value));
5735 }
5736
5737 RValue<Float> Abs(RValue<Float> x)
5738 {
5739 return IfThenElse(x > 0.0f, x, -x);
5740 }
5741
5742 RValue<Float> Max(RValue<Float> x, RValue<Float> y)
5743 {
5744 return IfThenElse(x > y, x, y);
5745 }
5746
5747 RValue<Float> Min(RValue<Float> x, RValue<Float> y)
5748 {
5749 return IfThenElse(x < y, x, y);
5750 }
5751
5752 RValue<Float> Rcp_pp(RValue<Float> x, bool exactAtPow2)
5753 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04005754 return 1.0f / x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005755 }
5756
5757 RValue<Float> RcpSqrt_pp(RValue<Float> x)
5758 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04005759 return Rcp_pp(Sqrt(x));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005760 }
5761
5762 RValue<Float> Sqrt(RValue<Float> x)
5763 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04005764 Ice::Variable *result = ::function->makeVariable(Ice::IceType_f32);
5765 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Sqrt, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5766 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5767 auto sqrt = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
5768 sqrt->addArg(x.value);
5769 ::basicBlock->appendInst(sqrt);
5770
5771 return RValue<Float>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005772 }
5773
5774 RValue<Float> Round(RValue<Float> x)
5775 {
Nicolas Capensa8086512016-11-07 17:32:17 -05005776 return Float4(Round(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005777 }
5778
5779 RValue<Float> Trunc(RValue<Float> x)
5780 {
Nicolas Capensa8086512016-11-07 17:32:17 -05005781 return Float4(Trunc(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005782 }
5783
5784 RValue<Float> Frac(RValue<Float> x)
5785 {
Nicolas Capensa8086512016-11-07 17:32:17 -05005786 return Float4(Frac(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005787 }
5788
5789 RValue<Float> Floor(RValue<Float> x)
5790 {
Nicolas Capensa8086512016-11-07 17:32:17 -05005791 return Float4(Floor(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005792 }
5793
5794 RValue<Float> Ceil(RValue<Float> x)
5795 {
Nicolas Capensa8086512016-11-07 17:32:17 -05005796 return Float4(Ceil(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005797 }
5798
5799 Type *Float::getType()
5800 {
Nicolas Capens9709d4f2016-09-30 11:44:14 -04005801 return T(Ice::IceType_f32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005802 }
5803
5804 Float2::Float2(RValue<Float4> cast)
5805 {
Nicolas Capens22008782016-10-20 01:11:47 -04005806 storeValue(Nucleus::createBitCast(cast.value, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005807 }
5808
5809 Type *Float2::getType()
5810 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04005811 return T(Type_v2f32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005812 }
5813
Nicolas Capensa25311a2017-01-16 17:19:00 -05005814 Float4::Float4(RValue<Byte4> cast) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005815 {
Nicolas Capensd4227962016-11-09 14:24:25 -05005816 Value *a = Int4(cast).loadValue();
5817 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
5818
5819 storeValue(xyzw);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005820 }
5821
Nicolas Capensa25311a2017-01-16 17:19:00 -05005822 Float4::Float4(RValue<SByte4> cast) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005823 {
Nicolas Capensd4227962016-11-09 14:24:25 -05005824 Value *a = Int4(cast).loadValue();
5825 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
5826
5827 storeValue(xyzw);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005828 }
5829
Nicolas Capensa25311a2017-01-16 17:19:00 -05005830 Float4::Float4(RValue<Short4> cast) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005831 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005832 Int4 c(cast);
5833 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
5834 }
5835
Nicolas Capensa25311a2017-01-16 17:19:00 -05005836 Float4::Float4(RValue<UShort4> cast) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005837 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005838 Int4 c(cast);
5839 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
5840 }
5841
Nicolas Capensa25311a2017-01-16 17:19:00 -05005842 Float4::Float4(RValue<Int4> cast) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005843 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005844 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType());
5845
5846 storeValue(xyzw);
5847 }
5848
Nicolas Capensa25311a2017-01-16 17:19:00 -05005849 Float4::Float4(RValue<UInt4> cast) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005850 {
Nicolas Capens96445fe2016-12-15 14:45:13 -05005851 RValue<Float4> result = Float4(Int4(cast & UInt4(0x7FFFFFFF))) +
5852 As<Float4>((As<Int4>(cast) >> 31) & As<Int4>(Float4(0x80000000u)));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005853
Nicolas Capens96445fe2016-12-15 14:45:13 -05005854 storeValue(result.value);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005855 }
5856
Nicolas Capensa25311a2017-01-16 17:19:00 -05005857 Float4::Float4() : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005858 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005859 }
5860
Nicolas Capensa25311a2017-01-16 17:19:00 -05005861 Float4::Float4(float xyzw) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005862 {
5863 constant(xyzw, xyzw, xyzw, xyzw);
5864 }
5865
Nicolas Capensa25311a2017-01-16 17:19:00 -05005866 Float4::Float4(float x, float yzw) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005867 {
5868 constant(x, yzw, yzw, yzw);
5869 }
5870
Nicolas Capensa25311a2017-01-16 17:19:00 -05005871 Float4::Float4(float x, float y, float zw) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005872 {
5873 constant(x, y, zw, zw);
5874 }
5875
Nicolas Capensa25311a2017-01-16 17:19:00 -05005876 Float4::Float4(float x, float y, float z, float w) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005877 {
5878 constant(x, y, z, w);
5879 }
5880
5881 void Float4::constant(float x, float y, float z, float w)
5882 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04005883 double constantVector[4] = {x, y, z, w};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04005884 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005885 }
5886
Nicolas Capensa25311a2017-01-16 17:19:00 -05005887 Float4::Float4(RValue<Float4> rhs) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005888 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005889 storeValue(rhs.value);
5890 }
5891
Nicolas Capensa25311a2017-01-16 17:19:00 -05005892 Float4::Float4(const Float4 &rhs) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005893 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005894 Value *value = rhs.loadValue();
5895 storeValue(value);
5896 }
5897
Nicolas Capensa25311a2017-01-16 17:19:00 -05005898 Float4::Float4(const Reference<Float4> &rhs) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005899 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005900 Value *value = rhs.loadValue();
5901 storeValue(value);
5902 }
5903
Nicolas Capensa25311a2017-01-16 17:19:00 -05005904 Float4::Float4(RValue<Float> rhs) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005905 {
Nicolas Capensd4227962016-11-09 14:24:25 -05005906 Value *vector = loadValue();
5907 Value *insert = Nucleus::createInsertElement(vector, rhs.value, 0);
5908
5909 int swizzle[4] = {0, 0, 0, 0};
5910 Value *replicate = Nucleus::createShuffleVector(insert, insert, swizzle);
5911
5912 storeValue(replicate);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005913 }
5914
Nicolas Capensa25311a2017-01-16 17:19:00 -05005915 Float4::Float4(const Float &rhs) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005916 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005917 *this = RValue<Float>(rhs.loadValue());
5918 }
5919
Nicolas Capensa25311a2017-01-16 17:19:00 -05005920 Float4::Float4(const Reference<Float> &rhs) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005921 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005922 *this = RValue<Float>(rhs.loadValue());
5923 }
5924
Nicolas Capens96d4e092016-11-18 14:22:38 -05005925 RValue<Float4> Float4::operator=(float x)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005926 {
5927 return *this = Float4(x, x, x, x);
5928 }
5929
Nicolas Capens96d4e092016-11-18 14:22:38 -05005930 RValue<Float4> Float4::operator=(RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005931 {
5932 storeValue(rhs.value);
5933
5934 return rhs;
5935 }
5936
Nicolas Capens96d4e092016-11-18 14:22:38 -05005937 RValue<Float4> Float4::operator=(const Float4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005938 {
5939 Value *value = rhs.loadValue();
5940 storeValue(value);
5941
5942 return RValue<Float4>(value);
5943 }
5944
Nicolas Capens96d4e092016-11-18 14:22:38 -05005945 RValue<Float4> Float4::operator=(const Reference<Float4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005946 {
5947 Value *value = rhs.loadValue();
5948 storeValue(value);
5949
5950 return RValue<Float4>(value);
5951 }
5952
Nicolas Capens96d4e092016-11-18 14:22:38 -05005953 RValue<Float4> Float4::operator=(RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005954 {
5955 return *this = Float4(rhs);
5956 }
5957
Nicolas Capens96d4e092016-11-18 14:22:38 -05005958 RValue<Float4> Float4::operator=(const Float &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005959 {
5960 return *this = Float4(rhs);
5961 }
5962
Nicolas Capens96d4e092016-11-18 14:22:38 -05005963 RValue<Float4> Float4::operator=(const Reference<Float> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005964 {
5965 return *this = Float4(rhs);
5966 }
5967
5968 RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs)
5969 {
5970 return RValue<Float4>(Nucleus::createFAdd(lhs.value, rhs.value));
5971 }
5972
5973 RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs)
5974 {
5975 return RValue<Float4>(Nucleus::createFSub(lhs.value, rhs.value));
5976 }
5977
5978 RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs)
5979 {
5980 return RValue<Float4>(Nucleus::createFMul(lhs.value, rhs.value));
5981 }
5982
5983 RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs)
5984 {
5985 return RValue<Float4>(Nucleus::createFDiv(lhs.value, rhs.value));
5986 }
5987
5988 RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs)
5989 {
5990 return RValue<Float4>(Nucleus::createFRem(lhs.value, rhs.value));
5991 }
5992
Nicolas Capens96d4e092016-11-18 14:22:38 -05005993 RValue<Float4> operator+=(Float4 &lhs, RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005994 {
5995 return lhs = lhs + rhs;
5996 }
5997
Nicolas Capens96d4e092016-11-18 14:22:38 -05005998 RValue<Float4> operator-=(Float4 &lhs, RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005999 {
6000 return lhs = lhs - rhs;
6001 }
6002
Nicolas Capens96d4e092016-11-18 14:22:38 -05006003 RValue<Float4> operator*=(Float4 &lhs, RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006004 {
6005 return lhs = lhs * rhs;
6006 }
6007
Nicolas Capens96d4e092016-11-18 14:22:38 -05006008 RValue<Float4> operator/=(Float4 &lhs, RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006009 {
6010 return lhs = lhs / rhs;
6011 }
6012
Nicolas Capens96d4e092016-11-18 14:22:38 -05006013 RValue<Float4> operator%=(Float4 &lhs, RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006014 {
6015 return lhs = lhs % rhs;
6016 }
6017
6018 RValue<Float4> operator+(RValue<Float4> val)
6019 {
6020 return val;
6021 }
6022
6023 RValue<Float4> operator-(RValue<Float4> val)
6024 {
6025 return RValue<Float4>(Nucleus::createFNeg(val.value));
6026 }
6027
6028 RValue<Float4> Abs(RValue<Float4> x)
6029 {
Nicolas Capens84272242016-11-09 13:31:06 -05006030 Value *vector = Nucleus::createBitCast(x.value, Int4::getType());
6031 int64_t constantVector[4] = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF};
6032 Value *result = Nucleus::createAnd(vector, V(Nucleus::createConstantVector(constantVector, Int4::getType())));
6033
6034 return As<Float4>(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006035 }
6036
6037 RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y)
6038 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006039 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
6040 auto cmp = Ice::InstFcmp::create(::function, Ice::InstFcmp::Ule, condition, x.value, y.value);
6041 ::basicBlock->appendInst(cmp);
6042
6043 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6044 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
6045 ::basicBlock->appendInst(select);
6046
6047 return RValue<Float4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006048 }
6049
6050 RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y)
6051 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006052 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
6053 auto cmp = Ice::InstFcmp::create(::function, Ice::InstFcmp::Ugt, condition, x.value, y.value);
6054 ::basicBlock->appendInst(cmp);
6055
6056 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6057 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
6058 ::basicBlock->appendInst(select);
6059
6060 return RValue<Float4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006061 }
6062
6063 RValue<Float4> Rcp_pp(RValue<Float4> x, bool exactAtPow2)
6064 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04006065 return Float4(1.0f) / x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04006066 }
6067
6068 RValue<Float4> RcpSqrt_pp(RValue<Float4> x)
6069 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04006070 return Rcp_pp(Sqrt(x));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006071 }
6072
6073 RValue<Float4> Sqrt(RValue<Float4> x)
6074 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04006075 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6076 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Sqrt, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6077 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6078 auto sqrt = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
6079 sqrt->addArg(x.value);
6080 ::basicBlock->appendInst(sqrt);
6081
6082 return RValue<Float4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006083 }
6084
Nicolas Capensc94ab742016-11-08 15:15:31 -05006085 RValue<Float4> Insert(RValue<Float4> x, RValue<Float> element, int i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006086 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05006087 return RValue<Float4>(Nucleus::createInsertElement(x.value, element.value, i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006088 }
6089
6090 RValue<Float> Extract(RValue<Float4> x, int i)
6091 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006092 return RValue<Float>(Nucleus::createExtractElement(x.value, Float::getType(), i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006093 }
6094
6095 RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select)
6096 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006097 return RValue<Float4>(createSwizzle4(x.value, select));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006098 }
6099
6100 RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
6101 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04006102 int shuffle[4] =
6103 {
6104 ((imm >> 0) & 0x03) + 0,
6105 ((imm >> 2) & 0x03) + 0,
6106 ((imm >> 4) & 0x03) + 4,
6107 ((imm >> 6) & 0x03) + 4,
6108 };
6109
6110 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006111 }
6112
6113 RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y)
6114 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04006115 int shuffle[4] = {0, 4, 1, 5};
6116 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006117 }
6118
6119 RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y)
6120 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04006121 int shuffle[4] = {2, 6, 3, 7};
6122 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006123 }
6124
6125 RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select)
6126 {
6127 Value *vector = lhs.loadValue();
Nicolas Capensa4c30b02016-11-08 15:43:17 -05006128 Value *result = createMask4(vector, rhs.value, select);
6129 lhs.storeValue(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006130
Nicolas Capensa4c30b02016-11-08 15:43:17 -05006131 return RValue<Float4>(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006132 }
6133
6134 RValue<Int> SignMask(RValue<Float4> x)
6135 {
Nicolas Capensf2cb9df2016-10-21 17:26:13 -04006136 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
6137 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6138 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6139 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
6140 movmsk->addArg(x.value);
6141 ::basicBlock->appendInst(movmsk);
6142
6143 return RValue<Int>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006144 }
6145
6146 RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y)
6147 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006148 return RValue<Int4>(Nucleus::createFCmpOEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006149 }
6150
6151 RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y)
6152 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006153 return RValue<Int4>(Nucleus::createFCmpOLT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006154 }
6155
6156 RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y)
6157 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006158 return RValue<Int4>(Nucleus::createFCmpOLE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006159 }
6160
6161 RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y)
6162 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006163 return RValue<Int4>(Nucleus::createFCmpONE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006164 }
6165
6166 RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y)
6167 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006168 return RValue<Int4>(Nucleus::createFCmpOGE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006169 }
6170
6171 RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y)
6172 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006173 return RValue<Int4>(Nucleus::createFCmpOGT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006174 }
6175
6176 RValue<Float4> Round(RValue<Float4> x)
6177 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05006178 if(CPUID::SSE4_1)
6179 {
6180 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6181 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6182 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6183 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
6184 round->addArg(x.value);
6185 round->addArg(::context->getConstantInt32(0));
6186 ::basicBlock->appendInst(round);
Nicolas Capensa8086512016-11-07 17:32:17 -05006187
Nicolas Capens9ca48d52017-01-14 12:52:55 -05006188 return RValue<Float4>(V(result));
6189 }
6190 else
6191 {
6192 return Float4(RoundInt(x));
6193 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04006194 }
6195
6196 RValue<Float4> Trunc(RValue<Float4> x)
6197 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05006198 if(CPUID::SSE4_1)
6199 {
6200 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6201 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6202 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6203 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
6204 round->addArg(x.value);
6205 round->addArg(::context->getConstantInt32(3));
6206 ::basicBlock->appendInst(round);
Nicolas Capensa8086512016-11-07 17:32:17 -05006207
Nicolas Capens9ca48d52017-01-14 12:52:55 -05006208 return RValue<Float4>(V(result));
6209 }
6210 else
6211 {
6212 return Float4(Int4(x));
6213 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04006214 }
6215
6216 RValue<Float4> Frac(RValue<Float4> x)
6217 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05006218 if(CPUID::SSE4_1)
6219 {
6220 return x - Floor(x);
6221 }
6222 else
6223 {
6224 Float4 frc = x - Float4(Int4(x)); // Signed fractional part
6225
6226 return frc + As<Float4>(As<Int4>(CmpNLE(Float4(0.0f), frc)) & As<Int4>(Float4(1, 1, 1, 1)));
6227 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04006228 }
6229
6230 RValue<Float4> Floor(RValue<Float4> x)
6231 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05006232 if(CPUID::SSE4_1)
6233 {
6234 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6235 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6236 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6237 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
6238 round->addArg(x.value);
6239 round->addArg(::context->getConstantInt32(1));
6240 ::basicBlock->appendInst(round);
Nicolas Capensa8086512016-11-07 17:32:17 -05006241
Nicolas Capens9ca48d52017-01-14 12:52:55 -05006242 return RValue<Float4>(V(result));
6243 }
6244 else
6245 {
6246 return x - Frac(x);
6247 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04006248 }
6249
6250 RValue<Float4> Ceil(RValue<Float4> x)
6251 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05006252 if(CPUID::SSE4_1)
6253 {
6254 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6255 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6256 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6257 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
6258 round->addArg(x.value);
6259 round->addArg(::context->getConstantInt32(2));
6260 ::basicBlock->appendInst(round);
Nicolas Capensa8086512016-11-07 17:32:17 -05006261
Nicolas Capens9ca48d52017-01-14 12:52:55 -05006262 return RValue<Float4>(V(result));
6263 }
6264 else
6265 {
6266 return -Floor(-x);
6267 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04006268 }
6269
6270 Type *Float4::getType()
6271 {
Nicolas Capens9709d4f2016-09-30 11:44:14 -04006272 return T(Ice::IceType_v4f32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006273 }
6274
6275 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset)
6276 {
Nicolas Capens8820f642016-09-30 04:42:43 -04006277 return lhs + RValue<Int>(Nucleus::createConstantInt(offset));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006278 }
6279
6280 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
6281 {
Nicolas Capens6d738712016-09-30 04:15:22 -04006282 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006283 }
6284
6285 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
6286 {
Nicolas Capens6d738712016-09-30 04:15:22 -04006287 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006288 }
6289
Nicolas Capens96d4e092016-11-18 14:22:38 -05006290 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, int offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006291 {
6292 return lhs = lhs + offset;
6293 }
6294
Nicolas Capens96d4e092016-11-18 14:22:38 -05006295 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<Int> offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006296 {
6297 return lhs = lhs + offset;
6298 }
6299
Nicolas Capens96d4e092016-11-18 14:22:38 -05006300 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<UInt> offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006301 {
6302 return lhs = lhs + offset;
6303 }
6304
6305 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset)
6306 {
6307 return lhs + -offset;
6308 }
6309
6310 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
6311 {
6312 return lhs + -offset;
6313 }
6314
6315 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
6316 {
6317 return lhs + -offset;
6318 }
6319
Nicolas Capens96d4e092016-11-18 14:22:38 -05006320 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, int offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006321 {
6322 return lhs = lhs - offset;
6323 }
6324
Nicolas Capens96d4e092016-11-18 14:22:38 -05006325 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<Int> offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006326 {
6327 return lhs = lhs - offset;
6328 }
6329
Nicolas Capens96d4e092016-11-18 14:22:38 -05006330 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<UInt> offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006331 {
6332 return lhs = lhs - offset;
6333 }
6334
6335 void Return()
6336 {
6337 Nucleus::createRetVoid();
6338 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
6339 Nucleus::createUnreachable();
6340 }
6341
Nicolas Capenseb253d02016-11-18 14:40:40 -05006342 void Return(RValue<Int> ret)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006343 {
Nicolas Capenseb253d02016-11-18 14:40:40 -05006344 Nucleus::createRet(ret.value);
Nicolas Capensfdcca2d2016-10-20 11:31:36 -04006345 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
6346 Nucleus::createUnreachable();
Nicolas Capens598f8d82016-09-26 15:09:10 -04006347 }
6348
Nicolas Capens598f8d82016-09-26 15:09:10 -04006349 bool branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB)
6350 {
6351 Nucleus::createCondBr(cmp.value, bodyBB, endBB);
6352 Nucleus::setInsertBlock(bodyBB);
6353
6354 return true;
6355 }
6356
Nicolas Capens598f8d82016-09-26 15:09:10 -04006357 RValue<Long> Ticks()
6358 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04006359 assert(false && "UNIMPLEMENTED"); return RValue<Long>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006360 }
6361}