blob: 30f47149b0b3208251c7ac4150260973500a9dfb [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 Capens411273e2017-01-26 15:13:36 -080043#if !defined(MAP_ANONYMOUS)
44#define MAP_ANONYMOUS MAP_ANON
Nicolas Capens8b275742017-01-20 17:11:41 -050045#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 Capens584088c2017-01-26 16:05:18 -0800143 static size_t typeSize(Type *type)
144 {
145 if(reinterpret_cast<std::intptr_t>(type) & EmulatedBits)
146 {
147 switch(reinterpret_cast<std::intptr_t>(type))
148 {
149 case Type_v2i32: return 8;
150 case Type_v4i16: return 8;
151 case Type_v2i16: return 4;
152 case Type_v8i8: return 8;
153 case Type_v4i8: return 4;
154 case Type_v2f32: return 8;
155 default: assert(false);
156 }
157 }
158
159 return Ice::typeWidthInBytes(T(type));
160 }
161
Nicolas Capens598f8d82016-09-26 15:09:10 -0400162 Optimization optimization[10] = {InstructionCombining, Disabled};
163
Nicolas Capens66478362016-10-13 15:36:36 -0400164 using ElfHeader = std::conditional<sizeof(void*) == 8, Elf64_Ehdr, Elf32_Ehdr>::type;
165 using SectionHeader = std::conditional<sizeof(void*) == 8, Elf64_Shdr, Elf32_Shdr>::type;
166
167 inline const SectionHeader *sectionHeader(const ElfHeader *elfHeader)
168 {
169 return reinterpret_cast<const SectionHeader*>((intptr_t)elfHeader + elfHeader->e_shoff);
170 }
Nicolas Capens87852e12016-11-24 14:45:06 -0500171
Nicolas Capens66478362016-10-13 15:36:36 -0400172 inline const SectionHeader *elfSection(const ElfHeader *elfHeader, int index)
173 {
174 return &sectionHeader(elfHeader)[index];
175 }
176
177 static void *relocateSymbol(const ElfHeader *elfHeader, const Elf32_Rel &relocation, const SectionHeader &relocationTable)
178 {
179 const SectionHeader *target = elfSection(elfHeader, relocationTable.sh_info);
Nicolas Capens87852e12016-11-24 14:45:06 -0500180
Nicolas Capens66478362016-10-13 15:36:36 -0400181 intptr_t address = (intptr_t)elfHeader + target->sh_offset;
182 int32_t *patchSite = (int*)(address + relocation.r_offset);
183 uint32_t index = relocation.getSymbol();
184 int table = relocationTable.sh_link;
185 void *symbolValue = nullptr;
Nicolas Capens87852e12016-11-24 14:45:06 -0500186
Nicolas Capens66478362016-10-13 15:36:36 -0400187 if(index != SHN_UNDEF)
188 {
189 if(table == SHN_UNDEF) return nullptr;
190 const SectionHeader *symbolTable = elfSection(elfHeader, table);
Nicolas Capens87852e12016-11-24 14:45:06 -0500191
Nicolas Capens66478362016-10-13 15:36:36 -0400192 uint32_t symtab_entries = symbolTable->sh_size / symbolTable->sh_entsize;
193 if(index >= symtab_entries)
194 {
195 assert(index < symtab_entries && "Symbol Index out of range");
196 return nullptr;
197 }
Nicolas Capens87852e12016-11-24 14:45:06 -0500198
Nicolas Capens66478362016-10-13 15:36:36 -0400199 intptr_t symbolAddress = (intptr_t)elfHeader + symbolTable->sh_offset;
200 Elf32_Sym &symbol = ((Elf32_Sym*)symbolAddress)[index];
201 uint16_t section = symbol.st_shndx;
202
203 if(section != SHN_UNDEF && section < SHN_LORESERVE)
204 {
205 const SectionHeader *target = elfSection(elfHeader, symbol.st_shndx);
206 symbolValue = reinterpret_cast<void*>((intptr_t)elfHeader + symbol.st_value + target->sh_offset);
207 }
208 else
209 {
210 return nullptr;
211 }
212 }
213
214 switch(relocation.getType())
215 {
216 case R_386_NONE:
217 // No relocation
218 break;
219 case R_386_32:
220 *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite);
221 break;
222 // case R_386_PC32:
223 // *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite - (intptr_t)patchSite);
224 // break;
225 default:
226 assert(false && "Unsupported relocation type");
227 return nullptr;
228 }
229
230 return symbolValue;
231 }
232
233 static void *relocateSymbol(const ElfHeader *elfHeader, const Elf64_Rela &relocation, const SectionHeader &relocationTable)
234 {
235 const SectionHeader *target = elfSection(elfHeader, relocationTable.sh_info);
Nicolas Capens87852e12016-11-24 14:45:06 -0500236
Nicolas Capens66478362016-10-13 15:36:36 -0400237 intptr_t address = (intptr_t)elfHeader + target->sh_offset;
238 int32_t *patchSite = (int*)(address + relocation.r_offset);
239 uint32_t index = relocation.getSymbol();
240 int table = relocationTable.sh_link;
241 void *symbolValue = nullptr;
242
243 if(index != SHN_UNDEF)
244 {
245 if(table == SHN_UNDEF) return nullptr;
246 const SectionHeader *symbolTable = elfSection(elfHeader, table);
Nicolas Capens87852e12016-11-24 14:45:06 -0500247
Nicolas Capens66478362016-10-13 15:36:36 -0400248 uint32_t symtab_entries = symbolTable->sh_size / symbolTable->sh_entsize;
249 if(index >= symtab_entries)
250 {
251 assert(index < symtab_entries && "Symbol Index out of range");
252 return nullptr;
253 }
Nicolas Capens87852e12016-11-24 14:45:06 -0500254
Nicolas Capens66478362016-10-13 15:36:36 -0400255 intptr_t symbolAddress = (intptr_t)elfHeader + symbolTable->sh_offset;
256 Elf64_Sym &symbol = ((Elf64_Sym*)symbolAddress)[index];
257 uint16_t section = symbol.st_shndx;
258
259 if(section != SHN_UNDEF && section < SHN_LORESERVE)
260 {
261 const SectionHeader *target = elfSection(elfHeader, symbol.st_shndx);
262 symbolValue = reinterpret_cast<void*>((intptr_t)elfHeader + symbol.st_value + target->sh_offset);
263 }
264 else
265 {
266 return nullptr;
267 }
268 }
269
270 switch(relocation.getType())
271 {
272 case R_X86_64_NONE:
273 // No relocation
274 break;
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500275 case R_X86_64_64:
276 *(int64_t*)patchSite = (int64_t)((intptr_t)symbolValue + *(int64_t*)patchSite) + relocation.r_addend;
277 break;
Nicolas Capens66478362016-10-13 15:36:36 -0400278 case R_X86_64_PC32:
279 *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite - (intptr_t)patchSite) + relocation.r_addend;
280 break;
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500281 case R_X86_64_32S:
282 *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite) + relocation.r_addend;
283 break;
Nicolas Capens66478362016-10-13 15:36:36 -0400284 default:
285 assert(false && "Unsupported relocation type");
286 return nullptr;
287 }
288
289 return symbolValue;
290 }
291
Nicolas Capens598f8d82016-09-26 15:09:10 -0400292 void *loadImage(uint8_t *const elfImage)
293 {
Nicolas Capens598f8d82016-09-26 15:09:10 -0400294 ElfHeader *elfHeader = (ElfHeader*)elfImage;
295
296 if(!elfHeader->checkMagic())
297 {
298 return nullptr;
299 }
300
Nicolas Capens66478362016-10-13 15:36:36 -0400301 // Expect ELF bitness to match platform
Nicolas Capens65047112016-11-07 13:01:07 -0500302 assert(sizeof(void*) == 8 ? elfHeader->getFileClass() == ELFCLASS64 : elfHeader->getFileClass() == ELFCLASS32);
Nicolas Capens66478362016-10-13 15:36:36 -0400303 assert(sizeof(void*) == 8 ? elfHeader->e_machine == EM_X86_64 : elfHeader->e_machine == EM_386);
304
Nicolas Capens598f8d82016-09-26 15:09:10 -0400305 SectionHeader *sectionHeader = (SectionHeader*)(elfImage + elfHeader->e_shoff);
306 void *entry = nullptr;
307
308 for(int i = 0; i < elfHeader->e_shnum; i++)
309 {
Nicolas Capens66478362016-10-13 15:36:36 -0400310 if(sectionHeader[i].sh_type == SHT_PROGBITS)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400311 {
Nicolas Capens66478362016-10-13 15:36:36 -0400312 if(sectionHeader[i].sh_flags & SHF_EXECINSTR)
313 {
314 entry = elfImage + sectionHeader[i].sh_offset;
315 }
316 }
317 else if(sectionHeader[i].sh_type == SHT_REL)
318 {
319 assert(sizeof(void*) == 4 && "UNIMPLEMENTED"); // Only expected/implemented for 32-bit code
320
Alexis Hetu113e33a2017-01-19 10:49:19 -0500321 for(Elf32_Word index = 0; index < sectionHeader[i].sh_size / sectionHeader[i].sh_entsize; index++)
Nicolas Capens66478362016-10-13 15:36:36 -0400322 {
323 const Elf32_Rel &relocation = ((const Elf32_Rel*)(elfImage + sectionHeader[i].sh_offset))[index];
Alexis Hetu113e33a2017-01-19 10:49:19 -0500324 relocateSymbol(elfHeader, relocation, sectionHeader[i]);
Nicolas Capens66478362016-10-13 15:36:36 -0400325 }
326 }
327 else if(sectionHeader[i].sh_type == SHT_RELA)
328 {
329 assert(sizeof(void*) == 8 && "UNIMPLEMENTED"); // Only expected/implemented for 64-bit code
330
Alexis Hetu113e33a2017-01-19 10:49:19 -0500331 for(Elf32_Word index = 0; index < sectionHeader[i].sh_size / sectionHeader[i].sh_entsize; index++)
Nicolas Capens66478362016-10-13 15:36:36 -0400332 {
333 const Elf64_Rela &relocation = ((const Elf64_Rela*)(elfImage + sectionHeader[i].sh_offset))[index];
Alexis Hetu113e33a2017-01-19 10:49:19 -0500334 relocateSymbol(elfHeader, relocation, sectionHeader[i]);
Nicolas Capens66478362016-10-13 15:36:36 -0400335 }
Nicolas Capens598f8d82016-09-26 15:09:10 -0400336 }
337 }
338
339 return entry;
340 }
341
342 template<typename T>
343 struct ExecutableAllocator
344 {
345 ExecutableAllocator() {};
346 template<class U> ExecutableAllocator(const ExecutableAllocator<U> &other) {};
347
348 using value_type = T;
349 using size_type = std::size_t;
350
351 T *allocate(size_type n)
352 {
Nicolas Capensbd65da92017-01-05 16:31:06 -0500353 #if defined(_WIN32)
354 return (T*)VirtualAlloc(NULL, sizeof(T) * n, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
355 #else
356 return (T*)mmap(nullptr, sizeof(T) * n, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
357 #endif
Nicolas Capens598f8d82016-09-26 15:09:10 -0400358 }
359
360 void deallocate(T *p, size_type n)
361 {
Nicolas Capensbd65da92017-01-05 16:31:06 -0500362 #if defined(_WIN32)
363 VirtualFree(p, 0, MEM_RELEASE);
364 #else
365 munmap(p, sizeof(T) * n);
366 #endif
Nicolas Capens598f8d82016-09-26 15:09:10 -0400367 }
368 };
369
370 class ELFMemoryStreamer : public Ice::ELFStreamer, public Routine
371 {
372 ELFMemoryStreamer(const ELFMemoryStreamer &) = delete;
373 ELFMemoryStreamer &operator=(const ELFMemoryStreamer &) = delete;
374
375 public:
Nicolas Capens58274b52016-10-19 23:45:19 -0400376 ELFMemoryStreamer() : Routine(), entry(nullptr)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400377 {
378 position = 0;
379 buffer.reserve(0x1000);
380 }
381
382 virtual ~ELFMemoryStreamer()
383 {
Nicolas Capensbd65da92017-01-05 16:31:06 -0500384 #if defined(_WIN32)
385 if(buffer.size() != 0)
386 {
387 DWORD exeProtection;
388 VirtualProtect(&buffer[0], buffer.size(), oldProtection, &exeProtection);
389 }
390 #endif
Nicolas Capens598f8d82016-09-26 15:09:10 -0400391 }
392
393 void write8(uint8_t Value) override
394 {
395 if(position == (uint64_t)buffer.size())
396 {
397 buffer.push_back(Value);
398 position++;
399 }
400 else if(position < (uint64_t)buffer.size())
401 {
402 buffer[position] = Value;
403 position++;
404 }
405 else assert(false && "UNIMPLEMENTED");
406 }
407
408 void writeBytes(llvm::StringRef Bytes) override
409 {
410 std::size_t oldSize = buffer.size();
411 buffer.resize(oldSize + Bytes.size());
412 memcpy(&buffer[oldSize], Bytes.begin(), Bytes.size());
413 position += Bytes.size();
414 }
415
416 uint64_t tell() const override { return position; }
417
418 void seek(uint64_t Off) override { position = Off; }
419
420 const void *getEntry() override
421 {
Nicolas Capens58274b52016-10-19 23:45:19 -0400422 if(!entry)
423 {
Nicolas Capensbd65da92017-01-05 16:31:06 -0500424 #if defined(_WIN32)
425 VirtualProtect(&buffer[0], buffer.size(), PAGE_EXECUTE_READWRITE, &oldProtection);
426 #else
427 mprotect(&buffer[0], buffer.size(), PROT_READ | PROT_WRITE | PROT_EXEC);
428 #endif
429
430 position = std::numeric_limits<std::size_t>::max(); // Can't stream more data after this
Nicolas Capens598f8d82016-09-26 15:09:10 -0400431
Nicolas Capens58274b52016-10-19 23:45:19 -0400432 entry = loadImage(&buffer[0]);
433 }
434
435 return entry;
Nicolas Capens598f8d82016-09-26 15:09:10 -0400436 }
437
438 private:
Nicolas Capens58274b52016-10-19 23:45:19 -0400439 void *entry;
Nicolas Capens598f8d82016-09-26 15:09:10 -0400440 std::vector<uint8_t, ExecutableAllocator<uint8_t>> buffer;
441 std::size_t position;
Nicolas Capensbd65da92017-01-05 16:31:06 -0500442
443 #if defined(_WIN32)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400444 DWORD oldProtection;
Nicolas Capensbd65da92017-01-05 16:31:06 -0500445 #endif
Nicolas Capens598f8d82016-09-26 15:09:10 -0400446 };
447
448 Nucleus::Nucleus()
449 {
450 ::codegenMutex.lock(); // Reactor is currently not thread safe
451
Nicolas Capens66478362016-10-13 15:36:36 -0400452 Ice::ClFlags &Flags = Ice::ClFlags::Flags;
453 Ice::ClFlags::getParsedClFlags(Flags);
454
455 Flags.setTargetArch(sizeof(void*) == 8 ? Ice::Target_X8664 : Ice::Target_X8632);
456 Flags.setOutFileType(Ice::FT_Elf);
457 Flags.setOptLevel(Ice::Opt_2);
458 Flags.setApplicationBinaryInterface(Ice::ABI_Platform);
Nicolas Capensccd5ecb2017-01-14 12:52:55 -0500459 Flags.setTargetInstructionSet(CPUID::SSE4_1 ? Ice::X86InstructionSet_SSE4_1 : Ice::X86InstructionSet_SSE2);
Nicolas Capens65047112016-11-07 13:01:07 -0500460 Flags.setVerbose(false ? Ice::IceV_All : Ice::IceV_None);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400461
Nicolas Capens65047112016-11-07 13:01:07 -0500462 static llvm::raw_os_ostream cout(std::cout);
463 static llvm::raw_os_ostream cerr(std::cerr);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400464
465 if(false) // Write out to a file
466 {
467 std::error_code errorCode;
468 ::out = new Ice::Fdstream("out.o", errorCode, llvm::sys::fs::F_None);
469 ::elfFile = new Ice::ELFFileStreamer(*out);
Nicolas Capens65047112016-11-07 13:01:07 -0500470 ::context = new Ice::GlobalContext(&cout, &cout, &cerr, elfFile);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400471 }
472 else
473 {
474 ELFMemoryStreamer *elfMemory = new ELFMemoryStreamer();
Nicolas Capens65047112016-11-07 13:01:07 -0500475 ::context = new Ice::GlobalContext(&cout, &cout, &cerr, elfMemory);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400476 ::routine = elfMemory;
477 }
478 }
479
480 Nucleus::~Nucleus()
481 {
482 delete ::allocator;
483 delete ::function;
484 delete ::context;
485
486 delete ::elfFile;
487 delete ::out;
488
489 ::codegenMutex.unlock();
490 }
491
492 Routine *Nucleus::acquireRoutine(const wchar_t *name, bool runOptimizations)
493 {
494 if(basicBlock->getInsts().empty() || basicBlock->getInsts().back().getKind() != Ice::Inst::Ret)
495 {
496 createRetVoid();
497 }
498
499 std::wstring wideName(name);
500 std::string asciiName(wideName.begin(), wideName.end());
501 ::function->setFunctionName(Ice::GlobalString::createWithString(::context, asciiName));
502
Nicolas Capens2ae9d742016-11-24 14:43:05 -0500503 optimize();
504
Nicolas Capens598f8d82016-09-26 15:09:10 -0400505 ::function->translate();
Nicolas Capensde19f392016-10-19 10:29:49 -0400506 assert(!::function->hasError());
507
Nicolas Capens66478362016-10-13 15:36:36 -0400508 auto *globals = ::function->getGlobalInits().release();
509
510 if(globals && !globals->empty())
511 {
512 ::context->getGlobals()->merge(globals);
513 }
Nicolas Capens598f8d82016-09-26 15:09:10 -0400514
515 ::context->emitFileHeader();
516 ::function->emitIAS();
517 auto assembler = ::function->releaseAssembler();
Nicolas Capens66478362016-10-13 15:36:36 -0400518 auto objectWriter = ::context->getObjectWriter();
519 assembler->alignFunction();
520 objectWriter->writeFunctionCode(::function->getFunctionName(), false, assembler.get());
521 ::context->lowerGlobals("last");
Nicolas Capens73dd7a22016-10-20 13:20:34 -0400522 ::context->lowerConstants();
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500523 ::context->lowerJumpTables();
Nicolas Capens66478362016-10-13 15:36:36 -0400524 objectWriter->setUndefinedSyms(::context->getConstantExternSyms());
525 objectWriter->writeNonUserSections();
Nicolas Capens598f8d82016-09-26 15:09:10 -0400526
527 return ::routine;
528 }
529
530 void Nucleus::optimize()
531 {
Nicolas Capens2ae9d742016-11-24 14:43:05 -0500532 sw::optimize(::function);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400533 }
534
535 Value *Nucleus::allocateStackVariable(Type *t, int arraySize)
536 {
537 Ice::Type type = T(t);
Nicolas Capensa8f98632016-10-20 11:25:55 -0400538 int typeSize = Ice::typeWidthInBytes(type);
539 int totalSize = typeSize * (arraySize ? arraySize : 1);
Nicolas Capense12780d2016-09-27 14:18:07 -0400540
Nicolas Capensa8f98632016-10-20 11:25:55 -0400541 auto bytes = Ice::ConstantInteger32::create(::context, type, totalSize);
Nicolas Capense12780d2016-09-27 14:18:07 -0400542 auto address = ::function->makeVariable(T(getPointerType(t)));
Nicolas Capensa8f98632016-10-20 11:25:55 -0400543 auto alloca = Ice::InstAlloca::create(::function, address, bytes, typeSize);
Nicolas Capense12780d2016-09-27 14:18:07 -0400544 ::function->getEntryNode()->getInsts().push_front(alloca);
545
546 return V(address);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400547 }
548
549 BasicBlock *Nucleus::createBasicBlock()
550 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400551 return B(::function->makeNode());
Nicolas Capens598f8d82016-09-26 15:09:10 -0400552 }
553
554 BasicBlock *Nucleus::getInsertBlock()
555 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400556 return B(::basicBlock);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400557 }
558
559 void Nucleus::setInsertBlock(BasicBlock *basicBlock)
560 {
Nicolas Capens9ed1a182016-10-24 09:52:23 -0400561 // assert(::basicBlock->getInsts().back().getTerminatorEdges().size() >= 0 && "Previous basic block must have a terminator");
Nicolas Capens611642a2016-09-28 16:45:04 -0400562 ::basicBlock = basicBlock;
Nicolas Capens598f8d82016-09-26 15:09:10 -0400563 }
564
Nicolas Capens598f8d82016-09-26 15:09:10 -0400565 void Nucleus::createFunction(Type *ReturnType, std::vector<Type*> &Params)
566 {
567 uint32_t sequenceNumber = 0;
568 ::function = Ice::Cfg::create(::context, sequenceNumber).release();
569 ::allocator = new Ice::CfgLocalAllocatorScope(::function);
570
571 for(Type *type : Params)
572 {
573 Ice::Variable *arg = ::function->makeVariable(T(type));
574 ::function->addArg(arg);
575 }
576
577 Ice::CfgNode *node = ::function->makeNode();
578 ::function->setEntryNode(node);
579 ::basicBlock = node;
580 }
581
582 Value *Nucleus::getArgument(unsigned int index)
583 {
584 return V(::function->getArgs()[index]);
585 }
586
587 void Nucleus::createRetVoid()
588 {
Nicolas Capensfdcca2d2016-10-20 11:31:36 -0400589 Ice::InstRet *ret = Ice::InstRet::create(::function);
590 ::basicBlock->appendInst(ret);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400591 }
592
593 void Nucleus::createRet(Value *v)
594 {
Nicolas Capensfdcca2d2016-10-20 11:31:36 -0400595 Ice::InstRet *ret = Ice::InstRet::create(::function, v);
596 ::basicBlock->appendInst(ret);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400597 }
598
599 void Nucleus::createBr(BasicBlock *dest)
600 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400601 auto br = Ice::InstBr::create(::function, dest);
602 ::basicBlock->appendInst(br);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400603 }
604
605 void Nucleus::createCondBr(Value *cond, BasicBlock *ifTrue, BasicBlock *ifFalse)
606 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400607 auto br = Ice::InstBr::create(::function, cond, ifTrue, ifFalse);
608 ::basicBlock->appendInst(br);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400609 }
610
Nicolas Capensf8360ba2017-01-25 11:35:00 -0800611 static bool isCommutative(Ice::InstArithmetic::OpKind op)
612 {
613 switch(op)
614 {
615 case Ice::InstArithmetic::Add:
616 case Ice::InstArithmetic::Fadd:
617 case Ice::InstArithmetic::Mul:
618 case Ice::InstArithmetic::Fmul:
619 case Ice::InstArithmetic::And:
620 case Ice::InstArithmetic::Or:
621 case Ice::InstArithmetic::Xor:
622 return true;
623 default:
624 return false;
625 }
626 }
627
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400628 static Value *createArithmetic(Ice::InstArithmetic::OpKind op, Value *lhs, Value *rhs)
629 {
Nicolas Capens327f1df2016-10-21 14:26:34 -0400630 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 -0400631
Nicolas Capensf8360ba2017-01-25 11:35:00 -0800632 bool swapOperands = llvm::isa<Ice::Constant>(lhs) && isCommutative(op);
633
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400634 Ice::Variable *result = ::function->makeVariable(lhs->getType());
Nicolas Capensf8360ba2017-01-25 11:35:00 -0800635 Ice::InstArithmetic *arithmetic = Ice::InstArithmetic::create(::function, op, result, swapOperands ? rhs : lhs, swapOperands ? lhs : rhs);
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400636 ::basicBlock->appendInst(arithmetic);
637
638 return V(result);
639 }
640
Nicolas Capens598f8d82016-09-26 15:09:10 -0400641 Value *Nucleus::createAdd(Value *lhs, Value *rhs)
642 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400643 return createArithmetic(Ice::InstArithmetic::Add, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400644 }
645
646 Value *Nucleus::createSub(Value *lhs, Value *rhs)
647 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400648 return createArithmetic(Ice::InstArithmetic::Sub, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400649 }
650
651 Value *Nucleus::createMul(Value *lhs, Value *rhs)
652 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400653 return createArithmetic(Ice::InstArithmetic::Mul, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400654 }
655
656 Value *Nucleus::createUDiv(Value *lhs, Value *rhs)
657 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400658 return createArithmetic(Ice::InstArithmetic::Udiv, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400659 }
660
661 Value *Nucleus::createSDiv(Value *lhs, Value *rhs)
662 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400663 return createArithmetic(Ice::InstArithmetic::Sdiv, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400664 }
665
666 Value *Nucleus::createFAdd(Value *lhs, Value *rhs)
667 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400668 return createArithmetic(Ice::InstArithmetic::Fadd, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400669 }
670
671 Value *Nucleus::createFSub(Value *lhs, Value *rhs)
672 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400673 return createArithmetic(Ice::InstArithmetic::Fsub, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400674 }
675
676 Value *Nucleus::createFMul(Value *lhs, Value *rhs)
677 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400678 return createArithmetic(Ice::InstArithmetic::Fmul, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400679 }
680
681 Value *Nucleus::createFDiv(Value *lhs, Value *rhs)
682 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400683 return createArithmetic(Ice::InstArithmetic::Fdiv, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400684 }
685
686 Value *Nucleus::createURem(Value *lhs, Value *rhs)
687 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400688 return createArithmetic(Ice::InstArithmetic::Urem, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400689 }
690
691 Value *Nucleus::createSRem(Value *lhs, Value *rhs)
692 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400693 return createArithmetic(Ice::InstArithmetic::Srem, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400694 }
695
696 Value *Nucleus::createFRem(Value *lhs, Value *rhs)
697 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400698 return createArithmetic(Ice::InstArithmetic::Frem, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400699 }
700
701 Value *Nucleus::createShl(Value *lhs, Value *rhs)
702 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400703 return createArithmetic(Ice::InstArithmetic::Shl, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400704 }
705
706 Value *Nucleus::createLShr(Value *lhs, Value *rhs)
707 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400708 return createArithmetic(Ice::InstArithmetic::Lshr, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400709 }
710
711 Value *Nucleus::createAShr(Value *lhs, Value *rhs)
712 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400713 return createArithmetic(Ice::InstArithmetic::Ashr, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400714 }
715
716 Value *Nucleus::createAnd(Value *lhs, Value *rhs)
717 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400718 return createArithmetic(Ice::InstArithmetic::And, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400719 }
720
721 Value *Nucleus::createOr(Value *lhs, Value *rhs)
722 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400723 return createArithmetic(Ice::InstArithmetic::Or, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400724 }
725
726 Value *Nucleus::createXor(Value *lhs, Value *rhs)
727 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400728 return createArithmetic(Ice::InstArithmetic::Xor, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400729 }
730
731 Value *Nucleus::createNeg(Value *v)
732 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500733 return createSub(createNullValue(T(v->getType())), v);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400734 }
735
736 Value *Nucleus::createFNeg(Value *v)
737 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500738 double c[4] = {-0.0, -0.0, -0.0, -0.0};
739 Value *negativeZero = Ice::isVectorType(v->getType()) ?
740 createConstantVector(c, T(v->getType())) :
Nicolas Capens15060bb2016-12-05 22:17:19 -0500741 V(::context->getConstantFloat(-0.0f));
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500742
743 return createFSub(negativeZero, v);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400744 }
745
746 Value *Nucleus::createNot(Value *v)
747 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500748 if(Ice::isScalarIntegerType(v->getType()))
749 {
Nicolas Capens15060bb2016-12-05 22:17:19 -0500750 return createXor(v, V(::context->getConstantInt(v->getType(), -1)));
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500751 }
752 else // Vector
753 {
754 int64_t c[4] = {-1, -1, -1, -1};
755 return createXor(v, createConstantVector(c, T(v->getType())));
756 }
Nicolas Capens598f8d82016-09-26 15:09:10 -0400757 }
758
Nicolas Capense12780d2016-09-27 14:18:07 -0400759 Value *Nucleus::createLoad(Value *ptr, Type *type, bool isVolatile, unsigned int align)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400760 {
Nicolas Capens23d99a42016-09-30 14:57:16 -0400761 int valueType = (int)reinterpret_cast<intptr_t>(type);
762 Ice::Variable *result = ::function->makeVariable(T(type));
763
764 if(valueType & EmulatedBits)
765 {
Nicolas Capens584088c2017-01-26 16:05:18 -0800766 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::LoadSubVector, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
767 auto target = ::context->getConstantUndef(Ice::IceType_i32);
768 auto load = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
769 load->addArg(ptr);
770 load->addArg(::context->getConstantInt32(typeSize(type)));
771 ::basicBlock->appendInst(load);
Nicolas Capens23d99a42016-09-30 14:57:16 -0400772 }
773 else
774 {
775 auto load = Ice::InstLoad::create(::function, result, ptr, align);
776 ::basicBlock->appendInst(load);
777 }
778
779 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400780 }
781
Nicolas Capens6d738712016-09-30 04:15:22 -0400782 Value *Nucleus::createStore(Value *value, Value *ptr, Type *type, bool isVolatile, unsigned int align)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400783 {
Nicolas Capens23d99a42016-09-30 14:57:16 -0400784 int valueType = (int)reinterpret_cast<intptr_t>(type);
785
786 if(valueType & EmulatedBits)
787 {
Nicolas Capens584088c2017-01-26 16:05:18 -0800788 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::StoreSubVector, Ice::Intrinsics::SideEffects_T, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_T};
789 auto target = ::context->getConstantUndef(Ice::IceType_i32);
790 auto store = Ice::InstIntrinsicCall::create(::function, 3, nullptr, target, intrinsic);
791 store->addArg(value);
792 store->addArg(ptr);
793 store->addArg(::context->getConstantInt32(typeSize(type)));
794 ::basicBlock->appendInst(store);
Nicolas Capens23d99a42016-09-30 14:57:16 -0400795 }
796 else
797 {
798 assert(T(value->getType()) == type);
799
800 auto store = Ice::InstStore::create(::function, value, ptr, align);
801 ::basicBlock->appendInst(store);
802 }
803
Nicolas Capens598f8d82016-09-26 15:09:10 -0400804 return value;
805 }
806
Nicolas Capensd294def2017-01-26 17:44:37 -0800807 Value *Nucleus::createGEP(Value *ptr, Type *type, Value *index, bool unsignedIndex)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400808 {
Nicolas Capens8820f642016-09-30 04:42:43 -0400809 assert(index->getType() == Ice::IceType_i32);
810
Nicolas Capens15060bb2016-12-05 22:17:19 -0500811 if(auto *constant = llvm::dyn_cast<Ice::ConstantInteger32>(index))
812 {
Nicolas Capens584088c2017-01-26 16:05:18 -0800813 int32_t offset = constant->getValue() * (int)typeSize(type);
Nicolas Capens15060bb2016-12-05 22:17:19 -0500814
815 if(offset == 0)
816 {
817 return ptr;
818 }
819
820 return createAdd(ptr, createConstantInt(offset));
821 }
822
Nicolas Capens8820f642016-09-30 04:42:43 -0400823 if(!Ice::isByteSizedType(T(type)))
824 {
Nicolas Capens584088c2017-01-26 16:05:18 -0800825 index = createMul(index, createConstantInt((int)typeSize(type)));
Nicolas Capens8820f642016-09-30 04:42:43 -0400826 }
827
828 if(sizeof(void*) == 8)
829 {
Nicolas Capensd294def2017-01-26 17:44:37 -0800830 if(unsignedIndex)
831 {
832 index = createZExt(index, T(Ice::IceType_i64));
833 }
834 else
835 {
836 index = createSExt(index, T(Ice::IceType_i64));
837 }
Nicolas Capens8820f642016-09-30 04:42:43 -0400838 }
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
Nicolas Capens411273e2017-01-26 15:13:36 -08002575 RValue<Short4> Unpack(RValue<Byte4> x, RValue<Byte4> y)
2576 {
2577 return UnpackLow(As<Byte8>(x), As<Byte8>(y));
2578 }
2579
Nicolas Capens598f8d82016-09-26 15:09:10 -04002580 RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y)
2581 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04002582 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
2583 return RValue<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002584 }
2585
2586 RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y)
2587 {
Nicolas Capens20e22c42016-10-25 17:32:37 -04002588 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
2589 auto lowHigh = RValue<Byte16>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
2590 return As<Short4>(Swizzle(As<Int4>(lowHigh), 0xEE));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002591 }
2592
2593 RValue<Int> SignMask(RValue<Byte8> x)
2594 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05002595 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
2596 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2597 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2598 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
2599 movmsk->addArg(x.value);
2600 ::basicBlock->appendInst(movmsk);
2601
2602 return RValue<Int>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002603 }
2604
2605// RValue<Byte8> CmpGT(RValue<Byte8> x, RValue<Byte8> y)
2606// {
Nicolas Capens2f970b62016-11-08 14:28:59 -05002607// return RValue<Byte8>(createIntCompare(Ice::InstIcmp::Ugt, x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002608// }
2609
2610 RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y)
2611 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05002612 return RValue<Byte8>(Nucleus::createICmpEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002613 }
2614
2615 Type *Byte8::getType()
2616 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04002617 return T(Type_v8i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002618 }
2619
Nicolas Capens598f8d82016-09-26 15:09:10 -04002620 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)
2621 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04002622 int64_t constantVector[8] = { x0, x1, x2, x3, x4, x5, x6, x7 };
2623 Value *vector = V(Nucleus::createConstantVector(constantVector, getType()));
2624
2625 storeValue(Nucleus::createBitCast(vector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002626 }
2627
Nicolas Capens598f8d82016-09-26 15:09:10 -04002628 SByte8::SByte8(RValue<SByte8> rhs)
2629 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002630 storeValue(rhs.value);
2631 }
2632
2633 SByte8::SByte8(const SByte8 &rhs)
2634 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002635 Value *value = rhs.loadValue();
2636 storeValue(value);
2637 }
2638
2639 SByte8::SByte8(const Reference<SByte8> &rhs)
2640 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002641 Value *value = rhs.loadValue();
2642 storeValue(value);
2643 }
2644
Nicolas Capens96d4e092016-11-18 14:22:38 -05002645 RValue<SByte8> SByte8::operator=(RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002646 {
2647 storeValue(rhs.value);
2648
2649 return rhs;
2650 }
2651
Nicolas Capens96d4e092016-11-18 14:22:38 -05002652 RValue<SByte8> SByte8::operator=(const SByte8 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002653 {
2654 Value *value = rhs.loadValue();
2655 storeValue(value);
2656
2657 return RValue<SByte8>(value);
2658 }
2659
Nicolas Capens96d4e092016-11-18 14:22:38 -05002660 RValue<SByte8> SByte8::operator=(const Reference<SByte8> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002661 {
2662 Value *value = rhs.loadValue();
2663 storeValue(value);
2664
2665 return RValue<SByte8>(value);
2666 }
2667
2668 RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs)
2669 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002670 return RValue<SByte8>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002671 }
2672
2673 RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs)
2674 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002675 return RValue<SByte8>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002676 }
2677
2678// RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs)
2679// {
2680// return RValue<SByte8>(Nucleus::createMul(lhs.value, rhs.value));
2681// }
2682
2683// RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs)
2684// {
2685// return RValue<SByte8>(Nucleus::createSDiv(lhs.value, rhs.value));
2686// }
2687
2688// RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs)
2689// {
2690// return RValue<SByte8>(Nucleus::createSRem(lhs.value, rhs.value));
2691// }
2692
2693 RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs)
2694 {
2695 return RValue<SByte8>(Nucleus::createAnd(lhs.value, rhs.value));
2696 }
2697
2698 RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs)
2699 {
2700 return RValue<SByte8>(Nucleus::createOr(lhs.value, rhs.value));
2701 }
2702
2703 RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs)
2704 {
2705 return RValue<SByte8>(Nucleus::createXor(lhs.value, rhs.value));
2706 }
2707
2708// RValue<SByte8> operator<<(RValue<SByte8> lhs, unsigned char rhs)
2709// {
Nicolas Capens15060bb2016-12-05 22:17:19 -05002710// return RValue<SByte8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002711// }
2712
2713// RValue<SByte8> operator>>(RValue<SByte8> lhs, unsigned char rhs)
2714// {
Nicolas Capens15060bb2016-12-05 22:17:19 -05002715// return RValue<SByte8>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002716// }
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
Nicolas Capens96d4e092016-11-18 14:22:38 -05002763// RValue<SByte8> operator>>=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002764// {
2765// return lhs = lhs >> rhs;
2766// }
2767
2768// RValue<SByte8> operator+(RValue<SByte8> val)
2769// {
2770// return val;
2771// }
2772
2773// RValue<SByte8> operator-(RValue<SByte8> val)
2774// {
2775// return RValue<SByte8>(Nucleus::createNeg(val.value));
2776// }
2777
2778 RValue<SByte8> operator~(RValue<SByte8> val)
2779 {
2780 return RValue<SByte8>(Nucleus::createNot(val.value));
2781 }
2782
2783 RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y)
2784 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05002785 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
2786 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2787 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2788 auto paddsb = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
2789 paddsb->addArg(x.value);
2790 paddsb->addArg(y.value);
2791 ::basicBlock->appendInst(paddsb);
2792
2793 return RValue<SByte8>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002794 }
2795
2796 RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y)
2797 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05002798 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
2799 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2800 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2801 auto psubsb = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
2802 psubsb->addArg(x.value);
2803 psubsb->addArg(y.value);
2804 ::basicBlock->appendInst(psubsb);
2805
2806 return RValue<SByte8>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002807 }
2808
2809 RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y)
2810 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04002811 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
2812 return RValue<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002813 }
2814
2815 RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y)
2816 {
Nicolas Capens20e22c42016-10-25 17:32:37 -04002817 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
2818 auto lowHigh = RValue<Byte16>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
2819 return As<Short4>(Swizzle(As<Int4>(lowHigh), 0xEE));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002820 }
2821
2822 RValue<Int> SignMask(RValue<SByte8> x)
2823 {
Nicolas Capensf2cb9df2016-10-21 17:26:13 -04002824 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
2825 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2826 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2827 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
2828 movmsk->addArg(x.value);
2829 ::basicBlock->appendInst(movmsk);
2830
2831 return RValue<Int>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002832 }
2833
2834 RValue<Byte8> CmpGT(RValue<SByte8> x, RValue<SByte8> y)
2835 {
Nicolas Capens2f970b62016-11-08 14:28:59 -05002836 return RValue<Byte8>(createIntCompare(Ice::InstIcmp::Sgt, x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002837 }
2838
2839 RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y)
2840 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05002841 return RValue<Byte8>(Nucleus::createICmpEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002842 }
2843
2844 Type *SByte8::getType()
2845 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04002846 return T(Type_v8i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002847 }
2848
2849 Byte16::Byte16(RValue<Byte16> rhs)
2850 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002851 storeValue(rhs.value);
2852 }
2853
2854 Byte16::Byte16(const Byte16 &rhs)
2855 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002856 Value *value = rhs.loadValue();
2857 storeValue(value);
2858 }
2859
2860 Byte16::Byte16(const Reference<Byte16> &rhs)
2861 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002862 Value *value = rhs.loadValue();
2863 storeValue(value);
2864 }
2865
Nicolas Capens96d4e092016-11-18 14:22:38 -05002866 RValue<Byte16> Byte16::operator=(RValue<Byte16> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002867 {
2868 storeValue(rhs.value);
2869
2870 return rhs;
2871 }
2872
Nicolas Capens96d4e092016-11-18 14:22:38 -05002873 RValue<Byte16> Byte16::operator=(const Byte16 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002874 {
2875 Value *value = rhs.loadValue();
2876 storeValue(value);
2877
2878 return RValue<Byte16>(value);
2879 }
2880
Nicolas Capens96d4e092016-11-18 14:22:38 -05002881 RValue<Byte16> Byte16::operator=(const Reference<Byte16> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002882 {
2883 Value *value = rhs.loadValue();
2884 storeValue(value);
2885
2886 return RValue<Byte16>(value);
2887 }
2888
2889 Type *Byte16::getType()
2890 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04002891 return T(Ice::IceType_v16i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002892 }
2893
2894 Type *SByte16::getType()
2895 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04002896 return T(Ice::IceType_v16i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002897 }
2898
Nicolas Capens16b5f152016-10-13 13:39:01 -04002899 Short2::Short2(RValue<Short4> cast)
2900 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05002901 storeValue(Nucleus::createBitCast(cast.value, getType()));
Nicolas Capens16b5f152016-10-13 13:39:01 -04002902 }
2903
2904 Type *Short2::getType()
2905 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04002906 return T(Type_v2i16);
Nicolas Capens16b5f152016-10-13 13:39:01 -04002907 }
2908
2909 UShort2::UShort2(RValue<UShort4> cast)
2910 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05002911 storeValue(Nucleus::createBitCast(cast.value, getType()));
Nicolas Capens16b5f152016-10-13 13:39:01 -04002912 }
2913
2914 Type *UShort2::getType()
2915 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04002916 return T(Type_v2i16);
Nicolas Capens16b5f152016-10-13 13:39:01 -04002917 }
2918
Nicolas Capens598f8d82016-09-26 15:09:10 -04002919 Short4::Short4(RValue<Int> cast)
2920 {
Nicolas Capensd4227962016-11-09 14:24:25 -05002921 Value *vector = loadValue();
Nicolas Capensbf22bbf2017-01-13 17:37:45 -05002922 Value *element = Nucleus::createTrunc(cast.value, Short::getType());
2923 Value *insert = Nucleus::createInsertElement(vector, element, 0);
Nicolas Capensd4227962016-11-09 14:24:25 -05002924 Value *swizzle = Swizzle(RValue<Short4>(insert), 0x00).value;
Nicolas Capens598f8d82016-09-26 15:09:10 -04002925
2926 storeValue(swizzle);
2927 }
2928
2929 Short4::Short4(RValue<Int4> cast)
2930 {
Nicolas Capensf8beb4b2017-01-27 02:55:44 -08002931 int select[8] = {0, 2, 4, 6, 0, 2, 4, 6};
2932 Value *short8 = Nucleus::createBitCast(cast.value, Short8::getType());
2933 Value *packed = Nucleus::createShuffleVector(short8, short8, select);
Nicolas Capensd4227962016-11-09 14:24:25 -05002934
2935 Value *int2 = RValue<Int2>(Int2(RValue<Int4>(packed))).value;
2936 Value *short4 = Nucleus::createBitCast(int2, Short4::getType());
2937
2938 storeValue(short4);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002939 }
2940
2941// Short4::Short4(RValue<Float> cast)
2942// {
2943// }
2944
2945 Short4::Short4(RValue<Float4> cast)
2946 {
2947 assert(false && "UNIMPLEMENTED");
2948 }
2949
Nicolas Capens598f8d82016-09-26 15:09:10 -04002950 Short4::Short4(short xyzw)
2951 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04002952 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
2953 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002954 }
2955
2956 Short4::Short4(short x, short y, short z, short w)
2957 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04002958 int64_t constantVector[4] = {x, y, z, w};
2959 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002960 }
2961
2962 Short4::Short4(RValue<Short4> rhs)
2963 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002964 storeValue(rhs.value);
2965 }
2966
2967 Short4::Short4(const Short4 &rhs)
2968 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002969 Value *value = rhs.loadValue();
2970 storeValue(value);
2971 }
2972
2973 Short4::Short4(const Reference<Short4> &rhs)
2974 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002975 Value *value = rhs.loadValue();
2976 storeValue(value);
2977 }
2978
2979 Short4::Short4(RValue<UShort4> rhs)
2980 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002981 storeValue(rhs.value);
2982 }
2983
2984 Short4::Short4(const UShort4 &rhs)
2985 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002986 storeValue(rhs.loadValue());
2987 }
2988
2989 Short4::Short4(const Reference<UShort4> &rhs)
2990 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002991 storeValue(rhs.loadValue());
2992 }
2993
Nicolas Capens96d4e092016-11-18 14:22:38 -05002994 RValue<Short4> Short4::operator=(RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002995 {
2996 storeValue(rhs.value);
2997
2998 return rhs;
2999 }
3000
Nicolas Capens96d4e092016-11-18 14:22:38 -05003001 RValue<Short4> Short4::operator=(const Short4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003002 {
3003 Value *value = rhs.loadValue();
3004 storeValue(value);
3005
3006 return RValue<Short4>(value);
3007 }
3008
Nicolas Capens96d4e092016-11-18 14:22:38 -05003009 RValue<Short4> Short4::operator=(const Reference<Short4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003010 {
3011 Value *value = rhs.loadValue();
3012 storeValue(value);
3013
3014 return RValue<Short4>(value);
3015 }
3016
Nicolas Capens96d4e092016-11-18 14:22:38 -05003017 RValue<Short4> Short4::operator=(RValue<UShort4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003018 {
3019 storeValue(rhs.value);
3020
3021 return RValue<Short4>(rhs);
3022 }
3023
Nicolas Capens96d4e092016-11-18 14:22:38 -05003024 RValue<Short4> Short4::operator=(const UShort4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003025 {
3026 Value *value = rhs.loadValue();
3027 storeValue(value);
3028
3029 return RValue<Short4>(value);
3030 }
3031
Nicolas Capens96d4e092016-11-18 14:22:38 -05003032 RValue<Short4> Short4::operator=(const Reference<UShort4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003033 {
3034 Value *value = rhs.loadValue();
3035 storeValue(value);
3036
3037 return RValue<Short4>(value);
3038 }
3039
3040 RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs)
3041 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003042 return RValue<Short4>(Nucleus::createAdd(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::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003048 }
3049
3050 RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs)
3051 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003052 return RValue<Short4>(Nucleus::createMul(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003053 }
3054
3055// RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs)
3056// {
3057// return RValue<Short4>(Nucleus::createSDiv(lhs.value, rhs.value));
3058// }
3059
3060// RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs)
3061// {
3062// return RValue<Short4>(Nucleus::createSRem(lhs.value, rhs.value));
3063// }
3064
3065 RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs)
3066 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003067 return RValue<Short4>(Nucleus::createAnd(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::createOr(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003073 }
3074
3075 RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs)
3076 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003077 return RValue<Short4>(Nucleus::createXor(lhs.value, rhs.value));
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::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003083 }
3084
3085 RValue<Short4> operator>>(RValue<Short4> lhs, unsigned char rhs)
3086 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05003087 return RValue<Short4>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003088 }
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, RValue<Short4> 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 Capens96d4e092016-11-18 14:22:38 -05003135 RValue<Short4> operator>>=(Short4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003136 {
3137 return lhs = lhs >> rhs;
3138 }
3139
Nicolas Capens598f8d82016-09-26 15:09:10 -04003140// RValue<Short4> operator+(RValue<Short4> val)
3141// {
3142// return val;
3143// }
3144
3145 RValue<Short4> operator-(RValue<Short4> val)
3146 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -05003147 return RValue<Short4>(Nucleus::createNeg(val.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003148 }
3149
3150 RValue<Short4> operator~(RValue<Short4> val)
3151 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -05003152 return RValue<Short4>(Nucleus::createNot(val.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003153 }
3154
3155 RValue<Short4> RoundShort4(RValue<Float4> cast)
3156 {
Nicolas Capensd4227962016-11-09 14:24:25 -05003157 RValue<Int4> int4 = RoundInt(cast);
3158 return As<Short4>(Pack(int4, int4));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003159 }
3160
3161 RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y)
3162 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04003163 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3164 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sle, condition, x.value, y.value);
3165 ::basicBlock->appendInst(cmp);
3166
3167 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3168 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3169 ::basicBlock->appendInst(select);
3170
3171 return RValue<Short4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003172 }
3173
3174 RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y)
3175 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04003176 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3177 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sgt, condition, x.value, y.value);
3178 ::basicBlock->appendInst(cmp);
3179
3180 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3181 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3182 ::basicBlock->appendInst(select);
3183
3184 return RValue<Short4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003185 }
3186
3187 RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y)
3188 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05003189 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3190 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3191 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3192 auto paddsw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3193 paddsw->addArg(x.value);
3194 paddsw->addArg(y.value);
3195 ::basicBlock->appendInst(paddsw);
3196
3197 return RValue<Short4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003198 }
3199
3200 RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y)
3201 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05003202 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3203 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3204 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3205 auto psubsw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3206 psubsw->addArg(x.value);
3207 psubsw->addArg(y.value);
3208 ::basicBlock->appendInst(psubsw);
3209
3210 return RValue<Short4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003211 }
3212
3213 RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y)
3214 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05003215 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3216 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::MultiplyHighSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3217 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3218 auto pmulhw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3219 pmulhw->addArg(x.value);
3220 pmulhw->addArg(y.value);
3221 ::basicBlock->appendInst(pmulhw);
3222
Nicolas Capens5b41ba32016-12-08 14:34:00 -05003223 return RValue<Short4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003224 }
3225
3226 RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y)
3227 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05003228 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3229 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::MultiplyAddPairs, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3230 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3231 auto pmaddwd = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3232 pmaddwd->addArg(x.value);
3233 pmaddwd->addArg(y.value);
3234 ::basicBlock->appendInst(pmaddwd);
3235
3236 return RValue<Int2>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003237 }
3238
3239 RValue<SByte8> Pack(RValue<Short4> x, RValue<Short4> y)
3240 {
Nicolas Capensec54a172016-10-25 17:32:37 -04003241 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
3242 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3243 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3244 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3245 pack->addArg(x.value);
3246 pack->addArg(y.value);
3247 ::basicBlock->appendInst(pack);
3248
Nicolas Capens70dfff42016-10-27 10:20:28 -04003249 return As<SByte8>(Swizzle(As<Int4>(V(result)), 0x88));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003250 }
3251
3252 RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y)
3253 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04003254 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11}; // Real type is v8i16
3255 return RValue<Int2>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003256 }
3257
3258 RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y)
3259 {
Nicolas Capens20e22c42016-10-25 17:32:37 -04003260 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11}; // Real type is v8i16
3261 auto lowHigh = RValue<Short8>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
3262 return As<Int2>(Swizzle(As<Int4>(lowHigh), 0xEE));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003263 }
3264
3265 RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select)
3266 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04003267 // Real type is v8i16
3268 int shuffle[8] =
3269 {
3270 (select >> 0) & 0x03,
3271 (select >> 2) & 0x03,
3272 (select >> 4) & 0x03,
3273 (select >> 6) & 0x03,
3274 (select >> 0) & 0x03,
3275 (select >> 2) & 0x03,
3276 (select >> 4) & 0x03,
3277 (select >> 6) & 0x03,
3278 };
3279
3280 return RValue<Short4>(Nucleus::createShuffleVector(x.value, x.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003281 }
3282
3283 RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i)
3284 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05003285 return RValue<Short4>(Nucleus::createInsertElement(val.value, element.value, i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003286 }
3287
3288 RValue<Short> Extract(RValue<Short4> val, int i)
3289 {
Nicolas Capens0133d0f2017-01-16 16:25:08 -05003290 return RValue<Short>(Nucleus::createExtractElement(val.value, Short::getType(), i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003291 }
3292
3293 RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y)
3294 {
Nicolas Capens2f970b62016-11-08 14:28:59 -05003295 return RValue<Short4>(createIntCompare(Ice::InstIcmp::Sgt, x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003296 }
3297
3298 RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y)
3299 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05003300 return RValue<Short4>(Nucleus::createICmpEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003301 }
3302
3303 Type *Short4::getType()
3304 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04003305 return T(Type_v4i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003306 }
3307
3308 UShort4::UShort4(RValue<Int4> cast)
3309 {
3310 *this = Short4(cast);
3311 }
3312
3313 UShort4::UShort4(RValue<Float4> cast, bool saturate)
3314 {
Nicolas Capensd4227962016-11-09 14:24:25 -05003315 if(saturate)
3316 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05003317 if(CPUID::SSE4_1)
Nicolas Capensd4227962016-11-09 14:24:25 -05003318 {
3319 Int4 int4(Min(cast, Float4(0xFFFF))); // packusdw takes care of 0x0000 saturation
3320 *this = As<Short4>(Pack(As<UInt4>(int4), As<UInt4>(int4)));
3321 }
3322 else
3323 {
3324 *this = Short4(Int4(Max(Min(cast, Float4(0xFFFF)), Float4(0x0000))));
3325 }
3326 }
3327 else
3328 {
3329 *this = Short4(Int4(cast));
3330 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003331 }
3332
Nicolas Capens598f8d82016-09-26 15:09:10 -04003333 UShort4::UShort4(unsigned short xyzw)
3334 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04003335 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
3336 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003337 }
3338
3339 UShort4::UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w)
3340 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04003341 int64_t constantVector[4] = {x, y, z, w};
3342 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003343 }
3344
3345 UShort4::UShort4(RValue<UShort4> rhs)
3346 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003347 storeValue(rhs.value);
3348 }
3349
3350 UShort4::UShort4(const UShort4 &rhs)
3351 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003352 Value *value = rhs.loadValue();
3353 storeValue(value);
3354 }
3355
3356 UShort4::UShort4(const Reference<UShort4> &rhs)
3357 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003358 Value *value = rhs.loadValue();
3359 storeValue(value);
3360 }
3361
3362 UShort4::UShort4(RValue<Short4> rhs)
3363 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003364 storeValue(rhs.value);
3365 }
3366
3367 UShort4::UShort4(const Short4 &rhs)
3368 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003369 Value *value = rhs.loadValue();
3370 storeValue(value);
3371 }
3372
3373 UShort4::UShort4(const Reference<Short4> &rhs)
3374 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003375 Value *value = rhs.loadValue();
3376 storeValue(value);
3377 }
3378
Nicolas Capens96d4e092016-11-18 14:22:38 -05003379 RValue<UShort4> UShort4::operator=(RValue<UShort4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003380 {
3381 storeValue(rhs.value);
3382
3383 return rhs;
3384 }
3385
Nicolas Capens96d4e092016-11-18 14:22:38 -05003386 RValue<UShort4> UShort4::operator=(const UShort4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003387 {
3388 Value *value = rhs.loadValue();
3389 storeValue(value);
3390
3391 return RValue<UShort4>(value);
3392 }
3393
Nicolas Capens96d4e092016-11-18 14:22:38 -05003394 RValue<UShort4> UShort4::operator=(const Reference<UShort4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003395 {
3396 Value *value = rhs.loadValue();
3397 storeValue(value);
3398
3399 return RValue<UShort4>(value);
3400 }
3401
Nicolas Capens96d4e092016-11-18 14:22:38 -05003402 RValue<UShort4> UShort4::operator=(RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003403 {
3404 storeValue(rhs.value);
3405
3406 return RValue<UShort4>(rhs);
3407 }
3408
Nicolas Capens96d4e092016-11-18 14:22:38 -05003409 RValue<UShort4> UShort4::operator=(const Short4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003410 {
3411 Value *value = rhs.loadValue();
3412 storeValue(value);
3413
3414 return RValue<UShort4>(value);
3415 }
3416
Nicolas Capens96d4e092016-11-18 14:22:38 -05003417 RValue<UShort4> UShort4::operator=(const Reference<Short4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003418 {
3419 Value *value = rhs.loadValue();
3420 storeValue(value);
3421
3422 return RValue<UShort4>(value);
3423 }
3424
3425 RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs)
3426 {
Nicolas Capens5b41ba32016-12-08 14:34:00 -05003427 return RValue<UShort4>(Nucleus::createAdd(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::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003433 }
3434
3435 RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs)
3436 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003437 return RValue<UShort4>(Nucleus::createMul(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003438 }
3439
Nicolas Capens16b5f152016-10-13 13:39:01 -04003440 RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs)
3441 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003442 return RValue<UShort4>(Nucleus::createAnd(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::createOr(lhs.value, rhs.value));
Nicolas Capens16b5f152016-10-13 13:39:01 -04003448 }
3449
3450 RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs)
3451 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003452 return RValue<UShort4>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens16b5f152016-10-13 13:39:01 -04003453 }
3454
Nicolas Capens598f8d82016-09-26 15:09:10 -04003455 RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs)
3456 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05003457 return RValue<UShort4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003458 }
3459
3460 RValue<UShort4> operator>>(RValue<UShort4> lhs, unsigned char rhs)
3461 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05003462 return RValue<UShort4>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003463 }
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 Capens96d4e092016-11-18 14:22:38 -05003470 RValue<UShort4> operator>>=(UShort4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003471 {
3472 return lhs = lhs >> rhs;
3473 }
3474
Nicolas Capens598f8d82016-09-26 15:09:10 -04003475 RValue<UShort4> operator~(RValue<UShort4> val)
3476 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -05003477 return RValue<UShort4>(Nucleus::createNot(val.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003478 }
3479
3480 RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y)
3481 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04003482 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3483 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ule, condition, x.value, y.value);
3484 ::basicBlock->appendInst(cmp);
3485
3486 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3487 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3488 ::basicBlock->appendInst(select);
3489
3490 return RValue<UShort4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003491 }
3492
3493 RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y)
3494 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04003495 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3496 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ugt, condition, x.value, y.value);
3497 ::basicBlock->appendInst(cmp);
3498
3499 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3500 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3501 ::basicBlock->appendInst(select);
3502
3503 return RValue<UShort4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003504 }
3505
3506 RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y)
3507 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05003508 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3509 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3510 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3511 auto paddusw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3512 paddusw->addArg(x.value);
3513 paddusw->addArg(y.value);
3514 ::basicBlock->appendInst(paddusw);
3515
3516 return RValue<UShort4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003517 }
3518
3519 RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y)
3520 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05003521 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3522 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3523 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3524 auto psubusw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3525 psubusw->addArg(x.value);
3526 psubusw->addArg(y.value);
3527 ::basicBlock->appendInst(psubusw);
3528
3529 return RValue<UShort4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003530 }
3531
3532 RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y)
3533 {
Nicolas Capensc71bed22016-11-07 22:25:14 -05003534 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3535 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::MultiplyHighUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3536 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3537 auto pmulhuw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3538 pmulhuw->addArg(x.value);
3539 pmulhuw->addArg(y.value);
3540 ::basicBlock->appendInst(pmulhuw);
3541
3542 return RValue<UShort4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003543 }
3544
3545 RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y)
3546 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003547 assert(false && "UNIMPLEMENTED"); return RValue<UShort4>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003548 }
3549
3550 RValue<Byte8> Pack(RValue<UShort4> x, RValue<UShort4> y)
3551 {
Nicolas Capensec54a172016-10-25 17:32:37 -04003552 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
3553 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3554 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3555 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3556 pack->addArg(x.value);
3557 pack->addArg(y.value);
3558 ::basicBlock->appendInst(pack);
3559
Nicolas Capens70dfff42016-10-27 10:20:28 -04003560 return As<Byte8>(Swizzle(As<Int4>(V(result)), 0x88));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003561 }
3562
3563 Type *UShort4::getType()
3564 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04003565 return T(Type_v4i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003566 }
3567
Nicolas Capens3e7062b2017-01-17 14:01:33 -05003568 Short8::Short8(short c)
3569 {
3570 int64_t constantVector[8] = {c, c, c, c, c, c, c, c};
3571 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3572 }
3573
Nicolas Capens598f8d82016-09-26 15:09:10 -04003574 Short8::Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7)
3575 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04003576 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
3577 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003578 }
3579
3580 Short8::Short8(RValue<Short8> rhs)
3581 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003582 storeValue(rhs.value);
3583 }
3584
3585 Short8::Short8(const Reference<Short8> &rhs)
3586 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003587 Value *value = rhs.loadValue();
3588 storeValue(value);
3589 }
3590
3591 Short8::Short8(RValue<Short4> lo, RValue<Short4> hi)
3592 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05003593 int shuffle[8] = {0, 1, 2, 3, 8, 9, 10, 11}; // Real type is v8i16
3594 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
3595
3596 storeValue(packed);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003597 }
3598
3599 RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs)
3600 {
3601 return RValue<Short8>(Nucleus::createAdd(lhs.value, rhs.value));
3602 }
3603
3604 RValue<Short8> operator&(RValue<Short8> lhs, RValue<Short8> rhs)
3605 {
3606 return RValue<Short8>(Nucleus::createAnd(lhs.value, rhs.value));
3607 }
3608
3609 RValue<Short8> operator<<(RValue<Short8> lhs, unsigned char rhs)
3610 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05003611 return RValue<Short8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003612 }
3613
3614 RValue<Short8> operator>>(RValue<Short8> lhs, unsigned char rhs)
3615 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05003616 return RValue<Short8>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003617 }
3618
3619 RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y)
3620 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003621 assert(false && "UNIMPLEMENTED"); return RValue<Int4>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003622 }
3623
3624 RValue<Int4> Abs(RValue<Int4> x)
3625 {
Nicolas Capens84272242016-11-09 13:31:06 -05003626 auto negative = x >> 31;
3627 return (x ^ negative) - negative;
Nicolas Capens598f8d82016-09-26 15:09:10 -04003628 }
3629
3630 RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y)
3631 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003632 assert(false && "UNIMPLEMENTED"); return RValue<Short8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003633 }
3634
3635 Type *Short8::getType()
3636 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04003637 return T(Ice::IceType_v8i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003638 }
3639
Nicolas Capens3e7062b2017-01-17 14:01:33 -05003640 UShort8::UShort8(unsigned short c)
3641 {
3642 int64_t constantVector[8] = {c, c, c, c, c, c, c, c};
3643 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3644 }
3645
Nicolas Capens598f8d82016-09-26 15:09:10 -04003646 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)
3647 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04003648 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
3649 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003650 }
3651
3652 UShort8::UShort8(RValue<UShort8> rhs)
3653 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003654 storeValue(rhs.value);
3655 }
3656
3657 UShort8::UShort8(const Reference<UShort8> &rhs)
3658 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003659 Value *value = rhs.loadValue();
3660 storeValue(value);
3661 }
3662
3663 UShort8::UShort8(RValue<UShort4> lo, RValue<UShort4> hi)
3664 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05003665 int shuffle[8] = {0, 1, 2, 3, 8, 9, 10, 11}; // Real type is v8i16
3666 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
3667
3668 storeValue(packed);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003669 }
3670
Nicolas Capens96d4e092016-11-18 14:22:38 -05003671 RValue<UShort8> UShort8::operator=(RValue<UShort8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003672 {
3673 storeValue(rhs.value);
3674
3675 return rhs;
3676 }
3677
Nicolas Capens96d4e092016-11-18 14:22:38 -05003678 RValue<UShort8> UShort8::operator=(const UShort8 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003679 {
3680 Value *value = rhs.loadValue();
3681 storeValue(value);
3682
3683 return RValue<UShort8>(value);
3684 }
3685
Nicolas Capens96d4e092016-11-18 14:22:38 -05003686 RValue<UShort8> UShort8::operator=(const Reference<UShort8> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003687 {
3688 Value *value = rhs.loadValue();
3689 storeValue(value);
3690
3691 return RValue<UShort8>(value);
3692 }
3693
3694 RValue<UShort8> operator&(RValue<UShort8> lhs, RValue<UShort8> rhs)
3695 {
3696 return RValue<UShort8>(Nucleus::createAnd(lhs.value, rhs.value));
3697 }
3698
3699 RValue<UShort8> operator<<(RValue<UShort8> lhs, unsigned char rhs)
3700 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05003701 return RValue<UShort8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003702 }
3703
3704 RValue<UShort8> operator>>(RValue<UShort8> lhs, unsigned char rhs)
3705 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05003706 return RValue<UShort8>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003707 }
3708
3709 RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs)
3710 {
3711 return RValue<UShort8>(Nucleus::createAdd(lhs.value, rhs.value));
3712 }
3713
3714 RValue<UShort8> operator*(RValue<UShort8> lhs, RValue<UShort8> rhs)
3715 {
3716 return RValue<UShort8>(Nucleus::createMul(lhs.value, rhs.value));
3717 }
3718
Nicolas Capens96d4e092016-11-18 14:22:38 -05003719 RValue<UShort8> operator+=(UShort8 &lhs, RValue<UShort8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003720 {
3721 return lhs = lhs + rhs;
3722 }
3723
3724 RValue<UShort8> operator~(RValue<UShort8> val)
3725 {
3726 return RValue<UShort8>(Nucleus::createNot(val.value));
3727 }
3728
3729 RValue<UShort8> Swizzle(RValue<UShort8> x, char select0, char select1, char select2, char select3, char select4, char select5, char select6, char select7)
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 RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y)
3735 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003736 assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003737 }
3738
3739 // FIXME: Implement as Shuffle(x, y, Select(i0, ..., i16)) and Shuffle(x, y, SELECT_PACK_REPEAT(element))
3740// RValue<UShort8> PackRepeat(RValue<Byte16> x, RValue<Byte16> y, int element)
3741// {
Nicolas Capensc37252c2016-09-28 16:11:54 -04003742// assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003743// }
3744
3745 Type *UShort8::getType()
3746 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04003747 return T(Ice::IceType_v8i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003748 }
3749
3750 Int::Int(Argument<Int> argument)
3751 {
3752 storeValue(argument.value);
3753 }
3754
3755 Int::Int(RValue<Byte> cast)
3756 {
3757 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3758
3759 storeValue(integer);
3760 }
3761
3762 Int::Int(RValue<SByte> cast)
3763 {
3764 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3765
3766 storeValue(integer);
3767 }
3768
3769 Int::Int(RValue<Short> cast)
3770 {
3771 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3772
3773 storeValue(integer);
3774 }
3775
3776 Int::Int(RValue<UShort> cast)
3777 {
3778 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3779
3780 storeValue(integer);
3781 }
3782
3783 Int::Int(RValue<Int2> cast)
3784 {
3785 *this = Extract(cast, 0);
3786 }
3787
3788 Int::Int(RValue<Long> cast)
3789 {
3790 Value *integer = Nucleus::createTrunc(cast.value, Int::getType());
3791
3792 storeValue(integer);
3793 }
3794
3795 Int::Int(RValue<Float> cast)
3796 {
3797 Value *integer = Nucleus::createFPToSI(cast.value, Int::getType());
3798
3799 storeValue(integer);
3800 }
3801
Nicolas Capens598f8d82016-09-26 15:09:10 -04003802 Int::Int(int x)
3803 {
3804 storeValue(Nucleus::createConstantInt(x));
3805 }
3806
3807 Int::Int(RValue<Int> rhs)
3808 {
3809 storeValue(rhs.value);
3810 }
3811
3812 Int::Int(RValue<UInt> rhs)
3813 {
3814 storeValue(rhs.value);
3815 }
3816
3817 Int::Int(const Int &rhs)
3818 {
3819 Value *value = rhs.loadValue();
3820 storeValue(value);
3821 }
3822
3823 Int::Int(const Reference<Int> &rhs)
3824 {
3825 Value *value = rhs.loadValue();
3826 storeValue(value);
3827 }
3828
3829 Int::Int(const UInt &rhs)
3830 {
3831 Value *value = rhs.loadValue();
3832 storeValue(value);
3833 }
3834
3835 Int::Int(const Reference<UInt> &rhs)
3836 {
3837 Value *value = rhs.loadValue();
3838 storeValue(value);
3839 }
3840
Nicolas Capens96d4e092016-11-18 14:22:38 -05003841 RValue<Int> Int::operator=(int rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003842 {
3843 return RValue<Int>(storeValue(Nucleus::createConstantInt(rhs)));
3844 }
3845
Nicolas Capens96d4e092016-11-18 14:22:38 -05003846 RValue<Int> Int::operator=(RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003847 {
3848 storeValue(rhs.value);
3849
3850 return rhs;
3851 }
3852
Nicolas Capens96d4e092016-11-18 14:22:38 -05003853 RValue<Int> Int::operator=(RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003854 {
3855 storeValue(rhs.value);
3856
3857 return RValue<Int>(rhs);
3858 }
3859
Nicolas Capens96d4e092016-11-18 14:22:38 -05003860 RValue<Int> Int::operator=(const Int &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003861 {
3862 Value *value = rhs.loadValue();
3863 storeValue(value);
3864
3865 return RValue<Int>(value);
3866 }
3867
Nicolas Capens96d4e092016-11-18 14:22:38 -05003868 RValue<Int> Int::operator=(const Reference<Int> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003869 {
3870 Value *value = rhs.loadValue();
3871 storeValue(value);
3872
3873 return RValue<Int>(value);
3874 }
3875
Nicolas Capens96d4e092016-11-18 14:22:38 -05003876 RValue<Int> Int::operator=(const UInt &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003877 {
3878 Value *value = rhs.loadValue();
3879 storeValue(value);
3880
3881 return RValue<Int>(value);
3882 }
3883
Nicolas Capens96d4e092016-11-18 14:22:38 -05003884 RValue<Int> Int::operator=(const Reference<UInt> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003885 {
3886 Value *value = rhs.loadValue();
3887 storeValue(value);
3888
3889 return RValue<Int>(value);
3890 }
3891
3892 RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs)
3893 {
3894 return RValue<Int>(Nucleus::createAdd(lhs.value, rhs.value));
3895 }
3896
3897 RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs)
3898 {
3899 return RValue<Int>(Nucleus::createSub(lhs.value, rhs.value));
3900 }
3901
3902 RValue<Int> operator*(RValue<Int> lhs, RValue<Int> rhs)
3903 {
3904 return RValue<Int>(Nucleus::createMul(lhs.value, rhs.value));
3905 }
3906
3907 RValue<Int> operator/(RValue<Int> lhs, RValue<Int> rhs)
3908 {
3909 return RValue<Int>(Nucleus::createSDiv(lhs.value, rhs.value));
3910 }
3911
3912 RValue<Int> operator%(RValue<Int> lhs, RValue<Int> rhs)
3913 {
3914 return RValue<Int>(Nucleus::createSRem(lhs.value, rhs.value));
3915 }
3916
3917 RValue<Int> operator&(RValue<Int> lhs, RValue<Int> rhs)
3918 {
3919 return RValue<Int>(Nucleus::createAnd(lhs.value, rhs.value));
3920 }
3921
3922 RValue<Int> operator|(RValue<Int> lhs, RValue<Int> rhs)
3923 {
3924 return RValue<Int>(Nucleus::createOr(lhs.value, rhs.value));
3925 }
3926
3927 RValue<Int> operator^(RValue<Int> lhs, RValue<Int> rhs)
3928 {
3929 return RValue<Int>(Nucleus::createXor(lhs.value, rhs.value));
3930 }
3931
3932 RValue<Int> operator<<(RValue<Int> lhs, RValue<Int> rhs)
3933 {
3934 return RValue<Int>(Nucleus::createShl(lhs.value, rhs.value));
3935 }
3936
3937 RValue<Int> operator>>(RValue<Int> lhs, RValue<Int> rhs)
3938 {
3939 return RValue<Int>(Nucleus::createAShr(lhs.value, rhs.value));
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
Nicolas Capens96d4e092016-11-18 14:22:38 -05003987 RValue<Int> operator>>=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003988 {
3989 return lhs = lhs >> rhs;
3990 }
3991
3992 RValue<Int> operator+(RValue<Int> val)
3993 {
3994 return val;
3995 }
3996
3997 RValue<Int> operator-(RValue<Int> val)
3998 {
3999 return RValue<Int>(Nucleus::createNeg(val.value));
4000 }
4001
4002 RValue<Int> operator~(RValue<Int> val)
4003 {
4004 return RValue<Int>(Nucleus::createNot(val.value));
4005 }
4006
Nicolas Capens96d4e092016-11-18 14:22:38 -05004007 RValue<Int> operator++(Int &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04004008 {
Nicolas Capens5b41ba32016-12-08 14:34:00 -05004009 RValue<Int> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05004010 val += 1;
4011 return res;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004012 }
4013
Nicolas Capens96d4e092016-11-18 14:22:38 -05004014 const Int &operator++(Int &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04004015 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004016 val += 1;
4017 return val;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004018 }
4019
Nicolas Capens96d4e092016-11-18 14:22:38 -05004020 RValue<Int> operator--(Int &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04004021 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004022 RValue<Int> res = val;
4023 val -= 1;
4024 return res;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004025 }
4026
Nicolas Capens96d4e092016-11-18 14:22:38 -05004027 const Int &operator--(Int &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04004028 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004029 val -= 1;
4030 return val;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004031 }
4032
4033 RValue<Bool> operator<(RValue<Int> lhs, RValue<Int> rhs)
4034 {
4035 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
4036 }
4037
4038 RValue<Bool> operator<=(RValue<Int> lhs, RValue<Int> rhs)
4039 {
4040 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
4041 }
4042
4043 RValue<Bool> operator>(RValue<Int> lhs, RValue<Int> rhs)
4044 {
4045 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
4046 }
4047
4048 RValue<Bool> operator>=(RValue<Int> lhs, RValue<Int> rhs)
4049 {
4050 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
4051 }
4052
4053 RValue<Bool> operator!=(RValue<Int> lhs, RValue<Int> rhs)
4054 {
4055 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
4056 }
4057
4058 RValue<Bool> operator==(RValue<Int> lhs, RValue<Int> rhs)
4059 {
4060 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
4061 }
4062
4063 RValue<Int> Max(RValue<Int> x, RValue<Int> y)
4064 {
4065 return IfThenElse(x > y, x, y);
4066 }
4067
4068 RValue<Int> Min(RValue<Int> x, RValue<Int> y)
4069 {
4070 return IfThenElse(x < y, x, y);
4071 }
4072
4073 RValue<Int> Clamp(RValue<Int> x, RValue<Int> min, RValue<Int> max)
4074 {
4075 return Min(Max(x, min), max);
4076 }
4077
4078 RValue<Int> RoundInt(RValue<Float> cast)
4079 {
Nicolas Capensa8086512016-11-07 17:32:17 -05004080 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
Nicolas Capens9ca48d52017-01-14 12:52:55 -05004081 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Nearbyint, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
4082 auto target = ::context->getConstantUndef(Ice::IceType_i32);
4083 auto nearbyint = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
4084 nearbyint->addArg(cast.value);
4085 ::basicBlock->appendInst(nearbyint);
Nicolas Capensa8086512016-11-07 17:32:17 -05004086
4087 return RValue<Int>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004088 }
4089
4090 Type *Int::getType()
4091 {
4092 return T(Ice::IceType_i32);
4093 }
4094
4095 Long::Long(RValue<Int> cast)
4096 {
4097 Value *integer = Nucleus::createSExt(cast.value, Long::getType());
4098
4099 storeValue(integer);
4100 }
4101
4102 Long::Long(RValue<UInt> cast)
4103 {
4104 Value *integer = Nucleus::createZExt(cast.value, Long::getType());
4105
4106 storeValue(integer);
4107 }
4108
Nicolas Capens598f8d82016-09-26 15:09:10 -04004109 Long::Long(RValue<Long> rhs)
4110 {
4111 storeValue(rhs.value);
4112 }
4113
Nicolas Capens96d4e092016-11-18 14:22:38 -05004114 RValue<Long> Long::operator=(int64_t rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004115 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04004116 return RValue<Long>(storeValue(Nucleus::createConstantLong(rhs)));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004117 }
4118
Nicolas Capens96d4e092016-11-18 14:22:38 -05004119 RValue<Long> Long::operator=(RValue<Long> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004120 {
4121 storeValue(rhs.value);
4122
4123 return rhs;
4124 }
4125
Nicolas Capens96d4e092016-11-18 14:22:38 -05004126 RValue<Long> Long::operator=(const Long &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004127 {
4128 Value *value = rhs.loadValue();
4129 storeValue(value);
4130
4131 return RValue<Long>(value);
4132 }
4133
Nicolas Capens96d4e092016-11-18 14:22:38 -05004134 RValue<Long> Long::operator=(const Reference<Long> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004135 {
4136 Value *value = rhs.loadValue();
4137 storeValue(value);
4138
4139 return RValue<Long>(value);
4140 }
4141
4142 RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs)
4143 {
4144 return RValue<Long>(Nucleus::createAdd(lhs.value, rhs.value));
4145 }
4146
4147 RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs)
4148 {
4149 return RValue<Long>(Nucleus::createSub(lhs.value, rhs.value));
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
Nicolas Capens96d4e092016-11-18 14:22:38 -05004157 RValue<Long> operator-=(Long &lhs, RValue<Long> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004158 {
4159 return lhs = lhs - rhs;
4160 }
4161
4162 RValue<Long> AddAtomic(RValue<Pointer<Long> > x, RValue<Long> y)
4163 {
4164 return RValue<Long>(Nucleus::createAtomicAdd(x.value, y.value));
4165 }
4166
4167 Type *Long::getType()
4168 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04004169 return T(Ice::IceType_i64);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004170 }
4171
Nicolas Capens598f8d82016-09-26 15:09:10 -04004172 UInt::UInt(Argument<UInt> argument)
4173 {
4174 storeValue(argument.value);
4175 }
4176
4177 UInt::UInt(RValue<UShort> cast)
4178 {
4179 Value *integer = Nucleus::createZExt(cast.value, UInt::getType());
4180
4181 storeValue(integer);
4182 }
4183
4184 UInt::UInt(RValue<Long> cast)
4185 {
4186 Value *integer = Nucleus::createTrunc(cast.value, UInt::getType());
4187
4188 storeValue(integer);
4189 }
4190
4191 UInt::UInt(RValue<Float> cast)
4192 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05004193 // Smallest positive value representable in UInt, but not in Int
4194 const unsigned int ustart = 0x80000000u;
4195 const float ustartf = float(ustart);
4196
4197 // If the value is negative, store 0, otherwise store the result of the conversion
4198 storeValue((~(As<Int>(cast) >> 31) &
4199 // Check if the value can be represented as an Int
4200 IfThenElse(cast >= ustartf,
4201 // If the value is too large, subtract ustart and re-add it after conversion.
4202 As<Int>(As<UInt>(Int(cast - Float(ustartf))) + UInt(ustart)),
4203 // Otherwise, just convert normally
4204 Int(cast))).value);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004205 }
4206
Nicolas Capens598f8d82016-09-26 15:09:10 -04004207 UInt::UInt(int x)
4208 {
4209 storeValue(Nucleus::createConstantInt(x));
4210 }
4211
4212 UInt::UInt(unsigned int x)
4213 {
4214 storeValue(Nucleus::createConstantInt(x));
4215 }
4216
4217 UInt::UInt(RValue<UInt> rhs)
4218 {
4219 storeValue(rhs.value);
4220 }
4221
4222 UInt::UInt(RValue<Int> rhs)
4223 {
4224 storeValue(rhs.value);
4225 }
4226
4227 UInt::UInt(const UInt &rhs)
4228 {
4229 Value *value = rhs.loadValue();
4230 storeValue(value);
4231 }
4232
4233 UInt::UInt(const Reference<UInt> &rhs)
4234 {
4235 Value *value = rhs.loadValue();
4236 storeValue(value);
4237 }
4238
4239 UInt::UInt(const Int &rhs)
4240 {
4241 Value *value = rhs.loadValue();
4242 storeValue(value);
4243 }
4244
4245 UInt::UInt(const Reference<Int> &rhs)
4246 {
4247 Value *value = rhs.loadValue();
4248 storeValue(value);
4249 }
4250
Nicolas Capens96d4e092016-11-18 14:22:38 -05004251 RValue<UInt> UInt::operator=(unsigned int rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004252 {
4253 return RValue<UInt>(storeValue(Nucleus::createConstantInt(rhs)));
4254 }
4255
Nicolas Capens96d4e092016-11-18 14:22:38 -05004256 RValue<UInt> UInt::operator=(RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004257 {
4258 storeValue(rhs.value);
4259
4260 return rhs;
4261 }
4262
Nicolas Capens96d4e092016-11-18 14:22:38 -05004263 RValue<UInt> UInt::operator=(RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004264 {
4265 storeValue(rhs.value);
4266
4267 return RValue<UInt>(rhs);
4268 }
4269
Nicolas Capens96d4e092016-11-18 14:22:38 -05004270 RValue<UInt> UInt::operator=(const UInt &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004271 {
4272 Value *value = rhs.loadValue();
4273 storeValue(value);
4274
4275 return RValue<UInt>(value);
4276 }
4277
Nicolas Capens96d4e092016-11-18 14:22:38 -05004278 RValue<UInt> UInt::operator=(const Reference<UInt> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004279 {
4280 Value *value = rhs.loadValue();
4281 storeValue(value);
4282
4283 return RValue<UInt>(value);
4284 }
4285
Nicolas Capens96d4e092016-11-18 14:22:38 -05004286 RValue<UInt> UInt::operator=(const Int &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004287 {
4288 Value *value = rhs.loadValue();
4289 storeValue(value);
4290
4291 return RValue<UInt>(value);
4292 }
4293
Nicolas Capens96d4e092016-11-18 14:22:38 -05004294 RValue<UInt> UInt::operator=(const Reference<Int> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004295 {
4296 Value *value = rhs.loadValue();
4297 storeValue(value);
4298
4299 return RValue<UInt>(value);
4300 }
4301
4302 RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs)
4303 {
4304 return RValue<UInt>(Nucleus::createAdd(lhs.value, rhs.value));
4305 }
4306
4307 RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs)
4308 {
4309 return RValue<UInt>(Nucleus::createSub(lhs.value, rhs.value));
4310 }
4311
4312 RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs)
4313 {
4314 return RValue<UInt>(Nucleus::createMul(lhs.value, rhs.value));
4315 }
4316
4317 RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs)
4318 {
4319 return RValue<UInt>(Nucleus::createUDiv(lhs.value, rhs.value));
4320 }
4321
4322 RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs)
4323 {
4324 return RValue<UInt>(Nucleus::createURem(lhs.value, rhs.value));
4325 }
4326
4327 RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs)
4328 {
4329 return RValue<UInt>(Nucleus::createAnd(lhs.value, rhs.value));
4330 }
4331
4332 RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs)
4333 {
4334 return RValue<UInt>(Nucleus::createOr(lhs.value, rhs.value));
4335 }
4336
4337 RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs)
4338 {
4339 return RValue<UInt>(Nucleus::createXor(lhs.value, rhs.value));
4340 }
4341
4342 RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs)
4343 {
4344 return RValue<UInt>(Nucleus::createShl(lhs.value, rhs.value));
4345 }
4346
4347 RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs)
4348 {
4349 return RValue<UInt>(Nucleus::createLShr(lhs.value, rhs.value));
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
Nicolas Capens96d4e092016-11-18 14:22:38 -05004397 RValue<UInt> operator>>=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004398 {
4399 return lhs = lhs >> rhs;
4400 }
4401
4402 RValue<UInt> operator+(RValue<UInt> val)
4403 {
4404 return val;
4405 }
4406
4407 RValue<UInt> operator-(RValue<UInt> val)
4408 {
4409 return RValue<UInt>(Nucleus::createNeg(val.value));
4410 }
4411
4412 RValue<UInt> operator~(RValue<UInt> val)
4413 {
4414 return RValue<UInt>(Nucleus::createNot(val.value));
4415 }
4416
Nicolas Capens96d4e092016-11-18 14:22:38 -05004417 RValue<UInt> operator++(UInt &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04004418 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004419 RValue<UInt> res = val;
4420 val += 1;
4421 return res;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004422 }
4423
Nicolas Capens96d4e092016-11-18 14:22:38 -05004424 const UInt &operator++(UInt &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04004425 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004426 val += 1;
4427 return val;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004428 }
4429
Nicolas Capens96d4e092016-11-18 14:22:38 -05004430 RValue<UInt> operator--(UInt &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04004431 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004432 RValue<UInt> res = val;
4433 val -= 1;
4434 return res;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004435 }
4436
Nicolas Capens96d4e092016-11-18 14:22:38 -05004437 const UInt &operator--(UInt &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04004438 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004439 val -= 1;
4440 return val;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004441 }
4442
4443 RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y)
4444 {
4445 return IfThenElse(x > y, x, y);
4446 }
4447
4448 RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y)
4449 {
4450 return IfThenElse(x < y, x, y);
4451 }
4452
4453 RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max)
4454 {
4455 return Min(Max(x, min), max);
4456 }
4457
4458 RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs)
4459 {
4460 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
4461 }
4462
4463 RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs)
4464 {
4465 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
4466 }
4467
4468 RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs)
4469 {
4470 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
4471 }
4472
4473 RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs)
4474 {
4475 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
4476 }
4477
4478 RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs)
4479 {
4480 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
4481 }
4482
4483 RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs)
4484 {
4485 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
4486 }
4487
4488// RValue<UInt> RoundUInt(RValue<Float> cast)
4489// {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004490// assert(false && "UNIMPLEMENTED"); return RValue<UInt>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004491// }
4492
4493 Type *UInt::getType()
4494 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04004495 return T(Ice::IceType_i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004496 }
4497
4498// Int2::Int2(RValue<Int> cast)
4499// {
4500// Value *extend = Nucleus::createZExt(cast.value, Long::getType());
4501// Value *vector = Nucleus::createBitCast(extend, Int2::getType());
4502//
4503// Constant *shuffle[2];
4504// shuffle[0] = Nucleus::createConstantInt(0);
4505// shuffle[1] = Nucleus::createConstantInt(0);
4506//
4507// Value *replicate = Nucleus::createShuffleVector(vector, UndefValue::get(Int2::getType()), Nucleus::createConstantVector(shuffle, 2));
4508//
4509// storeValue(replicate);
4510// }
4511
4512 Int2::Int2(RValue<Int4> cast)
4513 {
Nicolas Capens22008782016-10-20 01:11:47 -04004514 storeValue(Nucleus::createBitCast(cast.value, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004515 }
4516
Nicolas Capens598f8d82016-09-26 15:09:10 -04004517 Int2::Int2(int x, int y)
4518 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04004519 int64_t constantVector[2] = {x, y};
4520 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004521 }
4522
4523 Int2::Int2(RValue<Int2> rhs)
4524 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004525 storeValue(rhs.value);
4526 }
4527
4528 Int2::Int2(const Int2 &rhs)
4529 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004530 Value *value = rhs.loadValue();
4531 storeValue(value);
4532 }
4533
4534 Int2::Int2(const Reference<Int2> &rhs)
4535 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004536 Value *value = rhs.loadValue();
4537 storeValue(value);
4538 }
4539
4540 Int2::Int2(RValue<Int> lo, RValue<Int> hi)
4541 {
Nicolas Capensd4227962016-11-09 14:24:25 -05004542 int shuffle[4] = {0, 4, 1, 5};
4543 Value *packed = Nucleus::createShuffleVector(Int4(lo).loadValue(), Int4(hi).loadValue(), shuffle);
4544
4545 storeValue(Nucleus::createBitCast(packed, Int2::getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004546 }
4547
Nicolas Capens96d4e092016-11-18 14:22:38 -05004548 RValue<Int2> Int2::operator=(RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004549 {
4550 storeValue(rhs.value);
4551
4552 return rhs;
4553 }
4554
Nicolas Capens96d4e092016-11-18 14:22:38 -05004555 RValue<Int2> Int2::operator=(const Int2 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004556 {
4557 Value *value = rhs.loadValue();
4558 storeValue(value);
4559
4560 return RValue<Int2>(value);
4561 }
4562
Nicolas Capens96d4e092016-11-18 14:22:38 -05004563 RValue<Int2> Int2::operator=(const Reference<Int2> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004564 {
4565 Value *value = rhs.loadValue();
4566 storeValue(value);
4567
4568 return RValue<Int2>(value);
4569 }
4570
4571 RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs)
4572 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004573 return RValue<Int2>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004574 }
4575
4576 RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs)
4577 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004578 return RValue<Int2>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004579 }
4580
4581// RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs)
4582// {
4583// return RValue<Int2>(Nucleus::createMul(lhs.value, rhs.value));
4584// }
4585
4586// RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs)
4587// {
4588// return RValue<Int2>(Nucleus::createSDiv(lhs.value, rhs.value));
4589// }
4590
4591// RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs)
4592// {
4593// return RValue<Int2>(Nucleus::createSRem(lhs.value, rhs.value));
4594// }
4595
4596 RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs)
4597 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004598 return RValue<Int2>(Nucleus::createAnd(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::createOr(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004604 }
4605
4606 RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs)
4607 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004608 return RValue<Int2>(Nucleus::createXor(lhs.value, rhs.value));
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::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004614 }
4615
4616 RValue<Int2> operator>>(RValue<Int2> lhs, unsigned char rhs)
4617 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05004618 return RValue<Int2>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004619 }
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, RValue<Int2> 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 Capens96d4e092016-11-18 14:22:38 -05004666 RValue<Int2> operator>>=(Int2 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004667 {
4668 return lhs = lhs >> rhs;
4669 }
4670
Nicolas Capens598f8d82016-09-26 15:09:10 -04004671// RValue<Int2> operator+(RValue<Int2> val)
4672// {
4673// return val;
4674// }
4675
4676// RValue<Int2> operator-(RValue<Int2> val)
4677// {
4678// return RValue<Int2>(Nucleus::createNeg(val.value));
4679// }
4680
4681 RValue<Int2> operator~(RValue<Int2> val)
4682 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -05004683 return RValue<Int2>(Nucleus::createNot(val.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004684 }
4685
Nicolas Capens45f187a2016-12-02 15:30:56 -05004686 RValue<Short4> UnpackLow(RValue<Int2> x, RValue<Int2> y)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004687 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05004688 int shuffle[4] = {0, 4, 1, 5}; // Real type is v4i32
4689 return As<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004690 }
4691
Nicolas Capens45f187a2016-12-02 15:30:56 -05004692 RValue<Short4> UnpackHigh(RValue<Int2> x, RValue<Int2> y)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004693 {
Nicolas Capensf8beb4b2017-01-27 02:55:44 -08004694 int shuffle[4] = {0, 4, 1, 5}; // Real type is v4i32
Nicolas Capensc70a1162016-12-03 00:16:14 -05004695 auto lowHigh = RValue<Int4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
4696 return As<Short4>(Swizzle(lowHigh, 0xEE));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004697 }
4698
4699 RValue<Int> Extract(RValue<Int2> val, int i)
4700 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05004701 return RValue<Int>(Nucleus::createExtractElement(val.value, Int::getType(), i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004702 }
4703
4704 RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i)
4705 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05004706 return RValue<Int2>(Nucleus::createInsertElement(val.value, element.value, i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004707 }
4708
4709 Type *Int2::getType()
4710 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04004711 return T(Type_v2i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004712 }
4713
Nicolas Capens598f8d82016-09-26 15:09:10 -04004714 UInt2::UInt2(unsigned int x, unsigned int y)
4715 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04004716 int64_t constantVector[2] = {x, y};
4717 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004718 }
4719
4720 UInt2::UInt2(RValue<UInt2> rhs)
4721 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004722 storeValue(rhs.value);
4723 }
4724
4725 UInt2::UInt2(const UInt2 &rhs)
4726 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004727 Value *value = rhs.loadValue();
4728 storeValue(value);
4729 }
4730
4731 UInt2::UInt2(const Reference<UInt2> &rhs)
4732 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004733 Value *value = rhs.loadValue();
4734 storeValue(value);
4735 }
4736
Nicolas Capens96d4e092016-11-18 14:22:38 -05004737 RValue<UInt2> UInt2::operator=(RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004738 {
4739 storeValue(rhs.value);
4740
4741 return rhs;
4742 }
4743
Nicolas Capens96d4e092016-11-18 14:22:38 -05004744 RValue<UInt2> UInt2::operator=(const UInt2 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004745 {
4746 Value *value = rhs.loadValue();
4747 storeValue(value);
4748
4749 return RValue<UInt2>(value);
4750 }
4751
Nicolas Capens96d4e092016-11-18 14:22:38 -05004752 RValue<UInt2> UInt2::operator=(const Reference<UInt2> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004753 {
4754 Value *value = rhs.loadValue();
4755 storeValue(value);
4756
4757 return RValue<UInt2>(value);
4758 }
4759
4760 RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs)
4761 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004762 return RValue<UInt2>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004763 }
4764
4765 RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs)
4766 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004767 return RValue<UInt2>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004768 }
4769
4770// RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs)
4771// {
4772// return RValue<UInt2>(Nucleus::createMul(lhs.value, rhs.value));
4773// }
4774
4775// RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs)
4776// {
4777// return RValue<UInt2>(Nucleus::createUDiv(lhs.value, rhs.value));
4778// }
4779
4780// RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs)
4781// {
4782// return RValue<UInt2>(Nucleus::createURem(lhs.value, rhs.value));
4783// }
4784
4785 RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs)
4786 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004787 return RValue<UInt2>(Nucleus::createAnd(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::createOr(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004793 }
4794
4795 RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs)
4796 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04004797 return RValue<UInt2>(Nucleus::createXor(lhs.value, rhs.value));
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::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004803 }
4804
4805 RValue<UInt2> operator>>(RValue<UInt2> lhs, unsigned char rhs)
4806 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05004807 return RValue<UInt2>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004808 }
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, RValue<UInt2> 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 Capens96d4e092016-11-18 14:22:38 -05004855 RValue<UInt2> operator>>=(UInt2 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004856 {
4857 return lhs = lhs >> rhs;
4858 }
4859
Nicolas Capens598f8d82016-09-26 15:09:10 -04004860// RValue<UInt2> operator+(RValue<UInt2> val)
4861// {
4862// return val;
4863// }
4864
4865// RValue<UInt2> operator-(RValue<UInt2> val)
4866// {
4867// return RValue<UInt2>(Nucleus::createNeg(val.value));
4868// }
4869
4870 RValue<UInt2> operator~(RValue<UInt2> val)
4871 {
4872 return RValue<UInt2>(Nucleus::createNot(val.value));
4873 }
4874
4875 Type *UInt2::getType()
4876 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04004877 return T(Type_v2i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004878 }
4879
4880 Int4::Int4(RValue<Byte4> cast)
4881 {
Nicolas Capensd4227962016-11-09 14:24:25 -05004882 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
4883 Value *a = Nucleus::createInsertElement(loadValue(), x, 0);
4884
4885 Value *e;
4886 int swizzle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23};
4887 Value *b = Nucleus::createBitCast(a, Byte16::getType());
4888 Value *c = Nucleus::createShuffleVector(b, V(Nucleus::createNullValue(Byte16::getType())), swizzle);
4889
4890 int swizzle2[8] = {0, 8, 1, 9, 2, 10, 3, 11};
4891 Value *d = Nucleus::createBitCast(c, Short8::getType());
4892 e = Nucleus::createShuffleVector(d, V(Nucleus::createNullValue(Short8::getType())), swizzle2);
4893
4894 Value *f = Nucleus::createBitCast(e, Int4::getType());
4895 storeValue(f);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004896 }
4897
4898 Int4::Int4(RValue<SByte4> cast)
4899 {
Nicolas Capensd4227962016-11-09 14:24:25 -05004900 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
4901 Value *a = Nucleus::createInsertElement(loadValue(), x, 0);
4902
4903 Value *e;
4904 int swizzle[16] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7};
4905 Value *b = Nucleus::createBitCast(a, Byte16::getType());
4906 Value *c = Nucleus::createShuffleVector(b, b, swizzle);
4907
4908 int swizzle2[8] = {0, 0, 1, 1, 2, 2, 3, 3};
4909 Value *d = Nucleus::createBitCast(c, Short8::getType());
4910 e = Nucleus::createShuffleVector(d, d, swizzle2);
4911
4912 Value *f = Nucleus::createBitCast(e, Int4::getType());
Nicolas Capens15060bb2016-12-05 22:17:19 -05004913 Value *g = Nucleus::createAShr(f, V(::context->getConstantInt32(24)));
Nicolas Capensd4227962016-11-09 14:24:25 -05004914 storeValue(g);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004915 }
4916
4917 Int4::Int4(RValue<Float4> cast)
4918 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004919 Value *xyzw = Nucleus::createFPToSI(cast.value, Int4::getType());
4920
4921 storeValue(xyzw);
4922 }
4923
4924 Int4::Int4(RValue<Short4> cast)
4925 {
Nicolas Capensd4227962016-11-09 14:24:25 -05004926 int swizzle[8] = {0, 0, 1, 1, 2, 2, 3, 3};
4927 Value *c = Nucleus::createShuffleVector(cast.value, cast.value, swizzle);
4928 Value *d = Nucleus::createBitCast(c, Int4::getType());
Nicolas Capens15060bb2016-12-05 22:17:19 -05004929 Value *e = Nucleus::createAShr(d, V(::context->getConstantInt32(16)));
Nicolas Capensd4227962016-11-09 14:24:25 -05004930 storeValue(e);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004931 }
4932
4933 Int4::Int4(RValue<UShort4> cast)
4934 {
Nicolas Capensd4227962016-11-09 14:24:25 -05004935 int swizzle[8] = {0, 8, 1, 9, 2, 10, 3, 11};
4936 Value *c = Nucleus::createShuffleVector(cast.value, Short8(0, 0, 0, 0, 0, 0, 0, 0).loadValue(), swizzle);
4937 Value *d = Nucleus::createBitCast(c, Int4::getType());
4938 storeValue(d);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004939 }
4940
Nicolas Capens598f8d82016-09-26 15:09:10 -04004941 Int4::Int4(int xyzw)
4942 {
4943 constant(xyzw, xyzw, xyzw, xyzw);
4944 }
4945
4946 Int4::Int4(int x, int yzw)
4947 {
4948 constant(x, yzw, yzw, yzw);
4949 }
4950
4951 Int4::Int4(int x, int y, int zw)
4952 {
4953 constant(x, y, zw, zw);
4954 }
4955
4956 Int4::Int4(int x, int y, int z, int w)
4957 {
4958 constant(x, y, z, w);
4959 }
4960
4961 void Int4::constant(int x, int y, int z, int w)
4962 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04004963 int64_t constantVector[4] = {x, y, z, w};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04004964 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004965 }
4966
4967 Int4::Int4(RValue<Int4> rhs)
4968 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004969 storeValue(rhs.value);
4970 }
4971
4972 Int4::Int4(const Int4 &rhs)
4973 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004974 Value *value = rhs.loadValue();
4975 storeValue(value);
4976 }
4977
4978 Int4::Int4(const Reference<Int4> &rhs)
4979 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004980 Value *value = rhs.loadValue();
4981 storeValue(value);
4982 }
4983
4984 Int4::Int4(RValue<UInt4> rhs)
4985 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004986 storeValue(rhs.value);
4987 }
4988
4989 Int4::Int4(const UInt4 &rhs)
4990 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004991 Value *value = rhs.loadValue();
4992 storeValue(value);
4993 }
4994
4995 Int4::Int4(const Reference<UInt4> &rhs)
4996 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004997 Value *value = rhs.loadValue();
4998 storeValue(value);
4999 }
5000
5001 Int4::Int4(RValue<Int2> lo, RValue<Int2> hi)
5002 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05005003 int shuffle[4] = {0, 1, 4, 5}; // Real type is v4i32
5004 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
5005
5006 storeValue(packed);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005007 }
5008
5009 Int4::Int4(RValue<Int> rhs)
5010 {
Nicolas Capensf8beb4b2017-01-27 02:55:44 -08005011 Value *vector = Nucleus::createBitCast(rhs.value, Int4::getType());
Nicolas Capensd4227962016-11-09 14:24:25 -05005012
5013 int swizzle[4] = {0, 0, 0, 0};
Nicolas Capensf8beb4b2017-01-27 02:55:44 -08005014 Value *replicate = Nucleus::createShuffleVector(vector, vector, swizzle);
Nicolas Capensd4227962016-11-09 14:24:25 -05005015
5016 storeValue(replicate);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005017 }
5018
5019 Int4::Int4(const Int &rhs)
5020 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005021 *this = RValue<Int>(rhs.loadValue());
5022 }
5023
5024 Int4::Int4(const Reference<Int> &rhs)
5025 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005026 *this = RValue<Int>(rhs.loadValue());
5027 }
5028
Nicolas Capens96d4e092016-11-18 14:22:38 -05005029 RValue<Int4> Int4::operator=(RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005030 {
5031 storeValue(rhs.value);
5032
5033 return rhs;
5034 }
5035
Nicolas Capens96d4e092016-11-18 14:22:38 -05005036 RValue<Int4> Int4::operator=(const Int4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005037 {
5038 Value *value = rhs.loadValue();
5039 storeValue(value);
5040
5041 return RValue<Int4>(value);
5042 }
5043
Nicolas Capens96d4e092016-11-18 14:22:38 -05005044 RValue<Int4> Int4::operator=(const Reference<Int4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005045 {
5046 Value *value = rhs.loadValue();
5047 storeValue(value);
5048
5049 return RValue<Int4>(value);
5050 }
5051
5052 RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs)
5053 {
5054 return RValue<Int4>(Nucleus::createAdd(lhs.value, rhs.value));
5055 }
5056
5057 RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs)
5058 {
5059 return RValue<Int4>(Nucleus::createSub(lhs.value, rhs.value));
5060 }
5061
5062 RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs)
5063 {
5064 return RValue<Int4>(Nucleus::createMul(lhs.value, rhs.value));
5065 }
5066
5067 RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs)
5068 {
5069 return RValue<Int4>(Nucleus::createSDiv(lhs.value, rhs.value));
5070 }
5071
5072 RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs)
5073 {
5074 return RValue<Int4>(Nucleus::createSRem(lhs.value, rhs.value));
5075 }
5076
5077 RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs)
5078 {
5079 return RValue<Int4>(Nucleus::createAnd(lhs.value, rhs.value));
5080 }
5081
5082 RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs)
5083 {
5084 return RValue<Int4>(Nucleus::createOr(lhs.value, rhs.value));
5085 }
5086
5087 RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs)
5088 {
5089 return RValue<Int4>(Nucleus::createXor(lhs.value, rhs.value));
5090 }
5091
5092 RValue<Int4> operator<<(RValue<Int4> lhs, unsigned char rhs)
5093 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05005094 return RValue<Int4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005095 }
5096
5097 RValue<Int4> operator>>(RValue<Int4> lhs, unsigned char rhs)
5098 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05005099 return RValue<Int4>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005100 }
5101
5102 RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs)
5103 {
5104 return RValue<Int4>(Nucleus::createShl(lhs.value, rhs.value));
5105 }
5106
5107 RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs)
5108 {
5109 return RValue<Int4>(Nucleus::createAShr(lhs.value, rhs.value));
5110 }
5111
Nicolas Capens96d4e092016-11-18 14:22:38 -05005112 RValue<Int4> operator+=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005113 {
5114 return lhs = lhs + rhs;
5115 }
5116
Nicolas Capens96d4e092016-11-18 14:22:38 -05005117 RValue<Int4> operator-=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005118 {
5119 return lhs = lhs - rhs;
5120 }
5121
Nicolas Capens96d4e092016-11-18 14:22:38 -05005122 RValue<Int4> operator*=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005123 {
5124 return lhs = lhs * rhs;
5125 }
5126
Nicolas Capens96d4e092016-11-18 14:22:38 -05005127// RValue<Int4> operator/=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005128// {
5129// return lhs = lhs / rhs;
5130// }
5131
Nicolas Capens96d4e092016-11-18 14:22:38 -05005132// RValue<Int4> operator%=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005133// {
5134// return lhs = lhs % rhs;
5135// }
5136
Nicolas Capens96d4e092016-11-18 14:22:38 -05005137 RValue<Int4> operator&=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005138 {
5139 return lhs = lhs & rhs;
5140 }
5141
Nicolas Capens96d4e092016-11-18 14:22:38 -05005142 RValue<Int4> operator|=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005143 {
5144 return lhs = lhs | rhs;
5145 }
5146
Nicolas Capens96d4e092016-11-18 14:22:38 -05005147 RValue<Int4> operator^=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005148 {
5149 return lhs = lhs ^ rhs;
5150 }
5151
Nicolas Capens96d4e092016-11-18 14:22:38 -05005152 RValue<Int4> operator<<=(Int4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005153 {
5154 return lhs = lhs << rhs;
5155 }
5156
Nicolas Capens96d4e092016-11-18 14:22:38 -05005157 RValue<Int4> operator>>=(Int4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005158 {
5159 return lhs = lhs >> rhs;
5160 }
5161
5162 RValue<Int4> operator+(RValue<Int4> val)
5163 {
5164 return val;
5165 }
5166
5167 RValue<Int4> operator-(RValue<Int4> val)
5168 {
5169 return RValue<Int4>(Nucleus::createNeg(val.value));
5170 }
5171
5172 RValue<Int4> operator~(RValue<Int4> val)
5173 {
5174 return RValue<Int4>(Nucleus::createNot(val.value));
5175 }
5176
5177 RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y)
5178 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005179 return RValue<Int4>(Nucleus::createICmpEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005180 }
5181
5182 RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y)
5183 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005184 return RValue<Int4>(Nucleus::createICmpSLT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005185 }
5186
5187 RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y)
5188 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005189 return RValue<Int4>(Nucleus::createICmpSLE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005190 }
5191
5192 RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y)
5193 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005194 return RValue<Int4>(Nucleus::createICmpNE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005195 }
5196
5197 RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y)
5198 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005199 return RValue<Int4>(Nucleus::createICmpSGE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005200 }
5201
5202 RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y)
5203 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005204 return RValue<Int4>(Nucleus::createICmpSGT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005205 }
5206
5207 RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y)
5208 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04005209 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
5210 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sle, condition, x.value, y.value);
5211 ::basicBlock->appendInst(cmp);
5212
5213 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5214 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
5215 ::basicBlock->appendInst(select);
5216
5217 return RValue<Int4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005218 }
5219
5220 RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y)
5221 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04005222 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
5223 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sgt, condition, x.value, y.value);
5224 ::basicBlock->appendInst(cmp);
5225
5226 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5227 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
5228 ::basicBlock->appendInst(select);
5229
5230 return RValue<Int4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005231 }
5232
5233 RValue<Int4> RoundInt(RValue<Float4> cast)
5234 {
Nicolas Capensa8086512016-11-07 17:32:17 -05005235 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
Nicolas Capens9ca48d52017-01-14 12:52:55 -05005236 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Nearbyint, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5237 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5238 auto nearbyint = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
5239 nearbyint->addArg(cast.value);
5240 ::basicBlock->appendInst(nearbyint);
Nicolas Capensa8086512016-11-07 17:32:17 -05005241
5242 return RValue<Int4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005243 }
5244
5245 RValue<Short8> Pack(RValue<Int4> x, RValue<Int4> y)
5246 {
Nicolas Capensec54a172016-10-25 17:32:37 -04005247 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
5248 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5249 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5250 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
5251 pack->addArg(x.value);
5252 pack->addArg(y.value);
5253 ::basicBlock->appendInst(pack);
5254
5255 return RValue<Short8>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005256 }
5257
5258 RValue<Int> Extract(RValue<Int4> x, int i)
5259 {
Nicolas Capense95d5342016-09-30 11:37:28 -04005260 return RValue<Int>(Nucleus::createExtractElement(x.value, Int::getType(), i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005261 }
5262
5263 RValue<Int4> Insert(RValue<Int4> x, RValue<Int> element, int i)
5264 {
5265 return RValue<Int4>(Nucleus::createInsertElement(x.value, element.value, i));
5266 }
5267
5268 RValue<Int> SignMask(RValue<Int4> x)
5269 {
Nicolas Capensf2cb9df2016-10-21 17:26:13 -04005270 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
5271 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5272 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5273 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
5274 movmsk->addArg(x.value);
5275 ::basicBlock->appendInst(movmsk);
5276
5277 return RValue<Int>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005278 }
5279
5280 RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select)
5281 {
Nicolas Capense95d5342016-09-30 11:37:28 -04005282 return RValue<Int4>(createSwizzle4(x.value, select));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005283 }
5284
5285 Type *Int4::getType()
5286 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04005287 return T(Ice::IceType_v4i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005288 }
5289
5290 UInt4::UInt4(RValue<Float4> cast)
5291 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05005292 // Smallest positive value representable in UInt, but not in Int
5293 const unsigned int ustart = 0x80000000u;
5294 const float ustartf = float(ustart);
5295
5296 // Check if the value can be represented as an Int
5297 Int4 uiValue = CmpNLT(cast, Float4(ustartf));
5298 // If the value is too large, subtract ustart and re-add it after conversion.
5299 uiValue = (uiValue & As<Int4>(As<UInt4>(Int4(cast - Float4(ustartf))) + UInt4(ustart))) |
5300 // Otherwise, just convert normally
5301 (~uiValue & Int4(cast));
5302 // If the value is negative, store 0, otherwise store the result of the conversion
5303 storeValue((~(As<Int4>(cast) >> 31) & uiValue).value);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005304 }
5305
Nicolas Capens598f8d82016-09-26 15:09:10 -04005306 UInt4::UInt4(int xyzw)
5307 {
5308 constant(xyzw, xyzw, xyzw, xyzw);
5309 }
5310
5311 UInt4::UInt4(int x, int yzw)
5312 {
5313 constant(x, yzw, yzw, yzw);
5314 }
5315
5316 UInt4::UInt4(int x, int y, int zw)
5317 {
5318 constant(x, y, zw, zw);
5319 }
5320
5321 UInt4::UInt4(int x, int y, int z, int w)
5322 {
5323 constant(x, y, z, w);
5324 }
5325
5326 void UInt4::constant(int x, int y, int z, int w)
5327 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04005328 int64_t constantVector[4] = {x, y, z, w};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04005329 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005330 }
5331
5332 UInt4::UInt4(RValue<UInt4> rhs)
5333 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005334 storeValue(rhs.value);
5335 }
5336
5337 UInt4::UInt4(const UInt4 &rhs)
5338 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005339 Value *value = rhs.loadValue();
5340 storeValue(value);
5341 }
5342
5343 UInt4::UInt4(const Reference<UInt4> &rhs)
5344 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005345 Value *value = rhs.loadValue();
5346 storeValue(value);
5347 }
5348
5349 UInt4::UInt4(RValue<Int4> rhs)
5350 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005351 storeValue(rhs.value);
5352 }
5353
5354 UInt4::UInt4(const Int4 &rhs)
5355 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005356 Value *value = rhs.loadValue();
5357 storeValue(value);
5358 }
5359
5360 UInt4::UInt4(const Reference<Int4> &rhs)
5361 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005362 Value *value = rhs.loadValue();
5363 storeValue(value);
5364 }
5365
5366 UInt4::UInt4(RValue<UInt2> lo, RValue<UInt2> hi)
5367 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05005368 int shuffle[4] = {0, 1, 4, 5}; // Real type is v4i32
5369 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
5370
5371 storeValue(packed);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005372 }
5373
Nicolas Capens96d4e092016-11-18 14:22:38 -05005374 RValue<UInt4> UInt4::operator=(RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005375 {
5376 storeValue(rhs.value);
5377
5378 return rhs;
5379 }
5380
Nicolas Capens96d4e092016-11-18 14:22:38 -05005381 RValue<UInt4> UInt4::operator=(const UInt4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005382 {
5383 Value *value = rhs.loadValue();
5384 storeValue(value);
5385
5386 return RValue<UInt4>(value);
5387 }
5388
Nicolas Capens96d4e092016-11-18 14:22:38 -05005389 RValue<UInt4> UInt4::operator=(const Reference<UInt4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005390 {
5391 Value *value = rhs.loadValue();
5392 storeValue(value);
5393
5394 return RValue<UInt4>(value);
5395 }
5396
5397 RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs)
5398 {
5399 return RValue<UInt4>(Nucleus::createAdd(lhs.value, rhs.value));
5400 }
5401
5402 RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs)
5403 {
5404 return RValue<UInt4>(Nucleus::createSub(lhs.value, rhs.value));
5405 }
5406
5407 RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs)
5408 {
5409 return RValue<UInt4>(Nucleus::createMul(lhs.value, rhs.value));
5410 }
5411
5412 RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs)
5413 {
5414 return RValue<UInt4>(Nucleus::createUDiv(lhs.value, rhs.value));
5415 }
5416
5417 RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs)
5418 {
5419 return RValue<UInt4>(Nucleus::createURem(lhs.value, rhs.value));
5420 }
5421
5422 RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs)
5423 {
5424 return RValue<UInt4>(Nucleus::createAnd(lhs.value, rhs.value));
5425 }
5426
5427 RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs)
5428 {
5429 return RValue<UInt4>(Nucleus::createOr(lhs.value, rhs.value));
5430 }
5431
5432 RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs)
5433 {
5434 return RValue<UInt4>(Nucleus::createXor(lhs.value, rhs.value));
5435 }
5436
5437 RValue<UInt4> operator<<(RValue<UInt4> lhs, unsigned char rhs)
5438 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05005439 return RValue<UInt4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005440 }
5441
5442 RValue<UInt4> operator>>(RValue<UInt4> lhs, unsigned char rhs)
5443 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05005444 return RValue<UInt4>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005445 }
5446
5447 RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs)
5448 {
5449 return RValue<UInt4>(Nucleus::createShl(lhs.value, rhs.value));
5450 }
5451
5452 RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs)
5453 {
5454 return RValue<UInt4>(Nucleus::createLShr(lhs.value, rhs.value));
5455 }
5456
Nicolas Capens96d4e092016-11-18 14:22:38 -05005457 RValue<UInt4> operator+=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005458 {
5459 return lhs = lhs + rhs;
5460 }
5461
Nicolas Capens96d4e092016-11-18 14:22:38 -05005462 RValue<UInt4> operator-=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005463 {
5464 return lhs = lhs - rhs;
5465 }
5466
Nicolas Capens96d4e092016-11-18 14:22:38 -05005467 RValue<UInt4> operator*=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005468 {
5469 return lhs = lhs * rhs;
5470 }
5471
Nicolas Capens96d4e092016-11-18 14:22:38 -05005472// RValue<UInt4> operator/=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005473// {
5474// return lhs = lhs / rhs;
5475// }
5476
Nicolas Capens96d4e092016-11-18 14:22:38 -05005477// RValue<UInt4> operator%=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005478// {
5479// return lhs = lhs % rhs;
5480// }
5481
Nicolas Capens96d4e092016-11-18 14:22:38 -05005482 RValue<UInt4> operator&=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005483 {
5484 return lhs = lhs & rhs;
5485 }
5486
Nicolas Capens96d4e092016-11-18 14:22:38 -05005487 RValue<UInt4> operator|=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005488 {
5489 return lhs = lhs | rhs;
5490 }
5491
Nicolas Capens96d4e092016-11-18 14:22:38 -05005492 RValue<UInt4> operator^=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005493 {
5494 return lhs = lhs ^ rhs;
5495 }
5496
Nicolas Capens96d4e092016-11-18 14:22:38 -05005497 RValue<UInt4> operator<<=(UInt4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005498 {
5499 return lhs = lhs << rhs;
5500 }
5501
Nicolas Capens96d4e092016-11-18 14:22:38 -05005502 RValue<UInt4> operator>>=(UInt4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005503 {
5504 return lhs = lhs >> rhs;
5505 }
5506
5507 RValue<UInt4> operator+(RValue<UInt4> val)
5508 {
5509 return val;
5510 }
5511
5512 RValue<UInt4> operator-(RValue<UInt4> val)
5513 {
5514 return RValue<UInt4>(Nucleus::createNeg(val.value));
5515 }
5516
5517 RValue<UInt4> operator~(RValue<UInt4> val)
5518 {
5519 return RValue<UInt4>(Nucleus::createNot(val.value));
5520 }
5521
5522 RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y)
5523 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005524 return RValue<UInt4>(Nucleus::createICmpEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005525 }
5526
5527 RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y)
5528 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005529 return RValue<UInt4>(Nucleus::createICmpULT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005530 }
5531
5532 RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y)
5533 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005534 return RValue<UInt4>(Nucleus::createICmpULE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005535 }
5536
5537 RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y)
5538 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005539 return RValue<UInt4>(Nucleus::createICmpNE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005540 }
5541
5542 RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y)
5543 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005544 return RValue<UInt4>(Nucleus::createICmpUGE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005545 }
5546
5547 RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y)
5548 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005549 return RValue<UInt4>(Nucleus::createICmpUGT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005550 }
5551
5552 RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y)
5553 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04005554 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
5555 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ule, condition, x.value, y.value);
5556 ::basicBlock->appendInst(cmp);
5557
5558 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5559 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
5560 ::basicBlock->appendInst(select);
5561
5562 return RValue<UInt4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005563 }
5564
5565 RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y)
5566 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04005567 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
5568 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ugt, condition, x.value, y.value);
5569 ::basicBlock->appendInst(cmp);
5570
5571 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5572 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
5573 ::basicBlock->appendInst(select);
5574
5575 return RValue<UInt4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005576 }
5577
5578 RValue<UShort8> Pack(RValue<UInt4> x, RValue<UInt4> y)
5579 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05005580 if(CPUID::SSE4_1)
5581 {
5582 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
5583 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5584 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5585 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
5586 pack->addArg(x.value);
5587 pack->addArg(y.value);
5588 ::basicBlock->appendInst(pack);
Nicolas Capensec54a172016-10-25 17:32:37 -04005589
Nicolas Capens9ca48d52017-01-14 12:52:55 -05005590 return RValue<UShort8>(V(result));
5591 }
5592 else
5593 {
5594 RValue<Int4> sx = As<Int4>(x);
5595 RValue<Int4> bx = (sx & ~(sx >> 31)) - Int4(0x8000);
5596
5597 RValue<Int4> sy = As<Int4>(y);
5598 RValue<Int4> by = (sy & ~(sy >> 31)) - Int4(0x8000);
5599
5600 return As<UShort8>(Pack(bx, by) + Short8(0x8000u));
5601 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005602 }
5603
5604 Type *UInt4::getType()
5605 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04005606 return T(Ice::IceType_v4i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005607 }
5608
5609 Float::Float(RValue<Int> cast)
5610 {
5611 Value *integer = Nucleus::createSIToFP(cast.value, Float::getType());
5612
5613 storeValue(integer);
5614 }
5615
Nicolas Capens598f8d82016-09-26 15:09:10 -04005616 Float::Float(float x)
5617 {
5618 storeValue(Nucleus::createConstantFloat(x));
5619 }
5620
5621 Float::Float(RValue<Float> rhs)
5622 {
5623 storeValue(rhs.value);
5624 }
5625
5626 Float::Float(const Float &rhs)
5627 {
5628 Value *value = rhs.loadValue();
5629 storeValue(value);
5630 }
5631
5632 Float::Float(const Reference<Float> &rhs)
5633 {
5634 Value *value = rhs.loadValue();
5635 storeValue(value);
5636 }
5637
Nicolas Capens96d4e092016-11-18 14:22:38 -05005638 RValue<Float> Float::operator=(RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005639 {
5640 storeValue(rhs.value);
5641
5642 return rhs;
5643 }
5644
Nicolas Capens96d4e092016-11-18 14:22:38 -05005645 RValue<Float> Float::operator=(const Float &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005646 {
5647 Value *value = rhs.loadValue();
5648 storeValue(value);
5649
5650 return RValue<Float>(value);
5651 }
5652
Nicolas Capens96d4e092016-11-18 14:22:38 -05005653 RValue<Float> Float::operator=(const Reference<Float> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005654 {
5655 Value *value = rhs.loadValue();
5656 storeValue(value);
5657
5658 return RValue<Float>(value);
5659 }
5660
5661 RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs)
5662 {
5663 return RValue<Float>(Nucleus::createFAdd(lhs.value, rhs.value));
5664 }
5665
5666 RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs)
5667 {
5668 return RValue<Float>(Nucleus::createFSub(lhs.value, rhs.value));
5669 }
5670
5671 RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs)
5672 {
5673 return RValue<Float>(Nucleus::createFMul(lhs.value, rhs.value));
5674 }
5675
5676 RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs)
5677 {
5678 return RValue<Float>(Nucleus::createFDiv(lhs.value, rhs.value));
5679 }
5680
Nicolas Capens96d4e092016-11-18 14:22:38 -05005681 RValue<Float> operator+=(Float &lhs, RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005682 {
5683 return lhs = lhs + rhs;
5684 }
5685
Nicolas Capens96d4e092016-11-18 14:22:38 -05005686 RValue<Float> operator-=(Float &lhs, RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005687 {
5688 return lhs = lhs - rhs;
5689 }
5690
Nicolas Capens96d4e092016-11-18 14:22:38 -05005691 RValue<Float> operator*=(Float &lhs, RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005692 {
5693 return lhs = lhs * rhs;
5694 }
5695
Nicolas Capens96d4e092016-11-18 14:22:38 -05005696 RValue<Float> operator/=(Float &lhs, RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005697 {
5698 return lhs = lhs / rhs;
5699 }
5700
5701 RValue<Float> operator+(RValue<Float> val)
5702 {
5703 return val;
5704 }
5705
5706 RValue<Float> operator-(RValue<Float> val)
5707 {
5708 return RValue<Float>(Nucleus::createFNeg(val.value));
5709 }
5710
5711 RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs)
5712 {
5713 return RValue<Bool>(Nucleus::createFCmpOLT(lhs.value, rhs.value));
5714 }
5715
5716 RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs)
5717 {
5718 return RValue<Bool>(Nucleus::createFCmpOLE(lhs.value, rhs.value));
5719 }
5720
5721 RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs)
5722 {
5723 return RValue<Bool>(Nucleus::createFCmpOGT(lhs.value, rhs.value));
5724 }
5725
5726 RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs)
5727 {
5728 return RValue<Bool>(Nucleus::createFCmpOGE(lhs.value, rhs.value));
5729 }
5730
5731 RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs)
5732 {
5733 return RValue<Bool>(Nucleus::createFCmpONE(lhs.value, rhs.value));
5734 }
5735
5736 RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs)
5737 {
5738 return RValue<Bool>(Nucleus::createFCmpOEQ(lhs.value, rhs.value));
5739 }
5740
5741 RValue<Float> Abs(RValue<Float> x)
5742 {
5743 return IfThenElse(x > 0.0f, x, -x);
5744 }
5745
5746 RValue<Float> Max(RValue<Float> x, RValue<Float> y)
5747 {
5748 return IfThenElse(x > y, x, y);
5749 }
5750
5751 RValue<Float> Min(RValue<Float> x, RValue<Float> y)
5752 {
5753 return IfThenElse(x < y, x, y);
5754 }
5755
5756 RValue<Float> Rcp_pp(RValue<Float> x, bool exactAtPow2)
5757 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04005758 return 1.0f / x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005759 }
5760
5761 RValue<Float> RcpSqrt_pp(RValue<Float> x)
5762 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04005763 return Rcp_pp(Sqrt(x));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005764 }
5765
5766 RValue<Float> Sqrt(RValue<Float> x)
5767 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04005768 Ice::Variable *result = ::function->makeVariable(Ice::IceType_f32);
5769 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Sqrt, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5770 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5771 auto sqrt = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
5772 sqrt->addArg(x.value);
5773 ::basicBlock->appendInst(sqrt);
5774
5775 return RValue<Float>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005776 }
5777
5778 RValue<Float> Round(RValue<Float> x)
5779 {
Nicolas Capensa8086512016-11-07 17:32:17 -05005780 return Float4(Round(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005781 }
5782
5783 RValue<Float> Trunc(RValue<Float> x)
5784 {
Nicolas Capensa8086512016-11-07 17:32:17 -05005785 return Float4(Trunc(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005786 }
5787
5788 RValue<Float> Frac(RValue<Float> x)
5789 {
Nicolas Capensa8086512016-11-07 17:32:17 -05005790 return Float4(Frac(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005791 }
5792
5793 RValue<Float> Floor(RValue<Float> x)
5794 {
Nicolas Capensa8086512016-11-07 17:32:17 -05005795 return Float4(Floor(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005796 }
5797
5798 RValue<Float> Ceil(RValue<Float> x)
5799 {
Nicolas Capensa8086512016-11-07 17:32:17 -05005800 return Float4(Ceil(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005801 }
5802
5803 Type *Float::getType()
5804 {
Nicolas Capens9709d4f2016-09-30 11:44:14 -04005805 return T(Ice::IceType_f32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005806 }
5807
5808 Float2::Float2(RValue<Float4> cast)
5809 {
Nicolas Capens22008782016-10-20 01:11:47 -04005810 storeValue(Nucleus::createBitCast(cast.value, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005811 }
5812
5813 Type *Float2::getType()
5814 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04005815 return T(Type_v2f32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005816 }
5817
Nicolas Capensa25311a2017-01-16 17:19:00 -05005818 Float4::Float4(RValue<Byte4> cast) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005819 {
Nicolas Capensd4227962016-11-09 14:24:25 -05005820 Value *a = Int4(cast).loadValue();
5821 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
5822
5823 storeValue(xyzw);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005824 }
5825
Nicolas Capensa25311a2017-01-16 17:19:00 -05005826 Float4::Float4(RValue<SByte4> cast) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005827 {
Nicolas Capensd4227962016-11-09 14:24:25 -05005828 Value *a = Int4(cast).loadValue();
5829 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
5830
5831 storeValue(xyzw);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005832 }
5833
Nicolas Capensa25311a2017-01-16 17:19:00 -05005834 Float4::Float4(RValue<Short4> cast) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005835 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005836 Int4 c(cast);
5837 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
5838 }
5839
Nicolas Capensa25311a2017-01-16 17:19:00 -05005840 Float4::Float4(RValue<UShort4> cast) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005841 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005842 Int4 c(cast);
5843 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
5844 }
5845
Nicolas Capensa25311a2017-01-16 17:19:00 -05005846 Float4::Float4(RValue<Int4> cast) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005847 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005848 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType());
5849
5850 storeValue(xyzw);
5851 }
5852
Nicolas Capensa25311a2017-01-16 17:19:00 -05005853 Float4::Float4(RValue<UInt4> cast) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005854 {
Nicolas Capens96445fe2016-12-15 14:45:13 -05005855 RValue<Float4> result = Float4(Int4(cast & UInt4(0x7FFFFFFF))) +
5856 As<Float4>((As<Int4>(cast) >> 31) & As<Int4>(Float4(0x80000000u)));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005857
Nicolas Capens96445fe2016-12-15 14:45:13 -05005858 storeValue(result.value);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005859 }
5860
Nicolas Capensa25311a2017-01-16 17:19:00 -05005861 Float4::Float4() : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005862 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005863 }
5864
Nicolas Capensa25311a2017-01-16 17:19:00 -05005865 Float4::Float4(float xyzw) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005866 {
5867 constant(xyzw, xyzw, xyzw, xyzw);
5868 }
5869
Nicolas Capensa25311a2017-01-16 17:19:00 -05005870 Float4::Float4(float x, float yzw) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005871 {
5872 constant(x, yzw, yzw, yzw);
5873 }
5874
Nicolas Capensa25311a2017-01-16 17:19:00 -05005875 Float4::Float4(float x, float y, float zw) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005876 {
5877 constant(x, y, zw, zw);
5878 }
5879
Nicolas Capensa25311a2017-01-16 17:19:00 -05005880 Float4::Float4(float x, float y, float z, float w) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005881 {
5882 constant(x, y, z, w);
5883 }
5884
5885 void Float4::constant(float x, float y, float z, float w)
5886 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04005887 double constantVector[4] = {x, y, z, w};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04005888 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005889 }
5890
Nicolas Capensa25311a2017-01-16 17:19:00 -05005891 Float4::Float4(RValue<Float4> rhs) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005892 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005893 storeValue(rhs.value);
5894 }
5895
Nicolas Capensa25311a2017-01-16 17:19:00 -05005896 Float4::Float4(const Float4 &rhs) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005897 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005898 Value *value = rhs.loadValue();
5899 storeValue(value);
5900 }
5901
Nicolas Capensa25311a2017-01-16 17:19:00 -05005902 Float4::Float4(const Reference<Float4> &rhs) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005903 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005904 Value *value = rhs.loadValue();
5905 storeValue(value);
5906 }
5907
Nicolas Capensa25311a2017-01-16 17:19:00 -05005908 Float4::Float4(RValue<Float> rhs) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005909 {
Nicolas Capensf8beb4b2017-01-27 02:55:44 -08005910 Value *vector = Nucleus::createBitCast(rhs.value, Float4::getType());
Nicolas Capensd4227962016-11-09 14:24:25 -05005911
5912 int swizzle[4] = {0, 0, 0, 0};
Nicolas Capensf8beb4b2017-01-27 02:55:44 -08005913 Value *replicate = Nucleus::createShuffleVector(vector, vector, swizzle);
Nicolas Capensd4227962016-11-09 14:24:25 -05005914
5915 storeValue(replicate);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005916 }
5917
Nicolas Capensa25311a2017-01-16 17:19:00 -05005918 Float4::Float4(const Float &rhs) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005919 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005920 *this = RValue<Float>(rhs.loadValue());
5921 }
5922
Nicolas Capensa25311a2017-01-16 17:19:00 -05005923 Float4::Float4(const Reference<Float> &rhs) : FloatXYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005924 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005925 *this = RValue<Float>(rhs.loadValue());
5926 }
5927
Nicolas Capens96d4e092016-11-18 14:22:38 -05005928 RValue<Float4> Float4::operator=(float x)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005929 {
5930 return *this = Float4(x, x, x, x);
5931 }
5932
Nicolas Capens96d4e092016-11-18 14:22:38 -05005933 RValue<Float4> Float4::operator=(RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005934 {
5935 storeValue(rhs.value);
5936
5937 return rhs;
5938 }
5939
Nicolas Capens96d4e092016-11-18 14:22:38 -05005940 RValue<Float4> Float4::operator=(const Float4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005941 {
5942 Value *value = rhs.loadValue();
5943 storeValue(value);
5944
5945 return RValue<Float4>(value);
5946 }
5947
Nicolas Capens96d4e092016-11-18 14:22:38 -05005948 RValue<Float4> Float4::operator=(const Reference<Float4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005949 {
5950 Value *value = rhs.loadValue();
5951 storeValue(value);
5952
5953 return RValue<Float4>(value);
5954 }
5955
Nicolas Capens96d4e092016-11-18 14:22:38 -05005956 RValue<Float4> Float4::operator=(RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005957 {
5958 return *this = Float4(rhs);
5959 }
5960
Nicolas Capens96d4e092016-11-18 14:22:38 -05005961 RValue<Float4> Float4::operator=(const Float &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005962 {
5963 return *this = Float4(rhs);
5964 }
5965
Nicolas Capens96d4e092016-11-18 14:22:38 -05005966 RValue<Float4> Float4::operator=(const Reference<Float> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005967 {
5968 return *this = Float4(rhs);
5969 }
5970
5971 RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs)
5972 {
5973 return RValue<Float4>(Nucleus::createFAdd(lhs.value, rhs.value));
5974 }
5975
5976 RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs)
5977 {
5978 return RValue<Float4>(Nucleus::createFSub(lhs.value, rhs.value));
5979 }
5980
5981 RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs)
5982 {
5983 return RValue<Float4>(Nucleus::createFMul(lhs.value, rhs.value));
5984 }
5985
5986 RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs)
5987 {
5988 return RValue<Float4>(Nucleus::createFDiv(lhs.value, rhs.value));
5989 }
5990
5991 RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs)
5992 {
5993 return RValue<Float4>(Nucleus::createFRem(lhs.value, rhs.value));
5994 }
5995
Nicolas Capens96d4e092016-11-18 14:22:38 -05005996 RValue<Float4> operator+=(Float4 &lhs, RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005997 {
5998 return lhs = lhs + rhs;
5999 }
6000
Nicolas Capens96d4e092016-11-18 14:22:38 -05006001 RValue<Float4> operator-=(Float4 &lhs, RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006002 {
6003 return lhs = lhs - rhs;
6004 }
6005
Nicolas Capens96d4e092016-11-18 14:22:38 -05006006 RValue<Float4> operator*=(Float4 &lhs, RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006007 {
6008 return lhs = lhs * rhs;
6009 }
6010
Nicolas Capens96d4e092016-11-18 14:22:38 -05006011 RValue<Float4> operator/=(Float4 &lhs, RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006012 {
6013 return lhs = lhs / rhs;
6014 }
6015
Nicolas Capens96d4e092016-11-18 14:22:38 -05006016 RValue<Float4> operator%=(Float4 &lhs, RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006017 {
6018 return lhs = lhs % rhs;
6019 }
6020
6021 RValue<Float4> operator+(RValue<Float4> val)
6022 {
6023 return val;
6024 }
6025
6026 RValue<Float4> operator-(RValue<Float4> val)
6027 {
6028 return RValue<Float4>(Nucleus::createFNeg(val.value));
6029 }
6030
6031 RValue<Float4> Abs(RValue<Float4> x)
6032 {
Nicolas Capens84272242016-11-09 13:31:06 -05006033 Value *vector = Nucleus::createBitCast(x.value, Int4::getType());
6034 int64_t constantVector[4] = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF};
6035 Value *result = Nucleus::createAnd(vector, V(Nucleus::createConstantVector(constantVector, Int4::getType())));
6036
6037 return As<Float4>(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006038 }
6039
6040 RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y)
6041 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006042 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
Nicolas Capens5cdb91a2017-02-13 12:39:18 -05006043 auto cmp = Ice::InstFcmp::create(::function, Ice::InstFcmp::Ogt, condition, x.value, y.value);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006044 ::basicBlock->appendInst(cmp);
6045
6046 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
Nicolas Capens5cdb91a2017-02-13 12:39:18 -05006047 auto select = Ice::InstSelect::create(::function, result, condition, x.value, y.value);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006048 ::basicBlock->appendInst(select);
6049
6050 return RValue<Float4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006051 }
6052
6053 RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y)
6054 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006055 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
Nicolas Capens5cdb91a2017-02-13 12:39:18 -05006056 auto cmp = Ice::InstFcmp::create(::function, Ice::InstFcmp::Olt, condition, x.value, y.value);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006057 ::basicBlock->appendInst(cmp);
6058
6059 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
Nicolas Capens5cdb91a2017-02-13 12:39:18 -05006060 auto select = Ice::InstSelect::create(::function, result, condition, x.value, y.value);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006061 ::basicBlock->appendInst(select);
6062
6063 return RValue<Float4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006064 }
6065
6066 RValue<Float4> Rcp_pp(RValue<Float4> x, bool exactAtPow2)
6067 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04006068 return Float4(1.0f) / x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04006069 }
6070
6071 RValue<Float4> RcpSqrt_pp(RValue<Float4> x)
6072 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04006073 return Rcp_pp(Sqrt(x));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006074 }
6075
6076 RValue<Float4> Sqrt(RValue<Float4> x)
6077 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04006078 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6079 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Sqrt, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6080 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6081 auto sqrt = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
6082 sqrt->addArg(x.value);
6083 ::basicBlock->appendInst(sqrt);
6084
6085 return RValue<Float4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006086 }
6087
Nicolas Capensc94ab742016-11-08 15:15:31 -05006088 RValue<Float4> Insert(RValue<Float4> x, RValue<Float> element, int i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006089 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05006090 return RValue<Float4>(Nucleus::createInsertElement(x.value, element.value, i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006091 }
6092
6093 RValue<Float> Extract(RValue<Float4> x, int i)
6094 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006095 return RValue<Float>(Nucleus::createExtractElement(x.value, Float::getType(), i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006096 }
6097
6098 RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select)
6099 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006100 return RValue<Float4>(createSwizzle4(x.value, select));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006101 }
6102
6103 RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
6104 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04006105 int shuffle[4] =
6106 {
6107 ((imm >> 0) & 0x03) + 0,
6108 ((imm >> 2) & 0x03) + 0,
6109 ((imm >> 4) & 0x03) + 4,
6110 ((imm >> 6) & 0x03) + 4,
6111 };
6112
6113 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006114 }
6115
6116 RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y)
6117 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04006118 int shuffle[4] = {0, 4, 1, 5};
6119 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006120 }
6121
6122 RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y)
6123 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04006124 int shuffle[4] = {2, 6, 3, 7};
6125 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006126 }
6127
6128 RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select)
6129 {
6130 Value *vector = lhs.loadValue();
Nicolas Capensa4c30b02016-11-08 15:43:17 -05006131 Value *result = createMask4(vector, rhs.value, select);
6132 lhs.storeValue(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006133
Nicolas Capensa4c30b02016-11-08 15:43:17 -05006134 return RValue<Float4>(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006135 }
6136
6137 RValue<Int> SignMask(RValue<Float4> x)
6138 {
Nicolas Capensf2cb9df2016-10-21 17:26:13 -04006139 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
6140 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6141 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6142 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
6143 movmsk->addArg(x.value);
6144 ::basicBlock->appendInst(movmsk);
6145
6146 return RValue<Int>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006147 }
6148
6149 RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y)
6150 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006151 return RValue<Int4>(Nucleus::createFCmpOEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006152 }
6153
6154 RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y)
6155 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006156 return RValue<Int4>(Nucleus::createFCmpOLT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006157 }
6158
6159 RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y)
6160 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006161 return RValue<Int4>(Nucleus::createFCmpOLE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006162 }
6163
6164 RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y)
6165 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006166 return RValue<Int4>(Nucleus::createFCmpONE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006167 }
6168
6169 RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y)
6170 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006171 return RValue<Int4>(Nucleus::createFCmpOGE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006172 }
6173
6174 RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y)
6175 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006176 return RValue<Int4>(Nucleus::createFCmpOGT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006177 }
6178
6179 RValue<Float4> Round(RValue<Float4> x)
6180 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05006181 if(CPUID::SSE4_1)
6182 {
6183 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6184 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6185 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6186 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
6187 round->addArg(x.value);
6188 round->addArg(::context->getConstantInt32(0));
6189 ::basicBlock->appendInst(round);
Nicolas Capensa8086512016-11-07 17:32:17 -05006190
Nicolas Capens9ca48d52017-01-14 12:52:55 -05006191 return RValue<Float4>(V(result));
6192 }
6193 else
6194 {
6195 return Float4(RoundInt(x));
6196 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04006197 }
6198
6199 RValue<Float4> Trunc(RValue<Float4> x)
6200 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05006201 if(CPUID::SSE4_1)
6202 {
6203 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6204 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6205 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6206 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
6207 round->addArg(x.value);
6208 round->addArg(::context->getConstantInt32(3));
6209 ::basicBlock->appendInst(round);
Nicolas Capensa8086512016-11-07 17:32:17 -05006210
Nicolas Capens9ca48d52017-01-14 12:52:55 -05006211 return RValue<Float4>(V(result));
6212 }
6213 else
6214 {
6215 return Float4(Int4(x));
6216 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04006217 }
6218
6219 RValue<Float4> Frac(RValue<Float4> x)
6220 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05006221 if(CPUID::SSE4_1)
6222 {
6223 return x - Floor(x);
6224 }
6225 else
6226 {
6227 Float4 frc = x - Float4(Int4(x)); // Signed fractional part
6228
6229 return frc + As<Float4>(As<Int4>(CmpNLE(Float4(0.0f), frc)) & As<Int4>(Float4(1, 1, 1, 1)));
6230 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04006231 }
6232
6233 RValue<Float4> Floor(RValue<Float4> x)
6234 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05006235 if(CPUID::SSE4_1)
6236 {
6237 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6238 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6239 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6240 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
6241 round->addArg(x.value);
6242 round->addArg(::context->getConstantInt32(1));
6243 ::basicBlock->appendInst(round);
Nicolas Capensa8086512016-11-07 17:32:17 -05006244
Nicolas Capens9ca48d52017-01-14 12:52:55 -05006245 return RValue<Float4>(V(result));
6246 }
6247 else
6248 {
6249 return x - Frac(x);
6250 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04006251 }
6252
6253 RValue<Float4> Ceil(RValue<Float4> x)
6254 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05006255 if(CPUID::SSE4_1)
6256 {
6257 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6258 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6259 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6260 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
6261 round->addArg(x.value);
6262 round->addArg(::context->getConstantInt32(2));
6263 ::basicBlock->appendInst(round);
Nicolas Capensa8086512016-11-07 17:32:17 -05006264
Nicolas Capens9ca48d52017-01-14 12:52:55 -05006265 return RValue<Float4>(V(result));
6266 }
6267 else
6268 {
6269 return -Floor(-x);
6270 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04006271 }
6272
6273 Type *Float4::getType()
6274 {
Nicolas Capens9709d4f2016-09-30 11:44:14 -04006275 return T(Ice::IceType_v4f32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006276 }
6277
6278 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset)
6279 {
Nicolas Capens8820f642016-09-30 04:42:43 -04006280 return lhs + RValue<Int>(Nucleus::createConstantInt(offset));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006281 }
6282
6283 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
6284 {
Nicolas Capensd294def2017-01-26 17:44:37 -08006285 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value, false));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006286 }
6287
6288 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
6289 {
Nicolas Capensd294def2017-01-26 17:44:37 -08006290 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value, true));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006291 }
6292
Nicolas Capens96d4e092016-11-18 14:22:38 -05006293 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, int offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006294 {
6295 return lhs = lhs + offset;
6296 }
6297
Nicolas Capens96d4e092016-11-18 14:22:38 -05006298 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<Int> offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006299 {
6300 return lhs = lhs + offset;
6301 }
6302
Nicolas Capens96d4e092016-11-18 14:22:38 -05006303 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<UInt> offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006304 {
6305 return lhs = lhs + offset;
6306 }
6307
6308 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset)
6309 {
6310 return lhs + -offset;
6311 }
6312
6313 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
6314 {
6315 return lhs + -offset;
6316 }
6317
6318 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
6319 {
6320 return lhs + -offset;
6321 }
6322
Nicolas Capens96d4e092016-11-18 14:22:38 -05006323 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, int offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006324 {
6325 return lhs = lhs - offset;
6326 }
6327
Nicolas Capens96d4e092016-11-18 14:22:38 -05006328 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<Int> offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006329 {
6330 return lhs = lhs - offset;
6331 }
6332
Nicolas Capens96d4e092016-11-18 14:22:38 -05006333 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<UInt> offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006334 {
6335 return lhs = lhs - offset;
6336 }
6337
6338 void Return()
6339 {
6340 Nucleus::createRetVoid();
6341 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
6342 Nucleus::createUnreachable();
6343 }
6344
Nicolas Capenseb253d02016-11-18 14:40:40 -05006345 void Return(RValue<Int> ret)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006346 {
Nicolas Capenseb253d02016-11-18 14:40:40 -05006347 Nucleus::createRet(ret.value);
Nicolas Capensfdcca2d2016-10-20 11:31:36 -04006348 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
6349 Nucleus::createUnreachable();
Nicolas Capens598f8d82016-09-26 15:09:10 -04006350 }
6351
Nicolas Capens598f8d82016-09-26 15:09:10 -04006352 bool branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB)
6353 {
6354 Nucleus::createCondBr(cmp.value, bodyBB, endBB);
6355 Nucleus::setInsertBlock(bodyBB);
6356
6357 return true;
6358 }
6359
Nicolas Capens598f8d82016-09-26 15:09:10 -04006360 RValue<Long> Ticks()
6361 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04006362 assert(false && "UNIMPLEMENTED"); return RValue<Long>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006363 }
6364}