blob: a69103768e66b571f9bb6f59c0aa2b135c76777c [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
Nicolas Capens598f8d82016-09-26 15:09:10 -040015#include "Reactor.hpp"
Nicolas Capens598f8d82016-09-26 15:09:10 -040016
Nicolas Capens2ae9d742016-11-24 14:43:05 -050017#include "Optimizer.hpp"
Nicolas Capensc07dc4b2018-08-06 14:20:45 -040018#include "Memory.hpp"
Nicolas Capensa062f322018-09-06 15:34:46 -040019
Nicolas Capens598f8d82016-09-26 15:09:10 -040020#include "src/IceTypes.h"
21#include "src/IceCfg.h"
22#include "src/IceELFStreamer.h"
23#include "src/IceGlobalContext.h"
24#include "src/IceCfgNode.h"
25#include "src/IceELFObjectWriter.h"
Nicolas Capens8dfd9a72016-10-13 17:44:51 -040026#include "src/IceGlobalInits.h"
Nicolas Capens598f8d82016-09-26 15:09:10 -040027
28#include "llvm/Support/FileSystem.h"
29#include "llvm/Support/raw_os_ostream.h"
Nicolas Capens6a990f82018-07-06 15:54:07 -040030#include "llvm/Support/Compiler.h"
31
32#if __has_feature(memory_sanitizer)
33#include <sanitizer/msan_interface.h>
34#endif
Nicolas Capens598f8d82016-09-26 15:09:10 -040035
Nicolas Capensbd65da92017-01-05 16:31:06 -050036#if defined(_WIN32)
Alexis Hetu113e33a2017-01-19 10:49:19 -050037#ifndef WIN32_LEAN_AND_MEAN
Nicolas Capens598f8d82016-09-26 15:09:10 -040038#define WIN32_LEAN_AND_MEAN
Alexis Hetu113e33a2017-01-19 10:49:19 -050039#endif // !WIN32_LEAN_AND_MEAN
40#ifndef NOMINMAX
Nicolas Capens598f8d82016-09-26 15:09:10 -040041#define NOMINMAX
Alexis Hetu113e33a2017-01-19 10:49:19 -050042#endif // !NOMINMAX
Nicolas Capens598f8d82016-09-26 15:09:10 -040043#include <Windows.h>
Nicolas Capensbd65da92017-01-05 16:31:06 -050044#else
45#include <sys/mman.h>
Nicolas Capens411273e2017-01-26 15:13:36 -080046#if !defined(MAP_ANONYMOUS)
47#define MAP_ANONYMOUS MAP_ANON
Nicolas Capens8b275742017-01-20 17:11:41 -050048#endif
Nicolas Capensbd65da92017-01-05 16:31:06 -050049#endif
Nicolas Capens598f8d82016-09-26 15:09:10 -040050
Nicolas Capensc07dc4b2018-08-06 14:20:45 -040051#include <mutex>
Nicolas Capens598f8d82016-09-26 15:09:10 -040052#include <limits>
53#include <iostream>
54#include <cassert>
55
56namespace
57{
58 Ice::GlobalContext *context = nullptr;
59 Ice::Cfg *function = nullptr;
60 Ice::CfgNode *basicBlock = nullptr;
61 Ice::CfgLocalAllocatorScope *allocator = nullptr;
Nicolas Capens48461502018-08-06 14:20:45 -040062 rr::Routine *routine = nullptr;
Nicolas Capens598f8d82016-09-26 15:09:10 -040063
64 std::mutex codegenMutex;
65
66 Ice::ELFFileStreamer *elfFile = nullptr;
67 Ice::Fdstream *out = nullptr;
68}
69
Nicolas Capensccd5ecb2017-01-14 12:52:55 -050070namespace
71{
Nicolas Capens47dc8672017-04-25 12:54:39 -040072 #if !defined(__i386__) && defined(_M_IX86)
73 #define __i386__ 1
74 #endif
75
76 #if !defined(__x86_64__) && (defined(_M_AMD64) || defined (_M_X64))
77 #define __x86_64__ 1
78 #endif
79
Nicolas Capensccd5ecb2017-01-14 12:52:55 -050080 class CPUID
81 {
82 public:
Nicolas Capensf7b75882017-04-26 09:30:47 -040083 const static bool ARM;
Nicolas Capensccd5ecb2017-01-14 12:52:55 -050084 const static bool SSE4_1;
85
86 private:
87 static void cpuid(int registers[4], int info)
88 {
Nicolas Capens47dc8672017-04-25 12:54:39 -040089 #if defined(__i386__) || defined(__x86_64__)
90 #if defined(_WIN32)
91 __cpuid(registers, info);
92 #else
93 __asm volatile("cpuid": "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]): "a" (info));
94 #endif
Nicolas Capensccd5ecb2017-01-14 12:52:55 -050095 #else
Nicolas Capens47dc8672017-04-25 12:54:39 -040096 registers[0] = 0;
97 registers[1] = 0;
98 registers[2] = 0;
99 registers[3] = 0;
Nicolas Capensccd5ecb2017-01-14 12:52:55 -0500100 #endif
101 }
102
Nicolas Capensf7b75882017-04-26 09:30:47 -0400103 static bool detectARM()
104 {
Stephen Lanhamfe796492018-09-07 11:59:54 -0700105 #if defined(__arm__) || defined(__aarch64__)
Nicolas Capensf7b75882017-04-26 09:30:47 -0400106 return true;
107 #elif defined(__i386__) || defined(__x86_64__)
108 return false;
109 #else
110 #error "Unknown architecture"
111 #endif
112 }
113
Nicolas Capensccd5ecb2017-01-14 12:52:55 -0500114 static bool detectSSE4_1()
115 {
Nicolas Capens47dc8672017-04-25 12:54:39 -0400116 #if defined(__i386__) || defined(__x86_64__)
117 int registers[4];
118 cpuid(registers, 1);
119 return (registers[2] & 0x00080000) != 0;
120 #else
121 return false;
122 #endif
Nicolas Capensccd5ecb2017-01-14 12:52:55 -0500123 }
124 };
125
Nicolas Capensf7b75882017-04-26 09:30:47 -0400126 const bool CPUID::ARM = CPUID::detectARM();
Nicolas Capensccd5ecb2017-01-14 12:52:55 -0500127 const bool CPUID::SSE4_1 = CPUID::detectSSE4_1();
Nicolas Capens091f3502017-10-03 14:56:49 -0400128 const bool emulateIntrinsics = false;
Nicolas Capens2d8c3702017-07-25 13:56:46 -0400129 const bool emulateMismatchedBitCast = CPUID::ARM;
Nicolas Capensccd5ecb2017-01-14 12:52:55 -0500130}
131
Nicolas Capens48461502018-08-06 14:20:45 -0400132namespace rr
Nicolas Capens598f8d82016-09-26 15:09:10 -0400133{
Nicolas Capens23d99a42016-09-30 14:57:16 -0400134 enum EmulatedType
135 {
136 EmulatedShift = 16,
137 EmulatedV2 = 2 << EmulatedShift,
138 EmulatedV4 = 4 << EmulatedShift,
139 EmulatedV8 = 8 << EmulatedShift,
140 EmulatedBits = EmulatedV2 | EmulatedV4 | EmulatedV8,
141
142 Type_v2i32 = Ice::IceType_v4i32 | EmulatedV2,
143 Type_v4i16 = Ice::IceType_v8i16 | EmulatedV4,
144 Type_v2i16 = Ice::IceType_v8i16 | EmulatedV2,
145 Type_v8i8 = Ice::IceType_v16i8 | EmulatedV8,
146 Type_v4i8 = Ice::IceType_v16i8 | EmulatedV4,
Nicolas Capens4cfd4572016-10-20 01:00:19 -0400147 Type_v2f32 = Ice::IceType_v4f32 | EmulatedV2,
Nicolas Capens23d99a42016-09-30 14:57:16 -0400148 };
149
Nicolas Capens15060bb2016-12-05 22:17:19 -0500150 class Value : public Ice::Operand {};
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500151 class SwitchCases : public Ice::InstSwitch {};
Nicolas Capens598f8d82016-09-26 15:09:10 -0400152 class BasicBlock : public Ice::CfgNode {};
153
154 Ice::Type T(Type *t)
155 {
Alexis Hetu113e33a2017-01-19 10:49:19 -0500156 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 -0400157 return (Ice::Type)(reinterpret_cast<std::intptr_t>(t) & ~EmulatedBits);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400158 }
159
160 Type *T(Ice::Type t)
161 {
162 return reinterpret_cast<Type*>(t);
163 }
164
Nicolas Capens23d99a42016-09-30 14:57:16 -0400165 Type *T(EmulatedType t)
166 {
167 return reinterpret_cast<Type*>(t);
168 }
169
Nicolas Capens15060bb2016-12-05 22:17:19 -0500170 Value *V(Ice::Operand *v)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400171 {
172 return reinterpret_cast<Value*>(v);
173 }
174
Nicolas Capens611642a2016-09-28 16:45:04 -0400175 BasicBlock *B(Ice::CfgNode *b)
176 {
177 return reinterpret_cast<BasicBlock*>(b);
178 }
179
Nicolas Capens584088c2017-01-26 16:05:18 -0800180 static size_t typeSize(Type *type)
181 {
182 if(reinterpret_cast<std::intptr_t>(type) & EmulatedBits)
183 {
184 switch(reinterpret_cast<std::intptr_t>(type))
185 {
186 case Type_v2i32: return 8;
187 case Type_v4i16: return 8;
188 case Type_v2i16: return 4;
189 case Type_v8i8: return 8;
190 case Type_v4i8: return 4;
191 case Type_v2f32: return 8;
192 default: assert(false);
193 }
194 }
195
196 return Ice::typeWidthInBytes(T(type));
197 }
198
Nicolas Capens598f8d82016-09-26 15:09:10 -0400199 Optimization optimization[10] = {InstructionCombining, Disabled};
200
Nicolas Capens66478362016-10-13 15:36:36 -0400201 using ElfHeader = std::conditional<sizeof(void*) == 8, Elf64_Ehdr, Elf32_Ehdr>::type;
202 using SectionHeader = std::conditional<sizeof(void*) == 8, Elf64_Shdr, Elf32_Shdr>::type;
203
204 inline const SectionHeader *sectionHeader(const ElfHeader *elfHeader)
205 {
206 return reinterpret_cast<const SectionHeader*>((intptr_t)elfHeader + elfHeader->e_shoff);
207 }
Nicolas Capens87852e12016-11-24 14:45:06 -0500208
Nicolas Capens66478362016-10-13 15:36:36 -0400209 inline const SectionHeader *elfSection(const ElfHeader *elfHeader, int index)
210 {
211 return &sectionHeader(elfHeader)[index];
212 }
213
214 static void *relocateSymbol(const ElfHeader *elfHeader, const Elf32_Rel &relocation, const SectionHeader &relocationTable)
215 {
216 const SectionHeader *target = elfSection(elfHeader, relocationTable.sh_info);
Nicolas Capens87852e12016-11-24 14:45:06 -0500217
Nicolas Capens66478362016-10-13 15:36:36 -0400218 intptr_t address = (intptr_t)elfHeader + target->sh_offset;
219 int32_t *patchSite = (int*)(address + relocation.r_offset);
220 uint32_t index = relocation.getSymbol();
221 int table = relocationTable.sh_link;
222 void *symbolValue = nullptr;
Nicolas Capens87852e12016-11-24 14:45:06 -0500223
Nicolas Capens66478362016-10-13 15:36:36 -0400224 if(index != SHN_UNDEF)
225 {
226 if(table == SHN_UNDEF) return nullptr;
227 const SectionHeader *symbolTable = elfSection(elfHeader, table);
Nicolas Capens87852e12016-11-24 14:45:06 -0500228
Nicolas Capens66478362016-10-13 15:36:36 -0400229 uint32_t symtab_entries = symbolTable->sh_size / symbolTable->sh_entsize;
230 if(index >= symtab_entries)
231 {
232 assert(index < symtab_entries && "Symbol Index out of range");
233 return nullptr;
234 }
Nicolas Capens87852e12016-11-24 14:45:06 -0500235
Nicolas Capens66478362016-10-13 15:36:36 -0400236 intptr_t symbolAddress = (intptr_t)elfHeader + symbolTable->sh_offset;
237 Elf32_Sym &symbol = ((Elf32_Sym*)symbolAddress)[index];
238 uint16_t section = symbol.st_shndx;
239
240 if(section != SHN_UNDEF && section < SHN_LORESERVE)
241 {
242 const SectionHeader *target = elfSection(elfHeader, symbol.st_shndx);
243 symbolValue = reinterpret_cast<void*>((intptr_t)elfHeader + symbol.st_value + target->sh_offset);
244 }
245 else
246 {
247 return nullptr;
248 }
249 }
250
Nicolas Capensf110e4d2017-05-03 15:33:49 -0400251 if(CPUID::ARM)
252 {
253 switch(relocation.getType())
254 {
255 case R_ARM_NONE:
256 // No relocation
257 break;
258 case R_ARM_MOVW_ABS_NC:
259 {
260 uint32_t thumb = 0; // Calls to Thumb code not supported.
261 uint32_t lo = (uint32_t)(intptr_t)symbolValue | thumb;
262 *patchSite = (*patchSite & 0xFFF0F000) | ((lo & 0xF000) << 4) | (lo & 0x0FFF);
263 }
264 break;
265 case R_ARM_MOVT_ABS:
266 {
267 uint32_t hi = (uint32_t)(intptr_t)(symbolValue) >> 16;
268 *patchSite = (*patchSite & 0xFFF0F000) | ((hi & 0xF000) << 4) | (hi & 0x0FFF);
269 }
270 break;
271 default:
272 assert(false && "Unsupported relocation type");
273 return nullptr;
274 }
275 }
276 else
277 {
Nicolas Capens30cd7d42017-04-25 15:17:25 -0400278 switch(relocation.getType())
279 {
280 case R_386_NONE:
281 // No relocation
282 break;
283 case R_386_32:
284 *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite);
285 break;
286 // case R_386_PC32:
287 // *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite - (intptr_t)patchSite);
288 // break;
289 default:
290 assert(false && "Unsupported relocation type");
291 return nullptr;
292 }
Nicolas Capensf110e4d2017-05-03 15:33:49 -0400293 }
294
Nicolas Capens66478362016-10-13 15:36:36 -0400295 return symbolValue;
296 }
297
298 static void *relocateSymbol(const ElfHeader *elfHeader, const Elf64_Rela &relocation, const SectionHeader &relocationTable)
299 {
300 const SectionHeader *target = elfSection(elfHeader, relocationTable.sh_info);
Nicolas Capens87852e12016-11-24 14:45:06 -0500301
Nicolas Capens66478362016-10-13 15:36:36 -0400302 intptr_t address = (intptr_t)elfHeader + target->sh_offset;
303 int32_t *patchSite = (int*)(address + relocation.r_offset);
304 uint32_t index = relocation.getSymbol();
305 int table = relocationTable.sh_link;
306 void *symbolValue = nullptr;
307
308 if(index != SHN_UNDEF)
309 {
310 if(table == SHN_UNDEF) return nullptr;
311 const SectionHeader *symbolTable = elfSection(elfHeader, table);
Nicolas Capens87852e12016-11-24 14:45:06 -0500312
Nicolas Capens66478362016-10-13 15:36:36 -0400313 uint32_t symtab_entries = symbolTable->sh_size / symbolTable->sh_entsize;
314 if(index >= symtab_entries)
315 {
316 assert(index < symtab_entries && "Symbol Index out of range");
317 return nullptr;
318 }
Nicolas Capens87852e12016-11-24 14:45:06 -0500319
Nicolas Capens66478362016-10-13 15:36:36 -0400320 intptr_t symbolAddress = (intptr_t)elfHeader + symbolTable->sh_offset;
321 Elf64_Sym &symbol = ((Elf64_Sym*)symbolAddress)[index];
322 uint16_t section = symbol.st_shndx;
323
324 if(section != SHN_UNDEF && section < SHN_LORESERVE)
325 {
326 const SectionHeader *target = elfSection(elfHeader, symbol.st_shndx);
327 symbolValue = reinterpret_cast<void*>((intptr_t)elfHeader + symbol.st_value + target->sh_offset);
328 }
329 else
330 {
331 return nullptr;
332 }
333 }
334
Nicolas Capensf110e4d2017-05-03 15:33:49 -0400335 switch(relocation.getType())
336 {
337 case R_X86_64_NONE:
338 // No relocation
339 break;
340 case R_X86_64_64:
341 *(int64_t*)patchSite = (int64_t)((intptr_t)symbolValue + *(int64_t*)patchSite) + relocation.r_addend;
342 break;
343 case R_X86_64_PC32:
344 *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite - (intptr_t)patchSite) + relocation.r_addend;
345 break;
346 case R_X86_64_32S:
347 *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite) + relocation.r_addend;
348 break;
349 default:
350 assert(false && "Unsupported relocation type");
351 return nullptr;
352 }
Nicolas Capens66478362016-10-13 15:36:36 -0400353
354 return symbolValue;
355 }
356
Nicolas Capens1cc44382017-04-25 10:52:16 -0400357 void *loadImage(uint8_t *const elfImage, size_t &codeSize)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400358 {
Nicolas Capens598f8d82016-09-26 15:09:10 -0400359 ElfHeader *elfHeader = (ElfHeader*)elfImage;
360
361 if(!elfHeader->checkMagic())
362 {
363 return nullptr;
364 }
365
Nicolas Capens66478362016-10-13 15:36:36 -0400366 // Expect ELF bitness to match platform
Nicolas Capens65047112016-11-07 13:01:07 -0500367 assert(sizeof(void*) == 8 ? elfHeader->getFileClass() == ELFCLASS64 : elfHeader->getFileClass() == ELFCLASS32);
Nicolas Capens30cd7d42017-04-25 15:17:25 -0400368 #if defined(__i386__)
369 assert(sizeof(void*) == 4 && elfHeader->e_machine == EM_386);
370 #elif defined(__x86_64__)
371 assert(sizeof(void*) == 8 && elfHeader->e_machine == EM_X86_64);
372 #elif defined(__arm__)
373 assert(sizeof(void*) == 4 && elfHeader->e_machine == EM_ARM);
Stephen Lanhamfe796492018-09-07 11:59:54 -0700374 #elif defined(__aarch64__)
375 assert(sizeof(void*) == 8 && elfHeader->e_machine == EM_AARCH64);
Nicolas Capens30cd7d42017-04-25 15:17:25 -0400376 #else
377 #error "Unsupported platform"
378 #endif
Nicolas Capens66478362016-10-13 15:36:36 -0400379
Nicolas Capens598f8d82016-09-26 15:09:10 -0400380 SectionHeader *sectionHeader = (SectionHeader*)(elfImage + elfHeader->e_shoff);
381 void *entry = nullptr;
382
383 for(int i = 0; i < elfHeader->e_shnum; i++)
384 {
Nicolas Capens66478362016-10-13 15:36:36 -0400385 if(sectionHeader[i].sh_type == SHT_PROGBITS)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400386 {
Nicolas Capens66478362016-10-13 15:36:36 -0400387 if(sectionHeader[i].sh_flags & SHF_EXECINSTR)
388 {
389 entry = elfImage + sectionHeader[i].sh_offset;
Nicolas Capens1cc44382017-04-25 10:52:16 -0400390 codeSize = sectionHeader[i].sh_size;
Nicolas Capens66478362016-10-13 15:36:36 -0400391 }
392 }
393 else if(sectionHeader[i].sh_type == SHT_REL)
394 {
395 assert(sizeof(void*) == 4 && "UNIMPLEMENTED"); // Only expected/implemented for 32-bit code
396
Alexis Hetu113e33a2017-01-19 10:49:19 -0500397 for(Elf32_Word index = 0; index < sectionHeader[i].sh_size / sectionHeader[i].sh_entsize; index++)
Nicolas Capens66478362016-10-13 15:36:36 -0400398 {
399 const Elf32_Rel &relocation = ((const Elf32_Rel*)(elfImage + sectionHeader[i].sh_offset))[index];
Alexis Hetu113e33a2017-01-19 10:49:19 -0500400 relocateSymbol(elfHeader, relocation, sectionHeader[i]);
Nicolas Capens66478362016-10-13 15:36:36 -0400401 }
402 }
403 else if(sectionHeader[i].sh_type == SHT_RELA)
404 {
405 assert(sizeof(void*) == 8 && "UNIMPLEMENTED"); // Only expected/implemented for 64-bit code
406
Alexis Hetu113e33a2017-01-19 10:49:19 -0500407 for(Elf32_Word index = 0; index < sectionHeader[i].sh_size / sectionHeader[i].sh_entsize; index++)
Nicolas Capens66478362016-10-13 15:36:36 -0400408 {
409 const Elf64_Rela &relocation = ((const Elf64_Rela*)(elfImage + sectionHeader[i].sh_offset))[index];
Alexis Hetu113e33a2017-01-19 10:49:19 -0500410 relocateSymbol(elfHeader, relocation, sectionHeader[i]);
Nicolas Capens66478362016-10-13 15:36:36 -0400411 }
Nicolas Capens598f8d82016-09-26 15:09:10 -0400412 }
413 }
414
415 return entry;
416 }
417
418 template<typename T>
419 struct ExecutableAllocator
420 {
421 ExecutableAllocator() {};
422 template<class U> ExecutableAllocator(const ExecutableAllocator<U> &other) {};
423
424 using value_type = T;
425 using size_type = std::size_t;
426
427 T *allocate(size_type n)
428 {
Nicolas Capensc07dc4b2018-08-06 14:20:45 -0400429 return (T*)allocateExecutable(sizeof(T) * n);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400430 }
431
432 void deallocate(T *p, size_type n)
433 {
Nicolas Capensc07dc4b2018-08-06 14:20:45 -0400434 deallocateExecutable(p, sizeof(T) * n);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400435 }
436 };
437
438 class ELFMemoryStreamer : public Ice::ELFStreamer, public Routine
439 {
440 ELFMemoryStreamer(const ELFMemoryStreamer &) = delete;
441 ELFMemoryStreamer &operator=(const ELFMemoryStreamer &) = delete;
442
443 public:
Nicolas Capens58274b52016-10-19 23:45:19 -0400444 ELFMemoryStreamer() : Routine(), entry(nullptr)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400445 {
446 position = 0;
447 buffer.reserve(0x1000);
448 }
449
Nicolas Capens81aa97b2017-06-27 17:08:08 -0400450 ~ELFMemoryStreamer() override
Nicolas Capens598f8d82016-09-26 15:09:10 -0400451 {
Nicolas Capensbd65da92017-01-05 16:31:06 -0500452 #if defined(_WIN32)
453 if(buffer.size() != 0)
454 {
455 DWORD exeProtection;
456 VirtualProtect(&buffer[0], buffer.size(), oldProtection, &exeProtection);
457 }
458 #endif
Nicolas Capens598f8d82016-09-26 15:09:10 -0400459 }
460
461 void write8(uint8_t Value) override
462 {
463 if(position == (uint64_t)buffer.size())
464 {
465 buffer.push_back(Value);
466 position++;
467 }
468 else if(position < (uint64_t)buffer.size())
469 {
470 buffer[position] = Value;
471 position++;
472 }
473 else assert(false && "UNIMPLEMENTED");
474 }
475
476 void writeBytes(llvm::StringRef Bytes) override
477 {
478 std::size_t oldSize = buffer.size();
479 buffer.resize(oldSize + Bytes.size());
480 memcpy(&buffer[oldSize], Bytes.begin(), Bytes.size());
481 position += Bytes.size();
482 }
483
484 uint64_t tell() const override { return position; }
485
486 void seek(uint64_t Off) override { position = Off; }
487
488 const void *getEntry() override
489 {
Nicolas Capens58274b52016-10-19 23:45:19 -0400490 if(!entry)
491 {
Nicolas Capensbd65da92017-01-05 16:31:06 -0500492 position = std::numeric_limits<std::size_t>::max(); // Can't stream more data after this
Nicolas Capens598f8d82016-09-26 15:09:10 -0400493
Nicolas Capens1cc44382017-04-25 10:52:16 -0400494 size_t codeSize = 0;
495 entry = loadImage(&buffer[0], codeSize);
496
497 #if defined(_WIN32)
Nicolas Capense745f5a2017-05-29 10:00:32 -0400498 VirtualProtect(&buffer[0], buffer.size(), PAGE_EXECUTE_READ, &oldProtection);
Nicolas Capens1cc44382017-04-25 10:52:16 -0400499 FlushInstructionCache(GetCurrentProcess(), NULL, 0);
500 #else
Nicolas Capense745f5a2017-05-29 10:00:32 -0400501 mprotect(&buffer[0], buffer.size(), PROT_READ | PROT_EXEC);
Nicolas Capens1cc44382017-04-25 10:52:16 -0400502 __builtin___clear_cache((char*)entry, (char*)entry + codeSize);
503 #endif
Nicolas Capens58274b52016-10-19 23:45:19 -0400504 }
505
506 return entry;
Nicolas Capens598f8d82016-09-26 15:09:10 -0400507 }
508
509 private:
Nicolas Capens58274b52016-10-19 23:45:19 -0400510 void *entry;
Nicolas Capens598f8d82016-09-26 15:09:10 -0400511 std::vector<uint8_t, ExecutableAllocator<uint8_t>> buffer;
512 std::size_t position;
Nicolas Capensbd65da92017-01-05 16:31:06 -0500513
514 #if defined(_WIN32)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400515 DWORD oldProtection;
Nicolas Capensbd65da92017-01-05 16:31:06 -0500516 #endif
Nicolas Capens598f8d82016-09-26 15:09:10 -0400517 };
518
519 Nucleus::Nucleus()
520 {
521 ::codegenMutex.lock(); // Reactor is currently not thread safe
522
Nicolas Capens66478362016-10-13 15:36:36 -0400523 Ice::ClFlags &Flags = Ice::ClFlags::Flags;
524 Ice::ClFlags::getParsedClFlags(Flags);
525
Nicolas Capens30cd7d42017-04-25 15:17:25 -0400526 #if defined(__arm__)
527 Flags.setTargetArch(Ice::Target_ARM32);
528 Flags.setTargetInstructionSet(Ice::ARM32InstructionSet_HWDivArm);
529 #else // x86
530 Flags.setTargetArch(sizeof(void*) == 8 ? Ice::Target_X8664 : Ice::Target_X8632);
531 Flags.setTargetInstructionSet(CPUID::SSE4_1 ? Ice::X86InstructionSet_SSE4_1 : Ice::X86InstructionSet_SSE2);
532 #endif
Nicolas Capens66478362016-10-13 15:36:36 -0400533 Flags.setOutFileType(Ice::FT_Elf);
534 Flags.setOptLevel(Ice::Opt_2);
535 Flags.setApplicationBinaryInterface(Ice::ABI_Platform);
Nicolas Capens30cd7d42017-04-25 15:17:25 -0400536 Flags.setVerbose(false ? Ice::IceV_Most : Ice::IceV_None);
537 Flags.setDisableHybridAssembly(true);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400538
Nicolas Capens65047112016-11-07 13:01:07 -0500539 static llvm::raw_os_ostream cout(std::cout);
540 static llvm::raw_os_ostream cerr(std::cerr);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400541
542 if(false) // Write out to a file
543 {
544 std::error_code errorCode;
545 ::out = new Ice::Fdstream("out.o", errorCode, llvm::sys::fs::F_None);
546 ::elfFile = new Ice::ELFFileStreamer(*out);
Nicolas Capens65047112016-11-07 13:01:07 -0500547 ::context = new Ice::GlobalContext(&cout, &cout, &cerr, elfFile);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400548 }
549 else
550 {
551 ELFMemoryStreamer *elfMemory = new ELFMemoryStreamer();
Nicolas Capens65047112016-11-07 13:01:07 -0500552 ::context = new Ice::GlobalContext(&cout, &cout, &cerr, elfMemory);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400553 ::routine = elfMemory;
554 }
555 }
556
557 Nucleus::~Nucleus()
558 {
Nicolas Capens619a8c52017-07-05 14:10:46 -0400559 delete ::routine;
560
Nicolas Capens598f8d82016-09-26 15:09:10 -0400561 delete ::allocator;
562 delete ::function;
563 delete ::context;
564
565 delete ::elfFile;
566 delete ::out;
567
568 ::codegenMutex.unlock();
569 }
570
571 Routine *Nucleus::acquireRoutine(const wchar_t *name, bool runOptimizations)
572 {
573 if(basicBlock->getInsts().empty() || basicBlock->getInsts().back().getKind() != Ice::Inst::Ret)
574 {
575 createRetVoid();
576 }
577
578 std::wstring wideName(name);
579 std::string asciiName(wideName.begin(), wideName.end());
580 ::function->setFunctionName(Ice::GlobalString::createWithString(::context, asciiName));
581
Nicolas Capens2ae9d742016-11-24 14:43:05 -0500582 optimize();
583
Nicolas Capens598f8d82016-09-26 15:09:10 -0400584 ::function->translate();
Nicolas Capensde19f392016-10-19 10:29:49 -0400585 assert(!::function->hasError());
586
Nicolas Capens83a6bb92017-07-05 15:04:00 -0400587 auto globals = ::function->getGlobalInits();
Nicolas Capens66478362016-10-13 15:36:36 -0400588
589 if(globals && !globals->empty())
590 {
Nicolas Capens83a6bb92017-07-05 15:04:00 -0400591 ::context->getGlobals()->merge(globals.get());
Nicolas Capens66478362016-10-13 15:36:36 -0400592 }
Nicolas Capens598f8d82016-09-26 15:09:10 -0400593
594 ::context->emitFileHeader();
595 ::function->emitIAS();
596 auto assembler = ::function->releaseAssembler();
Nicolas Capens66478362016-10-13 15:36:36 -0400597 auto objectWriter = ::context->getObjectWriter();
598 assembler->alignFunction();
599 objectWriter->writeFunctionCode(::function->getFunctionName(), false, assembler.get());
600 ::context->lowerGlobals("last");
Nicolas Capens73dd7a22016-10-20 13:20:34 -0400601 ::context->lowerConstants();
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500602 ::context->lowerJumpTables();
Nicolas Capens66478362016-10-13 15:36:36 -0400603 objectWriter->setUndefinedSyms(::context->getConstantExternSyms());
604 objectWriter->writeNonUserSections();
Nicolas Capens598f8d82016-09-26 15:09:10 -0400605
Nicolas Capens619a8c52017-07-05 14:10:46 -0400606 Routine *handoffRoutine = ::routine;
607 ::routine = nullptr;
608
609 return handoffRoutine;
Nicolas Capens598f8d82016-09-26 15:09:10 -0400610 }
611
612 void Nucleus::optimize()
613 {
Nicolas Capens48461502018-08-06 14:20:45 -0400614 rr::optimize(::function);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400615 }
616
617 Value *Nucleus::allocateStackVariable(Type *t, int arraySize)
618 {
619 Ice::Type type = T(t);
Nicolas Capensa8f98632016-10-20 11:25:55 -0400620 int typeSize = Ice::typeWidthInBytes(type);
621 int totalSize = typeSize * (arraySize ? arraySize : 1);
Nicolas Capense12780d2016-09-27 14:18:07 -0400622
Nicolas Capensa8f98632016-10-20 11:25:55 -0400623 auto bytes = Ice::ConstantInteger32::create(::context, type, totalSize);
Nicolas Capense12780d2016-09-27 14:18:07 -0400624 auto address = ::function->makeVariable(T(getPointerType(t)));
Nicolas Capensa8f98632016-10-20 11:25:55 -0400625 auto alloca = Ice::InstAlloca::create(::function, address, bytes, typeSize);
Nicolas Capense12780d2016-09-27 14:18:07 -0400626 ::function->getEntryNode()->getInsts().push_front(alloca);
627
628 return V(address);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400629 }
630
631 BasicBlock *Nucleus::createBasicBlock()
632 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400633 return B(::function->makeNode());
Nicolas Capens598f8d82016-09-26 15:09:10 -0400634 }
635
636 BasicBlock *Nucleus::getInsertBlock()
637 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400638 return B(::basicBlock);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400639 }
640
641 void Nucleus::setInsertBlock(BasicBlock *basicBlock)
642 {
Nicolas Capens9ed1a182016-10-24 09:52:23 -0400643 // assert(::basicBlock->getInsts().back().getTerminatorEdges().size() >= 0 && "Previous basic block must have a terminator");
Nicolas Capens611642a2016-09-28 16:45:04 -0400644 ::basicBlock = basicBlock;
Nicolas Capens598f8d82016-09-26 15:09:10 -0400645 }
646
Nicolas Capens598f8d82016-09-26 15:09:10 -0400647 void Nucleus::createFunction(Type *ReturnType, std::vector<Type*> &Params)
648 {
649 uint32_t sequenceNumber = 0;
650 ::function = Ice::Cfg::create(::context, sequenceNumber).release();
651 ::allocator = new Ice::CfgLocalAllocatorScope(::function);
652
653 for(Type *type : Params)
654 {
655 Ice::Variable *arg = ::function->makeVariable(T(type));
656 ::function->addArg(arg);
657 }
658
659 Ice::CfgNode *node = ::function->makeNode();
660 ::function->setEntryNode(node);
661 ::basicBlock = node;
662 }
663
664 Value *Nucleus::getArgument(unsigned int index)
665 {
666 return V(::function->getArgs()[index]);
667 }
668
669 void Nucleus::createRetVoid()
670 {
Nicolas Capensfdcca2d2016-10-20 11:31:36 -0400671 Ice::InstRet *ret = Ice::InstRet::create(::function);
672 ::basicBlock->appendInst(ret);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400673 }
674
675 void Nucleus::createRet(Value *v)
676 {
Nicolas Capensfdcca2d2016-10-20 11:31:36 -0400677 Ice::InstRet *ret = Ice::InstRet::create(::function, v);
678 ::basicBlock->appendInst(ret);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400679 }
680
681 void Nucleus::createBr(BasicBlock *dest)
682 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400683 auto br = Ice::InstBr::create(::function, dest);
684 ::basicBlock->appendInst(br);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400685 }
686
687 void Nucleus::createCondBr(Value *cond, BasicBlock *ifTrue, BasicBlock *ifFalse)
688 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400689 auto br = Ice::InstBr::create(::function, cond, ifTrue, ifFalse);
690 ::basicBlock->appendInst(br);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400691 }
692
Nicolas Capensf8360ba2017-01-25 11:35:00 -0800693 static bool isCommutative(Ice::InstArithmetic::OpKind op)
694 {
695 switch(op)
696 {
697 case Ice::InstArithmetic::Add:
698 case Ice::InstArithmetic::Fadd:
699 case Ice::InstArithmetic::Mul:
700 case Ice::InstArithmetic::Fmul:
701 case Ice::InstArithmetic::And:
702 case Ice::InstArithmetic::Or:
703 case Ice::InstArithmetic::Xor:
704 return true;
705 default:
706 return false;
707 }
708 }
709
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400710 static Value *createArithmetic(Ice::InstArithmetic::OpKind op, Value *lhs, Value *rhs)
711 {
Nicolas Capensb64e0ce2018-01-26 01:24:57 +0000712 assert(lhs->getType() == rhs->getType() || llvm::isa<Ice::Constant>(rhs));
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400713
Nicolas Capensf8360ba2017-01-25 11:35:00 -0800714 bool swapOperands = llvm::isa<Ice::Constant>(lhs) && isCommutative(op);
715
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400716 Ice::Variable *result = ::function->makeVariable(lhs->getType());
Nicolas Capensf8360ba2017-01-25 11:35:00 -0800717 Ice::InstArithmetic *arithmetic = Ice::InstArithmetic::create(::function, op, result, swapOperands ? rhs : lhs, swapOperands ? lhs : rhs);
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400718 ::basicBlock->appendInst(arithmetic);
719
720 return V(result);
721 }
722
Nicolas Capens598f8d82016-09-26 15:09:10 -0400723 Value *Nucleus::createAdd(Value *lhs, Value *rhs)
724 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400725 return createArithmetic(Ice::InstArithmetic::Add, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400726 }
727
728 Value *Nucleus::createSub(Value *lhs, Value *rhs)
729 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400730 return createArithmetic(Ice::InstArithmetic::Sub, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400731 }
732
733 Value *Nucleus::createMul(Value *lhs, Value *rhs)
734 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400735 return createArithmetic(Ice::InstArithmetic::Mul, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400736 }
737
738 Value *Nucleus::createUDiv(Value *lhs, Value *rhs)
739 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400740 return createArithmetic(Ice::InstArithmetic::Udiv, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400741 }
742
743 Value *Nucleus::createSDiv(Value *lhs, Value *rhs)
744 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400745 return createArithmetic(Ice::InstArithmetic::Sdiv, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400746 }
747
748 Value *Nucleus::createFAdd(Value *lhs, Value *rhs)
749 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400750 return createArithmetic(Ice::InstArithmetic::Fadd, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400751 }
752
753 Value *Nucleus::createFSub(Value *lhs, Value *rhs)
754 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400755 return createArithmetic(Ice::InstArithmetic::Fsub, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400756 }
757
758 Value *Nucleus::createFMul(Value *lhs, Value *rhs)
759 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400760 return createArithmetic(Ice::InstArithmetic::Fmul, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400761 }
762
763 Value *Nucleus::createFDiv(Value *lhs, Value *rhs)
764 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400765 return createArithmetic(Ice::InstArithmetic::Fdiv, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400766 }
767
768 Value *Nucleus::createURem(Value *lhs, Value *rhs)
769 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400770 return createArithmetic(Ice::InstArithmetic::Urem, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400771 }
772
773 Value *Nucleus::createSRem(Value *lhs, Value *rhs)
774 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400775 return createArithmetic(Ice::InstArithmetic::Srem, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400776 }
777
778 Value *Nucleus::createFRem(Value *lhs, Value *rhs)
779 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400780 return createArithmetic(Ice::InstArithmetic::Frem, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400781 }
782
783 Value *Nucleus::createShl(Value *lhs, Value *rhs)
784 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400785 return createArithmetic(Ice::InstArithmetic::Shl, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400786 }
787
788 Value *Nucleus::createLShr(Value *lhs, Value *rhs)
789 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400790 return createArithmetic(Ice::InstArithmetic::Lshr, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400791 }
792
793 Value *Nucleus::createAShr(Value *lhs, Value *rhs)
794 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400795 return createArithmetic(Ice::InstArithmetic::Ashr, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400796 }
797
798 Value *Nucleus::createAnd(Value *lhs, Value *rhs)
799 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400800 return createArithmetic(Ice::InstArithmetic::And, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400801 }
802
803 Value *Nucleus::createOr(Value *lhs, Value *rhs)
804 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400805 return createArithmetic(Ice::InstArithmetic::Or, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400806 }
807
808 Value *Nucleus::createXor(Value *lhs, Value *rhs)
809 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400810 return createArithmetic(Ice::InstArithmetic::Xor, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400811 }
812
813 Value *Nucleus::createNeg(Value *v)
814 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500815 return createSub(createNullValue(T(v->getType())), v);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400816 }
817
818 Value *Nucleus::createFNeg(Value *v)
819 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500820 double c[4] = {-0.0, -0.0, -0.0, -0.0};
821 Value *negativeZero = Ice::isVectorType(v->getType()) ?
822 createConstantVector(c, T(v->getType())) :
Nicolas Capens15060bb2016-12-05 22:17:19 -0500823 V(::context->getConstantFloat(-0.0f));
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500824
825 return createFSub(negativeZero, v);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400826 }
827
828 Value *Nucleus::createNot(Value *v)
829 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500830 if(Ice::isScalarIntegerType(v->getType()))
831 {
Nicolas Capens15060bb2016-12-05 22:17:19 -0500832 return createXor(v, V(::context->getConstantInt(v->getType(), -1)));
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500833 }
834 else // Vector
835 {
Nicolas Capensf34d1ac2017-05-08 17:06:11 -0400836 int64_t c[16] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500837 return createXor(v, createConstantVector(c, T(v->getType())));
838 }
Nicolas Capens598f8d82016-09-26 15:09:10 -0400839 }
840
Nicolas Capense12780d2016-09-27 14:18:07 -0400841 Value *Nucleus::createLoad(Value *ptr, Type *type, bool isVolatile, unsigned int align)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400842 {
Nicolas Capens23d99a42016-09-30 14:57:16 -0400843 int valueType = (int)reinterpret_cast<intptr_t>(type);
844 Ice::Variable *result = ::function->makeVariable(T(type));
845
Nicolas Capensf4c4eca2017-10-03 14:26:07 -0400846 if((valueType & EmulatedBits) && (align != 0)) // Narrow vector not stored on stack.
Nicolas Capens23d99a42016-09-30 14:57:16 -0400847 {
Nicolas Capens070d9f42017-04-26 13:36:33 -0400848 if(emulateIntrinsics)
849 {
850 if(typeSize(type) == 4)
851 {
852 auto pointer = RValue<Pointer<Byte>>(ptr);
Nicolas Capens1894cfa2017-07-27 14:21:46 -0400853 Int x = *Pointer<Int>(pointer);
Nicolas Capens070d9f42017-04-26 13:36:33 -0400854
855 Int4 vector;
856 vector = Insert(vector, x, 0);
857
858 auto bitcast = Ice::InstCast::create(::function, Ice::InstCast::Bitcast, result, vector.loadValue());
859 ::basicBlock->appendInst(bitcast);
860 }
861 else if(typeSize(type) == 8)
862 {
863 auto pointer = RValue<Pointer<Byte>>(ptr);
Nicolas Capens1894cfa2017-07-27 14:21:46 -0400864 Int x = *Pointer<Int>(pointer);
Nicolas Capens070d9f42017-04-26 13:36:33 -0400865 Int y = *Pointer<Int>(pointer + 4);
866
867 Int4 vector;
868 vector = Insert(vector, x, 0);
869 vector = Insert(vector, y, 1);
870
871 auto bitcast = Ice::InstCast::create(::function, Ice::InstCast::Bitcast, result, vector.loadValue());
872 ::basicBlock->appendInst(bitcast);
873 }
874 else assert(false);
875 }
876 else
877 {
878 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::LoadSubVector, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
879 auto target = ::context->getConstantUndef(Ice::IceType_i32);
880 auto load = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
881 load->addArg(ptr);
882 load->addArg(::context->getConstantInt32(typeSize(type)));
883 ::basicBlock->appendInst(load);
884 }
Nicolas Capens23d99a42016-09-30 14:57:16 -0400885 }
886 else
887 {
888 auto load = Ice::InstLoad::create(::function, result, ptr, align);
889 ::basicBlock->appendInst(load);
890 }
891
892 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400893 }
894
Nicolas Capens6d738712016-09-30 04:15:22 -0400895 Value *Nucleus::createStore(Value *value, Value *ptr, Type *type, bool isVolatile, unsigned int align)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400896 {
Nicolas Capens6a990f82018-07-06 15:54:07 -0400897 #if __has_feature(memory_sanitizer)
898 // Mark all (non-stack) memory writes as initialized by calling __msan_unpoison
899 if(align != 0)
900 {
901 auto call = Ice::InstCall::create(::function, 2, nullptr, ::context->getConstantInt64(reinterpret_cast<intptr_t>(__msan_unpoison)), false);
902 call->addArg(ptr);
903 call->addArg(::context->getConstantInt64(typeSize(type)));
904 ::basicBlock->appendInst(call);
905 }
906 #endif
907
Nicolas Capens23d99a42016-09-30 14:57:16 -0400908 int valueType = (int)reinterpret_cast<intptr_t>(type);
909
Nicolas Capensf4c4eca2017-10-03 14:26:07 -0400910 if((valueType & EmulatedBits) && (align != 0)) // Narrow vector not stored on stack.
Nicolas Capens23d99a42016-09-30 14:57:16 -0400911 {
Nicolas Capens070d9f42017-04-26 13:36:33 -0400912 if(emulateIntrinsics)
913 {
914 if(typeSize(type) == 4)
915 {
916 Ice::Variable *vector = ::function->makeVariable(Ice::IceType_v4i32);
917 auto bitcast = Ice::InstCast::create(::function, Ice::InstCast::Bitcast, vector, value);
918 ::basicBlock->appendInst(bitcast);
919
920 RValue<Int4> v(V(vector));
921
922 auto pointer = RValue<Pointer<Byte>>(ptr);
923 Int x = Extract(v, 0);
924 *Pointer<Int>(pointer) = x;
925 }
926 else if(typeSize(type) == 8)
927 {
928 Ice::Variable *vector = ::function->makeVariable(Ice::IceType_v4i32);
929 auto bitcast = Ice::InstCast::create(::function, Ice::InstCast::Bitcast, vector, value);
930 ::basicBlock->appendInst(bitcast);
931
932 RValue<Int4> v(V(vector));
933
934 auto pointer = RValue<Pointer<Byte>>(ptr);
935 Int x = Extract(v, 0);
936 *Pointer<Int>(pointer) = x;
937 Int y = Extract(v, 1);
938 *Pointer<Int>(pointer + 4) = y;
939 }
940 else assert(false);
941 }
942 else
943 {
944 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::StoreSubVector, Ice::Intrinsics::SideEffects_T, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_T};
945 auto target = ::context->getConstantUndef(Ice::IceType_i32);
946 auto store = Ice::InstIntrinsicCall::create(::function, 3, nullptr, target, intrinsic);
947 store->addArg(value);
948 store->addArg(ptr);
949 store->addArg(::context->getConstantInt32(typeSize(type)));
950 ::basicBlock->appendInst(store);
951 }
Nicolas Capens23d99a42016-09-30 14:57:16 -0400952 }
953 else
954 {
Nicolas Capensf4c4eca2017-10-03 14:26:07 -0400955 assert(value->getType() == T(type));
Nicolas Capens23d99a42016-09-30 14:57:16 -0400956
957 auto store = Ice::InstStore::create(::function, value, ptr, align);
958 ::basicBlock->appendInst(store);
959 }
960
Nicolas Capens598f8d82016-09-26 15:09:10 -0400961 return value;
962 }
963
Nicolas Capensd294def2017-01-26 17:44:37 -0800964 Value *Nucleus::createGEP(Value *ptr, Type *type, Value *index, bool unsignedIndex)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400965 {
Nicolas Capens8820f642016-09-30 04:42:43 -0400966 assert(index->getType() == Ice::IceType_i32);
967
Nicolas Capens15060bb2016-12-05 22:17:19 -0500968 if(auto *constant = llvm::dyn_cast<Ice::ConstantInteger32>(index))
969 {
Nicolas Capens584088c2017-01-26 16:05:18 -0800970 int32_t offset = constant->getValue() * (int)typeSize(type);
Nicolas Capens15060bb2016-12-05 22:17:19 -0500971
972 if(offset == 0)
973 {
974 return ptr;
975 }
976
977 return createAdd(ptr, createConstantInt(offset));
978 }
979
Nicolas Capens8820f642016-09-30 04:42:43 -0400980 if(!Ice::isByteSizedType(T(type)))
981 {
Nicolas Capens584088c2017-01-26 16:05:18 -0800982 index = createMul(index, createConstantInt((int)typeSize(type)));
Nicolas Capens8820f642016-09-30 04:42:43 -0400983 }
984
985 if(sizeof(void*) == 8)
986 {
Nicolas Capensd294def2017-01-26 17:44:37 -0800987 if(unsignedIndex)
988 {
989 index = createZExt(index, T(Ice::IceType_i64));
990 }
991 else
992 {
993 index = createSExt(index, T(Ice::IceType_i64));
994 }
Nicolas Capens8820f642016-09-30 04:42:43 -0400995 }
996
997 return createAdd(ptr, index);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400998 }
999
1000 Value *Nucleus::createAtomicAdd(Value *ptr, Value *value)
1001 {
1002 assert(false && "UNIMPLEMENTED"); return nullptr;
1003 }
1004
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001005 static Value *createCast(Ice::InstCast::OpKind op, Value *v, Type *destType)
1006 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04001007 if(v->getType() == T(destType))
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001008 {
1009 return v;
1010 }
1011
1012 Ice::Variable *result = ::function->makeVariable(T(destType));
1013 Ice::InstCast *cast = Ice::InstCast::create(::function, op, result, v);
1014 ::basicBlock->appendInst(cast);
1015
1016 return V(result);
1017 }
1018
Nicolas Capens598f8d82016-09-26 15:09:10 -04001019 Value *Nucleus::createTrunc(Value *v, Type *destType)
1020 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001021 return createCast(Ice::InstCast::Trunc, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001022 }
1023
1024 Value *Nucleus::createZExt(Value *v, Type *destType)
1025 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001026 return createCast(Ice::InstCast::Zext, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001027 }
1028
1029 Value *Nucleus::createSExt(Value *v, Type *destType)
1030 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001031 return createCast(Ice::InstCast::Sext, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001032 }
1033
1034 Value *Nucleus::createFPToSI(Value *v, Type *destType)
1035 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001036 return createCast(Ice::InstCast::Fptosi, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001037 }
1038
Nicolas Capens598f8d82016-09-26 15:09:10 -04001039 Value *Nucleus::createSIToFP(Value *v, Type *destType)
1040 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001041 return createCast(Ice::InstCast::Sitofp, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001042 }
1043
1044 Value *Nucleus::createFPTrunc(Value *v, Type *destType)
1045 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001046 return createCast(Ice::InstCast::Fptrunc, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001047 }
1048
1049 Value *Nucleus::createFPExt(Value *v, Type *destType)
1050 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001051 return createCast(Ice::InstCast::Fpext, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001052 }
1053
1054 Value *Nucleus::createBitCast(Value *v, Type *destType)
1055 {
Nicolas Capens2d8c3702017-07-25 13:56:46 -04001056 // Bitcasts must be between types of the same logical size. But with emulated narrow vectors we need
1057 // support for casting between scalars and wide vectors. For platforms where this is not supported,
1058 // emulate them by writing to the stack and reading back as the destination type.
1059 if(emulateMismatchedBitCast)
1060 {
1061 if(!Ice::isVectorType(v->getType()) && Ice::isVectorType(T(destType)))
1062 {
1063 Value *address = allocateStackVariable(destType);
1064 createStore(v, address, T(v->getType()));
1065 return createLoad(address, destType);
1066 }
1067 else if(Ice::isVectorType(v->getType()) && !Ice::isVectorType(T(destType)))
1068 {
1069 Value *address = allocateStackVariable(T(v->getType()));
1070 createStore(v, address, T(v->getType()));
1071 return createLoad(address, destType);
1072 }
1073 }
1074
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001075 return createCast(Ice::InstCast::Bitcast, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001076 }
1077
Nicolas Capens43dc6292016-10-20 00:01:38 -04001078 static Value *createIntCompare(Ice::InstIcmp::ICond condition, Value *lhs, Value *rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001079 {
Nicolas Capens611642a2016-09-28 16:45:04 -04001080 assert(lhs->getType() == rhs->getType());
1081
Nicolas Capens43dc6292016-10-20 00:01:38 -04001082 auto result = ::function->makeVariable(Ice::isScalarIntegerType(lhs->getType()) ? Ice::IceType_i1 : lhs->getType());
1083 auto cmp = Ice::InstIcmp::create(::function, condition, result, lhs, rhs);
Nicolas Capens611642a2016-09-28 16:45:04 -04001084 ::basicBlock->appendInst(cmp);
1085
1086 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001087 }
1088
Nicolas Capens43dc6292016-10-20 00:01:38 -04001089 Value *Nucleus::createICmpEQ(Value *lhs, Value *rhs)
1090 {
1091 return createIntCompare(Ice::InstIcmp::Eq, lhs, rhs);
1092 }
1093
1094 Value *Nucleus::createICmpNE(Value *lhs, Value *rhs)
1095 {
1096 return createIntCompare(Ice::InstIcmp::Ne, lhs, rhs);
1097 }
1098
1099 Value *Nucleus::createICmpUGT(Value *lhs, Value *rhs)
1100 {
1101 return createIntCompare(Ice::InstIcmp::Ugt, lhs, rhs);
1102 }
1103
1104 Value *Nucleus::createICmpUGE(Value *lhs, Value *rhs)
1105 {
1106 return createIntCompare(Ice::InstIcmp::Uge, lhs, rhs);
1107 }
1108
1109 Value *Nucleus::createICmpULT(Value *lhs, Value *rhs)
1110 {
1111 return createIntCompare(Ice::InstIcmp::Ult, lhs, rhs);
1112 }
1113
1114 Value *Nucleus::createICmpULE(Value *lhs, Value *rhs)
1115 {
1116 return createIntCompare(Ice::InstIcmp::Ule, lhs, rhs);
1117 }
1118
1119 Value *Nucleus::createICmpSGT(Value *lhs, Value *rhs)
1120 {
1121 return createIntCompare(Ice::InstIcmp::Sgt, lhs, rhs);
1122 }
1123
1124 Value *Nucleus::createICmpSGE(Value *lhs, Value *rhs)
1125 {
1126 return createIntCompare(Ice::InstIcmp::Sge, lhs, rhs);
1127 }
1128
1129 Value *Nucleus::createICmpSLT(Value *lhs, Value *rhs)
1130 {
1131 return createIntCompare(Ice::InstIcmp::Slt, lhs, rhs);
1132 }
1133
Nicolas Capens598f8d82016-09-26 15:09:10 -04001134 Value *Nucleus::createICmpSLE(Value *lhs, Value *rhs)
1135 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001136 return createIntCompare(Ice::InstIcmp::Sle, lhs, rhs);
1137 }
1138
1139 static Value *createFloatCompare(Ice::InstFcmp::FCond condition, Value *lhs, Value *rhs)
1140 {
1141 assert(lhs->getType() == rhs->getType());
1142 assert(Ice::isScalarFloatingType(lhs->getType()) || lhs->getType() == Ice::IceType_v4f32);
1143
1144 auto result = ::function->makeVariable(Ice::isScalarFloatingType(lhs->getType()) ? Ice::IceType_i1 : Ice::IceType_v4i32);
1145 auto cmp = Ice::InstFcmp::create(::function, condition, result, lhs, rhs);
1146 ::basicBlock->appendInst(cmp);
1147
1148 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001149 }
1150
1151 Value *Nucleus::createFCmpOEQ(Value *lhs, Value *rhs)
1152 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001153 return createFloatCompare(Ice::InstFcmp::Oeq, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001154 }
1155
1156 Value *Nucleus::createFCmpOGT(Value *lhs, Value *rhs)
1157 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001158 return createFloatCompare(Ice::InstFcmp::Ogt, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001159 }
1160
1161 Value *Nucleus::createFCmpOGE(Value *lhs, Value *rhs)
1162 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001163 return createFloatCompare(Ice::InstFcmp::Oge, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001164 }
1165
1166 Value *Nucleus::createFCmpOLT(Value *lhs, Value *rhs)
1167 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001168 return createFloatCompare(Ice::InstFcmp::Olt, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001169 }
1170
1171 Value *Nucleus::createFCmpOLE(Value *lhs, Value *rhs)
1172 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001173 return createFloatCompare(Ice::InstFcmp::Ole, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001174 }
1175
1176 Value *Nucleus::createFCmpONE(Value *lhs, Value *rhs)
1177 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001178 return createFloatCompare(Ice::InstFcmp::One, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001179 }
1180
1181 Value *Nucleus::createFCmpORD(Value *lhs, Value *rhs)
1182 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001183 return createFloatCompare(Ice::InstFcmp::Ord, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001184 }
1185
1186 Value *Nucleus::createFCmpUNO(Value *lhs, Value *rhs)
1187 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001188 return createFloatCompare(Ice::InstFcmp::Uno, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001189 }
1190
1191 Value *Nucleus::createFCmpUEQ(Value *lhs, Value *rhs)
1192 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001193 return createFloatCompare(Ice::InstFcmp::Ueq, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001194 }
1195
1196 Value *Nucleus::createFCmpUGT(Value *lhs, Value *rhs)
1197 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001198 return createFloatCompare(Ice::InstFcmp::Ugt, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001199 }
1200
1201 Value *Nucleus::createFCmpUGE(Value *lhs, Value *rhs)
1202 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001203 return createFloatCompare(Ice::InstFcmp::Uge, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001204 }
1205
1206 Value *Nucleus::createFCmpULT(Value *lhs, Value *rhs)
1207 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001208 return createFloatCompare(Ice::InstFcmp::Ult, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001209 }
1210
1211 Value *Nucleus::createFCmpULE(Value *lhs, Value *rhs)
1212 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001213 return createFloatCompare(Ice::InstFcmp::Ule, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001214 }
1215
1216 Value *Nucleus::createFCmpUNE(Value *lhs, Value *rhs)
1217 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001218 return createFloatCompare(Ice::InstFcmp::Une, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001219 }
1220
Nicolas Capense95d5342016-09-30 11:37:28 -04001221 Value *Nucleus::createExtractElement(Value *vector, Type *type, int index)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001222 {
Nicolas Capens9709d4f2016-09-30 11:44:14 -04001223 auto result = ::function->makeVariable(T(type));
1224 auto extract = Ice::InstExtractElement::create(::function, result, vector, ::context->getConstantInt32(index));
1225 ::basicBlock->appendInst(extract);
1226
1227 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001228 }
1229
1230 Value *Nucleus::createInsertElement(Value *vector, Value *element, int index)
1231 {
Nicolas Capens9709d4f2016-09-30 11:44:14 -04001232 auto result = ::function->makeVariable(vector->getType());
1233 auto insert = Ice::InstInsertElement::create(::function, result, vector, element, ::context->getConstantInt32(index));
1234 ::basicBlock->appendInst(insert);
1235
1236 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001237 }
1238
Nicolas Capense89cd582016-09-30 14:23:47 -04001239 Value *Nucleus::createShuffleVector(Value *V1, Value *V2, const int *select)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001240 {
Nicolas Capens619c0ab2016-09-30 14:46:24 -04001241 assert(V1->getType() == V2->getType());
1242
1243 int size = Ice::typeNumElements(V1->getType());
1244 auto result = ::function->makeVariable(V1->getType());
1245 auto shuffle = Ice::InstShuffleVector::create(::function, result, V1, V2);
1246
1247 for(int i = 0; i < size; i++)
1248 {
1249 shuffle->addIndex(llvm::cast<Ice::ConstantInteger32>(::context->getConstantInt32(select[i])));
1250 }
1251
1252 ::basicBlock->appendInst(shuffle);
1253
1254 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001255 }
1256
1257 Value *Nucleus::createSelect(Value *C, Value *ifTrue, Value *ifFalse)
1258 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04001259 assert(ifTrue->getType() == ifFalse->getType());
1260
1261 auto result = ::function->makeVariable(ifTrue->getType());
1262 auto *select = Ice::InstSelect::create(::function, result, C, ifTrue, ifFalse);
1263 ::basicBlock->appendInst(select);
1264
1265 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001266 }
1267
Nicolas Capensb98fe5c2016-11-09 12:24:06 -05001268 SwitchCases *Nucleus::createSwitch(Value *control, BasicBlock *defaultBranch, unsigned numCases)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001269 {
Nicolas Capensb98fe5c2016-11-09 12:24:06 -05001270 auto switchInst = Ice::InstSwitch::create(::function, numCases, control, defaultBranch);
1271 ::basicBlock->appendInst(switchInst);
1272
1273 return reinterpret_cast<SwitchCases*>(switchInst);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001274 }
1275
Nicolas Capensb98fe5c2016-11-09 12:24:06 -05001276 void Nucleus::addSwitchCase(SwitchCases *switchCases, int label, BasicBlock *branch)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001277 {
Nicolas Capensb98fe5c2016-11-09 12:24:06 -05001278 switchCases->addBranch(label, label, branch);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001279 }
1280
1281 void Nucleus::createUnreachable()
1282 {
Nicolas Capensfdcca2d2016-10-20 11:31:36 -04001283 Ice::InstUnreachable *unreachable = Ice::InstUnreachable::create(::function);
1284 ::basicBlock->appendInst(unreachable);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001285 }
1286
Nicolas Capense95d5342016-09-30 11:37:28 -04001287 static Value *createSwizzle4(Value *val, unsigned char select)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001288 {
Nicolas Capens619c0ab2016-09-30 14:46:24 -04001289 int swizzle[4] =
1290 {
1291 (select >> 0) & 0x03,
1292 (select >> 2) & 0x03,
1293 (select >> 4) & 0x03,
1294 (select >> 6) & 0x03,
1295 };
Nicolas Capens9709d4f2016-09-30 11:44:14 -04001296
Nicolas Capens619c0ab2016-09-30 14:46:24 -04001297 return Nucleus::createShuffleVector(val, val, swizzle);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001298 }
1299
Nicolas Capense95d5342016-09-30 11:37:28 -04001300 static Value *createMask4(Value *lhs, Value *rhs, unsigned char select)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001301 {
Nicolas Capensa4c30b02016-11-08 15:43:17 -05001302 int64_t mask[4] = {0, 0, 0, 0};
1303
1304 mask[(select >> 0) & 0x03] = -1;
1305 mask[(select >> 2) & 0x03] = -1;
1306 mask[(select >> 4) & 0x03] = -1;
1307 mask[(select >> 6) & 0x03] = -1;
1308
1309 Value *condition = Nucleus::createConstantVector(mask, T(Ice::IceType_v4i1));
1310 Value *result = Nucleus::createSelect(condition, rhs, lhs);
1311
1312 return result;
Nicolas Capens598f8d82016-09-26 15:09:10 -04001313 }
1314
Nicolas Capens598f8d82016-09-26 15:09:10 -04001315 Type *Nucleus::getPointerType(Type *ElementType)
1316 {
Nicolas Capense12780d2016-09-27 14:18:07 -04001317 if(sizeof(void*) == 8)
1318 {
1319 return T(Ice::IceType_i64);
1320 }
1321 else
1322 {
1323 return T(Ice::IceType_i32);
1324 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04001325 }
1326
Nicolas Capens13ac2322016-10-13 14:52:12 -04001327 Value *Nucleus::createNullValue(Type *Ty)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001328 {
Nicolas Capens73dd7a22016-10-20 13:20:34 -04001329 if(Ice::isVectorType(T(Ty)))
1330 {
Nicolas Capens30385f02017-04-18 13:03:47 -04001331 assert(Ice::typeNumElements(T(Ty)) <= 16);
1332 int64_t c[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
Nicolas Capens73dd7a22016-10-20 13:20:34 -04001333 return createConstantVector(c, Ty);
1334 }
1335 else
1336 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001337 return V(::context->getConstantZero(T(Ty)));
Nicolas Capens73dd7a22016-10-20 13:20:34 -04001338 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04001339 }
1340
Nicolas Capens13ac2322016-10-13 14:52:12 -04001341 Value *Nucleus::createConstantLong(int64_t i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001342 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001343 return V(::context->getConstantInt64(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001344 }
1345
Nicolas Capens13ac2322016-10-13 14:52:12 -04001346 Value *Nucleus::createConstantInt(int i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001347 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001348 return V(::context->getConstantInt32(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001349 }
1350
Nicolas Capens13ac2322016-10-13 14:52:12 -04001351 Value *Nucleus::createConstantInt(unsigned int i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001352 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001353 return V(::context->getConstantInt32(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001354 }
1355
Nicolas Capens13ac2322016-10-13 14:52:12 -04001356 Value *Nucleus::createConstantBool(bool b)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001357 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001358 return V(::context->getConstantInt1(b));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001359 }
1360
Nicolas Capens13ac2322016-10-13 14:52:12 -04001361 Value *Nucleus::createConstantByte(signed char i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001362 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001363 return V(::context->getConstantInt8(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001364 }
1365
Nicolas Capens13ac2322016-10-13 14:52:12 -04001366 Value *Nucleus::createConstantByte(unsigned char i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001367 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001368 return V(::context->getConstantInt8(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001369 }
1370
Nicolas Capens13ac2322016-10-13 14:52:12 -04001371 Value *Nucleus::createConstantShort(short i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001372 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001373 return V(::context->getConstantInt16(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001374 }
1375
Nicolas Capens13ac2322016-10-13 14:52:12 -04001376 Value *Nucleus::createConstantShort(unsigned short i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001377 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001378 return V(::context->getConstantInt16(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001379 }
1380
Nicolas Capens13ac2322016-10-13 14:52:12 -04001381 Value *Nucleus::createConstantFloat(float x)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001382 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001383 return V(::context->getConstantFloat(x));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001384 }
1385
Nicolas Capens13ac2322016-10-13 14:52:12 -04001386 Value *Nucleus::createNullPointer(Type *Ty)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001387 {
Nicolas Capensa29d6532016-12-05 21:38:09 -05001388 return createNullValue(T(sizeof(void*) == 8 ? Ice::IceType_i64 : Ice::IceType_i32));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001389 }
1390
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001391 Value *Nucleus::createConstantVector(const int64_t *constants, Type *type)
Nicolas Capens13ac2322016-10-13 14:52:12 -04001392 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001393 const int vectorSize = 16;
1394 assert(Ice::typeWidthInBytes(T(type)) == vectorSize);
1395 const int alignment = vectorSize;
1396 auto globalPool = ::function->getGlobalPool();
1397
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001398 const int64_t *i = constants;
1399 const double *f = reinterpret_cast<const double*>(constants);
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001400 Ice::VariableDeclaration::DataInitializer *dataInitializer = nullptr;
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001401
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001402 switch((int)reinterpret_cast<intptr_t>(type))
1403 {
1404 case Ice::IceType_v4i32:
Nicolas Capensa4c30b02016-11-08 15:43:17 -05001405 case Ice::IceType_v4i1:
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001406 {
1407 const int initializer[4] = {(int)i[0], (int)i[1], (int)i[2], (int)i[3]};
1408 static_assert(sizeof(initializer) == vectorSize, "!");
1409 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1410 }
1411 break;
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001412 case Ice::IceType_v4f32:
1413 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001414 const float initializer[4] = {(float)f[0], (float)f[1], (float)f[2], (float)f[3]};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001415 static_assert(sizeof(initializer) == vectorSize, "!");
1416 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1417 }
1418 break;
1419 case Ice::IceType_v8i16:
Nicolas Capensa4c30b02016-11-08 15:43:17 -05001420 case Ice::IceType_v8i1:
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001421 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001422 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 -04001423 static_assert(sizeof(initializer) == vectorSize, "!");
1424 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1425 }
1426 break;
1427 case Ice::IceType_v16i8:
Nicolas Capensa4c30b02016-11-08 15:43:17 -05001428 case Ice::IceType_v16i1:
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001429 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001430 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 -04001431 static_assert(sizeof(initializer) == vectorSize, "!");
1432 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1433 }
1434 break;
1435 case Type_v2i32:
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001436 {
1437 const int initializer[4] = {(int)i[0], (int)i[1], (int)i[0], (int)i[1]};
1438 static_assert(sizeof(initializer) == vectorSize, "!");
1439 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1440 }
1441 break;
Nicolas Capens4cfd4572016-10-20 01:00:19 -04001442 case Type_v2f32:
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001443 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001444 const float initializer[4] = {(float)f[0], (float)f[1], (float)f[0], (float)f[1]};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001445 static_assert(sizeof(initializer) == vectorSize, "!");
1446 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1447 }
1448 break;
1449 case Type_v4i16:
1450 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001451 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 -04001452 static_assert(sizeof(initializer) == vectorSize, "!");
1453 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1454 }
1455 break;
1456 case Type_v8i8:
1457 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001458 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 -04001459 static_assert(sizeof(initializer) == vectorSize, "!");
1460 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1461 }
1462 break;
1463 case Type_v4i8:
1464 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001465 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 -04001466 static_assert(sizeof(initializer) == vectorSize, "!");
1467 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1468 }
1469 break;
1470 default:
1471 assert(false && "Unknown constant vector type" && type);
1472 }
1473
1474 auto name = Ice::GlobalString::createWithoutString(::context);
1475 auto *variableDeclaration = Ice::VariableDeclaration::create(globalPool);
1476 variableDeclaration->setName(name);
1477 variableDeclaration->setAlignment(alignment);
1478 variableDeclaration->setIsConstant(true);
1479 variableDeclaration->addInitializer(dataInitializer);
Nicolas Capens87852e12016-11-24 14:45:06 -05001480
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001481 ::function->addGlobal(variableDeclaration);
1482
1483 constexpr int32_t offset = 0;
1484 Ice::Operand *ptr = ::context->getConstantSym(offset, name);
1485
1486 Ice::Variable *result = ::function->makeVariable(T(type));
1487 auto load = Ice::InstLoad::create(::function, result, ptr, alignment);
1488 ::basicBlock->appendInst(load);
1489
1490 return V(result);
Nicolas Capens13ac2322016-10-13 14:52:12 -04001491 }
1492
1493 Value *Nucleus::createConstantVector(const double *constants, Type *type)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001494 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001495 return createConstantVector((const int64_t*)constants, type);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001496 }
1497
1498 Type *Void::getType()
1499 {
1500 return T(Ice::IceType_void);
1501 }
1502
Nicolas Capens598f8d82016-09-26 15:09:10 -04001503 Bool::Bool(Argument<Bool> argument)
1504 {
1505 storeValue(argument.value);
1506 }
1507
Nicolas Capens598f8d82016-09-26 15:09:10 -04001508 Bool::Bool(bool x)
1509 {
1510 storeValue(Nucleus::createConstantBool(x));
1511 }
1512
1513 Bool::Bool(RValue<Bool> rhs)
1514 {
1515 storeValue(rhs.value);
1516 }
1517
1518 Bool::Bool(const Bool &rhs)
1519 {
1520 Value *value = rhs.loadValue();
1521 storeValue(value);
1522 }
1523
1524 Bool::Bool(const Reference<Bool> &rhs)
1525 {
1526 Value *value = rhs.loadValue();
1527 storeValue(value);
1528 }
1529
Nicolas Capens96d4e092016-11-18 14:22:38 -05001530 RValue<Bool> Bool::operator=(RValue<Bool> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001531 {
1532 storeValue(rhs.value);
1533
1534 return rhs;
1535 }
1536
Nicolas Capens96d4e092016-11-18 14:22:38 -05001537 RValue<Bool> Bool::operator=(const Bool &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001538 {
1539 Value *value = rhs.loadValue();
1540 storeValue(value);
1541
1542 return RValue<Bool>(value);
1543 }
1544
Nicolas Capens96d4e092016-11-18 14:22:38 -05001545 RValue<Bool> Bool::operator=(const Reference<Bool> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001546 {
1547 Value *value = rhs.loadValue();
1548 storeValue(value);
1549
1550 return RValue<Bool>(value);
1551 }
1552
1553 RValue<Bool> operator!(RValue<Bool> val)
1554 {
1555 return RValue<Bool>(Nucleus::createNot(val.value));
1556 }
1557
1558 RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs)
1559 {
1560 return RValue<Bool>(Nucleus::createAnd(lhs.value, rhs.value));
1561 }
1562
1563 RValue<Bool> operator||(RValue<Bool> lhs, RValue<Bool> rhs)
1564 {
1565 return RValue<Bool>(Nucleus::createOr(lhs.value, rhs.value));
1566 }
1567
1568 Type *Bool::getType()
1569 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04001570 return T(Ice::IceType_i1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001571 }
1572
1573 Byte::Byte(Argument<Byte> argument)
1574 {
1575 storeValue(argument.value);
1576 }
1577
1578 Byte::Byte(RValue<Int> cast)
1579 {
1580 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
1581
1582 storeValue(integer);
1583 }
1584
1585 Byte::Byte(RValue<UInt> cast)
1586 {
1587 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
1588
1589 storeValue(integer);
1590 }
1591
1592 Byte::Byte(RValue<UShort> cast)
1593 {
1594 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
1595
1596 storeValue(integer);
1597 }
1598
Nicolas Capens598f8d82016-09-26 15:09:10 -04001599 Byte::Byte(int x)
1600 {
1601 storeValue(Nucleus::createConstantByte((unsigned char)x));
1602 }
1603
1604 Byte::Byte(unsigned char x)
1605 {
1606 storeValue(Nucleus::createConstantByte(x));
1607 }
1608
1609 Byte::Byte(RValue<Byte> rhs)
1610 {
1611 storeValue(rhs.value);
1612 }
1613
1614 Byte::Byte(const Byte &rhs)
1615 {
1616 Value *value = rhs.loadValue();
1617 storeValue(value);
1618 }
1619
1620 Byte::Byte(const Reference<Byte> &rhs)
1621 {
1622 Value *value = rhs.loadValue();
1623 storeValue(value);
1624 }
1625
Nicolas Capens96d4e092016-11-18 14:22:38 -05001626 RValue<Byte> Byte::operator=(RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001627 {
1628 storeValue(rhs.value);
1629
1630 return rhs;
1631 }
1632
Nicolas Capens96d4e092016-11-18 14:22:38 -05001633 RValue<Byte> Byte::operator=(const Byte &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001634 {
1635 Value *value = rhs.loadValue();
1636 storeValue(value);
1637
1638 return RValue<Byte>(value);
1639 }
1640
Nicolas Capens96d4e092016-11-18 14:22:38 -05001641 RValue<Byte> Byte::operator=(const Reference<Byte> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001642 {
1643 Value *value = rhs.loadValue();
1644 storeValue(value);
1645
1646 return RValue<Byte>(value);
1647 }
1648
1649 RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs)
1650 {
1651 return RValue<Byte>(Nucleus::createAdd(lhs.value, rhs.value));
1652 }
1653
1654 RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs)
1655 {
1656 return RValue<Byte>(Nucleus::createSub(lhs.value, rhs.value));
1657 }
1658
1659 RValue<Byte> operator*(RValue<Byte> lhs, RValue<Byte> rhs)
1660 {
1661 return RValue<Byte>(Nucleus::createMul(lhs.value, rhs.value));
1662 }
1663
1664 RValue<Byte> operator/(RValue<Byte> lhs, RValue<Byte> rhs)
1665 {
1666 return RValue<Byte>(Nucleus::createUDiv(lhs.value, rhs.value));
1667 }
1668
1669 RValue<Byte> operator%(RValue<Byte> lhs, RValue<Byte> rhs)
1670 {
1671 return RValue<Byte>(Nucleus::createURem(lhs.value, rhs.value));
1672 }
1673
1674 RValue<Byte> operator&(RValue<Byte> lhs, RValue<Byte> rhs)
1675 {
1676 return RValue<Byte>(Nucleus::createAnd(lhs.value, rhs.value));
1677 }
1678
1679 RValue<Byte> operator|(RValue<Byte> lhs, RValue<Byte> rhs)
1680 {
1681 return RValue<Byte>(Nucleus::createOr(lhs.value, rhs.value));
1682 }
1683
1684 RValue<Byte> operator^(RValue<Byte> lhs, RValue<Byte> rhs)
1685 {
1686 return RValue<Byte>(Nucleus::createXor(lhs.value, rhs.value));
1687 }
1688
1689 RValue<Byte> operator<<(RValue<Byte> lhs, RValue<Byte> rhs)
1690 {
1691 return RValue<Byte>(Nucleus::createShl(lhs.value, rhs.value));
1692 }
1693
1694 RValue<Byte> operator>>(RValue<Byte> lhs, RValue<Byte> rhs)
1695 {
1696 return RValue<Byte>(Nucleus::createLShr(lhs.value, rhs.value));
1697 }
1698
Nicolas Capens96d4e092016-11-18 14:22:38 -05001699 RValue<Byte> operator+=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001700 {
1701 return lhs = lhs + rhs;
1702 }
1703
Nicolas Capens96d4e092016-11-18 14:22:38 -05001704 RValue<Byte> operator-=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001705 {
1706 return lhs = lhs - rhs;
1707 }
1708
Nicolas Capens96d4e092016-11-18 14:22:38 -05001709 RValue<Byte> operator*=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001710 {
1711 return lhs = lhs * rhs;
1712 }
1713
Nicolas Capens96d4e092016-11-18 14:22:38 -05001714 RValue<Byte> operator/=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001715 {
1716 return lhs = lhs / rhs;
1717 }
1718
Nicolas Capens96d4e092016-11-18 14:22:38 -05001719 RValue<Byte> operator%=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001720 {
1721 return lhs = lhs % rhs;
1722 }
1723
Nicolas Capens96d4e092016-11-18 14:22:38 -05001724 RValue<Byte> operator&=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001725 {
1726 return lhs = lhs & rhs;
1727 }
1728
Nicolas Capens96d4e092016-11-18 14:22:38 -05001729 RValue<Byte> operator|=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001730 {
1731 return lhs = lhs | rhs;
1732 }
1733
Nicolas Capens96d4e092016-11-18 14:22:38 -05001734 RValue<Byte> operator^=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001735 {
1736 return lhs = lhs ^ rhs;
1737 }
1738
Nicolas Capens96d4e092016-11-18 14:22:38 -05001739 RValue<Byte> operator<<=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001740 {
1741 return lhs = lhs << rhs;
1742 }
1743
Nicolas Capens96d4e092016-11-18 14:22:38 -05001744 RValue<Byte> operator>>=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001745 {
1746 return lhs = lhs >> rhs;
1747 }
1748
1749 RValue<Byte> operator+(RValue<Byte> val)
1750 {
1751 return val;
1752 }
1753
1754 RValue<Byte> operator-(RValue<Byte> val)
1755 {
1756 return RValue<Byte>(Nucleus::createNeg(val.value));
1757 }
1758
1759 RValue<Byte> operator~(RValue<Byte> val)
1760 {
1761 return RValue<Byte>(Nucleus::createNot(val.value));
1762 }
1763
Nicolas Capens96d4e092016-11-18 14:22:38 -05001764 RValue<Byte> operator++(Byte &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04001765 {
1766 RValue<Byte> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05001767 val += Byte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001768 return res;
1769 }
1770
Nicolas Capens96d4e092016-11-18 14:22:38 -05001771 const Byte &operator++(Byte &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04001772 {
Nicolas Capensd1229402016-11-07 16:05:22 -05001773 val += Byte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001774 return val;
1775 }
1776
Nicolas Capens96d4e092016-11-18 14:22:38 -05001777 RValue<Byte> operator--(Byte &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04001778 {
1779 RValue<Byte> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05001780 val -= Byte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001781 return res;
1782 }
1783
Nicolas Capens96d4e092016-11-18 14:22:38 -05001784 const Byte &operator--(Byte &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04001785 {
Nicolas Capensd1229402016-11-07 16:05:22 -05001786 val -= Byte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001787 return val;
1788 }
1789
1790 RValue<Bool> operator<(RValue<Byte> lhs, RValue<Byte> rhs)
1791 {
1792 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1793 }
1794
1795 RValue<Bool> operator<=(RValue<Byte> lhs, RValue<Byte> rhs)
1796 {
1797 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1798 }
1799
1800 RValue<Bool> operator>(RValue<Byte> lhs, RValue<Byte> rhs)
1801 {
1802 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1803 }
1804
1805 RValue<Bool> operator>=(RValue<Byte> lhs, RValue<Byte> rhs)
1806 {
1807 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1808 }
1809
1810 RValue<Bool> operator!=(RValue<Byte> lhs, RValue<Byte> rhs)
1811 {
1812 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1813 }
1814
1815 RValue<Bool> operator==(RValue<Byte> lhs, RValue<Byte> rhs)
1816 {
1817 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1818 }
1819
1820 Type *Byte::getType()
1821 {
Nicolas Capens6d738712016-09-30 04:15:22 -04001822 return T(Ice::IceType_i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001823 }
1824
1825 SByte::SByte(Argument<SByte> argument)
1826 {
1827 storeValue(argument.value);
1828 }
1829
1830 SByte::SByte(RValue<Int> cast)
1831 {
1832 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1833
1834 storeValue(integer);
1835 }
1836
1837 SByte::SByte(RValue<Short> cast)
1838 {
1839 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1840
1841 storeValue(integer);
1842 }
1843
Nicolas Capens598f8d82016-09-26 15:09:10 -04001844 SByte::SByte(signed char x)
1845 {
1846 storeValue(Nucleus::createConstantByte(x));
1847 }
1848
1849 SByte::SByte(RValue<SByte> rhs)
1850 {
1851 storeValue(rhs.value);
1852 }
1853
1854 SByte::SByte(const SByte &rhs)
1855 {
1856 Value *value = rhs.loadValue();
1857 storeValue(value);
1858 }
1859
1860 SByte::SByte(const Reference<SByte> &rhs)
1861 {
1862 Value *value = rhs.loadValue();
1863 storeValue(value);
1864 }
1865
Nicolas Capens96d4e092016-11-18 14:22:38 -05001866 RValue<SByte> SByte::operator=(RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001867 {
1868 storeValue(rhs.value);
1869
1870 return rhs;
1871 }
1872
Nicolas Capens96d4e092016-11-18 14:22:38 -05001873 RValue<SByte> SByte::operator=(const SByte &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001874 {
1875 Value *value = rhs.loadValue();
1876 storeValue(value);
1877
1878 return RValue<SByte>(value);
1879 }
1880
Nicolas Capens96d4e092016-11-18 14:22:38 -05001881 RValue<SByte> SByte::operator=(const Reference<SByte> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001882 {
1883 Value *value = rhs.loadValue();
1884 storeValue(value);
1885
1886 return RValue<SByte>(value);
1887 }
1888
1889 RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs)
1890 {
1891 return RValue<SByte>(Nucleus::createAdd(lhs.value, rhs.value));
1892 }
1893
1894 RValue<SByte> operator-(RValue<SByte> lhs, RValue<SByte> rhs)
1895 {
1896 return RValue<SByte>(Nucleus::createSub(lhs.value, rhs.value));
1897 }
1898
1899 RValue<SByte> operator*(RValue<SByte> lhs, RValue<SByte> rhs)
1900 {
1901 return RValue<SByte>(Nucleus::createMul(lhs.value, rhs.value));
1902 }
1903
1904 RValue<SByte> operator/(RValue<SByte> lhs, RValue<SByte> rhs)
1905 {
1906 return RValue<SByte>(Nucleus::createSDiv(lhs.value, rhs.value));
1907 }
1908
1909 RValue<SByte> operator%(RValue<SByte> lhs, RValue<SByte> rhs)
1910 {
1911 return RValue<SByte>(Nucleus::createSRem(lhs.value, rhs.value));
1912 }
1913
1914 RValue<SByte> operator&(RValue<SByte> lhs, RValue<SByte> rhs)
1915 {
1916 return RValue<SByte>(Nucleus::createAnd(lhs.value, rhs.value));
1917 }
1918
1919 RValue<SByte> operator|(RValue<SByte> lhs, RValue<SByte> rhs)
1920 {
1921 return RValue<SByte>(Nucleus::createOr(lhs.value, rhs.value));
1922 }
1923
1924 RValue<SByte> operator^(RValue<SByte> lhs, RValue<SByte> rhs)
1925 {
1926 return RValue<SByte>(Nucleus::createXor(lhs.value, rhs.value));
1927 }
1928
1929 RValue<SByte> operator<<(RValue<SByte> lhs, RValue<SByte> rhs)
1930 {
1931 return RValue<SByte>(Nucleus::createShl(lhs.value, rhs.value));
1932 }
1933
1934 RValue<SByte> operator>>(RValue<SByte> lhs, RValue<SByte> rhs)
1935 {
1936 return RValue<SByte>(Nucleus::createAShr(lhs.value, rhs.value));
1937 }
1938
Nicolas Capens96d4e092016-11-18 14:22:38 -05001939 RValue<SByte> operator+=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001940 {
1941 return lhs = lhs + rhs;
1942 }
1943
Nicolas Capens96d4e092016-11-18 14:22:38 -05001944 RValue<SByte> operator-=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001945 {
1946 return lhs = lhs - rhs;
1947 }
1948
Nicolas Capens96d4e092016-11-18 14:22:38 -05001949 RValue<SByte> operator*=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001950 {
1951 return lhs = lhs * rhs;
1952 }
1953
Nicolas Capens96d4e092016-11-18 14:22:38 -05001954 RValue<SByte> operator/=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001955 {
1956 return lhs = lhs / rhs;
1957 }
1958
Nicolas Capens96d4e092016-11-18 14:22:38 -05001959 RValue<SByte> operator%=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001960 {
1961 return lhs = lhs % rhs;
1962 }
1963
Nicolas Capens96d4e092016-11-18 14:22:38 -05001964 RValue<SByte> operator&=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001965 {
1966 return lhs = lhs & rhs;
1967 }
1968
Nicolas Capens96d4e092016-11-18 14:22:38 -05001969 RValue<SByte> operator|=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001970 {
1971 return lhs = lhs | rhs;
1972 }
1973
Nicolas Capens96d4e092016-11-18 14:22:38 -05001974 RValue<SByte> operator^=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001975 {
1976 return lhs = lhs ^ rhs;
1977 }
1978
Nicolas Capens96d4e092016-11-18 14:22:38 -05001979 RValue<SByte> operator<<=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001980 {
1981 return lhs = lhs << rhs;
1982 }
1983
Nicolas Capens96d4e092016-11-18 14:22:38 -05001984 RValue<SByte> operator>>=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001985 {
1986 return lhs = lhs >> rhs;
1987 }
1988
1989 RValue<SByte> operator+(RValue<SByte> val)
1990 {
1991 return val;
1992 }
1993
1994 RValue<SByte> operator-(RValue<SByte> val)
1995 {
1996 return RValue<SByte>(Nucleus::createNeg(val.value));
1997 }
1998
1999 RValue<SByte> operator~(RValue<SByte> val)
2000 {
2001 return RValue<SByte>(Nucleus::createNot(val.value));
2002 }
2003
Nicolas Capens96d4e092016-11-18 14:22:38 -05002004 RValue<SByte> operator++(SByte &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04002005 {
2006 RValue<SByte> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002007 val += SByte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002008 return res;
2009 }
2010
Nicolas Capens96d4e092016-11-18 14:22:38 -05002011 const SByte &operator++(SByte &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04002012 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002013 val += SByte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002014 return val;
2015 }
2016
Nicolas Capens96d4e092016-11-18 14:22:38 -05002017 RValue<SByte> operator--(SByte &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04002018 {
2019 RValue<SByte> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002020 val -= SByte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002021 return res;
2022 }
2023
Nicolas Capens96d4e092016-11-18 14:22:38 -05002024 const SByte &operator--(SByte &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04002025 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002026 val -= SByte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002027 return val;
2028 }
2029
2030 RValue<Bool> operator<(RValue<SByte> lhs, RValue<SByte> rhs)
2031 {
2032 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
2033 }
2034
2035 RValue<Bool> operator<=(RValue<SByte> lhs, RValue<SByte> rhs)
2036 {
2037 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
2038 }
2039
2040 RValue<Bool> operator>(RValue<SByte> lhs, RValue<SByte> rhs)
2041 {
2042 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
2043 }
2044
2045 RValue<Bool> operator>=(RValue<SByte> lhs, RValue<SByte> rhs)
2046 {
2047 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
2048 }
2049
2050 RValue<Bool> operator!=(RValue<SByte> lhs, RValue<SByte> rhs)
2051 {
2052 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
2053 }
2054
2055 RValue<Bool> operator==(RValue<SByte> lhs, RValue<SByte> rhs)
2056 {
2057 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
2058 }
2059
2060 Type *SByte::getType()
2061 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04002062 return T(Ice::IceType_i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002063 }
2064
2065 Short::Short(Argument<Short> argument)
2066 {
2067 storeValue(argument.value);
2068 }
2069
2070 Short::Short(RValue<Int> cast)
2071 {
2072 Value *integer = Nucleus::createTrunc(cast.value, Short::getType());
2073
2074 storeValue(integer);
2075 }
2076
Nicolas Capens598f8d82016-09-26 15:09:10 -04002077 Short::Short(short x)
2078 {
2079 storeValue(Nucleus::createConstantShort(x));
2080 }
2081
2082 Short::Short(RValue<Short> rhs)
2083 {
2084 storeValue(rhs.value);
2085 }
2086
2087 Short::Short(const Short &rhs)
2088 {
2089 Value *value = rhs.loadValue();
2090 storeValue(value);
2091 }
2092
2093 Short::Short(const Reference<Short> &rhs)
2094 {
2095 Value *value = rhs.loadValue();
2096 storeValue(value);
2097 }
2098
Nicolas Capens96d4e092016-11-18 14:22:38 -05002099 RValue<Short> Short::operator=(RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002100 {
2101 storeValue(rhs.value);
2102
2103 return rhs;
2104 }
2105
Nicolas Capens96d4e092016-11-18 14:22:38 -05002106 RValue<Short> Short::operator=(const Short &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002107 {
2108 Value *value = rhs.loadValue();
2109 storeValue(value);
2110
2111 return RValue<Short>(value);
2112 }
2113
Nicolas Capens96d4e092016-11-18 14:22:38 -05002114 RValue<Short> Short::operator=(const Reference<Short> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002115 {
2116 Value *value = rhs.loadValue();
2117 storeValue(value);
2118
2119 return RValue<Short>(value);
2120 }
2121
2122 RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs)
2123 {
2124 return RValue<Short>(Nucleus::createAdd(lhs.value, rhs.value));
2125 }
2126
2127 RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs)
2128 {
2129 return RValue<Short>(Nucleus::createSub(lhs.value, rhs.value));
2130 }
2131
2132 RValue<Short> operator*(RValue<Short> lhs, RValue<Short> rhs)
2133 {
2134 return RValue<Short>(Nucleus::createMul(lhs.value, rhs.value));
2135 }
2136
2137 RValue<Short> operator/(RValue<Short> lhs, RValue<Short> rhs)
2138 {
2139 return RValue<Short>(Nucleus::createSDiv(lhs.value, rhs.value));
2140 }
2141
2142 RValue<Short> operator%(RValue<Short> lhs, RValue<Short> rhs)
2143 {
2144 return RValue<Short>(Nucleus::createSRem(lhs.value, rhs.value));
2145 }
2146
2147 RValue<Short> operator&(RValue<Short> lhs, RValue<Short> rhs)
2148 {
2149 return RValue<Short>(Nucleus::createAnd(lhs.value, rhs.value));
2150 }
2151
2152 RValue<Short> operator|(RValue<Short> lhs, RValue<Short> rhs)
2153 {
2154 return RValue<Short>(Nucleus::createOr(lhs.value, rhs.value));
2155 }
2156
2157 RValue<Short> operator^(RValue<Short> lhs, RValue<Short> rhs)
2158 {
2159 return RValue<Short>(Nucleus::createXor(lhs.value, rhs.value));
2160 }
2161
2162 RValue<Short> operator<<(RValue<Short> lhs, RValue<Short> rhs)
2163 {
2164 return RValue<Short>(Nucleus::createShl(lhs.value, rhs.value));
2165 }
2166
2167 RValue<Short> operator>>(RValue<Short> lhs, RValue<Short> rhs)
2168 {
2169 return RValue<Short>(Nucleus::createAShr(lhs.value, rhs.value));
2170 }
2171
Nicolas Capens96d4e092016-11-18 14:22:38 -05002172 RValue<Short> operator+=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002173 {
2174 return lhs = lhs + rhs;
2175 }
2176
Nicolas Capens96d4e092016-11-18 14:22:38 -05002177 RValue<Short> operator-=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002178 {
2179 return lhs = lhs - rhs;
2180 }
2181
Nicolas Capens96d4e092016-11-18 14:22:38 -05002182 RValue<Short> operator*=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002183 {
2184 return lhs = lhs * rhs;
2185 }
2186
Nicolas Capens96d4e092016-11-18 14:22:38 -05002187 RValue<Short> operator/=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002188 {
2189 return lhs = lhs / rhs;
2190 }
2191
Nicolas Capens96d4e092016-11-18 14:22:38 -05002192 RValue<Short> operator%=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002193 {
2194 return lhs = lhs % rhs;
2195 }
2196
Nicolas Capens96d4e092016-11-18 14:22:38 -05002197 RValue<Short> operator&=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002198 {
2199 return lhs = lhs & rhs;
2200 }
2201
Nicolas Capens96d4e092016-11-18 14:22:38 -05002202 RValue<Short> operator|=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002203 {
2204 return lhs = lhs | rhs;
2205 }
2206
Nicolas Capens96d4e092016-11-18 14:22:38 -05002207 RValue<Short> operator^=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002208 {
2209 return lhs = lhs ^ rhs;
2210 }
2211
Nicolas Capens96d4e092016-11-18 14:22:38 -05002212 RValue<Short> operator<<=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002213 {
2214 return lhs = lhs << rhs;
2215 }
2216
Nicolas Capens96d4e092016-11-18 14:22:38 -05002217 RValue<Short> operator>>=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002218 {
2219 return lhs = lhs >> rhs;
2220 }
2221
2222 RValue<Short> operator+(RValue<Short> val)
2223 {
2224 return val;
2225 }
2226
2227 RValue<Short> operator-(RValue<Short> val)
2228 {
2229 return RValue<Short>(Nucleus::createNeg(val.value));
2230 }
2231
2232 RValue<Short> operator~(RValue<Short> val)
2233 {
2234 return RValue<Short>(Nucleus::createNot(val.value));
2235 }
2236
Nicolas Capens96d4e092016-11-18 14:22:38 -05002237 RValue<Short> operator++(Short &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04002238 {
2239 RValue<Short> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002240 val += Short(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002241 return res;
2242 }
2243
Nicolas Capens96d4e092016-11-18 14:22:38 -05002244 const Short &operator++(Short &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04002245 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002246 val += Short(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002247 return val;
2248 }
2249
Nicolas Capens96d4e092016-11-18 14:22:38 -05002250 RValue<Short> operator--(Short &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04002251 {
2252 RValue<Short> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002253 val -= Short(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002254 return res;
2255 }
2256
Nicolas Capens96d4e092016-11-18 14:22:38 -05002257 const Short &operator--(Short &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04002258 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002259 val -= Short(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002260 return val;
2261 }
2262
2263 RValue<Bool> operator<(RValue<Short> lhs, RValue<Short> rhs)
2264 {
2265 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
2266 }
2267
2268 RValue<Bool> operator<=(RValue<Short> lhs, RValue<Short> rhs)
2269 {
2270 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
2271 }
2272
2273 RValue<Bool> operator>(RValue<Short> lhs, RValue<Short> rhs)
2274 {
2275 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
2276 }
2277
2278 RValue<Bool> operator>=(RValue<Short> lhs, RValue<Short> rhs)
2279 {
2280 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
2281 }
2282
2283 RValue<Bool> operator!=(RValue<Short> lhs, RValue<Short> rhs)
2284 {
2285 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
2286 }
2287
2288 RValue<Bool> operator==(RValue<Short> lhs, RValue<Short> rhs)
2289 {
2290 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
2291 }
2292
2293 Type *Short::getType()
2294 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04002295 return T(Ice::IceType_i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002296 }
2297
2298 UShort::UShort(Argument<UShort> argument)
2299 {
2300 storeValue(argument.value);
2301 }
2302
2303 UShort::UShort(RValue<UInt> cast)
2304 {
2305 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
2306
2307 storeValue(integer);
2308 }
2309
2310 UShort::UShort(RValue<Int> cast)
2311 {
2312 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
2313
2314 storeValue(integer);
2315 }
2316
Nicolas Capens598f8d82016-09-26 15:09:10 -04002317 UShort::UShort(unsigned short x)
2318 {
2319 storeValue(Nucleus::createConstantShort(x));
2320 }
2321
2322 UShort::UShort(RValue<UShort> rhs)
2323 {
2324 storeValue(rhs.value);
2325 }
2326
2327 UShort::UShort(const UShort &rhs)
2328 {
2329 Value *value = rhs.loadValue();
2330 storeValue(value);
2331 }
2332
2333 UShort::UShort(const Reference<UShort> &rhs)
2334 {
2335 Value *value = rhs.loadValue();
2336 storeValue(value);
2337 }
2338
Nicolas Capens96d4e092016-11-18 14:22:38 -05002339 RValue<UShort> UShort::operator=(RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002340 {
2341 storeValue(rhs.value);
2342
2343 return rhs;
2344 }
2345
Nicolas Capens96d4e092016-11-18 14:22:38 -05002346 RValue<UShort> UShort::operator=(const UShort &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002347 {
2348 Value *value = rhs.loadValue();
2349 storeValue(value);
2350
2351 return RValue<UShort>(value);
2352 }
2353
Nicolas Capens96d4e092016-11-18 14:22:38 -05002354 RValue<UShort> UShort::operator=(const Reference<UShort> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002355 {
2356 Value *value = rhs.loadValue();
2357 storeValue(value);
2358
2359 return RValue<UShort>(value);
2360 }
2361
2362 RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs)
2363 {
2364 return RValue<UShort>(Nucleus::createAdd(lhs.value, rhs.value));
2365 }
2366
2367 RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs)
2368 {
2369 return RValue<UShort>(Nucleus::createSub(lhs.value, rhs.value));
2370 }
2371
2372 RValue<UShort> operator*(RValue<UShort> lhs, RValue<UShort> rhs)
2373 {
2374 return RValue<UShort>(Nucleus::createMul(lhs.value, rhs.value));
2375 }
2376
2377 RValue<UShort> operator/(RValue<UShort> lhs, RValue<UShort> rhs)
2378 {
2379 return RValue<UShort>(Nucleus::createUDiv(lhs.value, rhs.value));
2380 }
2381
2382 RValue<UShort> operator%(RValue<UShort> lhs, RValue<UShort> rhs)
2383 {
2384 return RValue<UShort>(Nucleus::createURem(lhs.value, rhs.value));
2385 }
2386
2387 RValue<UShort> operator&(RValue<UShort> lhs, RValue<UShort> rhs)
2388 {
2389 return RValue<UShort>(Nucleus::createAnd(lhs.value, rhs.value));
2390 }
2391
2392 RValue<UShort> operator|(RValue<UShort> lhs, RValue<UShort> rhs)
2393 {
2394 return RValue<UShort>(Nucleus::createOr(lhs.value, rhs.value));
2395 }
2396
2397 RValue<UShort> operator^(RValue<UShort> lhs, RValue<UShort> rhs)
2398 {
2399 return RValue<UShort>(Nucleus::createXor(lhs.value, rhs.value));
2400 }
2401
2402 RValue<UShort> operator<<(RValue<UShort> lhs, RValue<UShort> rhs)
2403 {
2404 return RValue<UShort>(Nucleus::createShl(lhs.value, rhs.value));
2405 }
2406
2407 RValue<UShort> operator>>(RValue<UShort> lhs, RValue<UShort> rhs)
2408 {
2409 return RValue<UShort>(Nucleus::createLShr(lhs.value, rhs.value));
2410 }
2411
Nicolas Capens96d4e092016-11-18 14:22:38 -05002412 RValue<UShort> operator+=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002413 {
2414 return lhs = lhs + rhs;
2415 }
2416
Nicolas Capens96d4e092016-11-18 14:22:38 -05002417 RValue<UShort> operator-=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002418 {
2419 return lhs = lhs - rhs;
2420 }
2421
Nicolas Capens96d4e092016-11-18 14:22:38 -05002422 RValue<UShort> operator*=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002423 {
2424 return lhs = lhs * rhs;
2425 }
2426
Nicolas Capens96d4e092016-11-18 14:22:38 -05002427 RValue<UShort> operator/=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002428 {
2429 return lhs = lhs / rhs;
2430 }
2431
Nicolas Capens96d4e092016-11-18 14:22:38 -05002432 RValue<UShort> operator%=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002433 {
2434 return lhs = lhs % rhs;
2435 }
2436
Nicolas Capens96d4e092016-11-18 14:22:38 -05002437 RValue<UShort> operator&=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002438 {
2439 return lhs = lhs & rhs;
2440 }
2441
Nicolas Capens96d4e092016-11-18 14:22:38 -05002442 RValue<UShort> operator|=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002443 {
2444 return lhs = lhs | rhs;
2445 }
2446
Nicolas Capens96d4e092016-11-18 14:22:38 -05002447 RValue<UShort> operator^=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002448 {
2449 return lhs = lhs ^ rhs;
2450 }
2451
Nicolas Capens96d4e092016-11-18 14:22:38 -05002452 RValue<UShort> operator<<=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002453 {
2454 return lhs = lhs << rhs;
2455 }
2456
Nicolas Capens96d4e092016-11-18 14:22:38 -05002457 RValue<UShort> operator>>=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002458 {
2459 return lhs = lhs >> rhs;
2460 }
2461
2462 RValue<UShort> operator+(RValue<UShort> val)
2463 {
2464 return val;
2465 }
2466
2467 RValue<UShort> operator-(RValue<UShort> val)
2468 {
2469 return RValue<UShort>(Nucleus::createNeg(val.value));
2470 }
2471
2472 RValue<UShort> operator~(RValue<UShort> val)
2473 {
2474 return RValue<UShort>(Nucleus::createNot(val.value));
2475 }
2476
Nicolas Capens96d4e092016-11-18 14:22:38 -05002477 RValue<UShort> operator++(UShort &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04002478 {
2479 RValue<UShort> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002480 val += UShort(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002481 return res;
2482 }
2483
Nicolas Capens96d4e092016-11-18 14:22:38 -05002484 const UShort &operator++(UShort &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04002485 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002486 val += UShort(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002487 return val;
2488 }
2489
Nicolas Capens96d4e092016-11-18 14:22:38 -05002490 RValue<UShort> operator--(UShort &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04002491 {
2492 RValue<UShort> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002493 val -= UShort(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002494 return res;
2495 }
2496
Nicolas Capens96d4e092016-11-18 14:22:38 -05002497 const UShort &operator--(UShort &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04002498 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002499 val -= UShort(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002500 return val;
2501 }
2502
2503 RValue<Bool> operator<(RValue<UShort> lhs, RValue<UShort> rhs)
2504 {
2505 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
2506 }
2507
2508 RValue<Bool> operator<=(RValue<UShort> lhs, RValue<UShort> rhs)
2509 {
2510 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
2511 }
2512
2513 RValue<Bool> operator>(RValue<UShort> lhs, RValue<UShort> rhs)
2514 {
2515 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
2516 }
2517
2518 RValue<Bool> operator>=(RValue<UShort> lhs, RValue<UShort> rhs)
2519 {
2520 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
2521 }
2522
2523 RValue<Bool> operator!=(RValue<UShort> lhs, RValue<UShort> rhs)
2524 {
2525 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
2526 }
2527
2528 RValue<Bool> operator==(RValue<UShort> lhs, RValue<UShort> rhs)
2529 {
2530 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
2531 }
2532
2533 Type *UShort::getType()
2534 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04002535 return T(Ice::IceType_i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002536 }
2537
Nicolas Capens16b5f152016-10-13 13:39:01 -04002538 Byte4::Byte4(RValue<Byte8> cast)
2539 {
Nicolas Capens16b5f152016-10-13 13:39:01 -04002540 storeValue(Nucleus::createBitCast(cast.value, getType()));
2541 }
2542
2543 Byte4::Byte4(const Reference<Byte4> &rhs)
2544 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002545 Value *value = rhs.loadValue();
2546 storeValue(value);
Nicolas Capens16b5f152016-10-13 13:39:01 -04002547 }
2548
Nicolas Capens598f8d82016-09-26 15:09:10 -04002549 Type *Byte4::getType()
2550 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04002551 return T(Type_v4i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002552 }
2553
2554 Type *SByte4::getType()
2555 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04002556 return T(Type_v4i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002557 }
2558
Nicolas Capens598f8d82016-09-26 15:09:10 -04002559 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)
2560 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04002561 int64_t constantVector[8] = {x0, x1, x2, x3, x4, x5, x6, x7};
2562 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002563 }
2564
2565 Byte8::Byte8(RValue<Byte8> rhs)
2566 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002567 storeValue(rhs.value);
2568 }
2569
2570 Byte8::Byte8(const Byte8 &rhs)
2571 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002572 Value *value = rhs.loadValue();
2573 storeValue(value);
2574 }
2575
2576 Byte8::Byte8(const Reference<Byte8> &rhs)
2577 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002578 Value *value = rhs.loadValue();
2579 storeValue(value);
2580 }
2581
Nicolas Capens96d4e092016-11-18 14:22:38 -05002582 RValue<Byte8> Byte8::operator=(RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002583 {
2584 storeValue(rhs.value);
2585
2586 return rhs;
2587 }
2588
Nicolas Capens96d4e092016-11-18 14:22:38 -05002589 RValue<Byte8> Byte8::operator=(const Byte8 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002590 {
2591 Value *value = rhs.loadValue();
2592 storeValue(value);
2593
2594 return RValue<Byte8>(value);
2595 }
2596
Nicolas Capens96d4e092016-11-18 14:22:38 -05002597 RValue<Byte8> Byte8::operator=(const Reference<Byte8> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002598 {
2599 Value *value = rhs.loadValue();
2600 storeValue(value);
2601
2602 return RValue<Byte8>(value);
2603 }
2604
2605 RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs)
2606 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002607 return RValue<Byte8>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002608 }
2609
2610 RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs)
2611 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002612 return RValue<Byte8>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002613 }
2614
2615// RValue<Byte8> operator*(RValue<Byte8> lhs, RValue<Byte8> rhs)
2616// {
2617// return RValue<Byte8>(Nucleus::createMul(lhs.value, rhs.value));
2618// }
2619
2620// RValue<Byte8> operator/(RValue<Byte8> lhs, RValue<Byte8> rhs)
2621// {
2622// return RValue<Byte8>(Nucleus::createUDiv(lhs.value, rhs.value));
2623// }
2624
2625// RValue<Byte8> operator%(RValue<Byte8> lhs, RValue<Byte8> rhs)
2626// {
2627// return RValue<Byte8>(Nucleus::createURem(lhs.value, rhs.value));
2628// }
2629
2630 RValue<Byte8> operator&(RValue<Byte8> lhs, RValue<Byte8> rhs)
2631 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002632 return RValue<Byte8>(Nucleus::createAnd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002633 }
2634
2635 RValue<Byte8> operator|(RValue<Byte8> lhs, RValue<Byte8> rhs)
2636 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002637 return RValue<Byte8>(Nucleus::createOr(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002638 }
2639
2640 RValue<Byte8> operator^(RValue<Byte8> lhs, RValue<Byte8> rhs)
2641 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002642 return RValue<Byte8>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002643 }
2644
2645// RValue<Byte8> operator<<(RValue<Byte8> lhs, unsigned char rhs)
2646// {
Nicolas Capens15060bb2016-12-05 22:17:19 -05002647// return RValue<Byte8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002648// }
2649
2650// RValue<Byte8> operator>>(RValue<Byte8> lhs, unsigned char rhs)
2651// {
Nicolas Capens15060bb2016-12-05 22:17:19 -05002652// return RValue<Byte8>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002653// }
2654
Nicolas Capens96d4e092016-11-18 14:22:38 -05002655 RValue<Byte8> operator+=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002656 {
2657 return lhs = lhs + rhs;
2658 }
2659
Nicolas Capens96d4e092016-11-18 14:22:38 -05002660 RValue<Byte8> operator-=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002661 {
2662 return lhs = lhs - rhs;
2663 }
2664
Nicolas Capens96d4e092016-11-18 14:22:38 -05002665// RValue<Byte8> operator*=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002666// {
2667// return lhs = lhs * rhs;
2668// }
2669
Nicolas Capens96d4e092016-11-18 14:22:38 -05002670// RValue<Byte8> operator/=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002671// {
2672// return lhs = lhs / rhs;
2673// }
2674
Nicolas Capens96d4e092016-11-18 14:22:38 -05002675// RValue<Byte8> operator%=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002676// {
2677// return lhs = lhs % rhs;
2678// }
2679
Nicolas Capens96d4e092016-11-18 14:22:38 -05002680 RValue<Byte8> operator&=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002681 {
2682 return lhs = lhs & rhs;
2683 }
2684
Nicolas Capens96d4e092016-11-18 14:22:38 -05002685 RValue<Byte8> operator|=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002686 {
2687 return lhs = lhs | rhs;
2688 }
2689
Nicolas Capens96d4e092016-11-18 14:22:38 -05002690 RValue<Byte8> operator^=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002691 {
2692 return lhs = lhs ^ rhs;
2693 }
2694
Nicolas Capens96d4e092016-11-18 14:22:38 -05002695// RValue<Byte8> operator<<=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002696// {
2697// return lhs = lhs << rhs;
2698// }
2699
Nicolas Capens96d4e092016-11-18 14:22:38 -05002700// RValue<Byte8> operator>>=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002701// {
2702// return lhs = lhs >> rhs;
2703// }
2704
2705// RValue<Byte8> operator+(RValue<Byte8> val)
2706// {
2707// return val;
2708// }
2709
2710// RValue<Byte8> operator-(RValue<Byte8> val)
2711// {
2712// return RValue<Byte8>(Nucleus::createNeg(val.value));
2713// }
2714
2715 RValue<Byte8> operator~(RValue<Byte8> val)
2716 {
2717 return RValue<Byte8>(Nucleus::createNot(val.value));
2718 }
2719
Nicolas Capensd6cacad2017-07-25 15:32:12 -04002720 RValue<Byte> Extract(RValue<Byte8> val, int i)
2721 {
2722 return RValue<Byte>(Nucleus::createExtractElement(val.value, Byte::getType(), i));
2723 }
2724
2725 RValue<Byte8> Insert(RValue<Byte8> val, RValue<Byte> element, int i)
2726 {
2727 return RValue<Byte8>(Nucleus::createInsertElement(val.value, element.value, i));
2728 }
2729
Nicolas Capens33438a62017-09-27 11:47:35 -04002730 RValue<Byte> SaturateUnsigned(RValue<Short> x)
Nicolas Capens98436732017-07-25 15:32:12 -04002731 {
Nicolas Capens7f301812017-10-02 17:32:34 -04002732 return Byte(IfThenElse(Int(x) > 0xFF, Int(0xFF), IfThenElse(Int(x) < 0, Int(0), Int(x))));
Nicolas Capens98436732017-07-25 15:32:12 -04002733 }
2734
Nicolas Capens598f8d82016-09-26 15:09:10 -04002735 RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y)
2736 {
Nicolas Capens98436732017-07-25 15:32:12 -04002737 if(emulateIntrinsics)
2738 {
2739 Byte8 result;
Nicolas Capens33438a62017-09-27 11:47:35 -04002740 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 0)) + Int(Extract(y, 0)))), 0);
2741 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 1)) + Int(Extract(y, 1)))), 1);
2742 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 2)) + Int(Extract(y, 2)))), 2);
2743 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 3)) + Int(Extract(y, 3)))), 3);
2744 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 4)) + Int(Extract(y, 4)))), 4);
2745 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 5)) + Int(Extract(y, 5)))), 5);
2746 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 6)) + Int(Extract(y, 6)))), 6);
2747 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 7)) + Int(Extract(y, 7)))), 7);
Nicolas Capensc71bed22016-11-07 22:25:14 -05002748
Nicolas Capens98436732017-07-25 15:32:12 -04002749 return result;
2750 }
2751 else
2752 {
2753 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
2754 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2755 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2756 auto paddusb = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
2757 paddusb->addArg(x.value);
2758 paddusb->addArg(y.value);
2759 ::basicBlock->appendInst(paddusb);
2760
2761 return RValue<Byte8>(V(result));
2762 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04002763 }
2764
2765 RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y)
2766 {
Nicolas Capens98436732017-07-25 15:32:12 -04002767 if(emulateIntrinsics)
2768 {
2769 Byte8 result;
Nicolas Capens33438a62017-09-27 11:47:35 -04002770 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 0)) - Int(Extract(y, 0)))), 0);
2771 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 1)) - Int(Extract(y, 1)))), 1);
2772 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 2)) - Int(Extract(y, 2)))), 2);
2773 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 3)) - Int(Extract(y, 3)))), 3);
2774 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 4)) - Int(Extract(y, 4)))), 4);
2775 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 5)) - Int(Extract(y, 5)))), 5);
2776 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 6)) - Int(Extract(y, 6)))), 6);
2777 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 7)) - Int(Extract(y, 7)))), 7);
Nicolas Capensc71bed22016-11-07 22:25:14 -05002778
Nicolas Capens98436732017-07-25 15:32:12 -04002779 return result;
2780 }
2781 else
2782 {
2783 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
2784 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2785 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2786 auto psubusw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
2787 psubusw->addArg(x.value);
2788 psubusw->addArg(y.value);
2789 ::basicBlock->appendInst(psubusw);
2790
2791 return RValue<Byte8>(V(result));
2792 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04002793 }
2794
2795 RValue<Short4> Unpack(RValue<Byte4> x)
2796 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04002797 int shuffle[16] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7}; // Real type is v16i8
Nicolas Capensbea4dce2017-07-24 16:54:44 -04002798 return As<Short4>(Nucleus::createShuffleVector(x.value, x.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002799 }
2800
Nicolas Capens411273e2017-01-26 15:13:36 -08002801 RValue<Short4> Unpack(RValue<Byte4> x, RValue<Byte4> y)
2802 {
2803 return UnpackLow(As<Byte8>(x), As<Byte8>(y));
2804 }
2805
Nicolas Capens598f8d82016-09-26 15:09:10 -04002806 RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y)
2807 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04002808 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
Nicolas Capensbea4dce2017-07-24 16:54:44 -04002809 return As<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002810 }
2811
2812 RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y)
2813 {
Nicolas Capens20e22c42016-10-25 17:32:37 -04002814 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
2815 auto lowHigh = RValue<Byte16>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
2816 return As<Short4>(Swizzle(As<Int4>(lowHigh), 0xEE));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002817 }
2818
Nicolas Capensd6cacad2017-07-25 15:32:12 -04002819 RValue<SByte> Extract(RValue<SByte8> val, int i)
2820 {
2821 return RValue<SByte>(Nucleus::createExtractElement(val.value, SByte::getType(), i));
2822 }
2823
2824 RValue<SByte8> Insert(RValue<SByte8> val, RValue<SByte> element, int i)
2825 {
2826 return RValue<SByte8>(Nucleus::createInsertElement(val.value, element.value, i));
2827 }
2828
2829 RValue<SByte8> operator>>(RValue<SByte8> lhs, unsigned char rhs)
2830 {
2831 if(emulateIntrinsics)
2832 {
2833 SByte8 result;
2834 result = Insert(result, Extract(lhs, 0) >> SByte(rhs), 0);
2835 result = Insert(result, Extract(lhs, 1) >> SByte(rhs), 1);
2836 result = Insert(result, Extract(lhs, 2) >> SByte(rhs), 2);
2837 result = Insert(result, Extract(lhs, 3) >> SByte(rhs), 3);
2838 result = Insert(result, Extract(lhs, 4) >> SByte(rhs), 4);
2839 result = Insert(result, Extract(lhs, 5) >> SByte(rhs), 5);
2840 result = Insert(result, Extract(lhs, 6) >> SByte(rhs), 6);
2841 result = Insert(result, Extract(lhs, 7) >> SByte(rhs), 7);
2842
2843 return result;
2844 }
2845 else
2846 {
2847 #if defined(__i386__) || defined(__x86_64__)
2848 // SSE2 doesn't support byte vector shifts, so shift as shorts and recombine.
Alexis Hetue18c5302017-08-04 11:48:17 -04002849 RValue<Short4> hi = (As<Short4>(lhs) >> rhs) & Short4(0xFF00u);
Nicolas Capensd6cacad2017-07-25 15:32:12 -04002850 RValue<Short4> lo = As<Short4>(As<UShort4>((As<Short4>(lhs) << 8) >> rhs) >> 8);
2851
2852 return As<SByte8>(hi | lo);
2853 #else
2854 return RValue<SByte8>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
2855 #endif
2856 }
2857 }
2858
Nicolas Capens598f8d82016-09-26 15:09:10 -04002859 RValue<Int> SignMask(RValue<Byte8> x)
2860 {
Nicolas Capens091f3502017-10-03 14:56:49 -04002861 if(emulateIntrinsics || CPUID::ARM)
Nicolas Capensd6cacad2017-07-25 15:32:12 -04002862 {
2863 Byte8 xx = As<Byte8>(As<SByte8>(x) >> 7) & Byte8(0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80);
2864 return Int(Extract(xx, 0)) | Int(Extract(xx, 1)) | Int(Extract(xx, 2)) | Int(Extract(xx, 3)) | Int(Extract(xx, 4)) | Int(Extract(xx, 5)) | Int(Extract(xx, 6)) | Int(Extract(xx, 7));
2865 }
2866 else
2867 {
2868 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
2869 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2870 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2871 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
2872 movmsk->addArg(x.value);
2873 ::basicBlock->appendInst(movmsk);
Nicolas Capensc71bed22016-11-07 22:25:14 -05002874
Nicolas Capens0f70a7f2017-07-26 13:50:04 -04002875 return RValue<Int>(V(result)) & 0xFF;
Nicolas Capensd6cacad2017-07-25 15:32:12 -04002876 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04002877 }
2878
2879// RValue<Byte8> CmpGT(RValue<Byte8> x, RValue<Byte8> y)
2880// {
Nicolas Capens2f970b62016-11-08 14:28:59 -05002881// return RValue<Byte8>(createIntCompare(Ice::InstIcmp::Ugt, x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002882// }
2883
2884 RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y)
2885 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05002886 return RValue<Byte8>(Nucleus::createICmpEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002887 }
2888
2889 Type *Byte8::getType()
2890 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04002891 return T(Type_v8i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002892 }
2893
Nicolas Capens598f8d82016-09-26 15:09:10 -04002894 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)
2895 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04002896 int64_t constantVector[8] = { x0, x1, x2, x3, x4, x5, x6, x7 };
2897 Value *vector = V(Nucleus::createConstantVector(constantVector, getType()));
2898
2899 storeValue(Nucleus::createBitCast(vector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002900 }
2901
Nicolas Capens598f8d82016-09-26 15:09:10 -04002902 SByte8::SByte8(RValue<SByte8> rhs)
2903 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002904 storeValue(rhs.value);
2905 }
2906
2907 SByte8::SByte8(const SByte8 &rhs)
2908 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002909 Value *value = rhs.loadValue();
2910 storeValue(value);
2911 }
2912
2913 SByte8::SByte8(const Reference<SByte8> &rhs)
2914 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002915 Value *value = rhs.loadValue();
2916 storeValue(value);
2917 }
2918
Nicolas Capens96d4e092016-11-18 14:22:38 -05002919 RValue<SByte8> SByte8::operator=(RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002920 {
2921 storeValue(rhs.value);
2922
2923 return rhs;
2924 }
2925
Nicolas Capens96d4e092016-11-18 14:22:38 -05002926 RValue<SByte8> SByte8::operator=(const SByte8 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002927 {
2928 Value *value = rhs.loadValue();
2929 storeValue(value);
2930
2931 return RValue<SByte8>(value);
2932 }
2933
Nicolas Capens96d4e092016-11-18 14:22:38 -05002934 RValue<SByte8> SByte8::operator=(const Reference<SByte8> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002935 {
2936 Value *value = rhs.loadValue();
2937 storeValue(value);
2938
2939 return RValue<SByte8>(value);
2940 }
2941
2942 RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs)
2943 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002944 return RValue<SByte8>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002945 }
2946
2947 RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs)
2948 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002949 return RValue<SByte8>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002950 }
2951
2952// RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs)
2953// {
2954// return RValue<SByte8>(Nucleus::createMul(lhs.value, rhs.value));
2955// }
2956
2957// RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs)
2958// {
2959// return RValue<SByte8>(Nucleus::createSDiv(lhs.value, rhs.value));
2960// }
2961
2962// RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs)
2963// {
2964// return RValue<SByte8>(Nucleus::createSRem(lhs.value, rhs.value));
2965// }
2966
2967 RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs)
2968 {
2969 return RValue<SByte8>(Nucleus::createAnd(lhs.value, rhs.value));
2970 }
2971
2972 RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs)
2973 {
2974 return RValue<SByte8>(Nucleus::createOr(lhs.value, rhs.value));
2975 }
2976
2977 RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs)
2978 {
2979 return RValue<SByte8>(Nucleus::createXor(lhs.value, rhs.value));
2980 }
2981
2982// RValue<SByte8> operator<<(RValue<SByte8> lhs, unsigned char rhs)
2983// {
Nicolas Capens15060bb2016-12-05 22:17:19 -05002984// return RValue<SByte8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002985// }
2986
2987// RValue<SByte8> operator>>(RValue<SByte8> lhs, unsigned char rhs)
2988// {
Nicolas Capens15060bb2016-12-05 22:17:19 -05002989// return RValue<SByte8>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002990// }
2991
Nicolas Capens96d4e092016-11-18 14:22:38 -05002992 RValue<SByte8> operator+=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002993 {
2994 return lhs = lhs + rhs;
2995 }
2996
Nicolas Capens96d4e092016-11-18 14:22:38 -05002997 RValue<SByte8> operator-=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002998 {
2999 return lhs = lhs - rhs;
3000 }
3001
Nicolas Capens96d4e092016-11-18 14:22:38 -05003002// RValue<SByte8> operator*=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003003// {
3004// return lhs = lhs * rhs;
3005// }
3006
Nicolas Capens96d4e092016-11-18 14:22:38 -05003007// RValue<SByte8> operator/=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003008// {
3009// return lhs = lhs / rhs;
3010// }
3011
Nicolas Capens96d4e092016-11-18 14:22:38 -05003012// RValue<SByte8> operator%=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003013// {
3014// return lhs = lhs % rhs;
3015// }
3016
Nicolas Capens96d4e092016-11-18 14:22:38 -05003017 RValue<SByte8> operator&=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003018 {
3019 return lhs = lhs & rhs;
3020 }
3021
Nicolas Capens96d4e092016-11-18 14:22:38 -05003022 RValue<SByte8> operator|=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003023 {
3024 return lhs = lhs | rhs;
3025 }
3026
Nicolas Capens96d4e092016-11-18 14:22:38 -05003027 RValue<SByte8> operator^=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003028 {
3029 return lhs = lhs ^ rhs;
3030 }
3031
Nicolas Capens96d4e092016-11-18 14:22:38 -05003032// RValue<SByte8> operator<<=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003033// {
3034// return lhs = lhs << rhs;
3035// }
3036
Nicolas Capens96d4e092016-11-18 14:22:38 -05003037// RValue<SByte8> operator>>=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003038// {
3039// return lhs = lhs >> rhs;
3040// }
3041
3042// RValue<SByte8> operator+(RValue<SByte8> val)
3043// {
3044// return val;
3045// }
3046
3047// RValue<SByte8> operator-(RValue<SByte8> val)
3048// {
3049// return RValue<SByte8>(Nucleus::createNeg(val.value));
3050// }
3051
3052 RValue<SByte8> operator~(RValue<SByte8> val)
3053 {
3054 return RValue<SByte8>(Nucleus::createNot(val.value));
3055 }
3056
Nicolas Capens33438a62017-09-27 11:47:35 -04003057 RValue<SByte> SaturateSigned(RValue<Short> x)
Nicolas Capens98436732017-07-25 15:32:12 -04003058 {
3059 return SByte(IfThenElse(Int(x) > 0x7F, Int(0x7F), IfThenElse(Int(x) < -0x80, Int(0x80), Int(x))));
3060 }
3061
Nicolas Capens598f8d82016-09-26 15:09:10 -04003062 RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y)
3063 {
Nicolas Capens98436732017-07-25 15:32:12 -04003064 if(emulateIntrinsics)
3065 {
3066 SByte8 result;
Nicolas Capens33438a62017-09-27 11:47:35 -04003067 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 0)) + Int(Extract(y, 0)))), 0);
3068 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 1)) + Int(Extract(y, 1)))), 1);
3069 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 2)) + Int(Extract(y, 2)))), 2);
3070 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 3)) + Int(Extract(y, 3)))), 3);
3071 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 4)) + Int(Extract(y, 4)))), 4);
3072 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 5)) + Int(Extract(y, 5)))), 5);
3073 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 6)) + Int(Extract(y, 6)))), 6);
3074 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 7)) + Int(Extract(y, 7)))), 7);
Nicolas Capensc71bed22016-11-07 22:25:14 -05003075
Nicolas Capens98436732017-07-25 15:32:12 -04003076 return result;
3077 }
3078 else
3079 {
3080 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
3081 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3082 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3083 auto paddsb = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3084 paddsb->addArg(x.value);
3085 paddsb->addArg(y.value);
3086 ::basicBlock->appendInst(paddsb);
3087
3088 return RValue<SByte8>(V(result));
3089 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003090 }
3091
3092 RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y)
3093 {
Nicolas Capens98436732017-07-25 15:32:12 -04003094 if(emulateIntrinsics)
3095 {
3096 SByte8 result;
Nicolas Capens33438a62017-09-27 11:47:35 -04003097 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 0)) - Int(Extract(y, 0)))), 0);
3098 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 1)) - Int(Extract(y, 1)))), 1);
3099 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 2)) - Int(Extract(y, 2)))), 2);
3100 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 3)) - Int(Extract(y, 3)))), 3);
3101 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 4)) - Int(Extract(y, 4)))), 4);
3102 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 5)) - Int(Extract(y, 5)))), 5);
3103 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 6)) - Int(Extract(y, 6)))), 6);
3104 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 7)) - Int(Extract(y, 7)))), 7);
Nicolas Capensc71bed22016-11-07 22:25:14 -05003105
Nicolas Capens98436732017-07-25 15:32:12 -04003106 return result;
3107 }
3108 else
3109 {
3110 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
3111 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3112 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3113 auto psubsb = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3114 psubsb->addArg(x.value);
3115 psubsb->addArg(y.value);
3116 ::basicBlock->appendInst(psubsb);
3117
3118 return RValue<SByte8>(V(result));
3119 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003120 }
3121
3122 RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y)
3123 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04003124 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
Nicolas Capensbea4dce2017-07-24 16:54:44 -04003125 return As<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003126 }
3127
3128 RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y)
3129 {
Nicolas Capens20e22c42016-10-25 17:32:37 -04003130 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
3131 auto lowHigh = RValue<Byte16>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
3132 return As<Short4>(Swizzle(As<Int4>(lowHigh), 0xEE));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003133 }
3134
3135 RValue<Int> SignMask(RValue<SByte8> x)
3136 {
Nicolas Capens091f3502017-10-03 14:56:49 -04003137 if(emulateIntrinsics || CPUID::ARM)
Nicolas Capensd6cacad2017-07-25 15:32:12 -04003138 {
3139 SByte8 xx = (x >> 7) & SByte8(0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80);
3140 return Int(Extract(xx, 0)) | Int(Extract(xx, 1)) | Int(Extract(xx, 2)) | Int(Extract(xx, 3)) | Int(Extract(xx, 4)) | Int(Extract(xx, 5)) | Int(Extract(xx, 6)) | Int(Extract(xx, 7));
3141 }
3142 else
3143 {
3144 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
3145 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3146 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3147 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
3148 movmsk->addArg(x.value);
3149 ::basicBlock->appendInst(movmsk);
Nicolas Capensf2cb9df2016-10-21 17:26:13 -04003150
Nicolas Capens0f70a7f2017-07-26 13:50:04 -04003151 return RValue<Int>(V(result)) & 0xFF;
Nicolas Capensd6cacad2017-07-25 15:32:12 -04003152 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003153 }
3154
3155 RValue<Byte8> CmpGT(RValue<SByte8> x, RValue<SByte8> y)
3156 {
Nicolas Capens2f970b62016-11-08 14:28:59 -05003157 return RValue<Byte8>(createIntCompare(Ice::InstIcmp::Sgt, x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003158 }
3159
3160 RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y)
3161 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05003162 return RValue<Byte8>(Nucleus::createICmpEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003163 }
3164
3165 Type *SByte8::getType()
3166 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04003167 return T(Type_v8i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003168 }
3169
3170 Byte16::Byte16(RValue<Byte16> rhs)
3171 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003172 storeValue(rhs.value);
3173 }
3174
3175 Byte16::Byte16(const Byte16 &rhs)
3176 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003177 Value *value = rhs.loadValue();
3178 storeValue(value);
3179 }
3180
3181 Byte16::Byte16(const Reference<Byte16> &rhs)
3182 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003183 Value *value = rhs.loadValue();
3184 storeValue(value);
3185 }
3186
Nicolas Capens96d4e092016-11-18 14:22:38 -05003187 RValue<Byte16> Byte16::operator=(RValue<Byte16> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003188 {
3189 storeValue(rhs.value);
3190
3191 return rhs;
3192 }
3193
Nicolas Capens96d4e092016-11-18 14:22:38 -05003194 RValue<Byte16> Byte16::operator=(const Byte16 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003195 {
3196 Value *value = rhs.loadValue();
3197 storeValue(value);
3198
3199 return RValue<Byte16>(value);
3200 }
3201
Nicolas Capens96d4e092016-11-18 14:22:38 -05003202 RValue<Byte16> Byte16::operator=(const Reference<Byte16> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003203 {
3204 Value *value = rhs.loadValue();
3205 storeValue(value);
3206
3207 return RValue<Byte16>(value);
3208 }
3209
3210 Type *Byte16::getType()
3211 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04003212 return T(Ice::IceType_v16i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003213 }
3214
3215 Type *SByte16::getType()
3216 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04003217 return T(Ice::IceType_v16i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003218 }
3219
Nicolas Capens16b5f152016-10-13 13:39:01 -04003220 Short2::Short2(RValue<Short4> cast)
3221 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05003222 storeValue(Nucleus::createBitCast(cast.value, getType()));
Nicolas Capens16b5f152016-10-13 13:39:01 -04003223 }
3224
3225 Type *Short2::getType()
3226 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04003227 return T(Type_v2i16);
Nicolas Capens16b5f152016-10-13 13:39:01 -04003228 }
3229
3230 UShort2::UShort2(RValue<UShort4> cast)
3231 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05003232 storeValue(Nucleus::createBitCast(cast.value, getType()));
Nicolas Capens16b5f152016-10-13 13:39:01 -04003233 }
3234
3235 Type *UShort2::getType()
3236 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04003237 return T(Type_v2i16);
Nicolas Capens16b5f152016-10-13 13:39:01 -04003238 }
3239
Nicolas Capens598f8d82016-09-26 15:09:10 -04003240 Short4::Short4(RValue<Int> cast)
3241 {
Nicolas Capensd4227962016-11-09 14:24:25 -05003242 Value *vector = loadValue();
Nicolas Capensbf22bbf2017-01-13 17:37:45 -05003243 Value *element = Nucleus::createTrunc(cast.value, Short::getType());
3244 Value *insert = Nucleus::createInsertElement(vector, element, 0);
Nicolas Capensd4227962016-11-09 14:24:25 -05003245 Value *swizzle = Swizzle(RValue<Short4>(insert), 0x00).value;
Nicolas Capens598f8d82016-09-26 15:09:10 -04003246
3247 storeValue(swizzle);
3248 }
3249
3250 Short4::Short4(RValue<Int4> cast)
3251 {
Nicolas Capensf8beb4b2017-01-27 02:55:44 -08003252 int select[8] = {0, 2, 4, 6, 0, 2, 4, 6};
3253 Value *short8 = Nucleus::createBitCast(cast.value, Short8::getType());
3254 Value *packed = Nucleus::createShuffleVector(short8, short8, select);
Nicolas Capensd4227962016-11-09 14:24:25 -05003255
Nicolas Capensbea4dce2017-07-24 16:54:44 -04003256 Value *int2 = RValue<Int2>(Int2(As<Int4>(packed))).value;
Nicolas Capensd4227962016-11-09 14:24:25 -05003257 Value *short4 = Nucleus::createBitCast(int2, Short4::getType());
3258
3259 storeValue(short4);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003260 }
3261
3262// Short4::Short4(RValue<Float> cast)
3263// {
3264// }
3265
3266 Short4::Short4(RValue<Float4> cast)
3267 {
3268 assert(false && "UNIMPLEMENTED");
3269 }
3270
Nicolas Capens598f8d82016-09-26 15:09:10 -04003271 Short4::Short4(short xyzw)
3272 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04003273 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
3274 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003275 }
3276
3277 Short4::Short4(short x, short y, short z, short w)
3278 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04003279 int64_t constantVector[4] = {x, y, z, w};
3280 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003281 }
3282
3283 Short4::Short4(RValue<Short4> rhs)
3284 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003285 storeValue(rhs.value);
3286 }
3287
3288 Short4::Short4(const Short4 &rhs)
3289 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003290 Value *value = rhs.loadValue();
3291 storeValue(value);
3292 }
3293
3294 Short4::Short4(const Reference<Short4> &rhs)
3295 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003296 Value *value = rhs.loadValue();
3297 storeValue(value);
3298 }
3299
3300 Short4::Short4(RValue<UShort4> rhs)
3301 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003302 storeValue(rhs.value);
3303 }
3304
3305 Short4::Short4(const UShort4 &rhs)
3306 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003307 storeValue(rhs.loadValue());
3308 }
3309
3310 Short4::Short4(const Reference<UShort4> &rhs)
3311 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003312 storeValue(rhs.loadValue());
3313 }
3314
Nicolas Capens96d4e092016-11-18 14:22:38 -05003315 RValue<Short4> Short4::operator=(RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003316 {
3317 storeValue(rhs.value);
3318
3319 return rhs;
3320 }
3321
Nicolas Capens96d4e092016-11-18 14:22:38 -05003322 RValue<Short4> Short4::operator=(const Short4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003323 {
3324 Value *value = rhs.loadValue();
3325 storeValue(value);
3326
3327 return RValue<Short4>(value);
3328 }
3329
Nicolas Capens96d4e092016-11-18 14:22:38 -05003330 RValue<Short4> Short4::operator=(const Reference<Short4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003331 {
3332 Value *value = rhs.loadValue();
3333 storeValue(value);
3334
3335 return RValue<Short4>(value);
3336 }
3337
Nicolas Capens96d4e092016-11-18 14:22:38 -05003338 RValue<Short4> Short4::operator=(RValue<UShort4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003339 {
3340 storeValue(rhs.value);
3341
3342 return RValue<Short4>(rhs);
3343 }
3344
Nicolas Capens96d4e092016-11-18 14:22:38 -05003345 RValue<Short4> Short4::operator=(const UShort4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003346 {
3347 Value *value = rhs.loadValue();
3348 storeValue(value);
3349
3350 return RValue<Short4>(value);
3351 }
3352
Nicolas Capens96d4e092016-11-18 14:22:38 -05003353 RValue<Short4> Short4::operator=(const Reference<UShort4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003354 {
3355 Value *value = rhs.loadValue();
3356 storeValue(value);
3357
3358 return RValue<Short4>(value);
3359 }
3360
3361 RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs)
3362 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003363 return RValue<Short4>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003364 }
3365
3366 RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs)
3367 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003368 return RValue<Short4>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003369 }
3370
3371 RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs)
3372 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003373 return RValue<Short4>(Nucleus::createMul(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003374 }
3375
3376// RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs)
3377// {
3378// return RValue<Short4>(Nucleus::createSDiv(lhs.value, rhs.value));
3379// }
3380
3381// RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs)
3382// {
3383// return RValue<Short4>(Nucleus::createSRem(lhs.value, rhs.value));
3384// }
3385
3386 RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs)
3387 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003388 return RValue<Short4>(Nucleus::createAnd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003389 }
3390
3391 RValue<Short4> operator|(RValue<Short4> lhs, RValue<Short4> rhs)
3392 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003393 return RValue<Short4>(Nucleus::createOr(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003394 }
3395
3396 RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs)
3397 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003398 return RValue<Short4>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003399 }
3400
3401 RValue<Short4> operator<<(RValue<Short4> lhs, unsigned char rhs)
3402 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04003403 if(emulateIntrinsics)
3404 {
3405 Short4 result;
3406 result = Insert(result, Extract(lhs, 0) << Short(rhs), 0);
3407 result = Insert(result, Extract(lhs, 1) << Short(rhs), 1);
3408 result = Insert(result, Extract(lhs, 2) << Short(rhs), 2);
3409 result = Insert(result, Extract(lhs, 3) << Short(rhs), 3);
3410
3411 return result;
3412 }
3413 else
3414 {
3415 return RValue<Short4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
3416 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003417 }
3418
3419 RValue<Short4> operator>>(RValue<Short4> lhs, unsigned char rhs)
3420 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04003421 if(emulateIntrinsics)
3422 {
3423 Short4 result;
3424 result = Insert(result, Extract(lhs, 0) >> Short(rhs), 0);
3425 result = Insert(result, Extract(lhs, 1) >> Short(rhs), 1);
3426 result = Insert(result, Extract(lhs, 2) >> Short(rhs), 2);
3427 result = Insert(result, Extract(lhs, 3) >> Short(rhs), 3);
3428
3429 return result;
3430 }
3431 else
3432 {
3433 return RValue<Short4>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
3434 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003435 }
3436
Nicolas Capens96d4e092016-11-18 14:22:38 -05003437 RValue<Short4> operator+=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003438 {
3439 return lhs = lhs + rhs;
3440 }
3441
Nicolas Capens96d4e092016-11-18 14:22:38 -05003442 RValue<Short4> operator-=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003443 {
3444 return lhs = lhs - rhs;
3445 }
3446
Nicolas Capens96d4e092016-11-18 14:22:38 -05003447 RValue<Short4> operator*=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003448 {
3449 return lhs = lhs * rhs;
3450 }
3451
Nicolas Capens96d4e092016-11-18 14:22:38 -05003452// RValue<Short4> operator/=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003453// {
3454// return lhs = lhs / rhs;
3455// }
3456
Nicolas Capens96d4e092016-11-18 14:22:38 -05003457// RValue<Short4> operator%=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003458// {
3459// return lhs = lhs % rhs;
3460// }
3461
Nicolas Capens96d4e092016-11-18 14:22:38 -05003462 RValue<Short4> operator&=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003463 {
3464 return lhs = lhs & rhs;
3465 }
3466
Nicolas Capens96d4e092016-11-18 14:22:38 -05003467 RValue<Short4> operator|=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003468 {
3469 return lhs = lhs | rhs;
3470 }
3471
Nicolas Capens96d4e092016-11-18 14:22:38 -05003472 RValue<Short4> operator^=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003473 {
3474 return lhs = lhs ^ rhs;
3475 }
3476
Nicolas Capens96d4e092016-11-18 14:22:38 -05003477 RValue<Short4> operator<<=(Short4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003478 {
3479 return lhs = lhs << rhs;
3480 }
3481
Nicolas Capens96d4e092016-11-18 14:22:38 -05003482 RValue<Short4> operator>>=(Short4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003483 {
3484 return lhs = lhs >> rhs;
3485 }
3486
Nicolas Capens598f8d82016-09-26 15:09:10 -04003487// RValue<Short4> operator+(RValue<Short4> val)
3488// {
3489// return val;
3490// }
3491
3492 RValue<Short4> operator-(RValue<Short4> val)
3493 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -05003494 return RValue<Short4>(Nucleus::createNeg(val.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003495 }
3496
3497 RValue<Short4> operator~(RValue<Short4> val)
3498 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -05003499 return RValue<Short4>(Nucleus::createNot(val.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003500 }
3501
3502 RValue<Short4> RoundShort4(RValue<Float4> cast)
3503 {
Nicolas Capensd4227962016-11-09 14:24:25 -05003504 RValue<Int4> int4 = RoundInt(cast);
Nicolas Capens33438a62017-09-27 11:47:35 -04003505 return As<Short4>(PackSigned(int4, int4));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003506 }
3507
3508 RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y)
3509 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04003510 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3511 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sle, condition, x.value, y.value);
3512 ::basicBlock->appendInst(cmp);
3513
3514 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3515 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3516 ::basicBlock->appendInst(select);
3517
3518 return RValue<Short4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003519 }
3520
3521 RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y)
3522 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04003523 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3524 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sgt, condition, x.value, y.value);
3525 ::basicBlock->appendInst(cmp);
3526
3527 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3528 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3529 ::basicBlock->appendInst(select);
3530
3531 return RValue<Short4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003532 }
3533
Nicolas Capens33438a62017-09-27 11:47:35 -04003534 RValue<Short> SaturateSigned(RValue<Int> x)
Nicolas Capens98436732017-07-25 15:32:12 -04003535 {
3536 return Short(IfThenElse(x > 0x7FFF, Int(0x7FFF), IfThenElse(x < -0x8000, Int(0x8000), x)));
3537 }
3538
Nicolas Capens598f8d82016-09-26 15:09:10 -04003539 RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y)
3540 {
Nicolas Capens98436732017-07-25 15:32:12 -04003541 if(emulateIntrinsics)
3542 {
3543 Short4 result;
Nicolas Capens33438a62017-09-27 11:47:35 -04003544 result = Insert(result, SaturateSigned(Int(Extract(x, 0)) + Int(Extract(y, 0))), 0);
3545 result = Insert(result, SaturateSigned(Int(Extract(x, 1)) + Int(Extract(y, 1))), 1);
3546 result = Insert(result, SaturateSigned(Int(Extract(x, 2)) + Int(Extract(y, 2))), 2);
3547 result = Insert(result, SaturateSigned(Int(Extract(x, 3)) + Int(Extract(y, 3))), 3);
Nicolas Capensc71bed22016-11-07 22:25:14 -05003548
Nicolas Capens98436732017-07-25 15:32:12 -04003549 return result;
3550 }
3551 else
3552 {
3553 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3554 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3555 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3556 auto paddsw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3557 paddsw->addArg(x.value);
3558 paddsw->addArg(y.value);
3559 ::basicBlock->appendInst(paddsw);
3560
3561 return RValue<Short4>(V(result));
3562 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003563 }
3564
3565 RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y)
3566 {
Nicolas Capens98436732017-07-25 15:32:12 -04003567 if(emulateIntrinsics)
3568 {
3569 Short4 result;
Nicolas Capens33438a62017-09-27 11:47:35 -04003570 result = Insert(result, SaturateSigned(Int(Extract(x, 0)) - Int(Extract(y, 0))), 0);
3571 result = Insert(result, SaturateSigned(Int(Extract(x, 1)) - Int(Extract(y, 1))), 1);
3572 result = Insert(result, SaturateSigned(Int(Extract(x, 2)) - Int(Extract(y, 2))), 2);
3573 result = Insert(result, SaturateSigned(Int(Extract(x, 3)) - Int(Extract(y, 3))), 3);
Nicolas Capensc71bed22016-11-07 22:25:14 -05003574
Nicolas Capens98436732017-07-25 15:32:12 -04003575 return result;
3576 }
3577 else
3578 {
3579 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3580 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3581 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3582 auto psubsw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3583 psubsw->addArg(x.value);
3584 psubsw->addArg(y.value);
3585 ::basicBlock->appendInst(psubsw);
3586
3587 return RValue<Short4>(V(result));
3588 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003589 }
3590
3591 RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y)
3592 {
Nicolas Capens6c157442017-07-25 15:32:12 -04003593 if(emulateIntrinsics)
3594 {
3595 Short4 result;
3596 result = Insert(result, Short((Int(Extract(x, 0)) * Int(Extract(y, 0))) >> 16), 0);
3597 result = Insert(result, Short((Int(Extract(x, 1)) * Int(Extract(y, 1))) >> 16), 1);
3598 result = Insert(result, Short((Int(Extract(x, 2)) * Int(Extract(y, 2))) >> 16), 2);
3599 result = Insert(result, Short((Int(Extract(x, 3)) * Int(Extract(y, 3))) >> 16), 3);
Nicolas Capensc71bed22016-11-07 22:25:14 -05003600
Nicolas Capens6c157442017-07-25 15:32:12 -04003601 return result;
3602 }
3603 else
3604 {
3605 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3606 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::MultiplyHighSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3607 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3608 auto pmulhw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3609 pmulhw->addArg(x.value);
3610 pmulhw->addArg(y.value);
3611 ::basicBlock->appendInst(pmulhw);
3612
3613 return RValue<Short4>(V(result));
3614 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003615 }
3616
3617 RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y)
3618 {
Nicolas Capensafe27e92017-07-25 15:32:12 -04003619 if(emulateIntrinsics)
3620 {
3621 Int2 result;
3622 result = Insert(result, Int(Extract(x, 0)) * Int(Extract(y, 0)) + Int(Extract(x, 1)) * Int(Extract(y, 1)), 0);
3623 result = Insert(result, Int(Extract(x, 2)) * Int(Extract(y, 2)) + Int(Extract(x, 3)) * Int(Extract(y, 3)), 1);
Nicolas Capensc71bed22016-11-07 22:25:14 -05003624
Nicolas Capensafe27e92017-07-25 15:32:12 -04003625 return result;
3626 }
3627 else
3628 {
3629 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3630 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::MultiplyAddPairs, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3631 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3632 auto pmaddwd = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3633 pmaddwd->addArg(x.value);
3634 pmaddwd->addArg(y.value);
3635 ::basicBlock->appendInst(pmaddwd);
3636
3637 return As<Int2>(V(result));
3638 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003639 }
3640
Nicolas Capens33438a62017-09-27 11:47:35 -04003641 RValue<SByte8> PackSigned(RValue<Short4> x, RValue<Short4> y)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003642 {
Nicolas Capens8960fbf2017-07-25 15:32:12 -04003643 if(emulateIntrinsics)
3644 {
3645 SByte8 result;
Nicolas Capens33438a62017-09-27 11:47:35 -04003646 result = Insert(result, SaturateSigned(Extract(x, 0)), 0);
3647 result = Insert(result, SaturateSigned(Extract(x, 1)), 1);
3648 result = Insert(result, SaturateSigned(Extract(x, 2)), 2);
3649 result = Insert(result, SaturateSigned(Extract(x, 3)), 3);
3650 result = Insert(result, SaturateSigned(Extract(y, 0)), 4);
3651 result = Insert(result, SaturateSigned(Extract(y, 1)), 5);
3652 result = Insert(result, SaturateSigned(Extract(y, 2)), 6);
3653 result = Insert(result, SaturateSigned(Extract(y, 3)), 7);
Nicolas Capensec54a172016-10-25 17:32:37 -04003654
Nicolas Capens8960fbf2017-07-25 15:32:12 -04003655 return result;
3656 }
3657 else
3658 {
3659 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
3660 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3661 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3662 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3663 pack->addArg(x.value);
3664 pack->addArg(y.value);
3665 ::basicBlock->appendInst(pack);
3666
3667 return As<SByte8>(Swizzle(As<Int4>(V(result)), 0x88));
3668 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003669 }
3670
Nicolas Capens33438a62017-09-27 11:47:35 -04003671 RValue<Byte8> PackUnsigned(RValue<Short4> x, RValue<Short4> y)
3672 {
3673 if(emulateIntrinsics)
3674 {
3675 Byte8 result;
3676 result = Insert(result, SaturateUnsigned(Extract(x, 0)), 0);
3677 result = Insert(result, SaturateUnsigned(Extract(x, 1)), 1);
3678 result = Insert(result, SaturateUnsigned(Extract(x, 2)), 2);
3679 result = Insert(result, SaturateUnsigned(Extract(x, 3)), 3);
3680 result = Insert(result, SaturateUnsigned(Extract(y, 0)), 4);
3681 result = Insert(result, SaturateUnsigned(Extract(y, 1)), 5);
3682 result = Insert(result, SaturateUnsigned(Extract(y, 2)), 6);
3683 result = Insert(result, SaturateUnsigned(Extract(y, 3)), 7);
3684
3685 return result;
3686 }
3687 else
3688 {
3689 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
3690 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3691 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3692 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3693 pack->addArg(x.value);
3694 pack->addArg(y.value);
3695 ::basicBlock->appendInst(pack);
3696
3697 return As<Byte8>(Swizzle(As<Int4>(V(result)), 0x88));
3698 }
3699 }
3700
Nicolas Capens598f8d82016-09-26 15:09:10 -04003701 RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y)
3702 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04003703 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11}; // Real type is v8i16
Nicolas Capensbea4dce2017-07-24 16:54:44 -04003704 return As<Int2>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003705 }
3706
3707 RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y)
3708 {
Nicolas Capens20e22c42016-10-25 17:32:37 -04003709 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11}; // Real type is v8i16
3710 auto lowHigh = RValue<Short8>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
3711 return As<Int2>(Swizzle(As<Int4>(lowHigh), 0xEE));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003712 }
3713
3714 RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select)
3715 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04003716 // Real type is v8i16
3717 int shuffle[8] =
3718 {
3719 (select >> 0) & 0x03,
3720 (select >> 2) & 0x03,
3721 (select >> 4) & 0x03,
3722 (select >> 6) & 0x03,
3723 (select >> 0) & 0x03,
3724 (select >> 2) & 0x03,
3725 (select >> 4) & 0x03,
3726 (select >> 6) & 0x03,
3727 };
3728
3729 return RValue<Short4>(Nucleus::createShuffleVector(x.value, x.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003730 }
3731
3732 RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i)
3733 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05003734 return RValue<Short4>(Nucleus::createInsertElement(val.value, element.value, i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003735 }
3736
3737 RValue<Short> Extract(RValue<Short4> val, int i)
3738 {
Nicolas Capens0133d0f2017-01-16 16:25:08 -05003739 return RValue<Short>(Nucleus::createExtractElement(val.value, Short::getType(), i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003740 }
3741
3742 RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y)
3743 {
Nicolas Capens2f970b62016-11-08 14:28:59 -05003744 return RValue<Short4>(createIntCompare(Ice::InstIcmp::Sgt, x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003745 }
3746
3747 RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y)
3748 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05003749 return RValue<Short4>(Nucleus::createICmpEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003750 }
3751
3752 Type *Short4::getType()
3753 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04003754 return T(Type_v4i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003755 }
3756
3757 UShort4::UShort4(RValue<Int4> cast)
3758 {
3759 *this = Short4(cast);
3760 }
3761
3762 UShort4::UShort4(RValue<Float4> cast, bool saturate)
3763 {
Nicolas Capensd4227962016-11-09 14:24:25 -05003764 if(saturate)
3765 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05003766 if(CPUID::SSE4_1)
Nicolas Capensd4227962016-11-09 14:24:25 -05003767 {
Nicolas Capens091f3502017-10-03 14:56:49 -04003768 // x86 produces 0x80000000 on 32-bit integer overflow/underflow.
3769 // PackUnsigned takes care of 0x0000 saturation.
3770 Int4 int4(Min(cast, Float4(0xFFFF)));
3771 *this = As<UShort4>(PackUnsigned(int4, int4));
3772 }
3773 else if(CPUID::ARM)
3774 {
3775 // ARM saturates the 32-bit integer result on overflow/undeflow.
3776 Int4 int4(cast);
Nicolas Capens33438a62017-09-27 11:47:35 -04003777 *this = As<UShort4>(PackUnsigned(int4, int4));
Nicolas Capensd4227962016-11-09 14:24:25 -05003778 }
3779 else
3780 {
3781 *this = Short4(Int4(Max(Min(cast, Float4(0xFFFF)), Float4(0x0000))));
3782 }
3783 }
3784 else
3785 {
3786 *this = Short4(Int4(cast));
3787 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003788 }
3789
Nicolas Capens598f8d82016-09-26 15:09:10 -04003790 UShort4::UShort4(unsigned short xyzw)
3791 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04003792 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
3793 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003794 }
3795
3796 UShort4::UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w)
3797 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04003798 int64_t constantVector[4] = {x, y, z, w};
3799 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003800 }
3801
3802 UShort4::UShort4(RValue<UShort4> rhs)
3803 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003804 storeValue(rhs.value);
3805 }
3806
3807 UShort4::UShort4(const UShort4 &rhs)
3808 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003809 Value *value = rhs.loadValue();
3810 storeValue(value);
3811 }
3812
3813 UShort4::UShort4(const Reference<UShort4> &rhs)
3814 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003815 Value *value = rhs.loadValue();
3816 storeValue(value);
3817 }
3818
3819 UShort4::UShort4(RValue<Short4> rhs)
3820 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003821 storeValue(rhs.value);
3822 }
3823
3824 UShort4::UShort4(const Short4 &rhs)
3825 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003826 Value *value = rhs.loadValue();
3827 storeValue(value);
3828 }
3829
3830 UShort4::UShort4(const Reference<Short4> &rhs)
3831 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003832 Value *value = rhs.loadValue();
3833 storeValue(value);
3834 }
3835
Nicolas Capens96d4e092016-11-18 14:22:38 -05003836 RValue<UShort4> UShort4::operator=(RValue<UShort4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003837 {
3838 storeValue(rhs.value);
3839
3840 return rhs;
3841 }
3842
Nicolas Capens96d4e092016-11-18 14:22:38 -05003843 RValue<UShort4> UShort4::operator=(const UShort4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003844 {
3845 Value *value = rhs.loadValue();
3846 storeValue(value);
3847
3848 return RValue<UShort4>(value);
3849 }
3850
Nicolas Capens96d4e092016-11-18 14:22:38 -05003851 RValue<UShort4> UShort4::operator=(const Reference<UShort4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003852 {
3853 Value *value = rhs.loadValue();
3854 storeValue(value);
3855
3856 return RValue<UShort4>(value);
3857 }
3858
Nicolas Capens96d4e092016-11-18 14:22:38 -05003859 RValue<UShort4> UShort4::operator=(RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003860 {
3861 storeValue(rhs.value);
3862
3863 return RValue<UShort4>(rhs);
3864 }
3865
Nicolas Capens96d4e092016-11-18 14:22:38 -05003866 RValue<UShort4> UShort4::operator=(const Short4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003867 {
3868 Value *value = rhs.loadValue();
3869 storeValue(value);
3870
3871 return RValue<UShort4>(value);
3872 }
3873
Nicolas Capens96d4e092016-11-18 14:22:38 -05003874 RValue<UShort4> UShort4::operator=(const Reference<Short4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003875 {
3876 Value *value = rhs.loadValue();
3877 storeValue(value);
3878
3879 return RValue<UShort4>(value);
3880 }
3881
3882 RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs)
3883 {
Nicolas Capens5b41ba32016-12-08 14:34:00 -05003884 return RValue<UShort4>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003885 }
3886
3887 RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs)
3888 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003889 return RValue<UShort4>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003890 }
3891
3892 RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs)
3893 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003894 return RValue<UShort4>(Nucleus::createMul(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003895 }
3896
Nicolas Capens16b5f152016-10-13 13:39:01 -04003897 RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs)
3898 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003899 return RValue<UShort4>(Nucleus::createAnd(lhs.value, rhs.value));
Nicolas Capens16b5f152016-10-13 13:39:01 -04003900 }
3901
3902 RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs)
3903 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003904 return RValue<UShort4>(Nucleus::createOr(lhs.value, rhs.value));
Nicolas Capens16b5f152016-10-13 13:39:01 -04003905 }
3906
3907 RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs)
3908 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003909 return RValue<UShort4>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens16b5f152016-10-13 13:39:01 -04003910 }
3911
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04003912 RValue<UShort> Extract(RValue<UShort4> val, int i)
3913 {
3914 return RValue<UShort>(Nucleus::createExtractElement(val.value, UShort::getType(), i));
3915 }
3916
3917 RValue<UShort4> Insert(RValue<UShort4> val, RValue<UShort> element, int i)
3918 {
3919 return RValue<UShort4>(Nucleus::createInsertElement(val.value, element.value, i));
3920 }
3921
Nicolas Capens598f8d82016-09-26 15:09:10 -04003922 RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs)
3923 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04003924 if(emulateIntrinsics)
3925 {
3926 UShort4 result;
3927 result = Insert(result, Extract(lhs, 0) << UShort(rhs), 0);
3928 result = Insert(result, Extract(lhs, 1) << UShort(rhs), 1);
3929 result = Insert(result, Extract(lhs, 2) << UShort(rhs), 2);
3930 result = Insert(result, Extract(lhs, 3) << UShort(rhs), 3);
3931
3932 return result;
3933 }
3934 else
3935 {
3936 return RValue<UShort4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
3937 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003938 }
3939
3940 RValue<UShort4> operator>>(RValue<UShort4> lhs, unsigned char rhs)
3941 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04003942 if(emulateIntrinsics)
3943 {
3944 UShort4 result;
3945 result = Insert(result, Extract(lhs, 0) >> UShort(rhs), 0);
3946 result = Insert(result, Extract(lhs, 1) >> UShort(rhs), 1);
3947 result = Insert(result, Extract(lhs, 2) >> UShort(rhs), 2);
3948 result = Insert(result, Extract(lhs, 3) >> UShort(rhs), 3);
3949
3950 return result;
3951 }
3952 else
3953 {
3954 return RValue<UShort4>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
3955 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003956 }
3957
Nicolas Capens96d4e092016-11-18 14:22:38 -05003958 RValue<UShort4> operator<<=(UShort4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003959 {
3960 return lhs = lhs << rhs;
3961 }
3962
Nicolas Capens96d4e092016-11-18 14:22:38 -05003963 RValue<UShort4> operator>>=(UShort4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003964 {
3965 return lhs = lhs >> rhs;
3966 }
3967
Nicolas Capens598f8d82016-09-26 15:09:10 -04003968 RValue<UShort4> operator~(RValue<UShort4> val)
3969 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -05003970 return RValue<UShort4>(Nucleus::createNot(val.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003971 }
3972
3973 RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y)
3974 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04003975 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3976 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ule, condition, x.value, y.value);
3977 ::basicBlock->appendInst(cmp);
3978
3979 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3980 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3981 ::basicBlock->appendInst(select);
3982
3983 return RValue<UShort4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003984 }
3985
3986 RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y)
3987 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04003988 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3989 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ugt, condition, x.value, y.value);
3990 ::basicBlock->appendInst(cmp);
3991
3992 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3993 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3994 ::basicBlock->appendInst(select);
3995
3996 return RValue<UShort4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003997 }
3998
Nicolas Capens7f301812017-10-02 17:32:34 -04003999 RValue<UShort> SaturateUnsigned(RValue<Int> x)
Nicolas Capens98436732017-07-25 15:32:12 -04004000 {
4001 return UShort(IfThenElse(x > 0xFFFF, Int(0xFFFF), IfThenElse(x < 0, Int(0), x)));
4002 }
4003
Nicolas Capens598f8d82016-09-26 15:09:10 -04004004 RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y)
4005 {
Nicolas Capens98436732017-07-25 15:32:12 -04004006 if(emulateIntrinsics)
4007 {
4008 UShort4 result;
Nicolas Capens7f301812017-10-02 17:32:34 -04004009 result = Insert(result, SaturateUnsigned(Int(Extract(x, 0)) + Int(Extract(y, 0))), 0);
4010 result = Insert(result, SaturateUnsigned(Int(Extract(x, 1)) + Int(Extract(y, 1))), 1);
4011 result = Insert(result, SaturateUnsigned(Int(Extract(x, 2)) + Int(Extract(y, 2))), 2);
4012 result = Insert(result, SaturateUnsigned(Int(Extract(x, 3)) + Int(Extract(y, 3))), 3);
Nicolas Capensc71bed22016-11-07 22:25:14 -05004013
Nicolas Capens98436732017-07-25 15:32:12 -04004014 return result;
4015 }
4016 else
4017 {
4018 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
4019 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
4020 auto target = ::context->getConstantUndef(Ice::IceType_i32);
4021 auto paddusw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
4022 paddusw->addArg(x.value);
4023 paddusw->addArg(y.value);
4024 ::basicBlock->appendInst(paddusw);
4025
4026 return RValue<UShort4>(V(result));
4027 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04004028 }
4029
4030 RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y)
4031 {
Nicolas Capens98436732017-07-25 15:32:12 -04004032 if(emulateIntrinsics)
4033 {
4034 UShort4 result;
Nicolas Capens7f301812017-10-02 17:32:34 -04004035 result = Insert(result, SaturateUnsigned(Int(Extract(x, 0)) - Int(Extract(y, 0))), 0);
4036 result = Insert(result, SaturateUnsigned(Int(Extract(x, 1)) - Int(Extract(y, 1))), 1);
4037 result = Insert(result, SaturateUnsigned(Int(Extract(x, 2)) - Int(Extract(y, 2))), 2);
4038 result = Insert(result, SaturateUnsigned(Int(Extract(x, 3)) - Int(Extract(y, 3))), 3);
Nicolas Capensc71bed22016-11-07 22:25:14 -05004039
Nicolas Capens98436732017-07-25 15:32:12 -04004040 return result;
4041 }
4042 else
4043 {
4044 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
4045 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
4046 auto target = ::context->getConstantUndef(Ice::IceType_i32);
4047 auto psubusw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
4048 psubusw->addArg(x.value);
4049 psubusw->addArg(y.value);
4050 ::basicBlock->appendInst(psubusw);
4051
4052 return RValue<UShort4>(V(result));
4053 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04004054 }
4055
4056 RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y)
4057 {
Nicolas Capens6c157442017-07-25 15:32:12 -04004058 if(emulateIntrinsics)
4059 {
4060 UShort4 result;
4061 result = Insert(result, UShort((UInt(Extract(x, 0)) * UInt(Extract(y, 0))) >> 16), 0);
4062 result = Insert(result, UShort((UInt(Extract(x, 1)) * UInt(Extract(y, 1))) >> 16), 1);
4063 result = Insert(result, UShort((UInt(Extract(x, 2)) * UInt(Extract(y, 2))) >> 16), 2);
4064 result = Insert(result, UShort((UInt(Extract(x, 3)) * UInt(Extract(y, 3))) >> 16), 3);
Nicolas Capensc71bed22016-11-07 22:25:14 -05004065
Nicolas Capens6c157442017-07-25 15:32:12 -04004066 return result;
4067 }
4068 else
4069 {
4070 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
4071 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::MultiplyHighUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
4072 auto target = ::context->getConstantUndef(Ice::IceType_i32);
4073 auto pmulhuw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
4074 pmulhuw->addArg(x.value);
4075 pmulhuw->addArg(y.value);
4076 ::basicBlock->appendInst(pmulhuw);
4077
4078 return RValue<UShort4>(V(result));
4079 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04004080 }
4081
4082 RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y)
4083 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004084 assert(false && "UNIMPLEMENTED"); return RValue<UShort4>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004085 }
4086
Nicolas Capens598f8d82016-09-26 15:09:10 -04004087 Type *UShort4::getType()
4088 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04004089 return T(Type_v4i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004090 }
4091
Nicolas Capens3e7062b2017-01-17 14:01:33 -05004092 Short8::Short8(short c)
4093 {
4094 int64_t constantVector[8] = {c, c, c, c, c, c, c, c};
4095 storeValue(Nucleus::createConstantVector(constantVector, getType()));
4096 }
4097
Nicolas Capens598f8d82016-09-26 15:09:10 -04004098 Short8::Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7)
4099 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04004100 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
4101 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004102 }
4103
4104 Short8::Short8(RValue<Short8> rhs)
4105 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004106 storeValue(rhs.value);
4107 }
4108
4109 Short8::Short8(const Reference<Short8> &rhs)
4110 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004111 Value *value = rhs.loadValue();
4112 storeValue(value);
4113 }
4114
4115 Short8::Short8(RValue<Short4> lo, RValue<Short4> hi)
4116 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05004117 int shuffle[8] = {0, 1, 2, 3, 8, 9, 10, 11}; // Real type is v8i16
4118 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
4119
4120 storeValue(packed);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004121 }
4122
4123 RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs)
4124 {
4125 return RValue<Short8>(Nucleus::createAdd(lhs.value, rhs.value));
4126 }
4127
4128 RValue<Short8> operator&(RValue<Short8> lhs, RValue<Short8> rhs)
4129 {
4130 return RValue<Short8>(Nucleus::createAnd(lhs.value, rhs.value));
4131 }
4132
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04004133 RValue<Short> Extract(RValue<Short8> val, int i)
4134 {
4135 return RValue<Short>(Nucleus::createExtractElement(val.value, Short::getType(), i));
4136 }
4137
4138 RValue<Short8> Insert(RValue<Short8> val, RValue<Short> element, int i)
4139 {
4140 return RValue<Short8>(Nucleus::createInsertElement(val.value, element.value, i));
4141 }
4142
Nicolas Capens598f8d82016-09-26 15:09:10 -04004143 RValue<Short8> operator<<(RValue<Short8> lhs, unsigned char rhs)
4144 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04004145 if(emulateIntrinsics)
4146 {
4147 Short8 result;
4148 result = Insert(result, Extract(lhs, 0) << Short(rhs), 0);
4149 result = Insert(result, Extract(lhs, 1) << Short(rhs), 1);
4150 result = Insert(result, Extract(lhs, 2) << Short(rhs), 2);
4151 result = Insert(result, Extract(lhs, 3) << Short(rhs), 3);
4152 result = Insert(result, Extract(lhs, 4) << Short(rhs), 4);
4153 result = Insert(result, Extract(lhs, 5) << Short(rhs), 5);
4154 result = Insert(result, Extract(lhs, 6) << Short(rhs), 6);
4155 result = Insert(result, Extract(lhs, 7) << Short(rhs), 7);
4156
4157 return result;
4158 }
4159 else
4160 {
4161 return RValue<Short8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
4162 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04004163 }
4164
4165 RValue<Short8> operator>>(RValue<Short8> lhs, unsigned char rhs)
4166 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04004167 if(emulateIntrinsics)
4168 {
4169 Short8 result;
4170 result = Insert(result, Extract(lhs, 0) >> Short(rhs), 0);
4171 result = Insert(result, Extract(lhs, 1) >> Short(rhs), 1);
4172 result = Insert(result, Extract(lhs, 2) >> Short(rhs), 2);
4173 result = Insert(result, Extract(lhs, 3) >> Short(rhs), 3);
4174 result = Insert(result, Extract(lhs, 4) >> Short(rhs), 4);
4175 result = Insert(result, Extract(lhs, 5) >> Short(rhs), 5);
4176 result = Insert(result, Extract(lhs, 6) >> Short(rhs), 6);
4177 result = Insert(result, Extract(lhs, 7) >> Short(rhs), 7);
4178
4179 return result;
4180 }
4181 else
4182 {
4183 return RValue<Short8>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
4184 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04004185 }
4186
4187 RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y)
4188 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004189 assert(false && "UNIMPLEMENTED"); return RValue<Int4>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004190 }
4191
4192 RValue<Int4> Abs(RValue<Int4> x)
4193 {
Nicolas Capens84272242016-11-09 13:31:06 -05004194 auto negative = x >> 31;
4195 return (x ^ negative) - negative;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004196 }
4197
4198 RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y)
4199 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004200 assert(false && "UNIMPLEMENTED"); return RValue<Short8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004201 }
4202
4203 Type *Short8::getType()
4204 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04004205 return T(Ice::IceType_v8i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004206 }
4207
Nicolas Capens3e7062b2017-01-17 14:01:33 -05004208 UShort8::UShort8(unsigned short c)
4209 {
4210 int64_t constantVector[8] = {c, c, c, c, c, c, c, c};
4211 storeValue(Nucleus::createConstantVector(constantVector, getType()));
4212 }
4213
Nicolas Capens598f8d82016-09-26 15:09:10 -04004214 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)
4215 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04004216 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
4217 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004218 }
4219
4220 UShort8::UShort8(RValue<UShort8> rhs)
4221 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004222 storeValue(rhs.value);
4223 }
4224
4225 UShort8::UShort8(const Reference<UShort8> &rhs)
4226 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004227 Value *value = rhs.loadValue();
4228 storeValue(value);
4229 }
4230
4231 UShort8::UShort8(RValue<UShort4> lo, RValue<UShort4> hi)
4232 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05004233 int shuffle[8] = {0, 1, 2, 3, 8, 9, 10, 11}; // Real type is v8i16
4234 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
4235
4236 storeValue(packed);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004237 }
4238
Nicolas Capens96d4e092016-11-18 14:22:38 -05004239 RValue<UShort8> UShort8::operator=(RValue<UShort8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004240 {
4241 storeValue(rhs.value);
4242
4243 return rhs;
4244 }
4245
Nicolas Capens96d4e092016-11-18 14:22:38 -05004246 RValue<UShort8> UShort8::operator=(const UShort8 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004247 {
4248 Value *value = rhs.loadValue();
4249 storeValue(value);
4250
4251 return RValue<UShort8>(value);
4252 }
4253
Nicolas Capens96d4e092016-11-18 14:22:38 -05004254 RValue<UShort8> UShort8::operator=(const Reference<UShort8> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004255 {
4256 Value *value = rhs.loadValue();
4257 storeValue(value);
4258
4259 return RValue<UShort8>(value);
4260 }
4261
4262 RValue<UShort8> operator&(RValue<UShort8> lhs, RValue<UShort8> rhs)
4263 {
4264 return RValue<UShort8>(Nucleus::createAnd(lhs.value, rhs.value));
4265 }
4266
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04004267 RValue<UShort> Extract(RValue<UShort8> val, int i)
4268 {
4269 return RValue<UShort>(Nucleus::createExtractElement(val.value, UShort::getType(), i));
4270 }
4271
4272 RValue<UShort8> Insert(RValue<UShort8> val, RValue<UShort> element, int i)
4273 {
4274 return RValue<UShort8>(Nucleus::createInsertElement(val.value, element.value, i));
4275 }
4276
Nicolas Capens598f8d82016-09-26 15:09:10 -04004277 RValue<UShort8> operator<<(RValue<UShort8> lhs, unsigned char rhs)
4278 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04004279 if(emulateIntrinsics)
4280 {
4281 UShort8 result;
4282 result = Insert(result, Extract(lhs, 0) << UShort(rhs), 0);
4283 result = Insert(result, Extract(lhs, 1) << UShort(rhs), 1);
4284 result = Insert(result, Extract(lhs, 2) << UShort(rhs), 2);
4285 result = Insert(result, Extract(lhs, 3) << UShort(rhs), 3);
4286 result = Insert(result, Extract(lhs, 4) << UShort(rhs), 4);
4287 result = Insert(result, Extract(lhs, 5) << UShort(rhs), 5);
4288 result = Insert(result, Extract(lhs, 6) << UShort(rhs), 6);
4289 result = Insert(result, Extract(lhs, 7) << UShort(rhs), 7);
4290
4291 return result;
4292 }
4293 else
4294 {
4295 return RValue<UShort8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
4296 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04004297 }
4298
4299 RValue<UShort8> operator>>(RValue<UShort8> lhs, unsigned char rhs)
4300 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04004301 if(emulateIntrinsics)
4302 {
4303 UShort8 result;
4304 result = Insert(result, Extract(lhs, 0) >> UShort(rhs), 0);
4305 result = Insert(result, Extract(lhs, 1) >> UShort(rhs), 1);
4306 result = Insert(result, Extract(lhs, 2) >> UShort(rhs), 2);
4307 result = Insert(result, Extract(lhs, 3) >> UShort(rhs), 3);
4308 result = Insert(result, Extract(lhs, 4) >> UShort(rhs), 4);
4309 result = Insert(result, Extract(lhs, 5) >> UShort(rhs), 5);
4310 result = Insert(result, Extract(lhs, 6) >> UShort(rhs), 6);
4311 result = Insert(result, Extract(lhs, 7) >> UShort(rhs), 7);
4312
4313 return result;
4314 }
4315 else
4316 {
4317 return RValue<UShort8>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
4318 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04004319 }
4320
4321 RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs)
4322 {
4323 return RValue<UShort8>(Nucleus::createAdd(lhs.value, rhs.value));
4324 }
4325
4326 RValue<UShort8> operator*(RValue<UShort8> lhs, RValue<UShort8> rhs)
4327 {
4328 return RValue<UShort8>(Nucleus::createMul(lhs.value, rhs.value));
4329 }
4330
Nicolas Capens96d4e092016-11-18 14:22:38 -05004331 RValue<UShort8> operator+=(UShort8 &lhs, RValue<UShort8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004332 {
4333 return lhs = lhs + rhs;
4334 }
4335
4336 RValue<UShort8> operator~(RValue<UShort8> val)
4337 {
4338 return RValue<UShort8>(Nucleus::createNot(val.value));
4339 }
4340
4341 RValue<UShort8> Swizzle(RValue<UShort8> x, char select0, char select1, char select2, char select3, char select4, char select5, char select6, char select7)
4342 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004343 assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004344 }
4345
4346 RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y)
4347 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004348 assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004349 }
4350
4351 // FIXME: Implement as Shuffle(x, y, Select(i0, ..., i16)) and Shuffle(x, y, SELECT_PACK_REPEAT(element))
4352// RValue<UShort8> PackRepeat(RValue<Byte16> x, RValue<Byte16> y, int element)
4353// {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004354// assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004355// }
4356
4357 Type *UShort8::getType()
4358 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04004359 return T(Ice::IceType_v8i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004360 }
4361
4362 Int::Int(Argument<Int> argument)
4363 {
4364 storeValue(argument.value);
4365 }
4366
4367 Int::Int(RValue<Byte> cast)
4368 {
4369 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
4370
4371 storeValue(integer);
4372 }
4373
4374 Int::Int(RValue<SByte> cast)
4375 {
4376 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
4377
4378 storeValue(integer);
4379 }
4380
4381 Int::Int(RValue<Short> cast)
4382 {
4383 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
4384
4385 storeValue(integer);
4386 }
4387
4388 Int::Int(RValue<UShort> cast)
4389 {
4390 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
4391
4392 storeValue(integer);
4393 }
4394
4395 Int::Int(RValue<Int2> cast)
4396 {
4397 *this = Extract(cast, 0);
4398 }
4399
4400 Int::Int(RValue<Long> cast)
4401 {
4402 Value *integer = Nucleus::createTrunc(cast.value, Int::getType());
4403
4404 storeValue(integer);
4405 }
4406
4407 Int::Int(RValue<Float> cast)
4408 {
4409 Value *integer = Nucleus::createFPToSI(cast.value, Int::getType());
4410
4411 storeValue(integer);
4412 }
4413
Nicolas Capens598f8d82016-09-26 15:09:10 -04004414 Int::Int(int x)
4415 {
4416 storeValue(Nucleus::createConstantInt(x));
4417 }
4418
4419 Int::Int(RValue<Int> rhs)
4420 {
4421 storeValue(rhs.value);
4422 }
4423
4424 Int::Int(RValue<UInt> rhs)
4425 {
4426 storeValue(rhs.value);
4427 }
4428
4429 Int::Int(const Int &rhs)
4430 {
4431 Value *value = rhs.loadValue();
4432 storeValue(value);
4433 }
4434
4435 Int::Int(const Reference<Int> &rhs)
4436 {
4437 Value *value = rhs.loadValue();
4438 storeValue(value);
4439 }
4440
4441 Int::Int(const UInt &rhs)
4442 {
4443 Value *value = rhs.loadValue();
4444 storeValue(value);
4445 }
4446
4447 Int::Int(const Reference<UInt> &rhs)
4448 {
4449 Value *value = rhs.loadValue();
4450 storeValue(value);
4451 }
4452
Nicolas Capens96d4e092016-11-18 14:22:38 -05004453 RValue<Int> Int::operator=(int rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004454 {
4455 return RValue<Int>(storeValue(Nucleus::createConstantInt(rhs)));
4456 }
4457
Nicolas Capens96d4e092016-11-18 14:22:38 -05004458 RValue<Int> Int::operator=(RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004459 {
4460 storeValue(rhs.value);
4461
4462 return rhs;
4463 }
4464
Nicolas Capens96d4e092016-11-18 14:22:38 -05004465 RValue<Int> Int::operator=(RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004466 {
4467 storeValue(rhs.value);
4468
4469 return RValue<Int>(rhs);
4470 }
4471
Nicolas Capens96d4e092016-11-18 14:22:38 -05004472 RValue<Int> Int::operator=(const Int &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004473 {
4474 Value *value = rhs.loadValue();
4475 storeValue(value);
4476
4477 return RValue<Int>(value);
4478 }
4479
Nicolas Capens96d4e092016-11-18 14:22:38 -05004480 RValue<Int> Int::operator=(const Reference<Int> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004481 {
4482 Value *value = rhs.loadValue();
4483 storeValue(value);
4484
4485 return RValue<Int>(value);
4486 }
4487
Nicolas Capens96d4e092016-11-18 14:22:38 -05004488 RValue<Int> Int::operator=(const UInt &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004489 {
4490 Value *value = rhs.loadValue();
4491 storeValue(value);
4492
4493 return RValue<Int>(value);
4494 }
4495
Nicolas Capens96d4e092016-11-18 14:22:38 -05004496 RValue<Int> Int::operator=(const Reference<UInt> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004497 {
4498 Value *value = rhs.loadValue();
4499 storeValue(value);
4500
4501 return RValue<Int>(value);
4502 }
4503
4504 RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs)
4505 {
4506 return RValue<Int>(Nucleus::createAdd(lhs.value, rhs.value));
4507 }
4508
4509 RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs)
4510 {
4511 return RValue<Int>(Nucleus::createSub(lhs.value, rhs.value));
4512 }
4513
4514 RValue<Int> operator*(RValue<Int> lhs, RValue<Int> rhs)
4515 {
4516 return RValue<Int>(Nucleus::createMul(lhs.value, rhs.value));
4517 }
4518
4519 RValue<Int> operator/(RValue<Int> lhs, RValue<Int> rhs)
4520 {
4521 return RValue<Int>(Nucleus::createSDiv(lhs.value, rhs.value));
4522 }
4523
4524 RValue<Int> operator%(RValue<Int> lhs, RValue<Int> rhs)
4525 {
4526 return RValue<Int>(Nucleus::createSRem(lhs.value, rhs.value));
4527 }
4528
4529 RValue<Int> operator&(RValue<Int> lhs, RValue<Int> rhs)
4530 {
4531 return RValue<Int>(Nucleus::createAnd(lhs.value, rhs.value));
4532 }
4533
4534 RValue<Int> operator|(RValue<Int> lhs, RValue<Int> rhs)
4535 {
4536 return RValue<Int>(Nucleus::createOr(lhs.value, rhs.value));
4537 }
4538
4539 RValue<Int> operator^(RValue<Int> lhs, RValue<Int> rhs)
4540 {
4541 return RValue<Int>(Nucleus::createXor(lhs.value, rhs.value));
4542 }
4543
4544 RValue<Int> operator<<(RValue<Int> lhs, RValue<Int> rhs)
4545 {
4546 return RValue<Int>(Nucleus::createShl(lhs.value, rhs.value));
4547 }
4548
4549 RValue<Int> operator>>(RValue<Int> lhs, RValue<Int> rhs)
4550 {
4551 return RValue<Int>(Nucleus::createAShr(lhs.value, rhs.value));
4552 }
4553
Nicolas Capens96d4e092016-11-18 14:22:38 -05004554 RValue<Int> operator+=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004555 {
4556 return lhs = lhs + rhs;
4557 }
4558
Nicolas Capens96d4e092016-11-18 14:22:38 -05004559 RValue<Int> operator-=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004560 {
4561 return lhs = lhs - rhs;
4562 }
4563
Nicolas Capens96d4e092016-11-18 14:22:38 -05004564 RValue<Int> operator*=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004565 {
4566 return lhs = lhs * rhs;
4567 }
4568
Nicolas Capens96d4e092016-11-18 14:22:38 -05004569 RValue<Int> operator/=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004570 {
4571 return lhs = lhs / rhs;
4572 }
4573
Nicolas Capens96d4e092016-11-18 14:22:38 -05004574 RValue<Int> operator%=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004575 {
4576 return lhs = lhs % rhs;
4577 }
4578
Nicolas Capens96d4e092016-11-18 14:22:38 -05004579 RValue<Int> operator&=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004580 {
4581 return lhs = lhs & rhs;
4582 }
4583
Nicolas Capens96d4e092016-11-18 14:22:38 -05004584 RValue<Int> operator|=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004585 {
4586 return lhs = lhs | rhs;
4587 }
4588
Nicolas Capens96d4e092016-11-18 14:22:38 -05004589 RValue<Int> operator^=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004590 {
4591 return lhs = lhs ^ rhs;
4592 }
4593
Nicolas Capens96d4e092016-11-18 14:22:38 -05004594 RValue<Int> operator<<=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004595 {
4596 return lhs = lhs << rhs;
4597 }
4598
Nicolas Capens96d4e092016-11-18 14:22:38 -05004599 RValue<Int> operator>>=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004600 {
4601 return lhs = lhs >> rhs;
4602 }
4603
4604 RValue<Int> operator+(RValue<Int> val)
4605 {
4606 return val;
4607 }
4608
4609 RValue<Int> operator-(RValue<Int> val)
4610 {
4611 return RValue<Int>(Nucleus::createNeg(val.value));
4612 }
4613
4614 RValue<Int> operator~(RValue<Int> val)
4615 {
4616 return RValue<Int>(Nucleus::createNot(val.value));
4617 }
4618
Nicolas Capens96d4e092016-11-18 14:22:38 -05004619 RValue<Int> operator++(Int &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04004620 {
Nicolas Capens5b41ba32016-12-08 14:34:00 -05004621 RValue<Int> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05004622 val += 1;
4623 return res;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004624 }
4625
Nicolas Capens96d4e092016-11-18 14:22:38 -05004626 const Int &operator++(Int &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04004627 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004628 val += 1;
4629 return val;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004630 }
4631
Nicolas Capens96d4e092016-11-18 14:22:38 -05004632 RValue<Int> operator--(Int &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04004633 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004634 RValue<Int> res = val;
4635 val -= 1;
4636 return res;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004637 }
4638
Nicolas Capens96d4e092016-11-18 14:22:38 -05004639 const Int &operator--(Int &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04004640 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004641 val -= 1;
4642 return val;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004643 }
4644
4645 RValue<Bool> operator<(RValue<Int> lhs, RValue<Int> rhs)
4646 {
4647 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
4648 }
4649
4650 RValue<Bool> operator<=(RValue<Int> lhs, RValue<Int> rhs)
4651 {
4652 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
4653 }
4654
4655 RValue<Bool> operator>(RValue<Int> lhs, RValue<Int> rhs)
4656 {
4657 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
4658 }
4659
4660 RValue<Bool> operator>=(RValue<Int> lhs, RValue<Int> rhs)
4661 {
4662 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
4663 }
4664
4665 RValue<Bool> operator!=(RValue<Int> lhs, RValue<Int> rhs)
4666 {
4667 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
4668 }
4669
4670 RValue<Bool> operator==(RValue<Int> lhs, RValue<Int> rhs)
4671 {
4672 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
4673 }
4674
4675 RValue<Int> Max(RValue<Int> x, RValue<Int> y)
4676 {
4677 return IfThenElse(x > y, x, y);
4678 }
4679
4680 RValue<Int> Min(RValue<Int> x, RValue<Int> y)
4681 {
4682 return IfThenElse(x < y, x, y);
4683 }
4684
4685 RValue<Int> Clamp(RValue<Int> x, RValue<Int> min, RValue<Int> max)
4686 {
4687 return Min(Max(x, min), max);
4688 }
4689
4690 RValue<Int> RoundInt(RValue<Float> cast)
4691 {
Nicolas Capens091f3502017-10-03 14:56:49 -04004692 if(emulateIntrinsics || CPUID::ARM)
Nicolas Capensf7b75882017-04-26 09:30:47 -04004693 {
4694 // Push the fractional part off the mantissa. Accurate up to +/-2^22.
4695 return Int((cast + Float(0x00C00000)) - Float(0x00C00000));
4696 }
4697 else
4698 {
4699 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
4700 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Nearbyint, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
4701 auto target = ::context->getConstantUndef(Ice::IceType_i32);
4702 auto nearbyint = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
4703 nearbyint->addArg(cast.value);
4704 ::basicBlock->appendInst(nearbyint);
Nicolas Capensa8086512016-11-07 17:32:17 -05004705
Nicolas Capensf7b75882017-04-26 09:30:47 -04004706 return RValue<Int>(V(result));
4707 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04004708 }
4709
4710 Type *Int::getType()
4711 {
4712 return T(Ice::IceType_i32);
4713 }
4714
4715 Long::Long(RValue<Int> cast)
4716 {
4717 Value *integer = Nucleus::createSExt(cast.value, Long::getType());
4718
4719 storeValue(integer);
4720 }
4721
4722 Long::Long(RValue<UInt> cast)
4723 {
4724 Value *integer = Nucleus::createZExt(cast.value, Long::getType());
4725
4726 storeValue(integer);
4727 }
4728
Nicolas Capens598f8d82016-09-26 15:09:10 -04004729 Long::Long(RValue<Long> rhs)
4730 {
4731 storeValue(rhs.value);
4732 }
4733
Nicolas Capens96d4e092016-11-18 14:22:38 -05004734 RValue<Long> Long::operator=(int64_t rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004735 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04004736 return RValue<Long>(storeValue(Nucleus::createConstantLong(rhs)));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004737 }
4738
Nicolas Capens96d4e092016-11-18 14:22:38 -05004739 RValue<Long> Long::operator=(RValue<Long> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004740 {
4741 storeValue(rhs.value);
4742
4743 return rhs;
4744 }
4745
Nicolas Capens96d4e092016-11-18 14:22:38 -05004746 RValue<Long> Long::operator=(const Long &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004747 {
4748 Value *value = rhs.loadValue();
4749 storeValue(value);
4750
4751 return RValue<Long>(value);
4752 }
4753
Nicolas Capens96d4e092016-11-18 14:22:38 -05004754 RValue<Long> Long::operator=(const Reference<Long> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004755 {
4756 Value *value = rhs.loadValue();
4757 storeValue(value);
4758
4759 return RValue<Long>(value);
4760 }
4761
4762 RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs)
4763 {
4764 return RValue<Long>(Nucleus::createAdd(lhs.value, rhs.value));
4765 }
4766
4767 RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs)
4768 {
4769 return RValue<Long>(Nucleus::createSub(lhs.value, rhs.value));
4770 }
4771
Nicolas Capens96d4e092016-11-18 14:22:38 -05004772 RValue<Long> operator+=(Long &lhs, RValue<Long> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004773 {
4774 return lhs = lhs + rhs;
4775 }
4776
Nicolas Capens96d4e092016-11-18 14:22:38 -05004777 RValue<Long> operator-=(Long &lhs, RValue<Long> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004778 {
4779 return lhs = lhs - rhs;
4780 }
4781
4782 RValue<Long> AddAtomic(RValue<Pointer<Long> > x, RValue<Long> y)
4783 {
4784 return RValue<Long>(Nucleus::createAtomicAdd(x.value, y.value));
4785 }
4786
4787 Type *Long::getType()
4788 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04004789 return T(Ice::IceType_i64);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004790 }
4791
Nicolas Capens598f8d82016-09-26 15:09:10 -04004792 UInt::UInt(Argument<UInt> argument)
4793 {
4794 storeValue(argument.value);
4795 }
4796
4797 UInt::UInt(RValue<UShort> cast)
4798 {
4799 Value *integer = Nucleus::createZExt(cast.value, UInt::getType());
4800
4801 storeValue(integer);
4802 }
4803
4804 UInt::UInt(RValue<Long> cast)
4805 {
4806 Value *integer = Nucleus::createTrunc(cast.value, UInt::getType());
4807
4808 storeValue(integer);
4809 }
4810
4811 UInt::UInt(RValue<Float> cast)
4812 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05004813 // Smallest positive value representable in UInt, but not in Int
4814 const unsigned int ustart = 0x80000000u;
4815 const float ustartf = float(ustart);
4816
4817 // If the value is negative, store 0, otherwise store the result of the conversion
4818 storeValue((~(As<Int>(cast) >> 31) &
4819 // Check if the value can be represented as an Int
4820 IfThenElse(cast >= ustartf,
4821 // If the value is too large, subtract ustart and re-add it after conversion.
4822 As<Int>(As<UInt>(Int(cast - Float(ustartf))) + UInt(ustart)),
4823 // Otherwise, just convert normally
4824 Int(cast))).value);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004825 }
4826
Nicolas Capens598f8d82016-09-26 15:09:10 -04004827 UInt::UInt(int x)
4828 {
4829 storeValue(Nucleus::createConstantInt(x));
4830 }
4831
4832 UInt::UInt(unsigned int x)
4833 {
4834 storeValue(Nucleus::createConstantInt(x));
4835 }
4836
4837 UInt::UInt(RValue<UInt> rhs)
4838 {
4839 storeValue(rhs.value);
4840 }
4841
4842 UInt::UInt(RValue<Int> rhs)
4843 {
4844 storeValue(rhs.value);
4845 }
4846
4847 UInt::UInt(const UInt &rhs)
4848 {
4849 Value *value = rhs.loadValue();
4850 storeValue(value);
4851 }
4852
4853 UInt::UInt(const Reference<UInt> &rhs)
4854 {
4855 Value *value = rhs.loadValue();
4856 storeValue(value);
4857 }
4858
4859 UInt::UInt(const Int &rhs)
4860 {
4861 Value *value = rhs.loadValue();
4862 storeValue(value);
4863 }
4864
4865 UInt::UInt(const Reference<Int> &rhs)
4866 {
4867 Value *value = rhs.loadValue();
4868 storeValue(value);
4869 }
4870
Nicolas Capens96d4e092016-11-18 14:22:38 -05004871 RValue<UInt> UInt::operator=(unsigned int rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004872 {
4873 return RValue<UInt>(storeValue(Nucleus::createConstantInt(rhs)));
4874 }
4875
Nicolas Capens96d4e092016-11-18 14:22:38 -05004876 RValue<UInt> UInt::operator=(RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004877 {
4878 storeValue(rhs.value);
4879
4880 return rhs;
4881 }
4882
Nicolas Capens96d4e092016-11-18 14:22:38 -05004883 RValue<UInt> UInt::operator=(RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004884 {
4885 storeValue(rhs.value);
4886
4887 return RValue<UInt>(rhs);
4888 }
4889
Nicolas Capens96d4e092016-11-18 14:22:38 -05004890 RValue<UInt> UInt::operator=(const UInt &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004891 {
4892 Value *value = rhs.loadValue();
4893 storeValue(value);
4894
4895 return RValue<UInt>(value);
4896 }
4897
Nicolas Capens96d4e092016-11-18 14:22:38 -05004898 RValue<UInt> UInt::operator=(const Reference<UInt> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004899 {
4900 Value *value = rhs.loadValue();
4901 storeValue(value);
4902
4903 return RValue<UInt>(value);
4904 }
4905
Nicolas Capens96d4e092016-11-18 14:22:38 -05004906 RValue<UInt> UInt::operator=(const Int &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004907 {
4908 Value *value = rhs.loadValue();
4909 storeValue(value);
4910
4911 return RValue<UInt>(value);
4912 }
4913
Nicolas Capens96d4e092016-11-18 14:22:38 -05004914 RValue<UInt> UInt::operator=(const Reference<Int> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004915 {
4916 Value *value = rhs.loadValue();
4917 storeValue(value);
4918
4919 return RValue<UInt>(value);
4920 }
4921
4922 RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs)
4923 {
4924 return RValue<UInt>(Nucleus::createAdd(lhs.value, rhs.value));
4925 }
4926
4927 RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs)
4928 {
4929 return RValue<UInt>(Nucleus::createSub(lhs.value, rhs.value));
4930 }
4931
4932 RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs)
4933 {
4934 return RValue<UInt>(Nucleus::createMul(lhs.value, rhs.value));
4935 }
4936
4937 RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs)
4938 {
4939 return RValue<UInt>(Nucleus::createUDiv(lhs.value, rhs.value));
4940 }
4941
4942 RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs)
4943 {
4944 return RValue<UInt>(Nucleus::createURem(lhs.value, rhs.value));
4945 }
4946
4947 RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs)
4948 {
4949 return RValue<UInt>(Nucleus::createAnd(lhs.value, rhs.value));
4950 }
4951
4952 RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs)
4953 {
4954 return RValue<UInt>(Nucleus::createOr(lhs.value, rhs.value));
4955 }
4956
4957 RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs)
4958 {
4959 return RValue<UInt>(Nucleus::createXor(lhs.value, rhs.value));
4960 }
4961
4962 RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs)
4963 {
4964 return RValue<UInt>(Nucleus::createShl(lhs.value, rhs.value));
4965 }
4966
4967 RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs)
4968 {
4969 return RValue<UInt>(Nucleus::createLShr(lhs.value, rhs.value));
4970 }
4971
Nicolas Capens96d4e092016-11-18 14:22:38 -05004972 RValue<UInt> operator+=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004973 {
4974 return lhs = lhs + rhs;
4975 }
4976
Nicolas Capens96d4e092016-11-18 14:22:38 -05004977 RValue<UInt> operator-=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004978 {
4979 return lhs = lhs - rhs;
4980 }
4981
Nicolas Capens96d4e092016-11-18 14:22:38 -05004982 RValue<UInt> operator*=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004983 {
4984 return lhs = lhs * rhs;
4985 }
4986
Nicolas Capens96d4e092016-11-18 14:22:38 -05004987 RValue<UInt> operator/=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004988 {
4989 return lhs = lhs / rhs;
4990 }
4991
Nicolas Capens96d4e092016-11-18 14:22:38 -05004992 RValue<UInt> operator%=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004993 {
4994 return lhs = lhs % rhs;
4995 }
4996
Nicolas Capens96d4e092016-11-18 14:22:38 -05004997 RValue<UInt> operator&=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004998 {
4999 return lhs = lhs & rhs;
5000 }
5001
Nicolas Capens96d4e092016-11-18 14:22:38 -05005002 RValue<UInt> operator|=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005003 {
5004 return lhs = lhs | rhs;
5005 }
5006
Nicolas Capens96d4e092016-11-18 14:22:38 -05005007 RValue<UInt> operator^=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005008 {
5009 return lhs = lhs ^ rhs;
5010 }
5011
Nicolas Capens96d4e092016-11-18 14:22:38 -05005012 RValue<UInt> operator<<=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005013 {
5014 return lhs = lhs << rhs;
5015 }
5016
Nicolas Capens96d4e092016-11-18 14:22:38 -05005017 RValue<UInt> operator>>=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005018 {
5019 return lhs = lhs >> rhs;
5020 }
5021
5022 RValue<UInt> operator+(RValue<UInt> val)
5023 {
5024 return val;
5025 }
5026
5027 RValue<UInt> operator-(RValue<UInt> val)
5028 {
5029 return RValue<UInt>(Nucleus::createNeg(val.value));
5030 }
5031
5032 RValue<UInt> operator~(RValue<UInt> val)
5033 {
5034 return RValue<UInt>(Nucleus::createNot(val.value));
5035 }
5036
Nicolas Capens96d4e092016-11-18 14:22:38 -05005037 RValue<UInt> operator++(UInt &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04005038 {
Nicolas Capensd1229402016-11-07 16:05:22 -05005039 RValue<UInt> res = val;
5040 val += 1;
5041 return res;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005042 }
5043
Nicolas Capens96d4e092016-11-18 14:22:38 -05005044 const UInt &operator++(UInt &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04005045 {
Nicolas Capensd1229402016-11-07 16:05:22 -05005046 val += 1;
5047 return val;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005048 }
5049
Nicolas Capens96d4e092016-11-18 14:22:38 -05005050 RValue<UInt> operator--(UInt &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04005051 {
Nicolas Capensd1229402016-11-07 16:05:22 -05005052 RValue<UInt> res = val;
5053 val -= 1;
5054 return res;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005055 }
5056
Nicolas Capens96d4e092016-11-18 14:22:38 -05005057 const UInt &operator--(UInt &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04005058 {
Nicolas Capensd1229402016-11-07 16:05:22 -05005059 val -= 1;
5060 return val;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005061 }
5062
5063 RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y)
5064 {
5065 return IfThenElse(x > y, x, y);
5066 }
5067
5068 RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y)
5069 {
5070 return IfThenElse(x < y, x, y);
5071 }
5072
5073 RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max)
5074 {
5075 return Min(Max(x, min), max);
5076 }
5077
5078 RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs)
5079 {
5080 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
5081 }
5082
5083 RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs)
5084 {
5085 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
5086 }
5087
5088 RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs)
5089 {
5090 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
5091 }
5092
5093 RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs)
5094 {
5095 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
5096 }
5097
5098 RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs)
5099 {
5100 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
5101 }
5102
5103 RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs)
5104 {
5105 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
5106 }
5107
5108// RValue<UInt> RoundUInt(RValue<Float> cast)
5109// {
Nicolas Capensc37252c2016-09-28 16:11:54 -04005110// assert(false && "UNIMPLEMENTED"); return RValue<UInt>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005111// }
5112
5113 Type *UInt::getType()
5114 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04005115 return T(Ice::IceType_i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005116 }
5117
5118// Int2::Int2(RValue<Int> cast)
5119// {
5120// Value *extend = Nucleus::createZExt(cast.value, Long::getType());
5121// Value *vector = Nucleus::createBitCast(extend, Int2::getType());
5122//
5123// Constant *shuffle[2];
5124// shuffle[0] = Nucleus::createConstantInt(0);
5125// shuffle[1] = Nucleus::createConstantInt(0);
5126//
5127// Value *replicate = Nucleus::createShuffleVector(vector, UndefValue::get(Int2::getType()), Nucleus::createConstantVector(shuffle, 2));
5128//
5129// storeValue(replicate);
5130// }
5131
5132 Int2::Int2(RValue<Int4> cast)
5133 {
Nicolas Capens22008782016-10-20 01:11:47 -04005134 storeValue(Nucleus::createBitCast(cast.value, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005135 }
5136
Nicolas Capens598f8d82016-09-26 15:09:10 -04005137 Int2::Int2(int x, int y)
5138 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04005139 int64_t constantVector[2] = {x, y};
5140 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005141 }
5142
5143 Int2::Int2(RValue<Int2> rhs)
5144 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005145 storeValue(rhs.value);
5146 }
5147
5148 Int2::Int2(const Int2 &rhs)
5149 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005150 Value *value = rhs.loadValue();
5151 storeValue(value);
5152 }
5153
5154 Int2::Int2(const Reference<Int2> &rhs)
5155 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005156 Value *value = rhs.loadValue();
5157 storeValue(value);
5158 }
5159
5160 Int2::Int2(RValue<Int> lo, RValue<Int> hi)
5161 {
Nicolas Capensd4227962016-11-09 14:24:25 -05005162 int shuffle[4] = {0, 4, 1, 5};
5163 Value *packed = Nucleus::createShuffleVector(Int4(lo).loadValue(), Int4(hi).loadValue(), shuffle);
5164
5165 storeValue(Nucleus::createBitCast(packed, Int2::getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005166 }
5167
Nicolas Capens96d4e092016-11-18 14:22:38 -05005168 RValue<Int2> Int2::operator=(RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005169 {
5170 storeValue(rhs.value);
5171
5172 return rhs;
5173 }
5174
Nicolas Capens96d4e092016-11-18 14:22:38 -05005175 RValue<Int2> Int2::operator=(const Int2 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005176 {
5177 Value *value = rhs.loadValue();
5178 storeValue(value);
5179
5180 return RValue<Int2>(value);
5181 }
5182
Nicolas Capens96d4e092016-11-18 14:22:38 -05005183 RValue<Int2> Int2::operator=(const Reference<Int2> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005184 {
5185 Value *value = rhs.loadValue();
5186 storeValue(value);
5187
5188 return RValue<Int2>(value);
5189 }
5190
5191 RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs)
5192 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005193 return RValue<Int2>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005194 }
5195
5196 RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs)
5197 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005198 return RValue<Int2>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005199 }
5200
5201// RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs)
5202// {
5203// return RValue<Int2>(Nucleus::createMul(lhs.value, rhs.value));
5204// }
5205
5206// RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs)
5207// {
5208// return RValue<Int2>(Nucleus::createSDiv(lhs.value, rhs.value));
5209// }
5210
5211// RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs)
5212// {
5213// return RValue<Int2>(Nucleus::createSRem(lhs.value, rhs.value));
5214// }
5215
5216 RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs)
5217 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005218 return RValue<Int2>(Nucleus::createAnd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005219 }
5220
5221 RValue<Int2> operator|(RValue<Int2> lhs, RValue<Int2> rhs)
5222 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005223 return RValue<Int2>(Nucleus::createOr(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005224 }
5225
5226 RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs)
5227 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005228 return RValue<Int2>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005229 }
5230
5231 RValue<Int2> operator<<(RValue<Int2> lhs, unsigned char rhs)
5232 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005233 if(emulateIntrinsics)
5234 {
5235 Int2 result;
5236 result = Insert(result, Extract(lhs, 0) << Int(rhs), 0);
5237 result = Insert(result, Extract(lhs, 1) << Int(rhs), 1);
5238
5239 return result;
5240 }
5241 else
5242 {
5243 return RValue<Int2>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
5244 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005245 }
5246
5247 RValue<Int2> operator>>(RValue<Int2> lhs, unsigned char rhs)
5248 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005249 if(emulateIntrinsics)
5250 {
5251 Int2 result;
5252 result = Insert(result, Extract(lhs, 0) >> Int(rhs), 0);
5253 result = Insert(result, Extract(lhs, 1) >> Int(rhs), 1);
5254
5255 return result;
5256 }
5257 else
5258 {
5259 return RValue<Int2>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
5260 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005261 }
5262
Nicolas Capens96d4e092016-11-18 14:22:38 -05005263 RValue<Int2> operator+=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005264 {
5265 return lhs = lhs + rhs;
5266 }
5267
Nicolas Capens96d4e092016-11-18 14:22:38 -05005268 RValue<Int2> operator-=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005269 {
5270 return lhs = lhs - rhs;
5271 }
5272
Nicolas Capens96d4e092016-11-18 14:22:38 -05005273// RValue<Int2> operator*=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005274// {
5275// return lhs = lhs * rhs;
5276// }
5277
Nicolas Capens96d4e092016-11-18 14:22:38 -05005278// RValue<Int2> operator/=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005279// {
5280// return lhs = lhs / rhs;
5281// }
5282
Nicolas Capens96d4e092016-11-18 14:22:38 -05005283// RValue<Int2> operator%=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005284// {
5285// return lhs = lhs % rhs;
5286// }
5287
Nicolas Capens96d4e092016-11-18 14:22:38 -05005288 RValue<Int2> operator&=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005289 {
5290 return lhs = lhs & rhs;
5291 }
5292
Nicolas Capens96d4e092016-11-18 14:22:38 -05005293 RValue<Int2> operator|=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005294 {
5295 return lhs = lhs | rhs;
5296 }
5297
Nicolas Capens96d4e092016-11-18 14:22:38 -05005298 RValue<Int2> operator^=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005299 {
5300 return lhs = lhs ^ rhs;
5301 }
5302
Nicolas Capens96d4e092016-11-18 14:22:38 -05005303 RValue<Int2> operator<<=(Int2 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005304 {
5305 return lhs = lhs << rhs;
5306 }
5307
Nicolas Capens96d4e092016-11-18 14:22:38 -05005308 RValue<Int2> operator>>=(Int2 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005309 {
5310 return lhs = lhs >> rhs;
5311 }
5312
Nicolas Capens598f8d82016-09-26 15:09:10 -04005313// RValue<Int2> operator+(RValue<Int2> val)
5314// {
5315// return val;
5316// }
5317
5318// RValue<Int2> operator-(RValue<Int2> val)
5319// {
5320// return RValue<Int2>(Nucleus::createNeg(val.value));
5321// }
5322
5323 RValue<Int2> operator~(RValue<Int2> val)
5324 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -05005325 return RValue<Int2>(Nucleus::createNot(val.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005326 }
5327
Nicolas Capens45f187a2016-12-02 15:30:56 -05005328 RValue<Short4> UnpackLow(RValue<Int2> x, RValue<Int2> y)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005329 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05005330 int shuffle[4] = {0, 4, 1, 5}; // Real type is v4i32
5331 return As<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005332 }
5333
Nicolas Capens45f187a2016-12-02 15:30:56 -05005334 RValue<Short4> UnpackHigh(RValue<Int2> x, RValue<Int2> y)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005335 {
Nicolas Capensf8beb4b2017-01-27 02:55:44 -08005336 int shuffle[4] = {0, 4, 1, 5}; // Real type is v4i32
Nicolas Capensc70a1162016-12-03 00:16:14 -05005337 auto lowHigh = RValue<Int4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
5338 return As<Short4>(Swizzle(lowHigh, 0xEE));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005339 }
5340
5341 RValue<Int> Extract(RValue<Int2> val, int i)
5342 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05005343 return RValue<Int>(Nucleus::createExtractElement(val.value, Int::getType(), i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005344 }
5345
5346 RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i)
5347 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05005348 return RValue<Int2>(Nucleus::createInsertElement(val.value, element.value, i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005349 }
5350
5351 Type *Int2::getType()
5352 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04005353 return T(Type_v2i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005354 }
5355
Nicolas Capens598f8d82016-09-26 15:09:10 -04005356 UInt2::UInt2(unsigned int x, unsigned int y)
5357 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04005358 int64_t constantVector[2] = {x, y};
5359 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005360 }
5361
5362 UInt2::UInt2(RValue<UInt2> rhs)
5363 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005364 storeValue(rhs.value);
5365 }
5366
5367 UInt2::UInt2(const UInt2 &rhs)
5368 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005369 Value *value = rhs.loadValue();
5370 storeValue(value);
5371 }
5372
5373 UInt2::UInt2(const Reference<UInt2> &rhs)
5374 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005375 Value *value = rhs.loadValue();
5376 storeValue(value);
5377 }
5378
Nicolas Capens96d4e092016-11-18 14:22:38 -05005379 RValue<UInt2> UInt2::operator=(RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005380 {
5381 storeValue(rhs.value);
5382
5383 return rhs;
5384 }
5385
Nicolas Capens96d4e092016-11-18 14:22:38 -05005386 RValue<UInt2> UInt2::operator=(const UInt2 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005387 {
5388 Value *value = rhs.loadValue();
5389 storeValue(value);
5390
5391 return RValue<UInt2>(value);
5392 }
5393
Nicolas Capens96d4e092016-11-18 14:22:38 -05005394 RValue<UInt2> UInt2::operator=(const Reference<UInt2> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005395 {
5396 Value *value = rhs.loadValue();
5397 storeValue(value);
5398
5399 return RValue<UInt2>(value);
5400 }
5401
5402 RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs)
5403 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005404 return RValue<UInt2>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005405 }
5406
5407 RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs)
5408 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005409 return RValue<UInt2>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005410 }
5411
5412// RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs)
5413// {
5414// return RValue<UInt2>(Nucleus::createMul(lhs.value, rhs.value));
5415// }
5416
5417// RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs)
5418// {
5419// return RValue<UInt2>(Nucleus::createUDiv(lhs.value, rhs.value));
5420// }
5421
5422// RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs)
5423// {
5424// return RValue<UInt2>(Nucleus::createURem(lhs.value, rhs.value));
5425// }
5426
5427 RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs)
5428 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005429 return RValue<UInt2>(Nucleus::createAnd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005430 }
5431
5432 RValue<UInt2> operator|(RValue<UInt2> lhs, RValue<UInt2> rhs)
5433 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005434 return RValue<UInt2>(Nucleus::createOr(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005435 }
5436
5437 RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs)
5438 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005439 return RValue<UInt2>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005440 }
5441
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005442 RValue<UInt> Extract(RValue<UInt2> val, int i)
5443 {
5444 return RValue<UInt>(Nucleus::createExtractElement(val.value, UInt::getType(), i));
5445 }
5446
5447 RValue<UInt2> Insert(RValue<UInt2> val, RValue<UInt> element, int i)
5448 {
5449 return RValue<UInt2>(Nucleus::createInsertElement(val.value, element.value, i));
5450 }
5451
Nicolas Capens598f8d82016-09-26 15:09:10 -04005452 RValue<UInt2> operator<<(RValue<UInt2> lhs, unsigned char rhs)
5453 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005454 if(emulateIntrinsics)
5455 {
5456 UInt2 result;
5457 result = Insert(result, Extract(lhs, 0) << UInt(rhs), 0);
5458 result = Insert(result, Extract(lhs, 1) << UInt(rhs), 1);
5459
5460 return result;
5461 }
5462 else
5463 {
5464 return RValue<UInt2>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
5465 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005466 }
5467
5468 RValue<UInt2> operator>>(RValue<UInt2> lhs, unsigned char rhs)
5469 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005470 if(emulateIntrinsics)
5471 {
5472 UInt2 result;
5473 result = Insert(result, Extract(lhs, 0) >> UInt(rhs), 0);
5474 result = Insert(result, Extract(lhs, 1) >> UInt(rhs), 1);
5475
5476 return result;
5477 }
5478 else
5479 {
5480 return RValue<UInt2>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
5481 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005482 }
5483
Nicolas Capens96d4e092016-11-18 14:22:38 -05005484 RValue<UInt2> operator+=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005485 {
5486 return lhs = lhs + rhs;
5487 }
5488
Nicolas Capens96d4e092016-11-18 14:22:38 -05005489 RValue<UInt2> operator-=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005490 {
5491 return lhs = lhs - rhs;
5492 }
5493
Nicolas Capens96d4e092016-11-18 14:22:38 -05005494// RValue<UInt2> operator*=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005495// {
5496// return lhs = lhs * rhs;
5497// }
5498
Nicolas Capens96d4e092016-11-18 14:22:38 -05005499// RValue<UInt2> operator/=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005500// {
5501// return lhs = lhs / rhs;
5502// }
5503
Nicolas Capens96d4e092016-11-18 14:22:38 -05005504// RValue<UInt2> operator%=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005505// {
5506// return lhs = lhs % rhs;
5507// }
5508
Nicolas Capens96d4e092016-11-18 14:22:38 -05005509 RValue<UInt2> operator&=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005510 {
5511 return lhs = lhs & rhs;
5512 }
5513
Nicolas Capens96d4e092016-11-18 14:22:38 -05005514 RValue<UInt2> operator|=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005515 {
5516 return lhs = lhs | rhs;
5517 }
5518
Nicolas Capens96d4e092016-11-18 14:22:38 -05005519 RValue<UInt2> operator^=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005520 {
5521 return lhs = lhs ^ rhs;
5522 }
5523
Nicolas Capens96d4e092016-11-18 14:22:38 -05005524 RValue<UInt2> operator<<=(UInt2 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005525 {
5526 return lhs = lhs << rhs;
5527 }
5528
Nicolas Capens96d4e092016-11-18 14:22:38 -05005529 RValue<UInt2> operator>>=(UInt2 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005530 {
5531 return lhs = lhs >> rhs;
5532 }
5533
Nicolas Capens598f8d82016-09-26 15:09:10 -04005534// RValue<UInt2> operator+(RValue<UInt2> val)
5535// {
5536// return val;
5537// }
5538
5539// RValue<UInt2> operator-(RValue<UInt2> val)
5540// {
5541// return RValue<UInt2>(Nucleus::createNeg(val.value));
5542// }
5543
5544 RValue<UInt2> operator~(RValue<UInt2> val)
5545 {
5546 return RValue<UInt2>(Nucleus::createNot(val.value));
5547 }
5548
5549 Type *UInt2::getType()
5550 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04005551 return T(Type_v2i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005552 }
5553
Nicolas Capenscb986762017-01-20 11:34:37 -05005554 Int4::Int4() : XYZW(this)
5555 {
5556 }
5557
5558 Int4::Int4(RValue<Byte4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005559 {
Nicolas Capensd4227962016-11-09 14:24:25 -05005560 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
5561 Value *a = Nucleus::createInsertElement(loadValue(), x, 0);
5562
5563 Value *e;
5564 int swizzle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23};
5565 Value *b = Nucleus::createBitCast(a, Byte16::getType());
5566 Value *c = Nucleus::createShuffleVector(b, V(Nucleus::createNullValue(Byte16::getType())), swizzle);
5567
5568 int swizzle2[8] = {0, 8, 1, 9, 2, 10, 3, 11};
5569 Value *d = Nucleus::createBitCast(c, Short8::getType());
5570 e = Nucleus::createShuffleVector(d, V(Nucleus::createNullValue(Short8::getType())), swizzle2);
5571
5572 Value *f = Nucleus::createBitCast(e, Int4::getType());
5573 storeValue(f);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005574 }
5575
Nicolas Capenscb986762017-01-20 11:34:37 -05005576 Int4::Int4(RValue<SByte4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005577 {
Nicolas Capensd4227962016-11-09 14:24:25 -05005578 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
5579 Value *a = Nucleus::createInsertElement(loadValue(), x, 0);
5580
Nicolas Capensd4227962016-11-09 14:24:25 -05005581 int swizzle[16] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7};
5582 Value *b = Nucleus::createBitCast(a, Byte16::getType());
5583 Value *c = Nucleus::createShuffleVector(b, b, swizzle);
5584
5585 int swizzle2[8] = {0, 0, 1, 1, 2, 2, 3, 3};
5586 Value *d = Nucleus::createBitCast(c, Short8::getType());
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005587 Value *e = Nucleus::createShuffleVector(d, d, swizzle2);
Nicolas Capensd4227962016-11-09 14:24:25 -05005588
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005589 *this = As<Int4>(e) >> 24;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005590 }
5591
Nicolas Capenscb986762017-01-20 11:34:37 -05005592 Int4::Int4(RValue<Float4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005593 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005594 Value *xyzw = Nucleus::createFPToSI(cast.value, Int4::getType());
5595
5596 storeValue(xyzw);
5597 }
5598
Nicolas Capenscb986762017-01-20 11:34:37 -05005599 Int4::Int4(RValue<Short4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005600 {
Nicolas Capensd4227962016-11-09 14:24:25 -05005601 int swizzle[8] = {0, 0, 1, 1, 2, 2, 3, 3};
5602 Value *c = Nucleus::createShuffleVector(cast.value, cast.value, swizzle);
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005603
5604 *this = As<Int4>(c) >> 16;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005605 }
5606
Nicolas Capenscb986762017-01-20 11:34:37 -05005607 Int4::Int4(RValue<UShort4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005608 {
Nicolas Capensd4227962016-11-09 14:24:25 -05005609 int swizzle[8] = {0, 8, 1, 9, 2, 10, 3, 11};
5610 Value *c = Nucleus::createShuffleVector(cast.value, Short8(0, 0, 0, 0, 0, 0, 0, 0).loadValue(), swizzle);
5611 Value *d = Nucleus::createBitCast(c, Int4::getType());
5612 storeValue(d);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005613 }
5614
Nicolas Capenscb986762017-01-20 11:34:37 -05005615 Int4::Int4(int xyzw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005616 {
5617 constant(xyzw, xyzw, xyzw, xyzw);
5618 }
5619
Nicolas Capenscb986762017-01-20 11:34:37 -05005620 Int4::Int4(int x, int yzw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005621 {
5622 constant(x, yzw, yzw, yzw);
5623 }
5624
Nicolas Capenscb986762017-01-20 11:34:37 -05005625 Int4::Int4(int x, int y, int zw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005626 {
5627 constant(x, y, zw, zw);
5628 }
5629
Nicolas Capenscb986762017-01-20 11:34:37 -05005630 Int4::Int4(int x, int y, int z, int w) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005631 {
5632 constant(x, y, z, w);
5633 }
5634
5635 void Int4::constant(int x, int y, int z, int w)
5636 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04005637 int64_t constantVector[4] = {x, y, z, w};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04005638 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005639 }
5640
Nicolas Capenscb986762017-01-20 11:34:37 -05005641 Int4::Int4(RValue<Int4> rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005642 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005643 storeValue(rhs.value);
5644 }
5645
Nicolas Capenscb986762017-01-20 11:34:37 -05005646 Int4::Int4(const Int4 &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005647 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005648 Value *value = rhs.loadValue();
5649 storeValue(value);
5650 }
5651
Nicolas Capenscb986762017-01-20 11:34:37 -05005652 Int4::Int4(const Reference<Int4> &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005653 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005654 Value *value = rhs.loadValue();
5655 storeValue(value);
5656 }
5657
Nicolas Capenscb986762017-01-20 11:34:37 -05005658 Int4::Int4(RValue<UInt4> rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005659 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005660 storeValue(rhs.value);
5661 }
5662
Nicolas Capenscb986762017-01-20 11:34:37 -05005663 Int4::Int4(const UInt4 &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005664 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005665 Value *value = rhs.loadValue();
5666 storeValue(value);
5667 }
5668
Nicolas Capenscb986762017-01-20 11:34:37 -05005669 Int4::Int4(const Reference<UInt4> &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005670 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005671 Value *value = rhs.loadValue();
5672 storeValue(value);
5673 }
5674
Nicolas Capenscb986762017-01-20 11:34:37 -05005675 Int4::Int4(RValue<Int2> lo, RValue<Int2> hi) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005676 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05005677 int shuffle[4] = {0, 1, 4, 5}; // Real type is v4i32
5678 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
5679
5680 storeValue(packed);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005681 }
5682
Nicolas Capenscb986762017-01-20 11:34:37 -05005683 Int4::Int4(RValue<Int> rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005684 {
Nicolas Capensf8beb4b2017-01-27 02:55:44 -08005685 Value *vector = Nucleus::createBitCast(rhs.value, Int4::getType());
Nicolas Capensd4227962016-11-09 14:24:25 -05005686
5687 int swizzle[4] = {0, 0, 0, 0};
Nicolas Capensf8beb4b2017-01-27 02:55:44 -08005688 Value *replicate = Nucleus::createShuffleVector(vector, vector, swizzle);
Nicolas Capensd4227962016-11-09 14:24:25 -05005689
5690 storeValue(replicate);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005691 }
5692
Nicolas Capenscb986762017-01-20 11:34:37 -05005693 Int4::Int4(const Int &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005694 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005695 *this = RValue<Int>(rhs.loadValue());
5696 }
5697
Nicolas Capenscb986762017-01-20 11:34:37 -05005698 Int4::Int4(const Reference<Int> &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005699 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005700 *this = RValue<Int>(rhs.loadValue());
5701 }
5702
Nicolas Capens96d4e092016-11-18 14:22:38 -05005703 RValue<Int4> Int4::operator=(RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005704 {
5705 storeValue(rhs.value);
5706
5707 return rhs;
5708 }
5709
Nicolas Capens96d4e092016-11-18 14:22:38 -05005710 RValue<Int4> Int4::operator=(const Int4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005711 {
5712 Value *value = rhs.loadValue();
5713 storeValue(value);
5714
5715 return RValue<Int4>(value);
5716 }
5717
Nicolas Capens96d4e092016-11-18 14:22:38 -05005718 RValue<Int4> Int4::operator=(const Reference<Int4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005719 {
5720 Value *value = rhs.loadValue();
5721 storeValue(value);
5722
5723 return RValue<Int4>(value);
5724 }
5725
5726 RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs)
5727 {
5728 return RValue<Int4>(Nucleus::createAdd(lhs.value, rhs.value));
5729 }
5730
5731 RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs)
5732 {
5733 return RValue<Int4>(Nucleus::createSub(lhs.value, rhs.value));
5734 }
5735
5736 RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs)
5737 {
5738 return RValue<Int4>(Nucleus::createMul(lhs.value, rhs.value));
5739 }
5740
5741 RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs)
5742 {
5743 return RValue<Int4>(Nucleus::createSDiv(lhs.value, rhs.value));
5744 }
5745
5746 RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs)
5747 {
5748 return RValue<Int4>(Nucleus::createSRem(lhs.value, rhs.value));
5749 }
5750
5751 RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs)
5752 {
5753 return RValue<Int4>(Nucleus::createAnd(lhs.value, rhs.value));
5754 }
5755
5756 RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs)
5757 {
5758 return RValue<Int4>(Nucleus::createOr(lhs.value, rhs.value));
5759 }
5760
5761 RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs)
5762 {
5763 return RValue<Int4>(Nucleus::createXor(lhs.value, rhs.value));
5764 }
5765
5766 RValue<Int4> operator<<(RValue<Int4> lhs, unsigned char rhs)
5767 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005768 if(emulateIntrinsics)
5769 {
5770 Int4 result;
5771 result = Insert(result, Extract(lhs, 0) << Int(rhs), 0);
5772 result = Insert(result, Extract(lhs, 1) << Int(rhs), 1);
5773 result = Insert(result, Extract(lhs, 2) << Int(rhs), 2);
5774 result = Insert(result, Extract(lhs, 3) << Int(rhs), 3);
5775
5776 return result;
5777 }
5778 else
5779 {
5780 return RValue<Int4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
5781 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005782 }
5783
5784 RValue<Int4> operator>>(RValue<Int4> lhs, unsigned char rhs)
5785 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005786 if(emulateIntrinsics)
5787 {
5788 Int4 result;
5789 result = Insert(result, Extract(lhs, 0) >> Int(rhs), 0);
5790 result = Insert(result, Extract(lhs, 1) >> Int(rhs), 1);
5791 result = Insert(result, Extract(lhs, 2) >> Int(rhs), 2);
5792 result = Insert(result, Extract(lhs, 3) >> Int(rhs), 3);
5793
5794 return result;
5795 }
5796 else
5797 {
5798 return RValue<Int4>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
5799 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005800 }
5801
5802 RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs)
5803 {
5804 return RValue<Int4>(Nucleus::createShl(lhs.value, rhs.value));
5805 }
5806
5807 RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs)
5808 {
5809 return RValue<Int4>(Nucleus::createAShr(lhs.value, rhs.value));
5810 }
5811
Nicolas Capens96d4e092016-11-18 14:22:38 -05005812 RValue<Int4> operator+=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005813 {
5814 return lhs = lhs + rhs;
5815 }
5816
Nicolas Capens96d4e092016-11-18 14:22:38 -05005817 RValue<Int4> operator-=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005818 {
5819 return lhs = lhs - rhs;
5820 }
5821
Nicolas Capens96d4e092016-11-18 14:22:38 -05005822 RValue<Int4> operator*=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005823 {
5824 return lhs = lhs * rhs;
5825 }
5826
Nicolas Capens96d4e092016-11-18 14:22:38 -05005827// RValue<Int4> operator/=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005828// {
5829// return lhs = lhs / rhs;
5830// }
5831
Nicolas Capens96d4e092016-11-18 14:22:38 -05005832// RValue<Int4> operator%=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005833// {
5834// return lhs = lhs % rhs;
5835// }
5836
Nicolas Capens96d4e092016-11-18 14:22:38 -05005837 RValue<Int4> operator&=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005838 {
5839 return lhs = lhs & rhs;
5840 }
5841
Nicolas Capens96d4e092016-11-18 14:22:38 -05005842 RValue<Int4> operator|=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005843 {
5844 return lhs = lhs | rhs;
5845 }
5846
Nicolas Capens96d4e092016-11-18 14:22:38 -05005847 RValue<Int4> operator^=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005848 {
5849 return lhs = lhs ^ rhs;
5850 }
5851
Nicolas Capens96d4e092016-11-18 14:22:38 -05005852 RValue<Int4> operator<<=(Int4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005853 {
5854 return lhs = lhs << rhs;
5855 }
5856
Nicolas Capens96d4e092016-11-18 14:22:38 -05005857 RValue<Int4> operator>>=(Int4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005858 {
5859 return lhs = lhs >> rhs;
5860 }
5861
5862 RValue<Int4> operator+(RValue<Int4> val)
5863 {
5864 return val;
5865 }
5866
5867 RValue<Int4> operator-(RValue<Int4> val)
5868 {
5869 return RValue<Int4>(Nucleus::createNeg(val.value));
5870 }
5871
5872 RValue<Int4> operator~(RValue<Int4> val)
5873 {
5874 return RValue<Int4>(Nucleus::createNot(val.value));
5875 }
5876
5877 RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y)
5878 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005879 return RValue<Int4>(Nucleus::createICmpEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005880 }
5881
5882 RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y)
5883 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005884 return RValue<Int4>(Nucleus::createICmpSLT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005885 }
5886
5887 RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y)
5888 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005889 return RValue<Int4>(Nucleus::createICmpSLE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005890 }
5891
5892 RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y)
5893 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005894 return RValue<Int4>(Nucleus::createICmpNE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005895 }
5896
5897 RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y)
5898 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005899 return RValue<Int4>(Nucleus::createICmpSGE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005900 }
5901
5902 RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y)
5903 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005904 return RValue<Int4>(Nucleus::createICmpSGT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005905 }
5906
5907 RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y)
5908 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04005909 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
5910 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sle, condition, x.value, y.value);
5911 ::basicBlock->appendInst(cmp);
5912
5913 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5914 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
5915 ::basicBlock->appendInst(select);
5916
5917 return RValue<Int4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005918 }
5919
5920 RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y)
5921 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04005922 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
5923 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sgt, condition, x.value, y.value);
5924 ::basicBlock->appendInst(cmp);
5925
5926 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5927 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
5928 ::basicBlock->appendInst(select);
5929
5930 return RValue<Int4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005931 }
5932
5933 RValue<Int4> RoundInt(RValue<Float4> cast)
5934 {
Nicolas Capens091f3502017-10-03 14:56:49 -04005935 if(emulateIntrinsics || CPUID::ARM)
Nicolas Capensf7b75882017-04-26 09:30:47 -04005936 {
5937 // Push the fractional part off the mantissa. Accurate up to +/-2^22.
5938 return Int4((cast + Float4(0x00C00000)) - Float4(0x00C00000));
5939 }
5940 else
5941 {
5942 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5943 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Nearbyint, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5944 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5945 auto nearbyint = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
5946 nearbyint->addArg(cast.value);
5947 ::basicBlock->appendInst(nearbyint);
Nicolas Capensa8086512016-11-07 17:32:17 -05005948
Nicolas Capensf7b75882017-04-26 09:30:47 -04005949 return RValue<Int4>(V(result));
5950 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005951 }
5952
Nicolas Capens33438a62017-09-27 11:47:35 -04005953 RValue<Short8> PackSigned(RValue<Int4> x, RValue<Int4> y)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005954 {
Nicolas Capens8960fbf2017-07-25 15:32:12 -04005955 if(emulateIntrinsics)
5956 {
5957 Short8 result;
Nicolas Capens33438a62017-09-27 11:47:35 -04005958 result = Insert(result, SaturateSigned(Extract(x, 0)), 0);
5959 result = Insert(result, SaturateSigned(Extract(x, 1)), 1);
5960 result = Insert(result, SaturateSigned(Extract(x, 2)), 2);
5961 result = Insert(result, SaturateSigned(Extract(x, 3)), 3);
5962 result = Insert(result, SaturateSigned(Extract(y, 0)), 4);
5963 result = Insert(result, SaturateSigned(Extract(y, 1)), 5);
5964 result = Insert(result, SaturateSigned(Extract(y, 2)), 6);
5965 result = Insert(result, SaturateSigned(Extract(y, 3)), 7);
Nicolas Capensec54a172016-10-25 17:32:37 -04005966
Nicolas Capens8960fbf2017-07-25 15:32:12 -04005967 return result;
5968 }
5969 else
5970 {
5971 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
5972 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5973 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5974 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
5975 pack->addArg(x.value);
5976 pack->addArg(y.value);
5977 ::basicBlock->appendInst(pack);
5978
5979 return RValue<Short8>(V(result));
5980 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005981 }
5982
Nicolas Capens33438a62017-09-27 11:47:35 -04005983 RValue<UShort8> PackUnsigned(RValue<Int4> x, RValue<Int4> y)
5984 {
Nicolas Capens091f3502017-10-03 14:56:49 -04005985 if(emulateIntrinsics || !(CPUID::SSE4_1 || CPUID::ARM))
5986 {
5987 RValue<Int4> sx = As<Int4>(x);
5988 RValue<Int4> bx = (sx & ~(sx >> 31)) - Int4(0x8000);
5989
5990 RValue<Int4> sy = As<Int4>(y);
5991 RValue<Int4> by = (sy & ~(sy >> 31)) - Int4(0x8000);
5992
5993 return As<UShort8>(PackSigned(bx, by) + Short8(0x8000u));
5994 }
5995 else
Nicolas Capens33438a62017-09-27 11:47:35 -04005996 {
5997 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
5998 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5999 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6000 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
6001 pack->addArg(x.value);
6002 pack->addArg(y.value);
6003 ::basicBlock->appendInst(pack);
6004
6005 return RValue<UShort8>(V(result));
6006 }
Nicolas Capens33438a62017-09-27 11:47:35 -04006007 }
6008
Nicolas Capens598f8d82016-09-26 15:09:10 -04006009 RValue<Int> Extract(RValue<Int4> x, int i)
6010 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006011 return RValue<Int>(Nucleus::createExtractElement(x.value, Int::getType(), i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006012 }
6013
6014 RValue<Int4> Insert(RValue<Int4> x, RValue<Int> element, int i)
6015 {
6016 return RValue<Int4>(Nucleus::createInsertElement(x.value, element.value, i));
6017 }
6018
6019 RValue<Int> SignMask(RValue<Int4> x)
6020 {
Nicolas Capens091f3502017-10-03 14:56:49 -04006021 if(emulateIntrinsics || CPUID::ARM)
Nicolas Capensd6cacad2017-07-25 15:32:12 -04006022 {
6023 Int4 xx = (x >> 31) & Int4(0x00000001, 0x00000002, 0x00000004, 0x00000008);
6024 return Extract(xx, 0) | Extract(xx, 1) | Extract(xx, 2) | Extract(xx, 3);
6025 }
6026 else
6027 {
6028 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
6029 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6030 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6031 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
6032 movmsk->addArg(x.value);
6033 ::basicBlock->appendInst(movmsk);
Nicolas Capensf2cb9df2016-10-21 17:26:13 -04006034
Nicolas Capensd6cacad2017-07-25 15:32:12 -04006035 return RValue<Int>(V(result));
6036 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04006037 }
6038
6039 RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select)
6040 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006041 return RValue<Int4>(createSwizzle4(x.value, select));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006042 }
6043
6044 Type *Int4::getType()
6045 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04006046 return T(Ice::IceType_v4i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006047 }
6048
Nicolas Capenscb986762017-01-20 11:34:37 -05006049 UInt4::UInt4() : XYZW(this)
6050 {
6051 }
6052
6053 UInt4::UInt4(RValue<Float4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006054 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05006055 // Smallest positive value representable in UInt, but not in Int
6056 const unsigned int ustart = 0x80000000u;
6057 const float ustartf = float(ustart);
6058
6059 // Check if the value can be represented as an Int
6060 Int4 uiValue = CmpNLT(cast, Float4(ustartf));
6061 // If the value is too large, subtract ustart and re-add it after conversion.
6062 uiValue = (uiValue & As<Int4>(As<UInt4>(Int4(cast - Float4(ustartf))) + UInt4(ustart))) |
6063 // Otherwise, just convert normally
6064 (~uiValue & Int4(cast));
6065 // If the value is negative, store 0, otherwise store the result of the conversion
6066 storeValue((~(As<Int4>(cast) >> 31) & uiValue).value);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006067 }
6068
Nicolas Capenscb986762017-01-20 11:34:37 -05006069 UInt4::UInt4(int xyzw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006070 {
6071 constant(xyzw, xyzw, xyzw, xyzw);
6072 }
6073
Nicolas Capenscb986762017-01-20 11:34:37 -05006074 UInt4::UInt4(int x, int yzw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006075 {
6076 constant(x, yzw, yzw, yzw);
6077 }
6078
Nicolas Capenscb986762017-01-20 11:34:37 -05006079 UInt4::UInt4(int x, int y, int zw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006080 {
6081 constant(x, y, zw, zw);
6082 }
6083
Nicolas Capenscb986762017-01-20 11:34:37 -05006084 UInt4::UInt4(int x, int y, int z, int w) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006085 {
6086 constant(x, y, z, w);
6087 }
6088
6089 void UInt4::constant(int x, int y, int z, int w)
6090 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04006091 int64_t constantVector[4] = {x, y, z, w};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04006092 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006093 }
6094
Nicolas Capenscb986762017-01-20 11:34:37 -05006095 UInt4::UInt4(RValue<UInt4> rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006096 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006097 storeValue(rhs.value);
6098 }
6099
Nicolas Capenscb986762017-01-20 11:34:37 -05006100 UInt4::UInt4(const UInt4 &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006101 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006102 Value *value = rhs.loadValue();
6103 storeValue(value);
6104 }
6105
Nicolas Capenscb986762017-01-20 11:34:37 -05006106 UInt4::UInt4(const Reference<UInt4> &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006107 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006108 Value *value = rhs.loadValue();
6109 storeValue(value);
6110 }
6111
Nicolas Capenscb986762017-01-20 11:34:37 -05006112 UInt4::UInt4(RValue<Int4> rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006113 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006114 storeValue(rhs.value);
6115 }
6116
Nicolas Capenscb986762017-01-20 11:34:37 -05006117 UInt4::UInt4(const Int4 &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006118 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006119 Value *value = rhs.loadValue();
6120 storeValue(value);
6121 }
6122
Nicolas Capenscb986762017-01-20 11:34:37 -05006123 UInt4::UInt4(const Reference<Int4> &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006124 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006125 Value *value = rhs.loadValue();
6126 storeValue(value);
6127 }
6128
Nicolas Capenscb986762017-01-20 11:34:37 -05006129 UInt4::UInt4(RValue<UInt2> lo, RValue<UInt2> hi) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006130 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05006131 int shuffle[4] = {0, 1, 4, 5}; // Real type is v4i32
6132 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
6133
6134 storeValue(packed);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006135 }
6136
Nicolas Capens96d4e092016-11-18 14:22:38 -05006137 RValue<UInt4> UInt4::operator=(RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006138 {
6139 storeValue(rhs.value);
6140
6141 return rhs;
6142 }
6143
Nicolas Capens96d4e092016-11-18 14:22:38 -05006144 RValue<UInt4> UInt4::operator=(const UInt4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006145 {
6146 Value *value = rhs.loadValue();
6147 storeValue(value);
6148
6149 return RValue<UInt4>(value);
6150 }
6151
Nicolas Capens96d4e092016-11-18 14:22:38 -05006152 RValue<UInt4> UInt4::operator=(const Reference<UInt4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006153 {
6154 Value *value = rhs.loadValue();
6155 storeValue(value);
6156
6157 return RValue<UInt4>(value);
6158 }
6159
6160 RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs)
6161 {
6162 return RValue<UInt4>(Nucleus::createAdd(lhs.value, rhs.value));
6163 }
6164
6165 RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs)
6166 {
6167 return RValue<UInt4>(Nucleus::createSub(lhs.value, rhs.value));
6168 }
6169
6170 RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs)
6171 {
6172 return RValue<UInt4>(Nucleus::createMul(lhs.value, rhs.value));
6173 }
6174
6175 RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs)
6176 {
6177 return RValue<UInt4>(Nucleus::createUDiv(lhs.value, rhs.value));
6178 }
6179
6180 RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs)
6181 {
6182 return RValue<UInt4>(Nucleus::createURem(lhs.value, rhs.value));
6183 }
6184
6185 RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs)
6186 {
6187 return RValue<UInt4>(Nucleus::createAnd(lhs.value, rhs.value));
6188 }
6189
6190 RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs)
6191 {
6192 return RValue<UInt4>(Nucleus::createOr(lhs.value, rhs.value));
6193 }
6194
6195 RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs)
6196 {
6197 return RValue<UInt4>(Nucleus::createXor(lhs.value, rhs.value));
6198 }
6199
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04006200 RValue<UInt> Extract(RValue<UInt4> x, int i)
6201 {
6202 return RValue<UInt>(Nucleus::createExtractElement(x.value, UInt::getType(), i));
6203 }
6204
6205 RValue<UInt4> Insert(RValue<UInt4> x, RValue<UInt> element, int i)
6206 {
6207 return RValue<UInt4>(Nucleus::createInsertElement(x.value, element.value, i));
6208 }
6209
Nicolas Capens598f8d82016-09-26 15:09:10 -04006210 RValue<UInt4> operator<<(RValue<UInt4> lhs, unsigned char rhs)
6211 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04006212 if(emulateIntrinsics)
6213 {
6214 UInt4 result;
6215 result = Insert(result, Extract(lhs, 0) << UInt(rhs), 0);
6216 result = Insert(result, Extract(lhs, 1) << UInt(rhs), 1);
6217 result = Insert(result, Extract(lhs, 2) << UInt(rhs), 2);
6218 result = Insert(result, Extract(lhs, 3) << UInt(rhs), 3);
6219
6220 return result;
6221 }
6222 else
6223 {
6224 return RValue<UInt4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
6225 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04006226 }
6227
6228 RValue<UInt4> operator>>(RValue<UInt4> lhs, unsigned char rhs)
6229 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04006230 if(emulateIntrinsics)
6231 {
6232 UInt4 result;
6233 result = Insert(result, Extract(lhs, 0) >> UInt(rhs), 0);
6234 result = Insert(result, Extract(lhs, 1) >> UInt(rhs), 1);
6235 result = Insert(result, Extract(lhs, 2) >> UInt(rhs), 2);
6236 result = Insert(result, Extract(lhs, 3) >> UInt(rhs), 3);
6237
6238 return result;
6239 }
6240 else
6241 {
6242 return RValue<UInt4>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
6243 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04006244 }
6245
6246 RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs)
6247 {
6248 return RValue<UInt4>(Nucleus::createShl(lhs.value, rhs.value));
6249 }
6250
6251 RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs)
6252 {
6253 return RValue<UInt4>(Nucleus::createLShr(lhs.value, rhs.value));
6254 }
6255
Nicolas Capens96d4e092016-11-18 14:22:38 -05006256 RValue<UInt4> operator+=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006257 {
6258 return lhs = lhs + rhs;
6259 }
6260
Nicolas Capens96d4e092016-11-18 14:22:38 -05006261 RValue<UInt4> operator-=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006262 {
6263 return lhs = lhs - rhs;
6264 }
6265
Nicolas Capens96d4e092016-11-18 14:22:38 -05006266 RValue<UInt4> operator*=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006267 {
6268 return lhs = lhs * rhs;
6269 }
6270
Nicolas Capens96d4e092016-11-18 14:22:38 -05006271// RValue<UInt4> operator/=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006272// {
6273// return lhs = lhs / rhs;
6274// }
6275
Nicolas Capens96d4e092016-11-18 14:22:38 -05006276// RValue<UInt4> operator%=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006277// {
6278// return lhs = lhs % rhs;
6279// }
6280
Nicolas Capens96d4e092016-11-18 14:22:38 -05006281 RValue<UInt4> operator&=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006282 {
6283 return lhs = lhs & rhs;
6284 }
6285
Nicolas Capens96d4e092016-11-18 14:22:38 -05006286 RValue<UInt4> operator|=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006287 {
6288 return lhs = lhs | rhs;
6289 }
6290
Nicolas Capens96d4e092016-11-18 14:22:38 -05006291 RValue<UInt4> operator^=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006292 {
6293 return lhs = lhs ^ rhs;
6294 }
6295
Nicolas Capens96d4e092016-11-18 14:22:38 -05006296 RValue<UInt4> operator<<=(UInt4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006297 {
6298 return lhs = lhs << rhs;
6299 }
6300
Nicolas Capens96d4e092016-11-18 14:22:38 -05006301 RValue<UInt4> operator>>=(UInt4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006302 {
6303 return lhs = lhs >> rhs;
6304 }
6305
6306 RValue<UInt4> operator+(RValue<UInt4> val)
6307 {
6308 return val;
6309 }
6310
6311 RValue<UInt4> operator-(RValue<UInt4> val)
6312 {
6313 return RValue<UInt4>(Nucleus::createNeg(val.value));
6314 }
6315
6316 RValue<UInt4> operator~(RValue<UInt4> val)
6317 {
6318 return RValue<UInt4>(Nucleus::createNot(val.value));
6319 }
6320
6321 RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y)
6322 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006323 return RValue<UInt4>(Nucleus::createICmpEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006324 }
6325
6326 RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y)
6327 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006328 return RValue<UInt4>(Nucleus::createICmpULT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006329 }
6330
6331 RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y)
6332 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006333 return RValue<UInt4>(Nucleus::createICmpULE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006334 }
6335
6336 RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y)
6337 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006338 return RValue<UInt4>(Nucleus::createICmpNE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006339 }
6340
6341 RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y)
6342 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006343 return RValue<UInt4>(Nucleus::createICmpUGE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006344 }
6345
6346 RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y)
6347 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006348 return RValue<UInt4>(Nucleus::createICmpUGT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006349 }
6350
6351 RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y)
6352 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006353 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
6354 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ule, condition, x.value, y.value);
6355 ::basicBlock->appendInst(cmp);
6356
6357 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
6358 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
6359 ::basicBlock->appendInst(select);
6360
6361 return RValue<UInt4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006362 }
6363
6364 RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y)
6365 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006366 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
6367 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ugt, condition, x.value, y.value);
6368 ::basicBlock->appendInst(cmp);
6369
6370 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
6371 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
6372 ::basicBlock->appendInst(select);
6373
6374 return RValue<UInt4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006375 }
6376
Nicolas Capens598f8d82016-09-26 15:09:10 -04006377 Type *UInt4::getType()
6378 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04006379 return T(Ice::IceType_v4i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006380 }
6381
6382 Float::Float(RValue<Int> cast)
6383 {
6384 Value *integer = Nucleus::createSIToFP(cast.value, Float::getType());
6385
6386 storeValue(integer);
6387 }
6388
Alexis Hetucfd96322017-07-24 14:44:33 -04006389 Float::Float(RValue<UInt> cast)
6390 {
6391 RValue<Float> result = Float(Int(cast & UInt(0x7FFFFFFF))) +
6392 As<Float>((As<Int>(cast) >> 31) & As<Int>(Float(0x80000000u)));
6393
6394 storeValue(result.value);
6395 }
6396
Nicolas Capens598f8d82016-09-26 15:09:10 -04006397 Float::Float(float x)
6398 {
6399 storeValue(Nucleus::createConstantFloat(x));
6400 }
6401
6402 Float::Float(RValue<Float> rhs)
6403 {
6404 storeValue(rhs.value);
6405 }
6406
6407 Float::Float(const Float &rhs)
6408 {
6409 Value *value = rhs.loadValue();
6410 storeValue(value);
6411 }
6412
6413 Float::Float(const Reference<Float> &rhs)
6414 {
6415 Value *value = rhs.loadValue();
6416 storeValue(value);
6417 }
6418
Nicolas Capens96d4e092016-11-18 14:22:38 -05006419 RValue<Float> Float::operator=(RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006420 {
6421 storeValue(rhs.value);
6422
6423 return rhs;
6424 }
6425
Nicolas Capens96d4e092016-11-18 14:22:38 -05006426 RValue<Float> Float::operator=(const Float &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006427 {
6428 Value *value = rhs.loadValue();
6429 storeValue(value);
6430
6431 return RValue<Float>(value);
6432 }
6433
Nicolas Capens96d4e092016-11-18 14:22:38 -05006434 RValue<Float> Float::operator=(const Reference<Float> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006435 {
6436 Value *value = rhs.loadValue();
6437 storeValue(value);
6438
6439 return RValue<Float>(value);
6440 }
6441
6442 RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs)
6443 {
6444 return RValue<Float>(Nucleus::createFAdd(lhs.value, rhs.value));
6445 }
6446
6447 RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs)
6448 {
6449 return RValue<Float>(Nucleus::createFSub(lhs.value, rhs.value));
6450 }
6451
6452 RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs)
6453 {
6454 return RValue<Float>(Nucleus::createFMul(lhs.value, rhs.value));
6455 }
6456
6457 RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs)
6458 {
6459 return RValue<Float>(Nucleus::createFDiv(lhs.value, rhs.value));
6460 }
6461
Nicolas Capens96d4e092016-11-18 14:22:38 -05006462 RValue<Float> operator+=(Float &lhs, RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006463 {
6464 return lhs = lhs + rhs;
6465 }
6466
Nicolas Capens96d4e092016-11-18 14:22:38 -05006467 RValue<Float> operator-=(Float &lhs, RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006468 {
6469 return lhs = lhs - rhs;
6470 }
6471
Nicolas Capens96d4e092016-11-18 14:22:38 -05006472 RValue<Float> operator*=(Float &lhs, RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006473 {
6474 return lhs = lhs * rhs;
6475 }
6476
Nicolas Capens96d4e092016-11-18 14:22:38 -05006477 RValue<Float> operator/=(Float &lhs, RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006478 {
6479 return lhs = lhs / rhs;
6480 }
6481
6482 RValue<Float> operator+(RValue<Float> val)
6483 {
6484 return val;
6485 }
6486
6487 RValue<Float> operator-(RValue<Float> val)
6488 {
6489 return RValue<Float>(Nucleus::createFNeg(val.value));
6490 }
6491
6492 RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs)
6493 {
6494 return RValue<Bool>(Nucleus::createFCmpOLT(lhs.value, rhs.value));
6495 }
6496
6497 RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs)
6498 {
6499 return RValue<Bool>(Nucleus::createFCmpOLE(lhs.value, rhs.value));
6500 }
6501
6502 RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs)
6503 {
6504 return RValue<Bool>(Nucleus::createFCmpOGT(lhs.value, rhs.value));
6505 }
6506
6507 RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs)
6508 {
6509 return RValue<Bool>(Nucleus::createFCmpOGE(lhs.value, rhs.value));
6510 }
6511
6512 RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs)
6513 {
6514 return RValue<Bool>(Nucleus::createFCmpONE(lhs.value, rhs.value));
6515 }
6516
6517 RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs)
6518 {
6519 return RValue<Bool>(Nucleus::createFCmpOEQ(lhs.value, rhs.value));
6520 }
6521
6522 RValue<Float> Abs(RValue<Float> x)
6523 {
6524 return IfThenElse(x > 0.0f, x, -x);
6525 }
6526
6527 RValue<Float> Max(RValue<Float> x, RValue<Float> y)
6528 {
6529 return IfThenElse(x > y, x, y);
6530 }
6531
6532 RValue<Float> Min(RValue<Float> x, RValue<Float> y)
6533 {
6534 return IfThenElse(x < y, x, y);
6535 }
6536
6537 RValue<Float> Rcp_pp(RValue<Float> x, bool exactAtPow2)
6538 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04006539 return 1.0f / x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04006540 }
6541
6542 RValue<Float> RcpSqrt_pp(RValue<Float> x)
6543 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04006544 return Rcp_pp(Sqrt(x));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006545 }
6546
6547 RValue<Float> Sqrt(RValue<Float> x)
6548 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04006549 Ice::Variable *result = ::function->makeVariable(Ice::IceType_f32);
6550 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Sqrt, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6551 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6552 auto sqrt = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
6553 sqrt->addArg(x.value);
6554 ::basicBlock->appendInst(sqrt);
6555
6556 return RValue<Float>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006557 }
6558
6559 RValue<Float> Round(RValue<Float> x)
6560 {
Nicolas Capensa8086512016-11-07 17:32:17 -05006561 return Float4(Round(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04006562 }
6563
6564 RValue<Float> Trunc(RValue<Float> x)
6565 {
Nicolas Capensa8086512016-11-07 17:32:17 -05006566 return Float4(Trunc(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04006567 }
6568
6569 RValue<Float> Frac(RValue<Float> x)
6570 {
Nicolas Capensa8086512016-11-07 17:32:17 -05006571 return Float4(Frac(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04006572 }
6573
6574 RValue<Float> Floor(RValue<Float> x)
6575 {
Nicolas Capensa8086512016-11-07 17:32:17 -05006576 return Float4(Floor(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04006577 }
6578
6579 RValue<Float> Ceil(RValue<Float> x)
6580 {
Nicolas Capensa8086512016-11-07 17:32:17 -05006581 return Float4(Ceil(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04006582 }
6583
6584 Type *Float::getType()
6585 {
Nicolas Capens9709d4f2016-09-30 11:44:14 -04006586 return T(Ice::IceType_f32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006587 }
6588
6589 Float2::Float2(RValue<Float4> cast)
6590 {
Nicolas Capens22008782016-10-20 01:11:47 -04006591 storeValue(Nucleus::createBitCast(cast.value, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006592 }
6593
6594 Type *Float2::getType()
6595 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04006596 return T(Type_v2f32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006597 }
6598
Nicolas Capenscb986762017-01-20 11:34:37 -05006599 Float4::Float4(RValue<Byte4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006600 {
Nicolas Capensd4227962016-11-09 14:24:25 -05006601 Value *a = Int4(cast).loadValue();
6602 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
6603
6604 storeValue(xyzw);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006605 }
6606
Nicolas Capenscb986762017-01-20 11:34:37 -05006607 Float4::Float4(RValue<SByte4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006608 {
Nicolas Capensd4227962016-11-09 14:24:25 -05006609 Value *a = Int4(cast).loadValue();
6610 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
6611
6612 storeValue(xyzw);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006613 }
6614
Nicolas Capenscb986762017-01-20 11:34:37 -05006615 Float4::Float4(RValue<Short4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006616 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006617 Int4 c(cast);
6618 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
6619 }
6620
Nicolas Capenscb986762017-01-20 11:34:37 -05006621 Float4::Float4(RValue<UShort4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006622 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006623 Int4 c(cast);
6624 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
6625 }
6626
Nicolas Capenscb986762017-01-20 11:34:37 -05006627 Float4::Float4(RValue<Int4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006628 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006629 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType());
6630
6631 storeValue(xyzw);
6632 }
6633
Nicolas Capenscb986762017-01-20 11:34:37 -05006634 Float4::Float4(RValue<UInt4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006635 {
Nicolas Capens96445fe2016-12-15 14:45:13 -05006636 RValue<Float4> result = Float4(Int4(cast & UInt4(0x7FFFFFFF))) +
6637 As<Float4>((As<Int4>(cast) >> 31) & As<Int4>(Float4(0x80000000u)));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006638
Nicolas Capens96445fe2016-12-15 14:45:13 -05006639 storeValue(result.value);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006640 }
6641
Nicolas Capenscb986762017-01-20 11:34:37 -05006642 Float4::Float4() : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006643 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006644 }
6645
Nicolas Capenscb986762017-01-20 11:34:37 -05006646 Float4::Float4(float xyzw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006647 {
6648 constant(xyzw, xyzw, xyzw, xyzw);
6649 }
6650
Nicolas Capenscb986762017-01-20 11:34:37 -05006651 Float4::Float4(float x, float yzw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006652 {
6653 constant(x, yzw, yzw, yzw);
6654 }
6655
Nicolas Capenscb986762017-01-20 11:34:37 -05006656 Float4::Float4(float x, float y, float zw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006657 {
6658 constant(x, y, zw, zw);
6659 }
6660
Nicolas Capenscb986762017-01-20 11:34:37 -05006661 Float4::Float4(float x, float y, float z, float w) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006662 {
6663 constant(x, y, z, w);
6664 }
6665
6666 void Float4::constant(float x, float y, float z, float w)
6667 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04006668 double constantVector[4] = {x, y, z, w};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04006669 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006670 }
6671
Nicolas Capenscb986762017-01-20 11:34:37 -05006672 Float4::Float4(RValue<Float4> rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006673 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006674 storeValue(rhs.value);
6675 }
6676
Nicolas Capenscb986762017-01-20 11:34:37 -05006677 Float4::Float4(const Float4 &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006678 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006679 Value *value = rhs.loadValue();
6680 storeValue(value);
6681 }
6682
Nicolas Capenscb986762017-01-20 11:34:37 -05006683 Float4::Float4(const Reference<Float4> &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006684 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006685 Value *value = rhs.loadValue();
6686 storeValue(value);
6687 }
6688
Nicolas Capenscb986762017-01-20 11:34:37 -05006689 Float4::Float4(RValue<Float> rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006690 {
Nicolas Capensf8beb4b2017-01-27 02:55:44 -08006691 Value *vector = Nucleus::createBitCast(rhs.value, Float4::getType());
Nicolas Capensd4227962016-11-09 14:24:25 -05006692
6693 int swizzle[4] = {0, 0, 0, 0};
Nicolas Capensf8beb4b2017-01-27 02:55:44 -08006694 Value *replicate = Nucleus::createShuffleVector(vector, vector, swizzle);
Nicolas Capensd4227962016-11-09 14:24:25 -05006695
6696 storeValue(replicate);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006697 }
6698
Nicolas Capenscb986762017-01-20 11:34:37 -05006699 Float4::Float4(const Float &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006700 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006701 *this = RValue<Float>(rhs.loadValue());
6702 }
6703
Nicolas Capenscb986762017-01-20 11:34:37 -05006704 Float4::Float4(const Reference<Float> &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006705 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006706 *this = RValue<Float>(rhs.loadValue());
6707 }
6708
Nicolas Capens96d4e092016-11-18 14:22:38 -05006709 RValue<Float4> Float4::operator=(float x)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006710 {
6711 return *this = Float4(x, x, x, x);
6712 }
6713
Nicolas Capens96d4e092016-11-18 14:22:38 -05006714 RValue<Float4> Float4::operator=(RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006715 {
6716 storeValue(rhs.value);
6717
6718 return rhs;
6719 }
6720
Nicolas Capens96d4e092016-11-18 14:22:38 -05006721 RValue<Float4> Float4::operator=(const Float4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006722 {
6723 Value *value = rhs.loadValue();
6724 storeValue(value);
6725
6726 return RValue<Float4>(value);
6727 }
6728
Nicolas Capens96d4e092016-11-18 14:22:38 -05006729 RValue<Float4> Float4::operator=(const Reference<Float4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006730 {
6731 Value *value = rhs.loadValue();
6732 storeValue(value);
6733
6734 return RValue<Float4>(value);
6735 }
6736
Nicolas Capens96d4e092016-11-18 14:22:38 -05006737 RValue<Float4> Float4::operator=(RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006738 {
6739 return *this = Float4(rhs);
6740 }
6741
Nicolas Capens96d4e092016-11-18 14:22:38 -05006742 RValue<Float4> Float4::operator=(const Float &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006743 {
6744 return *this = Float4(rhs);
6745 }
6746
Nicolas Capens96d4e092016-11-18 14:22:38 -05006747 RValue<Float4> Float4::operator=(const Reference<Float> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006748 {
6749 return *this = Float4(rhs);
6750 }
6751
6752 RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs)
6753 {
6754 return RValue<Float4>(Nucleus::createFAdd(lhs.value, rhs.value));
6755 }
6756
6757 RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs)
6758 {
6759 return RValue<Float4>(Nucleus::createFSub(lhs.value, rhs.value));
6760 }
6761
6762 RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs)
6763 {
6764 return RValue<Float4>(Nucleus::createFMul(lhs.value, rhs.value));
6765 }
6766
6767 RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs)
6768 {
6769 return RValue<Float4>(Nucleus::createFDiv(lhs.value, rhs.value));
6770 }
6771
6772 RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs)
6773 {
6774 return RValue<Float4>(Nucleus::createFRem(lhs.value, rhs.value));
6775 }
6776
Nicolas Capens96d4e092016-11-18 14:22:38 -05006777 RValue<Float4> operator+=(Float4 &lhs, RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006778 {
6779 return lhs = lhs + rhs;
6780 }
6781
Nicolas Capens96d4e092016-11-18 14:22:38 -05006782 RValue<Float4> operator-=(Float4 &lhs, RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006783 {
6784 return lhs = lhs - rhs;
6785 }
6786
Nicolas Capens96d4e092016-11-18 14:22:38 -05006787 RValue<Float4> operator*=(Float4 &lhs, RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006788 {
6789 return lhs = lhs * rhs;
6790 }
6791
Nicolas Capens96d4e092016-11-18 14:22:38 -05006792 RValue<Float4> operator/=(Float4 &lhs, RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006793 {
6794 return lhs = lhs / rhs;
6795 }
6796
Nicolas Capens96d4e092016-11-18 14:22:38 -05006797 RValue<Float4> operator%=(Float4 &lhs, RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006798 {
6799 return lhs = lhs % rhs;
6800 }
6801
6802 RValue<Float4> operator+(RValue<Float4> val)
6803 {
6804 return val;
6805 }
6806
6807 RValue<Float4> operator-(RValue<Float4> val)
6808 {
6809 return RValue<Float4>(Nucleus::createFNeg(val.value));
6810 }
6811
6812 RValue<Float4> Abs(RValue<Float4> x)
6813 {
Nicolas Capens84272242016-11-09 13:31:06 -05006814 Value *vector = Nucleus::createBitCast(x.value, Int4::getType());
6815 int64_t constantVector[4] = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF};
6816 Value *result = Nucleus::createAnd(vector, V(Nucleus::createConstantVector(constantVector, Int4::getType())));
6817
6818 return As<Float4>(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006819 }
6820
6821 RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y)
6822 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006823 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
Nicolas Capens5cdb91a2017-02-13 12:39:18 -05006824 auto cmp = Ice::InstFcmp::create(::function, Ice::InstFcmp::Ogt, condition, x.value, y.value);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006825 ::basicBlock->appendInst(cmp);
6826
6827 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
Nicolas Capens5cdb91a2017-02-13 12:39:18 -05006828 auto select = Ice::InstSelect::create(::function, result, condition, x.value, y.value);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006829 ::basicBlock->appendInst(select);
6830
6831 return RValue<Float4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006832 }
6833
6834 RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y)
6835 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006836 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
Nicolas Capens5cdb91a2017-02-13 12:39:18 -05006837 auto cmp = Ice::InstFcmp::create(::function, Ice::InstFcmp::Olt, condition, x.value, y.value);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006838 ::basicBlock->appendInst(cmp);
6839
6840 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
Nicolas Capens5cdb91a2017-02-13 12:39:18 -05006841 auto select = Ice::InstSelect::create(::function, result, condition, x.value, y.value);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006842 ::basicBlock->appendInst(select);
6843
6844 return RValue<Float4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006845 }
6846
6847 RValue<Float4> Rcp_pp(RValue<Float4> x, bool exactAtPow2)
6848 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04006849 return Float4(1.0f) / x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04006850 }
6851
6852 RValue<Float4> RcpSqrt_pp(RValue<Float4> x)
6853 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04006854 return Rcp_pp(Sqrt(x));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006855 }
6856
6857 RValue<Float4> Sqrt(RValue<Float4> x)
6858 {
Nicolas Capens091f3502017-10-03 14:56:49 -04006859 if(emulateIntrinsics || CPUID::ARM)
Nicolas Capens9f737d32017-07-25 17:26:14 -04006860 {
6861 Float4 result;
6862 result.x = Sqrt(Float(Float4(x).x));
6863 result.y = Sqrt(Float(Float4(x).y));
6864 result.z = Sqrt(Float(Float4(x).z));
6865 result.w = Sqrt(Float(Float4(x).w));
Nicolas Capensd52e9362016-10-31 23:23:15 -04006866
Nicolas Capens9f737d32017-07-25 17:26:14 -04006867 return result;
6868 }
6869 else
6870 {
6871 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6872 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Sqrt, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6873 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6874 auto sqrt = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
6875 sqrt->addArg(x.value);
6876 ::basicBlock->appendInst(sqrt);
6877
6878 return RValue<Float4>(V(result));
6879 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04006880 }
6881
Nicolas Capensc94ab742016-11-08 15:15:31 -05006882 RValue<Float4> Insert(RValue<Float4> x, RValue<Float> element, int i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006883 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05006884 return RValue<Float4>(Nucleus::createInsertElement(x.value, element.value, i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006885 }
6886
6887 RValue<Float> Extract(RValue<Float4> x, int i)
6888 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006889 return RValue<Float>(Nucleus::createExtractElement(x.value, Float::getType(), i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006890 }
6891
6892 RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select)
6893 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006894 return RValue<Float4>(createSwizzle4(x.value, select));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006895 }
6896
6897 RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
6898 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04006899 int shuffle[4] =
6900 {
6901 ((imm >> 0) & 0x03) + 0,
6902 ((imm >> 2) & 0x03) + 0,
6903 ((imm >> 4) & 0x03) + 4,
6904 ((imm >> 6) & 0x03) + 4,
6905 };
6906
6907 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006908 }
6909
6910 RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y)
6911 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04006912 int shuffle[4] = {0, 4, 1, 5};
6913 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006914 }
6915
6916 RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y)
6917 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04006918 int shuffle[4] = {2, 6, 3, 7};
6919 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006920 }
6921
6922 RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select)
6923 {
6924 Value *vector = lhs.loadValue();
Nicolas Capensa4c30b02016-11-08 15:43:17 -05006925 Value *result = createMask4(vector, rhs.value, select);
6926 lhs.storeValue(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006927
Nicolas Capensa4c30b02016-11-08 15:43:17 -05006928 return RValue<Float4>(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006929 }
6930
6931 RValue<Int> SignMask(RValue<Float4> x)
6932 {
Nicolas Capens091f3502017-10-03 14:56:49 -04006933 if(emulateIntrinsics || CPUID::ARM)
Nicolas Capensd6cacad2017-07-25 15:32:12 -04006934 {
6935 Int4 xx = (As<Int4>(x) >> 31) & Int4(0x00000001, 0x00000002, 0x00000004, 0x00000008);
6936 return Extract(xx, 0) | Extract(xx, 1) | Extract(xx, 2) | Extract(xx, 3);
6937 }
6938 else
6939 {
6940 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
6941 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6942 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6943 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
6944 movmsk->addArg(x.value);
6945 ::basicBlock->appendInst(movmsk);
Nicolas Capensf2cb9df2016-10-21 17:26:13 -04006946
Nicolas Capensd6cacad2017-07-25 15:32:12 -04006947 return RValue<Int>(V(result));
6948 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04006949 }
6950
6951 RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y)
6952 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006953 return RValue<Int4>(Nucleus::createFCmpOEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006954 }
6955
6956 RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y)
6957 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006958 return RValue<Int4>(Nucleus::createFCmpOLT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006959 }
6960
6961 RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y)
6962 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006963 return RValue<Int4>(Nucleus::createFCmpOLE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006964 }
6965
6966 RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y)
6967 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006968 return RValue<Int4>(Nucleus::createFCmpONE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006969 }
6970
6971 RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y)
6972 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006973 return RValue<Int4>(Nucleus::createFCmpOGE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006974 }
6975
6976 RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y)
6977 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006978 return RValue<Int4>(Nucleus::createFCmpOGT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006979 }
6980
Alexis Hetu8ef6d102017-11-09 15:49:09 -05006981 RValue<Int4> IsInf(RValue<Float4> x)
6982 {
6983 return CmpEQ(As<Int4>(x) & Int4(0x7FFFFFFF), Int4(0x7F800000));
6984 }
6985
6986 RValue<Int4> IsNan(RValue<Float4> x)
6987 {
6988 return ~CmpEQ(x, x);
6989 }
6990
Nicolas Capens598f8d82016-09-26 15:09:10 -04006991 RValue<Float4> Round(RValue<Float4> x)
6992 {
Nicolas Capens091f3502017-10-03 14:56:49 -04006993 if(emulateIntrinsics || CPUID::ARM)
Nicolas Capensf7b75882017-04-26 09:30:47 -04006994 {
6995 // Push the fractional part off the mantissa. Accurate up to +/-2^22.
6996 return (x + Float4(0x00C00000)) - Float4(0x00C00000);
6997 }
6998 else if(CPUID::SSE4_1)
Nicolas Capens9ca48d52017-01-14 12:52:55 -05006999 {
7000 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
7001 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
7002 auto target = ::context->getConstantUndef(Ice::IceType_i32);
7003 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
7004 round->addArg(x.value);
7005 round->addArg(::context->getConstantInt32(0));
7006 ::basicBlock->appendInst(round);
Nicolas Capensa8086512016-11-07 17:32:17 -05007007
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007008 return RValue<Float4>(V(result));
7009 }
7010 else
7011 {
7012 return Float4(RoundInt(x));
7013 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04007014 }
7015
7016 RValue<Float4> Trunc(RValue<Float4> x)
7017 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007018 if(CPUID::SSE4_1)
7019 {
7020 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
7021 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
7022 auto target = ::context->getConstantUndef(Ice::IceType_i32);
7023 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
7024 round->addArg(x.value);
7025 round->addArg(::context->getConstantInt32(3));
7026 ::basicBlock->appendInst(round);
Nicolas Capensa8086512016-11-07 17:32:17 -05007027
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007028 return RValue<Float4>(V(result));
7029 }
7030 else
7031 {
7032 return Float4(Int4(x));
7033 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04007034 }
7035
7036 RValue<Float4> Frac(RValue<Float4> x)
7037 {
Nicolas Capensb9230422017-07-17 10:27:33 -04007038 Float4 frc;
7039
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007040 if(CPUID::SSE4_1)
7041 {
Nicolas Capensb9230422017-07-17 10:27:33 -04007042 frc = x - Floor(x);
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007043 }
7044 else
7045 {
Nicolas Capensb9230422017-07-17 10:27:33 -04007046 frc = x - Float4(Int4(x)); // Signed fractional part.
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007047
Nicolas Capensb9230422017-07-17 10:27:33 -04007048 frc += As<Float4>(As<Int4>(CmpNLE(Float4(0.0f), frc)) & As<Int4>(Float4(1, 1, 1, 1))); // Add 1.0 if negative.
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007049 }
Nicolas Capensb9230422017-07-17 10:27:33 -04007050
7051 // x - floor(x) can be 1.0 for very small negative x.
7052 // Clamp against the value just below 1.0.
7053 return Min(frc, As<Float4>(Int4(0x3F7FFFFF)));
Nicolas Capens598f8d82016-09-26 15:09:10 -04007054 }
7055
7056 RValue<Float4> Floor(RValue<Float4> x)
7057 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007058 if(CPUID::SSE4_1)
7059 {
7060 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
7061 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
7062 auto target = ::context->getConstantUndef(Ice::IceType_i32);
7063 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
7064 round->addArg(x.value);
7065 round->addArg(::context->getConstantInt32(1));
7066 ::basicBlock->appendInst(round);
Nicolas Capensa8086512016-11-07 17:32:17 -05007067
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007068 return RValue<Float4>(V(result));
7069 }
7070 else
7071 {
7072 return x - Frac(x);
7073 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04007074 }
7075
7076 RValue<Float4> Ceil(RValue<Float4> x)
7077 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007078 if(CPUID::SSE4_1)
7079 {
7080 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
7081 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
7082 auto target = ::context->getConstantUndef(Ice::IceType_i32);
7083 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
7084 round->addArg(x.value);
7085 round->addArg(::context->getConstantInt32(2));
7086 ::basicBlock->appendInst(round);
Nicolas Capensa8086512016-11-07 17:32:17 -05007087
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007088 return RValue<Float4>(V(result));
7089 }
7090 else
7091 {
7092 return -Floor(-x);
7093 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04007094 }
7095
7096 Type *Float4::getType()
7097 {
Nicolas Capens9709d4f2016-09-30 11:44:14 -04007098 return T(Ice::IceType_v4f32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04007099 }
7100
7101 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset)
7102 {
Nicolas Capens8820f642016-09-30 04:42:43 -04007103 return lhs + RValue<Int>(Nucleus::createConstantInt(offset));
Nicolas Capens598f8d82016-09-26 15:09:10 -04007104 }
7105
7106 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
7107 {
Nicolas Capensd294def2017-01-26 17:44:37 -08007108 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value, false));
Nicolas Capens598f8d82016-09-26 15:09:10 -04007109 }
7110
7111 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
7112 {
Nicolas Capensd294def2017-01-26 17:44:37 -08007113 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value, true));
Nicolas Capens598f8d82016-09-26 15:09:10 -04007114 }
7115
Nicolas Capens96d4e092016-11-18 14:22:38 -05007116 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, int offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04007117 {
7118 return lhs = lhs + offset;
7119 }
7120
Nicolas Capens96d4e092016-11-18 14:22:38 -05007121 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<Int> offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04007122 {
7123 return lhs = lhs + offset;
7124 }
7125
Nicolas Capens96d4e092016-11-18 14:22:38 -05007126 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<UInt> offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04007127 {
7128 return lhs = lhs + offset;
7129 }
7130
7131 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset)
7132 {
7133 return lhs + -offset;
7134 }
7135
7136 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
7137 {
7138 return lhs + -offset;
7139 }
7140
7141 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
7142 {
7143 return lhs + -offset;
7144 }
7145
Nicolas Capens96d4e092016-11-18 14:22:38 -05007146 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, int offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04007147 {
7148 return lhs = lhs - offset;
7149 }
7150
Nicolas Capens96d4e092016-11-18 14:22:38 -05007151 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<Int> offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04007152 {
7153 return lhs = lhs - offset;
7154 }
7155
Nicolas Capens96d4e092016-11-18 14:22:38 -05007156 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<UInt> offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04007157 {
7158 return lhs = lhs - offset;
7159 }
7160
7161 void Return()
7162 {
7163 Nucleus::createRetVoid();
7164 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
7165 Nucleus::createUnreachable();
7166 }
7167
Nicolas Capenseb253d02016-11-18 14:40:40 -05007168 void Return(RValue<Int> ret)
Nicolas Capens598f8d82016-09-26 15:09:10 -04007169 {
Nicolas Capenseb253d02016-11-18 14:40:40 -05007170 Nucleus::createRet(ret.value);
Nicolas Capensfdcca2d2016-10-20 11:31:36 -04007171 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
7172 Nucleus::createUnreachable();
Nicolas Capens598f8d82016-09-26 15:09:10 -04007173 }
7174
Nicolas Capensf4eec2f2017-05-24 15:46:48 -04007175 void branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB)
Nicolas Capens598f8d82016-09-26 15:09:10 -04007176 {
7177 Nucleus::createCondBr(cmp.value, bodyBB, endBB);
7178 Nucleus::setInsertBlock(bodyBB);
Nicolas Capens598f8d82016-09-26 15:09:10 -04007179 }
7180
Nicolas Capens598f8d82016-09-26 15:09:10 -04007181 RValue<Long> Ticks()
7182 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04007183 assert(false && "UNIMPLEMENTED"); return RValue<Long>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04007184 }
7185}