blob: 3d4965867a86d50f5ad4ef13a4c8fa048528bf1c [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"
18
Nicolas Capensa062f322018-09-06 15:34:46 -040019#include "Common/Memory.hpp"
20
Nicolas Capens598f8d82016-09-26 15:09:10 -040021#include "src/IceTypes.h"
22#include "src/IceCfg.h"
23#include "src/IceELFStreamer.h"
24#include "src/IceGlobalContext.h"
25#include "src/IceCfgNode.h"
26#include "src/IceELFObjectWriter.h"
Nicolas Capens8dfd9a72016-10-13 17:44:51 -040027#include "src/IceGlobalInits.h"
Nicolas Capens598f8d82016-09-26 15:09:10 -040028
29#include "llvm/Support/FileSystem.h"
30#include "llvm/Support/raw_os_ostream.h"
Nicolas Capens6a990f82018-07-06 15:54:07 -040031#include "llvm/Support/Compiler.h"
32
33#if __has_feature(memory_sanitizer)
34#include <sanitizer/msan_interface.h>
35#endif
Nicolas Capens598f8d82016-09-26 15:09:10 -040036
Nicolas Capensbd65da92017-01-05 16:31:06 -050037#if defined(_WIN32)
Alexis Hetu113e33a2017-01-19 10:49:19 -050038#ifndef WIN32_LEAN_AND_MEAN
Nicolas Capens598f8d82016-09-26 15:09:10 -040039#define WIN32_LEAN_AND_MEAN
Alexis Hetu113e33a2017-01-19 10:49:19 -050040#endif // !WIN32_LEAN_AND_MEAN
41#ifndef NOMINMAX
Nicolas Capens598f8d82016-09-26 15:09:10 -040042#define NOMINMAX
Alexis Hetu113e33a2017-01-19 10:49:19 -050043#endif // !NOMINMAX
Nicolas Capens598f8d82016-09-26 15:09:10 -040044#include <Windows.h>
Nicolas Capensbd65da92017-01-05 16:31:06 -050045#else
46#include <sys/mman.h>
Nicolas Capens411273e2017-01-26 15:13:36 -080047#if !defined(MAP_ANONYMOUS)
48#define MAP_ANONYMOUS MAP_ANON
Nicolas Capens8b275742017-01-20 17:11:41 -050049#endif
Nicolas Capensbd65da92017-01-05 16:31:06 -050050#endif
Nicolas Capens598f8d82016-09-26 15:09:10 -040051
Nicolas Capenscb986762017-01-20 11:34:37 -050052//#include <mutex>
Nicolas Capens598f8d82016-09-26 15:09:10 -040053#include <limits>
54#include <iostream>
55#include <cassert>
56
57namespace
58{
59 Ice::GlobalContext *context = nullptr;
60 Ice::Cfg *function = nullptr;
61 Ice::CfgNode *basicBlock = nullptr;
62 Ice::CfgLocalAllocatorScope *allocator = nullptr;
63 sw::Routine *routine = nullptr;
64
65 std::mutex codegenMutex;
66
67 Ice::ELFFileStreamer *elfFile = nullptr;
68 Ice::Fdstream *out = nullptr;
69}
70
Nicolas Capensccd5ecb2017-01-14 12:52:55 -050071namespace
72{
Nicolas Capens47dc8672017-04-25 12:54:39 -040073 #if !defined(__i386__) && defined(_M_IX86)
74 #define __i386__ 1
75 #endif
76
77 #if !defined(__x86_64__) && (defined(_M_AMD64) || defined (_M_X64))
78 #define __x86_64__ 1
79 #endif
80
Nicolas Capensccd5ecb2017-01-14 12:52:55 -050081 class CPUID
82 {
83 public:
Nicolas Capensf7b75882017-04-26 09:30:47 -040084 const static bool ARM;
Nicolas Capensccd5ecb2017-01-14 12:52:55 -050085 const static bool SSE4_1;
86
87 private:
88 static void cpuid(int registers[4], int info)
89 {
Nicolas Capens47dc8672017-04-25 12:54:39 -040090 #if defined(__i386__) || defined(__x86_64__)
91 #if defined(_WIN32)
92 __cpuid(registers, info);
93 #else
94 __asm volatile("cpuid": "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]): "a" (info));
95 #endif
Nicolas Capensccd5ecb2017-01-14 12:52:55 -050096 #else
Nicolas Capens47dc8672017-04-25 12:54:39 -040097 registers[0] = 0;
98 registers[1] = 0;
99 registers[2] = 0;
100 registers[3] = 0;
Nicolas Capensccd5ecb2017-01-14 12:52:55 -0500101 #endif
102 }
103
Nicolas Capensf7b75882017-04-26 09:30:47 -0400104 static bool detectARM()
105 {
106 #if defined(__arm__)
107 return true;
108 #elif defined(__i386__) || defined(__x86_64__)
109 return false;
110 #else
111 #error "Unknown architecture"
112 #endif
113 }
114
Nicolas Capensccd5ecb2017-01-14 12:52:55 -0500115 static bool detectSSE4_1()
116 {
Nicolas Capens47dc8672017-04-25 12:54:39 -0400117 #if defined(__i386__) || defined(__x86_64__)
118 int registers[4];
119 cpuid(registers, 1);
120 return (registers[2] & 0x00080000) != 0;
121 #else
122 return false;
123 #endif
Nicolas Capensccd5ecb2017-01-14 12:52:55 -0500124 }
125 };
126
Nicolas Capensf7b75882017-04-26 09:30:47 -0400127 const bool CPUID::ARM = CPUID::detectARM();
Nicolas Capensccd5ecb2017-01-14 12:52:55 -0500128 const bool CPUID::SSE4_1 = CPUID::detectSSE4_1();
Nicolas Capens091f3502017-10-03 14:56:49 -0400129 const bool emulateIntrinsics = false;
Nicolas Capens2d8c3702017-07-25 13:56:46 -0400130 const bool emulateMismatchedBitCast = CPUID::ARM;
Nicolas Capensccd5ecb2017-01-14 12:52:55 -0500131}
132
Nicolas Capens598f8d82016-09-26 15:09:10 -0400133namespace sw
134{
Nicolas Capens23d99a42016-09-30 14:57:16 -0400135 enum EmulatedType
136 {
137 EmulatedShift = 16,
138 EmulatedV2 = 2 << EmulatedShift,
139 EmulatedV4 = 4 << EmulatedShift,
140 EmulatedV8 = 8 << EmulatedShift,
141 EmulatedBits = EmulatedV2 | EmulatedV4 | EmulatedV8,
142
143 Type_v2i32 = Ice::IceType_v4i32 | EmulatedV2,
144 Type_v4i16 = Ice::IceType_v8i16 | EmulatedV4,
145 Type_v2i16 = Ice::IceType_v8i16 | EmulatedV2,
146 Type_v8i8 = Ice::IceType_v16i8 | EmulatedV8,
147 Type_v4i8 = Ice::IceType_v16i8 | EmulatedV4,
Nicolas Capens4cfd4572016-10-20 01:00:19 -0400148 Type_v2f32 = Ice::IceType_v4f32 | EmulatedV2,
Nicolas Capens23d99a42016-09-30 14:57:16 -0400149 };
150
Nicolas Capens15060bb2016-12-05 22:17:19 -0500151 class Value : public Ice::Operand {};
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500152 class SwitchCases : public Ice::InstSwitch {};
Nicolas Capens598f8d82016-09-26 15:09:10 -0400153 class BasicBlock : public Ice::CfgNode {};
154
155 Ice::Type T(Type *t)
156 {
Alexis Hetu113e33a2017-01-19 10:49:19 -0500157 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 -0400158 return (Ice::Type)(reinterpret_cast<std::intptr_t>(t) & ~EmulatedBits);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400159 }
160
161 Type *T(Ice::Type t)
162 {
163 return reinterpret_cast<Type*>(t);
164 }
165
Nicolas Capens23d99a42016-09-30 14:57:16 -0400166 Type *T(EmulatedType t)
167 {
168 return reinterpret_cast<Type*>(t);
169 }
170
Nicolas Capens15060bb2016-12-05 22:17:19 -0500171 Value *V(Ice::Operand *v)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400172 {
173 return reinterpret_cast<Value*>(v);
174 }
175
Nicolas Capens611642a2016-09-28 16:45:04 -0400176 BasicBlock *B(Ice::CfgNode *b)
177 {
178 return reinterpret_cast<BasicBlock*>(b);
179 }
180
Nicolas Capens584088c2017-01-26 16:05:18 -0800181 static size_t typeSize(Type *type)
182 {
183 if(reinterpret_cast<std::intptr_t>(type) & EmulatedBits)
184 {
185 switch(reinterpret_cast<std::intptr_t>(type))
186 {
187 case Type_v2i32: return 8;
188 case Type_v4i16: return 8;
189 case Type_v2i16: return 4;
190 case Type_v8i8: return 8;
191 case Type_v4i8: return 4;
192 case Type_v2f32: return 8;
193 default: assert(false);
194 }
195 }
196
197 return Ice::typeWidthInBytes(T(type));
198 }
199
Nicolas Capens598f8d82016-09-26 15:09:10 -0400200 Optimization optimization[10] = {InstructionCombining, Disabled};
201
Nicolas Capens66478362016-10-13 15:36:36 -0400202 using ElfHeader = std::conditional<sizeof(void*) == 8, Elf64_Ehdr, Elf32_Ehdr>::type;
203 using SectionHeader = std::conditional<sizeof(void*) == 8, Elf64_Shdr, Elf32_Shdr>::type;
204
205 inline const SectionHeader *sectionHeader(const ElfHeader *elfHeader)
206 {
207 return reinterpret_cast<const SectionHeader*>((intptr_t)elfHeader + elfHeader->e_shoff);
208 }
Nicolas Capens87852e12016-11-24 14:45:06 -0500209
Nicolas Capens66478362016-10-13 15:36:36 -0400210 inline const SectionHeader *elfSection(const ElfHeader *elfHeader, int index)
211 {
212 return &sectionHeader(elfHeader)[index];
213 }
214
215 static void *relocateSymbol(const ElfHeader *elfHeader, const Elf32_Rel &relocation, const SectionHeader &relocationTable)
216 {
217 const SectionHeader *target = elfSection(elfHeader, relocationTable.sh_info);
Nicolas Capens87852e12016-11-24 14:45:06 -0500218
Nicolas Capens66478362016-10-13 15:36:36 -0400219 intptr_t address = (intptr_t)elfHeader + target->sh_offset;
220 int32_t *patchSite = (int*)(address + relocation.r_offset);
221 uint32_t index = relocation.getSymbol();
222 int table = relocationTable.sh_link;
223 void *symbolValue = nullptr;
Nicolas Capens87852e12016-11-24 14:45:06 -0500224
Nicolas Capens66478362016-10-13 15:36:36 -0400225 if(index != SHN_UNDEF)
226 {
227 if(table == SHN_UNDEF) return nullptr;
228 const SectionHeader *symbolTable = elfSection(elfHeader, table);
Nicolas Capens87852e12016-11-24 14:45:06 -0500229
Nicolas Capens66478362016-10-13 15:36:36 -0400230 uint32_t symtab_entries = symbolTable->sh_size / symbolTable->sh_entsize;
231 if(index >= symtab_entries)
232 {
233 assert(index < symtab_entries && "Symbol Index out of range");
234 return nullptr;
235 }
Nicolas Capens87852e12016-11-24 14:45:06 -0500236
Nicolas Capens66478362016-10-13 15:36:36 -0400237 intptr_t symbolAddress = (intptr_t)elfHeader + symbolTable->sh_offset;
238 Elf32_Sym &symbol = ((Elf32_Sym*)symbolAddress)[index];
239 uint16_t section = symbol.st_shndx;
240
241 if(section != SHN_UNDEF && section < SHN_LORESERVE)
242 {
243 const SectionHeader *target = elfSection(elfHeader, symbol.st_shndx);
244 symbolValue = reinterpret_cast<void*>((intptr_t)elfHeader + symbol.st_value + target->sh_offset);
245 }
246 else
247 {
248 return nullptr;
249 }
250 }
251
Nicolas Capensf110e4d2017-05-03 15:33:49 -0400252 if(CPUID::ARM)
253 {
254 switch(relocation.getType())
255 {
256 case R_ARM_NONE:
257 // No relocation
258 break;
259 case R_ARM_MOVW_ABS_NC:
260 {
261 uint32_t thumb = 0; // Calls to Thumb code not supported.
262 uint32_t lo = (uint32_t)(intptr_t)symbolValue | thumb;
263 *patchSite = (*patchSite & 0xFFF0F000) | ((lo & 0xF000) << 4) | (lo & 0x0FFF);
264 }
265 break;
266 case R_ARM_MOVT_ABS:
267 {
268 uint32_t hi = (uint32_t)(intptr_t)(symbolValue) >> 16;
269 *patchSite = (*patchSite & 0xFFF0F000) | ((hi & 0xF000) << 4) | (hi & 0x0FFF);
270 }
271 break;
272 default:
273 assert(false && "Unsupported relocation type");
274 return nullptr;
275 }
276 }
277 else
278 {
Nicolas Capens30cd7d42017-04-25 15:17:25 -0400279 switch(relocation.getType())
280 {
281 case R_386_NONE:
282 // No relocation
283 break;
284 case R_386_32:
285 *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite);
286 break;
287 // case R_386_PC32:
288 // *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite - (intptr_t)patchSite);
289 // break;
290 default:
291 assert(false && "Unsupported relocation type");
292 return nullptr;
293 }
Nicolas Capensf110e4d2017-05-03 15:33:49 -0400294 }
295
Nicolas Capens66478362016-10-13 15:36:36 -0400296 return symbolValue;
297 }
298
299 static void *relocateSymbol(const ElfHeader *elfHeader, const Elf64_Rela &relocation, const SectionHeader &relocationTable)
300 {
301 const SectionHeader *target = elfSection(elfHeader, relocationTable.sh_info);
Nicolas Capens87852e12016-11-24 14:45:06 -0500302
Nicolas Capens66478362016-10-13 15:36:36 -0400303 intptr_t address = (intptr_t)elfHeader + target->sh_offset;
304 int32_t *patchSite = (int*)(address + relocation.r_offset);
305 uint32_t index = relocation.getSymbol();
306 int table = relocationTable.sh_link;
307 void *symbolValue = nullptr;
308
309 if(index != SHN_UNDEF)
310 {
311 if(table == SHN_UNDEF) return nullptr;
312 const SectionHeader *symbolTable = elfSection(elfHeader, table);
Nicolas Capens87852e12016-11-24 14:45:06 -0500313
Nicolas Capens66478362016-10-13 15:36:36 -0400314 uint32_t symtab_entries = symbolTable->sh_size / symbolTable->sh_entsize;
315 if(index >= symtab_entries)
316 {
317 assert(index < symtab_entries && "Symbol Index out of range");
318 return nullptr;
319 }
Nicolas Capens87852e12016-11-24 14:45:06 -0500320
Nicolas Capens66478362016-10-13 15:36:36 -0400321 intptr_t symbolAddress = (intptr_t)elfHeader + symbolTable->sh_offset;
322 Elf64_Sym &symbol = ((Elf64_Sym*)symbolAddress)[index];
323 uint16_t section = symbol.st_shndx;
324
325 if(section != SHN_UNDEF && section < SHN_LORESERVE)
326 {
327 const SectionHeader *target = elfSection(elfHeader, symbol.st_shndx);
328 symbolValue = reinterpret_cast<void*>((intptr_t)elfHeader + symbol.st_value + target->sh_offset);
329 }
330 else
331 {
332 return nullptr;
333 }
334 }
335
Nicolas Capensf110e4d2017-05-03 15:33:49 -0400336 switch(relocation.getType())
337 {
338 case R_X86_64_NONE:
339 // No relocation
340 break;
341 case R_X86_64_64:
342 *(int64_t*)patchSite = (int64_t)((intptr_t)symbolValue + *(int64_t*)patchSite) + relocation.r_addend;
343 break;
344 case R_X86_64_PC32:
345 *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite - (intptr_t)patchSite) + relocation.r_addend;
346 break;
347 case R_X86_64_32S:
348 *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite) + relocation.r_addend;
349 break;
350 default:
351 assert(false && "Unsupported relocation type");
352 return nullptr;
353 }
Nicolas Capens66478362016-10-13 15:36:36 -0400354
355 return symbolValue;
356 }
357
Nicolas Capens1cc44382017-04-25 10:52:16 -0400358 void *loadImage(uint8_t *const elfImage, size_t &codeSize)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400359 {
Nicolas Capens598f8d82016-09-26 15:09:10 -0400360 ElfHeader *elfHeader = (ElfHeader*)elfImage;
361
362 if(!elfHeader->checkMagic())
363 {
364 return nullptr;
365 }
366
Nicolas Capens66478362016-10-13 15:36:36 -0400367 // Expect ELF bitness to match platform
Nicolas Capens65047112016-11-07 13:01:07 -0500368 assert(sizeof(void*) == 8 ? elfHeader->getFileClass() == ELFCLASS64 : elfHeader->getFileClass() == ELFCLASS32);
Nicolas Capens30cd7d42017-04-25 15:17:25 -0400369 #if defined(__i386__)
370 assert(sizeof(void*) == 4 && elfHeader->e_machine == EM_386);
371 #elif defined(__x86_64__)
372 assert(sizeof(void*) == 8 && elfHeader->e_machine == EM_X86_64);
373 #elif defined(__arm__)
374 assert(sizeof(void*) == 4 && elfHeader->e_machine == EM_ARM);
375 #else
376 #error "Unsupported platform"
377 #endif
Nicolas Capens66478362016-10-13 15:36:36 -0400378
Nicolas Capens598f8d82016-09-26 15:09:10 -0400379 SectionHeader *sectionHeader = (SectionHeader*)(elfImage + elfHeader->e_shoff);
380 void *entry = nullptr;
381
382 for(int i = 0; i < elfHeader->e_shnum; i++)
383 {
Nicolas Capens66478362016-10-13 15:36:36 -0400384 if(sectionHeader[i].sh_type == SHT_PROGBITS)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400385 {
Nicolas Capens66478362016-10-13 15:36:36 -0400386 if(sectionHeader[i].sh_flags & SHF_EXECINSTR)
387 {
388 entry = elfImage + sectionHeader[i].sh_offset;
Nicolas Capens1cc44382017-04-25 10:52:16 -0400389 codeSize = sectionHeader[i].sh_size;
Nicolas Capens66478362016-10-13 15:36:36 -0400390 }
391 }
392 else if(sectionHeader[i].sh_type == SHT_REL)
393 {
394 assert(sizeof(void*) == 4 && "UNIMPLEMENTED"); // Only expected/implemented for 32-bit code
395
Alexis Hetu113e33a2017-01-19 10:49:19 -0500396 for(Elf32_Word index = 0; index < sectionHeader[i].sh_size / sectionHeader[i].sh_entsize; index++)
Nicolas Capens66478362016-10-13 15:36:36 -0400397 {
398 const Elf32_Rel &relocation = ((const Elf32_Rel*)(elfImage + sectionHeader[i].sh_offset))[index];
Alexis Hetu113e33a2017-01-19 10:49:19 -0500399 relocateSymbol(elfHeader, relocation, sectionHeader[i]);
Nicolas Capens66478362016-10-13 15:36:36 -0400400 }
401 }
402 else if(sectionHeader[i].sh_type == SHT_RELA)
403 {
404 assert(sizeof(void*) == 8 && "UNIMPLEMENTED"); // Only expected/implemented for 64-bit code
405
Alexis Hetu113e33a2017-01-19 10:49:19 -0500406 for(Elf32_Word index = 0; index < sectionHeader[i].sh_size / sectionHeader[i].sh_entsize; index++)
Nicolas Capens66478362016-10-13 15:36:36 -0400407 {
408 const Elf64_Rela &relocation = ((const Elf64_Rela*)(elfImage + sectionHeader[i].sh_offset))[index];
Alexis Hetu113e33a2017-01-19 10:49:19 -0500409 relocateSymbol(elfHeader, relocation, sectionHeader[i]);
Nicolas Capens66478362016-10-13 15:36:36 -0400410 }
Nicolas Capens598f8d82016-09-26 15:09:10 -0400411 }
412 }
413
414 return entry;
415 }
416
417 template<typename T>
418 struct ExecutableAllocator
419 {
420 ExecutableAllocator() {};
421 template<class U> ExecutableAllocator(const ExecutableAllocator<U> &other) {};
422
423 using value_type = T;
424 using size_type = std::size_t;
425
426 T *allocate(size_type n)
427 {
Nicolas Capensa062f322018-09-06 15:34:46 -0400428 return (T*)allocateExecutable(sizeof(T) * n);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400429 }
430
431 void deallocate(T *p, size_type n)
432 {
Nicolas Capensa062f322018-09-06 15:34:46 -0400433 deallocateExecutable(p, sizeof(T) * n);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400434 }
435 };
436
437 class ELFMemoryStreamer : public Ice::ELFStreamer, public Routine
438 {
439 ELFMemoryStreamer(const ELFMemoryStreamer &) = delete;
440 ELFMemoryStreamer &operator=(const ELFMemoryStreamer &) = delete;
441
442 public:
Nicolas Capens58274b52016-10-19 23:45:19 -0400443 ELFMemoryStreamer() : Routine(), entry(nullptr)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400444 {
445 position = 0;
446 buffer.reserve(0x1000);
447 }
448
Nicolas Capens81aa97b2017-06-27 17:08:08 -0400449 ~ELFMemoryStreamer() override
Nicolas Capens598f8d82016-09-26 15:09:10 -0400450 {
Nicolas Capensbd65da92017-01-05 16:31:06 -0500451 #if defined(_WIN32)
452 if(buffer.size() != 0)
453 {
454 DWORD exeProtection;
455 VirtualProtect(&buffer[0], buffer.size(), oldProtection, &exeProtection);
456 }
457 #endif
Nicolas Capens598f8d82016-09-26 15:09:10 -0400458 }
459
460 void write8(uint8_t Value) override
461 {
462 if(position == (uint64_t)buffer.size())
463 {
464 buffer.push_back(Value);
465 position++;
466 }
467 else if(position < (uint64_t)buffer.size())
468 {
469 buffer[position] = Value;
470 position++;
471 }
472 else assert(false && "UNIMPLEMENTED");
473 }
474
475 void writeBytes(llvm::StringRef Bytes) override
476 {
477 std::size_t oldSize = buffer.size();
478 buffer.resize(oldSize + Bytes.size());
479 memcpy(&buffer[oldSize], Bytes.begin(), Bytes.size());
480 position += Bytes.size();
481 }
482
483 uint64_t tell() const override { return position; }
484
485 void seek(uint64_t Off) override { position = Off; }
486
487 const void *getEntry() override
488 {
Nicolas Capens58274b52016-10-19 23:45:19 -0400489 if(!entry)
490 {
Nicolas Capensbd65da92017-01-05 16:31:06 -0500491 position = std::numeric_limits<std::size_t>::max(); // Can't stream more data after this
Nicolas Capens598f8d82016-09-26 15:09:10 -0400492
Nicolas Capens1cc44382017-04-25 10:52:16 -0400493 size_t codeSize = 0;
494 entry = loadImage(&buffer[0], codeSize);
495
496 #if defined(_WIN32)
Nicolas Capense745f5a2017-05-29 10:00:32 -0400497 VirtualProtect(&buffer[0], buffer.size(), PAGE_EXECUTE_READ, &oldProtection);
Nicolas Capens1cc44382017-04-25 10:52:16 -0400498 FlushInstructionCache(GetCurrentProcess(), NULL, 0);
499 #else
Nicolas Capense745f5a2017-05-29 10:00:32 -0400500 mprotect(&buffer[0], buffer.size(), PROT_READ | PROT_EXEC);
Nicolas Capens1cc44382017-04-25 10:52:16 -0400501 __builtin___clear_cache((char*)entry, (char*)entry + codeSize);
502 #endif
Nicolas Capens58274b52016-10-19 23:45:19 -0400503 }
504
505 return entry;
Nicolas Capens598f8d82016-09-26 15:09:10 -0400506 }
507
508 private:
Nicolas Capens58274b52016-10-19 23:45:19 -0400509 void *entry;
Nicolas Capens598f8d82016-09-26 15:09:10 -0400510 std::vector<uint8_t, ExecutableAllocator<uint8_t>> buffer;
511 std::size_t position;
Nicolas Capensbd65da92017-01-05 16:31:06 -0500512
513 #if defined(_WIN32)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400514 DWORD oldProtection;
Nicolas Capensbd65da92017-01-05 16:31:06 -0500515 #endif
Nicolas Capens598f8d82016-09-26 15:09:10 -0400516 };
517
518 Nucleus::Nucleus()
519 {
520 ::codegenMutex.lock(); // Reactor is currently not thread safe
521
Nicolas Capens66478362016-10-13 15:36:36 -0400522 Ice::ClFlags &Flags = Ice::ClFlags::Flags;
523 Ice::ClFlags::getParsedClFlags(Flags);
524
Nicolas Capens30cd7d42017-04-25 15:17:25 -0400525 #if defined(__arm__)
526 Flags.setTargetArch(Ice::Target_ARM32);
527 Flags.setTargetInstructionSet(Ice::ARM32InstructionSet_HWDivArm);
528 #else // x86
529 Flags.setTargetArch(sizeof(void*) == 8 ? Ice::Target_X8664 : Ice::Target_X8632);
530 Flags.setTargetInstructionSet(CPUID::SSE4_1 ? Ice::X86InstructionSet_SSE4_1 : Ice::X86InstructionSet_SSE2);
531 #endif
Nicolas Capens66478362016-10-13 15:36:36 -0400532 Flags.setOutFileType(Ice::FT_Elf);
533 Flags.setOptLevel(Ice::Opt_2);
534 Flags.setApplicationBinaryInterface(Ice::ABI_Platform);
Nicolas Capens30cd7d42017-04-25 15:17:25 -0400535 Flags.setVerbose(false ? Ice::IceV_Most : Ice::IceV_None);
536 Flags.setDisableHybridAssembly(true);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400537
Nicolas Capens65047112016-11-07 13:01:07 -0500538 static llvm::raw_os_ostream cout(std::cout);
539 static llvm::raw_os_ostream cerr(std::cerr);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400540
541 if(false) // Write out to a file
542 {
543 std::error_code errorCode;
544 ::out = new Ice::Fdstream("out.o", errorCode, llvm::sys::fs::F_None);
545 ::elfFile = new Ice::ELFFileStreamer(*out);
Nicolas Capens65047112016-11-07 13:01:07 -0500546 ::context = new Ice::GlobalContext(&cout, &cout, &cerr, elfFile);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400547 }
548 else
549 {
550 ELFMemoryStreamer *elfMemory = new ELFMemoryStreamer();
Nicolas Capens65047112016-11-07 13:01:07 -0500551 ::context = new Ice::GlobalContext(&cout, &cout, &cerr, elfMemory);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400552 ::routine = elfMemory;
553 }
554 }
555
556 Nucleus::~Nucleus()
557 {
Nicolas Capens619a8c52017-07-05 14:10:46 -0400558 delete ::routine;
559
Nicolas Capens598f8d82016-09-26 15:09:10 -0400560 delete ::allocator;
561 delete ::function;
562 delete ::context;
563
564 delete ::elfFile;
565 delete ::out;
566
567 ::codegenMutex.unlock();
568 }
569
570 Routine *Nucleus::acquireRoutine(const wchar_t *name, bool runOptimizations)
571 {
572 if(basicBlock->getInsts().empty() || basicBlock->getInsts().back().getKind() != Ice::Inst::Ret)
573 {
574 createRetVoid();
575 }
576
577 std::wstring wideName(name);
578 std::string asciiName(wideName.begin(), wideName.end());
579 ::function->setFunctionName(Ice::GlobalString::createWithString(::context, asciiName));
580
Nicolas Capens2ae9d742016-11-24 14:43:05 -0500581 optimize();
582
Nicolas Capens598f8d82016-09-26 15:09:10 -0400583 ::function->translate();
Nicolas Capensde19f392016-10-19 10:29:49 -0400584 assert(!::function->hasError());
585
Nicolas Capens83a6bb92017-07-05 15:04:00 -0400586 auto globals = ::function->getGlobalInits();
Nicolas Capens66478362016-10-13 15:36:36 -0400587
588 if(globals && !globals->empty())
589 {
Nicolas Capens83a6bb92017-07-05 15:04:00 -0400590 ::context->getGlobals()->merge(globals.get());
Nicolas Capens66478362016-10-13 15:36:36 -0400591 }
Nicolas Capens598f8d82016-09-26 15:09:10 -0400592
593 ::context->emitFileHeader();
594 ::function->emitIAS();
595 auto assembler = ::function->releaseAssembler();
Nicolas Capens66478362016-10-13 15:36:36 -0400596 auto objectWriter = ::context->getObjectWriter();
597 assembler->alignFunction();
598 objectWriter->writeFunctionCode(::function->getFunctionName(), false, assembler.get());
599 ::context->lowerGlobals("last");
Nicolas Capens73dd7a22016-10-20 13:20:34 -0400600 ::context->lowerConstants();
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500601 ::context->lowerJumpTables();
Nicolas Capens66478362016-10-13 15:36:36 -0400602 objectWriter->setUndefinedSyms(::context->getConstantExternSyms());
603 objectWriter->writeNonUserSections();
Nicolas Capens598f8d82016-09-26 15:09:10 -0400604
Nicolas Capens619a8c52017-07-05 14:10:46 -0400605 Routine *handoffRoutine = ::routine;
606 ::routine = nullptr;
607
608 return handoffRoutine;
Nicolas Capens598f8d82016-09-26 15:09:10 -0400609 }
610
611 void Nucleus::optimize()
612 {
Nicolas Capens2ae9d742016-11-24 14:43:05 -0500613 sw::optimize(::function);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400614 }
615
616 Value *Nucleus::allocateStackVariable(Type *t, int arraySize)
617 {
618 Ice::Type type = T(t);
Nicolas Capensa8f98632016-10-20 11:25:55 -0400619 int typeSize = Ice::typeWidthInBytes(type);
620 int totalSize = typeSize * (arraySize ? arraySize : 1);
Nicolas Capense12780d2016-09-27 14:18:07 -0400621
Nicolas Capensa8f98632016-10-20 11:25:55 -0400622 auto bytes = Ice::ConstantInteger32::create(::context, type, totalSize);
Nicolas Capense12780d2016-09-27 14:18:07 -0400623 auto address = ::function->makeVariable(T(getPointerType(t)));
Nicolas Capensa8f98632016-10-20 11:25:55 -0400624 auto alloca = Ice::InstAlloca::create(::function, address, bytes, typeSize);
Nicolas Capense12780d2016-09-27 14:18:07 -0400625 ::function->getEntryNode()->getInsts().push_front(alloca);
626
627 return V(address);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400628 }
629
630 BasicBlock *Nucleus::createBasicBlock()
631 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400632 return B(::function->makeNode());
Nicolas Capens598f8d82016-09-26 15:09:10 -0400633 }
634
635 BasicBlock *Nucleus::getInsertBlock()
636 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400637 return B(::basicBlock);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400638 }
639
640 void Nucleus::setInsertBlock(BasicBlock *basicBlock)
641 {
Nicolas Capens9ed1a182016-10-24 09:52:23 -0400642 // assert(::basicBlock->getInsts().back().getTerminatorEdges().size() >= 0 && "Previous basic block must have a terminator");
Nicolas Capens611642a2016-09-28 16:45:04 -0400643 ::basicBlock = basicBlock;
Nicolas Capens598f8d82016-09-26 15:09:10 -0400644 }
645
Nicolas Capens598f8d82016-09-26 15:09:10 -0400646 void Nucleus::createFunction(Type *ReturnType, std::vector<Type*> &Params)
647 {
648 uint32_t sequenceNumber = 0;
649 ::function = Ice::Cfg::create(::context, sequenceNumber).release();
650 ::allocator = new Ice::CfgLocalAllocatorScope(::function);
651
652 for(Type *type : Params)
653 {
654 Ice::Variable *arg = ::function->makeVariable(T(type));
655 ::function->addArg(arg);
656 }
657
658 Ice::CfgNode *node = ::function->makeNode();
659 ::function->setEntryNode(node);
660 ::basicBlock = node;
661 }
662
663 Value *Nucleus::getArgument(unsigned int index)
664 {
665 return V(::function->getArgs()[index]);
666 }
667
668 void Nucleus::createRetVoid()
669 {
Nicolas Capensfdcca2d2016-10-20 11:31:36 -0400670 Ice::InstRet *ret = Ice::InstRet::create(::function);
671 ::basicBlock->appendInst(ret);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400672 }
673
674 void Nucleus::createRet(Value *v)
675 {
Nicolas Capensfdcca2d2016-10-20 11:31:36 -0400676 Ice::InstRet *ret = Ice::InstRet::create(::function, v);
677 ::basicBlock->appendInst(ret);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400678 }
679
680 void Nucleus::createBr(BasicBlock *dest)
681 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400682 auto br = Ice::InstBr::create(::function, dest);
683 ::basicBlock->appendInst(br);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400684 }
685
686 void Nucleus::createCondBr(Value *cond, BasicBlock *ifTrue, BasicBlock *ifFalse)
687 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400688 auto br = Ice::InstBr::create(::function, cond, ifTrue, ifFalse);
689 ::basicBlock->appendInst(br);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400690 }
691
Nicolas Capensf8360ba2017-01-25 11:35:00 -0800692 static bool isCommutative(Ice::InstArithmetic::OpKind op)
693 {
694 switch(op)
695 {
696 case Ice::InstArithmetic::Add:
697 case Ice::InstArithmetic::Fadd:
698 case Ice::InstArithmetic::Mul:
699 case Ice::InstArithmetic::Fmul:
700 case Ice::InstArithmetic::And:
701 case Ice::InstArithmetic::Or:
702 case Ice::InstArithmetic::Xor:
703 return true;
704 default:
705 return false;
706 }
707 }
708
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400709 static Value *createArithmetic(Ice::InstArithmetic::OpKind op, Value *lhs, Value *rhs)
710 {
Nicolas Capensb64e0ce2018-01-26 01:24:57 +0000711 assert(lhs->getType() == rhs->getType() || llvm::isa<Ice::Constant>(rhs));
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400712
Nicolas Capensf8360ba2017-01-25 11:35:00 -0800713 bool swapOperands = llvm::isa<Ice::Constant>(lhs) && isCommutative(op);
714
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400715 Ice::Variable *result = ::function->makeVariable(lhs->getType());
Nicolas Capensf8360ba2017-01-25 11:35:00 -0800716 Ice::InstArithmetic *arithmetic = Ice::InstArithmetic::create(::function, op, result, swapOperands ? rhs : lhs, swapOperands ? lhs : rhs);
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400717 ::basicBlock->appendInst(arithmetic);
718
719 return V(result);
720 }
721
Nicolas Capens598f8d82016-09-26 15:09:10 -0400722 Value *Nucleus::createAdd(Value *lhs, Value *rhs)
723 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400724 return createArithmetic(Ice::InstArithmetic::Add, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400725 }
726
727 Value *Nucleus::createSub(Value *lhs, Value *rhs)
728 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400729 return createArithmetic(Ice::InstArithmetic::Sub, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400730 }
731
732 Value *Nucleus::createMul(Value *lhs, Value *rhs)
733 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400734 return createArithmetic(Ice::InstArithmetic::Mul, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400735 }
736
737 Value *Nucleus::createUDiv(Value *lhs, Value *rhs)
738 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400739 return createArithmetic(Ice::InstArithmetic::Udiv, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400740 }
741
742 Value *Nucleus::createSDiv(Value *lhs, Value *rhs)
743 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400744 return createArithmetic(Ice::InstArithmetic::Sdiv, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400745 }
746
747 Value *Nucleus::createFAdd(Value *lhs, Value *rhs)
748 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400749 return createArithmetic(Ice::InstArithmetic::Fadd, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400750 }
751
752 Value *Nucleus::createFSub(Value *lhs, Value *rhs)
753 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400754 return createArithmetic(Ice::InstArithmetic::Fsub, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400755 }
756
757 Value *Nucleus::createFMul(Value *lhs, Value *rhs)
758 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400759 return createArithmetic(Ice::InstArithmetic::Fmul, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400760 }
761
762 Value *Nucleus::createFDiv(Value *lhs, Value *rhs)
763 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400764 return createArithmetic(Ice::InstArithmetic::Fdiv, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400765 }
766
767 Value *Nucleus::createURem(Value *lhs, Value *rhs)
768 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400769 return createArithmetic(Ice::InstArithmetic::Urem, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400770 }
771
772 Value *Nucleus::createSRem(Value *lhs, Value *rhs)
773 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400774 return createArithmetic(Ice::InstArithmetic::Srem, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400775 }
776
777 Value *Nucleus::createFRem(Value *lhs, Value *rhs)
778 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400779 return createArithmetic(Ice::InstArithmetic::Frem, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400780 }
781
782 Value *Nucleus::createShl(Value *lhs, Value *rhs)
783 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400784 return createArithmetic(Ice::InstArithmetic::Shl, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400785 }
786
787 Value *Nucleus::createLShr(Value *lhs, Value *rhs)
788 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400789 return createArithmetic(Ice::InstArithmetic::Lshr, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400790 }
791
792 Value *Nucleus::createAShr(Value *lhs, Value *rhs)
793 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400794 return createArithmetic(Ice::InstArithmetic::Ashr, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400795 }
796
797 Value *Nucleus::createAnd(Value *lhs, Value *rhs)
798 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400799 return createArithmetic(Ice::InstArithmetic::And, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400800 }
801
802 Value *Nucleus::createOr(Value *lhs, Value *rhs)
803 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400804 return createArithmetic(Ice::InstArithmetic::Or, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400805 }
806
807 Value *Nucleus::createXor(Value *lhs, Value *rhs)
808 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400809 return createArithmetic(Ice::InstArithmetic::Xor, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400810 }
811
812 Value *Nucleus::createNeg(Value *v)
813 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500814 return createSub(createNullValue(T(v->getType())), v);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400815 }
816
817 Value *Nucleus::createFNeg(Value *v)
818 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500819 double c[4] = {-0.0, -0.0, -0.0, -0.0};
820 Value *negativeZero = Ice::isVectorType(v->getType()) ?
821 createConstantVector(c, T(v->getType())) :
Nicolas Capens15060bb2016-12-05 22:17:19 -0500822 V(::context->getConstantFloat(-0.0f));
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500823
824 return createFSub(negativeZero, v);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400825 }
826
827 Value *Nucleus::createNot(Value *v)
828 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500829 if(Ice::isScalarIntegerType(v->getType()))
830 {
Nicolas Capens15060bb2016-12-05 22:17:19 -0500831 return createXor(v, V(::context->getConstantInt(v->getType(), -1)));
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500832 }
833 else // Vector
834 {
Nicolas Capensf34d1ac2017-05-08 17:06:11 -0400835 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 -0500836 return createXor(v, createConstantVector(c, T(v->getType())));
837 }
Nicolas Capens598f8d82016-09-26 15:09:10 -0400838 }
839
Nicolas Capense12780d2016-09-27 14:18:07 -0400840 Value *Nucleus::createLoad(Value *ptr, Type *type, bool isVolatile, unsigned int align)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400841 {
Nicolas Capens23d99a42016-09-30 14:57:16 -0400842 int valueType = (int)reinterpret_cast<intptr_t>(type);
843 Ice::Variable *result = ::function->makeVariable(T(type));
844
Nicolas Capensf4c4eca2017-10-03 14:26:07 -0400845 if((valueType & EmulatedBits) && (align != 0)) // Narrow vector not stored on stack.
Nicolas Capens23d99a42016-09-30 14:57:16 -0400846 {
Nicolas Capens070d9f42017-04-26 13:36:33 -0400847 if(emulateIntrinsics)
848 {
849 if(typeSize(type) == 4)
850 {
851 auto pointer = RValue<Pointer<Byte>>(ptr);
Nicolas Capens1894cfa2017-07-27 14:21:46 -0400852 Int x = *Pointer<Int>(pointer);
Nicolas Capens070d9f42017-04-26 13:36:33 -0400853
854 Int4 vector;
855 vector = Insert(vector, x, 0);
856
857 auto bitcast = Ice::InstCast::create(::function, Ice::InstCast::Bitcast, result, vector.loadValue());
858 ::basicBlock->appendInst(bitcast);
859 }
860 else if(typeSize(type) == 8)
861 {
862 auto pointer = RValue<Pointer<Byte>>(ptr);
Nicolas Capens1894cfa2017-07-27 14:21:46 -0400863 Int x = *Pointer<Int>(pointer);
Nicolas Capens070d9f42017-04-26 13:36:33 -0400864 Int y = *Pointer<Int>(pointer + 4);
865
866 Int4 vector;
867 vector = Insert(vector, x, 0);
868 vector = Insert(vector, y, 1);
869
870 auto bitcast = Ice::InstCast::create(::function, Ice::InstCast::Bitcast, result, vector.loadValue());
871 ::basicBlock->appendInst(bitcast);
872 }
873 else assert(false);
874 }
875 else
876 {
877 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::LoadSubVector, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
878 auto target = ::context->getConstantUndef(Ice::IceType_i32);
879 auto load = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
880 load->addArg(ptr);
881 load->addArg(::context->getConstantInt32(typeSize(type)));
882 ::basicBlock->appendInst(load);
883 }
Nicolas Capens23d99a42016-09-30 14:57:16 -0400884 }
885 else
886 {
887 auto load = Ice::InstLoad::create(::function, result, ptr, align);
888 ::basicBlock->appendInst(load);
889 }
890
891 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400892 }
893
Nicolas Capens6d738712016-09-30 04:15:22 -0400894 Value *Nucleus::createStore(Value *value, Value *ptr, Type *type, bool isVolatile, unsigned int align)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400895 {
Nicolas Capens6a990f82018-07-06 15:54:07 -0400896 #if __has_feature(memory_sanitizer)
897 // Mark all (non-stack) memory writes as initialized by calling __msan_unpoison
898 if(align != 0)
899 {
900 auto call = Ice::InstCall::create(::function, 2, nullptr, ::context->getConstantInt64(reinterpret_cast<intptr_t>(__msan_unpoison)), false);
901 call->addArg(ptr);
902 call->addArg(::context->getConstantInt64(typeSize(type)));
903 ::basicBlock->appendInst(call);
904 }
905 #endif
906
Nicolas Capens23d99a42016-09-30 14:57:16 -0400907 int valueType = (int)reinterpret_cast<intptr_t>(type);
908
Nicolas Capensf4c4eca2017-10-03 14:26:07 -0400909 if((valueType & EmulatedBits) && (align != 0)) // Narrow vector not stored on stack.
Nicolas Capens23d99a42016-09-30 14:57:16 -0400910 {
Nicolas Capens070d9f42017-04-26 13:36:33 -0400911 if(emulateIntrinsics)
912 {
913 if(typeSize(type) == 4)
914 {
915 Ice::Variable *vector = ::function->makeVariable(Ice::IceType_v4i32);
916 auto bitcast = Ice::InstCast::create(::function, Ice::InstCast::Bitcast, vector, value);
917 ::basicBlock->appendInst(bitcast);
918
919 RValue<Int4> v(V(vector));
920
921 auto pointer = RValue<Pointer<Byte>>(ptr);
922 Int x = Extract(v, 0);
923 *Pointer<Int>(pointer) = x;
924 }
925 else if(typeSize(type) == 8)
926 {
927 Ice::Variable *vector = ::function->makeVariable(Ice::IceType_v4i32);
928 auto bitcast = Ice::InstCast::create(::function, Ice::InstCast::Bitcast, vector, value);
929 ::basicBlock->appendInst(bitcast);
930
931 RValue<Int4> v(V(vector));
932
933 auto pointer = RValue<Pointer<Byte>>(ptr);
934 Int x = Extract(v, 0);
935 *Pointer<Int>(pointer) = x;
936 Int y = Extract(v, 1);
937 *Pointer<Int>(pointer + 4) = y;
938 }
939 else assert(false);
940 }
941 else
942 {
943 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::StoreSubVector, Ice::Intrinsics::SideEffects_T, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_T};
944 auto target = ::context->getConstantUndef(Ice::IceType_i32);
945 auto store = Ice::InstIntrinsicCall::create(::function, 3, nullptr, target, intrinsic);
946 store->addArg(value);
947 store->addArg(ptr);
948 store->addArg(::context->getConstantInt32(typeSize(type)));
949 ::basicBlock->appendInst(store);
950 }
Nicolas Capens23d99a42016-09-30 14:57:16 -0400951 }
952 else
953 {
Nicolas Capensf4c4eca2017-10-03 14:26:07 -0400954 assert(value->getType() == T(type));
Nicolas Capens23d99a42016-09-30 14:57:16 -0400955
956 auto store = Ice::InstStore::create(::function, value, ptr, align);
957 ::basicBlock->appendInst(store);
958 }
959
Nicolas Capens598f8d82016-09-26 15:09:10 -0400960 return value;
961 }
962
Nicolas Capensd294def2017-01-26 17:44:37 -0800963 Value *Nucleus::createGEP(Value *ptr, Type *type, Value *index, bool unsignedIndex)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400964 {
Nicolas Capens8820f642016-09-30 04:42:43 -0400965 assert(index->getType() == Ice::IceType_i32);
966
Nicolas Capens15060bb2016-12-05 22:17:19 -0500967 if(auto *constant = llvm::dyn_cast<Ice::ConstantInteger32>(index))
968 {
Nicolas Capens584088c2017-01-26 16:05:18 -0800969 int32_t offset = constant->getValue() * (int)typeSize(type);
Nicolas Capens15060bb2016-12-05 22:17:19 -0500970
971 if(offset == 0)
972 {
973 return ptr;
974 }
975
976 return createAdd(ptr, createConstantInt(offset));
977 }
978
Nicolas Capens8820f642016-09-30 04:42:43 -0400979 if(!Ice::isByteSizedType(T(type)))
980 {
Nicolas Capens584088c2017-01-26 16:05:18 -0800981 index = createMul(index, createConstantInt((int)typeSize(type)));
Nicolas Capens8820f642016-09-30 04:42:43 -0400982 }
983
984 if(sizeof(void*) == 8)
985 {
Nicolas Capensd294def2017-01-26 17:44:37 -0800986 if(unsignedIndex)
987 {
988 index = createZExt(index, T(Ice::IceType_i64));
989 }
990 else
991 {
992 index = createSExt(index, T(Ice::IceType_i64));
993 }
Nicolas Capens8820f642016-09-30 04:42:43 -0400994 }
995
996 return createAdd(ptr, index);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400997 }
998
999 Value *Nucleus::createAtomicAdd(Value *ptr, Value *value)
1000 {
1001 assert(false && "UNIMPLEMENTED"); return nullptr;
1002 }
1003
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001004 static Value *createCast(Ice::InstCast::OpKind op, Value *v, Type *destType)
1005 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04001006 if(v->getType() == T(destType))
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001007 {
1008 return v;
1009 }
1010
1011 Ice::Variable *result = ::function->makeVariable(T(destType));
1012 Ice::InstCast *cast = Ice::InstCast::create(::function, op, result, v);
1013 ::basicBlock->appendInst(cast);
1014
1015 return V(result);
1016 }
1017
Nicolas Capens598f8d82016-09-26 15:09:10 -04001018 Value *Nucleus::createTrunc(Value *v, Type *destType)
1019 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001020 return createCast(Ice::InstCast::Trunc, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001021 }
1022
1023 Value *Nucleus::createZExt(Value *v, Type *destType)
1024 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001025 return createCast(Ice::InstCast::Zext, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001026 }
1027
1028 Value *Nucleus::createSExt(Value *v, Type *destType)
1029 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001030 return createCast(Ice::InstCast::Sext, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001031 }
1032
1033 Value *Nucleus::createFPToSI(Value *v, Type *destType)
1034 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001035 return createCast(Ice::InstCast::Fptosi, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001036 }
1037
Nicolas Capens598f8d82016-09-26 15:09:10 -04001038 Value *Nucleus::createSIToFP(Value *v, Type *destType)
1039 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001040 return createCast(Ice::InstCast::Sitofp, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001041 }
1042
1043 Value *Nucleus::createFPTrunc(Value *v, Type *destType)
1044 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001045 return createCast(Ice::InstCast::Fptrunc, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001046 }
1047
1048 Value *Nucleus::createFPExt(Value *v, Type *destType)
1049 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001050 return createCast(Ice::InstCast::Fpext, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001051 }
1052
1053 Value *Nucleus::createBitCast(Value *v, Type *destType)
1054 {
Nicolas Capens2d8c3702017-07-25 13:56:46 -04001055 // Bitcasts must be between types of the same logical size. But with emulated narrow vectors we need
1056 // support for casting between scalars and wide vectors. For platforms where this is not supported,
1057 // emulate them by writing to the stack and reading back as the destination type.
1058 if(emulateMismatchedBitCast)
1059 {
1060 if(!Ice::isVectorType(v->getType()) && Ice::isVectorType(T(destType)))
1061 {
1062 Value *address = allocateStackVariable(destType);
1063 createStore(v, address, T(v->getType()));
1064 return createLoad(address, destType);
1065 }
1066 else if(Ice::isVectorType(v->getType()) && !Ice::isVectorType(T(destType)))
1067 {
1068 Value *address = allocateStackVariable(T(v->getType()));
1069 createStore(v, address, T(v->getType()));
1070 return createLoad(address, destType);
1071 }
1072 }
1073
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001074 return createCast(Ice::InstCast::Bitcast, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001075 }
1076
Nicolas Capens43dc6292016-10-20 00:01:38 -04001077 static Value *createIntCompare(Ice::InstIcmp::ICond condition, Value *lhs, Value *rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001078 {
Nicolas Capens611642a2016-09-28 16:45:04 -04001079 assert(lhs->getType() == rhs->getType());
1080
Nicolas Capens43dc6292016-10-20 00:01:38 -04001081 auto result = ::function->makeVariable(Ice::isScalarIntegerType(lhs->getType()) ? Ice::IceType_i1 : lhs->getType());
1082 auto cmp = Ice::InstIcmp::create(::function, condition, result, lhs, rhs);
Nicolas Capens611642a2016-09-28 16:45:04 -04001083 ::basicBlock->appendInst(cmp);
1084
1085 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001086 }
1087
Nicolas Capens43dc6292016-10-20 00:01:38 -04001088 Value *Nucleus::createICmpEQ(Value *lhs, Value *rhs)
1089 {
1090 return createIntCompare(Ice::InstIcmp::Eq, lhs, rhs);
1091 }
1092
1093 Value *Nucleus::createICmpNE(Value *lhs, Value *rhs)
1094 {
1095 return createIntCompare(Ice::InstIcmp::Ne, lhs, rhs);
1096 }
1097
1098 Value *Nucleus::createICmpUGT(Value *lhs, Value *rhs)
1099 {
1100 return createIntCompare(Ice::InstIcmp::Ugt, lhs, rhs);
1101 }
1102
1103 Value *Nucleus::createICmpUGE(Value *lhs, Value *rhs)
1104 {
1105 return createIntCompare(Ice::InstIcmp::Uge, lhs, rhs);
1106 }
1107
1108 Value *Nucleus::createICmpULT(Value *lhs, Value *rhs)
1109 {
1110 return createIntCompare(Ice::InstIcmp::Ult, lhs, rhs);
1111 }
1112
1113 Value *Nucleus::createICmpULE(Value *lhs, Value *rhs)
1114 {
1115 return createIntCompare(Ice::InstIcmp::Ule, lhs, rhs);
1116 }
1117
1118 Value *Nucleus::createICmpSGT(Value *lhs, Value *rhs)
1119 {
1120 return createIntCompare(Ice::InstIcmp::Sgt, lhs, rhs);
1121 }
1122
1123 Value *Nucleus::createICmpSGE(Value *lhs, Value *rhs)
1124 {
1125 return createIntCompare(Ice::InstIcmp::Sge, lhs, rhs);
1126 }
1127
1128 Value *Nucleus::createICmpSLT(Value *lhs, Value *rhs)
1129 {
1130 return createIntCompare(Ice::InstIcmp::Slt, lhs, rhs);
1131 }
1132
Nicolas Capens598f8d82016-09-26 15:09:10 -04001133 Value *Nucleus::createICmpSLE(Value *lhs, Value *rhs)
1134 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001135 return createIntCompare(Ice::InstIcmp::Sle, lhs, rhs);
1136 }
1137
1138 static Value *createFloatCompare(Ice::InstFcmp::FCond condition, Value *lhs, Value *rhs)
1139 {
1140 assert(lhs->getType() == rhs->getType());
1141 assert(Ice::isScalarFloatingType(lhs->getType()) || lhs->getType() == Ice::IceType_v4f32);
1142
1143 auto result = ::function->makeVariable(Ice::isScalarFloatingType(lhs->getType()) ? Ice::IceType_i1 : Ice::IceType_v4i32);
1144 auto cmp = Ice::InstFcmp::create(::function, condition, result, lhs, rhs);
1145 ::basicBlock->appendInst(cmp);
1146
1147 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001148 }
1149
1150 Value *Nucleus::createFCmpOEQ(Value *lhs, Value *rhs)
1151 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001152 return createFloatCompare(Ice::InstFcmp::Oeq, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001153 }
1154
1155 Value *Nucleus::createFCmpOGT(Value *lhs, Value *rhs)
1156 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001157 return createFloatCompare(Ice::InstFcmp::Ogt, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001158 }
1159
1160 Value *Nucleus::createFCmpOGE(Value *lhs, Value *rhs)
1161 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001162 return createFloatCompare(Ice::InstFcmp::Oge, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001163 }
1164
1165 Value *Nucleus::createFCmpOLT(Value *lhs, Value *rhs)
1166 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001167 return createFloatCompare(Ice::InstFcmp::Olt, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001168 }
1169
1170 Value *Nucleus::createFCmpOLE(Value *lhs, Value *rhs)
1171 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001172 return createFloatCompare(Ice::InstFcmp::Ole, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001173 }
1174
1175 Value *Nucleus::createFCmpONE(Value *lhs, Value *rhs)
1176 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001177 return createFloatCompare(Ice::InstFcmp::One, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001178 }
1179
1180 Value *Nucleus::createFCmpORD(Value *lhs, Value *rhs)
1181 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001182 return createFloatCompare(Ice::InstFcmp::Ord, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001183 }
1184
1185 Value *Nucleus::createFCmpUNO(Value *lhs, Value *rhs)
1186 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001187 return createFloatCompare(Ice::InstFcmp::Uno, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001188 }
1189
1190 Value *Nucleus::createFCmpUEQ(Value *lhs, Value *rhs)
1191 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001192 return createFloatCompare(Ice::InstFcmp::Ueq, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001193 }
1194
1195 Value *Nucleus::createFCmpUGT(Value *lhs, Value *rhs)
1196 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001197 return createFloatCompare(Ice::InstFcmp::Ugt, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001198 }
1199
1200 Value *Nucleus::createFCmpUGE(Value *lhs, Value *rhs)
1201 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001202 return createFloatCompare(Ice::InstFcmp::Uge, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001203 }
1204
1205 Value *Nucleus::createFCmpULT(Value *lhs, Value *rhs)
1206 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001207 return createFloatCompare(Ice::InstFcmp::Ult, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001208 }
1209
1210 Value *Nucleus::createFCmpULE(Value *lhs, Value *rhs)
1211 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001212 return createFloatCompare(Ice::InstFcmp::Ule, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001213 }
1214
1215 Value *Nucleus::createFCmpUNE(Value *lhs, Value *rhs)
1216 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001217 return createFloatCompare(Ice::InstFcmp::Une, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001218 }
1219
Nicolas Capense95d5342016-09-30 11:37:28 -04001220 Value *Nucleus::createExtractElement(Value *vector, Type *type, int index)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001221 {
Nicolas Capens9709d4f2016-09-30 11:44:14 -04001222 auto result = ::function->makeVariable(T(type));
1223 auto extract = Ice::InstExtractElement::create(::function, result, vector, ::context->getConstantInt32(index));
1224 ::basicBlock->appendInst(extract);
1225
1226 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001227 }
1228
1229 Value *Nucleus::createInsertElement(Value *vector, Value *element, int index)
1230 {
Nicolas Capens9709d4f2016-09-30 11:44:14 -04001231 auto result = ::function->makeVariable(vector->getType());
1232 auto insert = Ice::InstInsertElement::create(::function, result, vector, element, ::context->getConstantInt32(index));
1233 ::basicBlock->appendInst(insert);
1234
1235 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001236 }
1237
Nicolas Capense89cd582016-09-30 14:23:47 -04001238 Value *Nucleus::createShuffleVector(Value *V1, Value *V2, const int *select)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001239 {
Nicolas Capens619c0ab2016-09-30 14:46:24 -04001240 assert(V1->getType() == V2->getType());
1241
1242 int size = Ice::typeNumElements(V1->getType());
1243 auto result = ::function->makeVariable(V1->getType());
1244 auto shuffle = Ice::InstShuffleVector::create(::function, result, V1, V2);
1245
1246 for(int i = 0; i < size; i++)
1247 {
1248 shuffle->addIndex(llvm::cast<Ice::ConstantInteger32>(::context->getConstantInt32(select[i])));
1249 }
1250
1251 ::basicBlock->appendInst(shuffle);
1252
1253 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001254 }
1255
1256 Value *Nucleus::createSelect(Value *C, Value *ifTrue, Value *ifFalse)
1257 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04001258 assert(ifTrue->getType() == ifFalse->getType());
1259
1260 auto result = ::function->makeVariable(ifTrue->getType());
1261 auto *select = Ice::InstSelect::create(::function, result, C, ifTrue, ifFalse);
1262 ::basicBlock->appendInst(select);
1263
1264 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001265 }
1266
Nicolas Capensb98fe5c2016-11-09 12:24:06 -05001267 SwitchCases *Nucleus::createSwitch(Value *control, BasicBlock *defaultBranch, unsigned numCases)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001268 {
Nicolas Capensb98fe5c2016-11-09 12:24:06 -05001269 auto switchInst = Ice::InstSwitch::create(::function, numCases, control, defaultBranch);
1270 ::basicBlock->appendInst(switchInst);
1271
1272 return reinterpret_cast<SwitchCases*>(switchInst);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001273 }
1274
Nicolas Capensb98fe5c2016-11-09 12:24:06 -05001275 void Nucleus::addSwitchCase(SwitchCases *switchCases, int label, BasicBlock *branch)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001276 {
Nicolas Capensb98fe5c2016-11-09 12:24:06 -05001277 switchCases->addBranch(label, label, branch);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001278 }
1279
1280 void Nucleus::createUnreachable()
1281 {
Nicolas Capensfdcca2d2016-10-20 11:31:36 -04001282 Ice::InstUnreachable *unreachable = Ice::InstUnreachable::create(::function);
1283 ::basicBlock->appendInst(unreachable);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001284 }
1285
Nicolas Capense95d5342016-09-30 11:37:28 -04001286 static Value *createSwizzle4(Value *val, unsigned char select)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001287 {
Nicolas Capens619c0ab2016-09-30 14:46:24 -04001288 int swizzle[4] =
1289 {
1290 (select >> 0) & 0x03,
1291 (select >> 2) & 0x03,
1292 (select >> 4) & 0x03,
1293 (select >> 6) & 0x03,
1294 };
Nicolas Capens9709d4f2016-09-30 11:44:14 -04001295
Nicolas Capens619c0ab2016-09-30 14:46:24 -04001296 return Nucleus::createShuffleVector(val, val, swizzle);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001297 }
1298
Nicolas Capense95d5342016-09-30 11:37:28 -04001299 static Value *createMask4(Value *lhs, Value *rhs, unsigned char select)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001300 {
Nicolas Capensa4c30b02016-11-08 15:43:17 -05001301 int64_t mask[4] = {0, 0, 0, 0};
1302
1303 mask[(select >> 0) & 0x03] = -1;
1304 mask[(select >> 2) & 0x03] = -1;
1305 mask[(select >> 4) & 0x03] = -1;
1306 mask[(select >> 6) & 0x03] = -1;
1307
1308 Value *condition = Nucleus::createConstantVector(mask, T(Ice::IceType_v4i1));
1309 Value *result = Nucleus::createSelect(condition, rhs, lhs);
1310
1311 return result;
Nicolas Capens598f8d82016-09-26 15:09:10 -04001312 }
1313
Nicolas Capens598f8d82016-09-26 15:09:10 -04001314 Type *Nucleus::getPointerType(Type *ElementType)
1315 {
Nicolas Capense12780d2016-09-27 14:18:07 -04001316 if(sizeof(void*) == 8)
1317 {
1318 return T(Ice::IceType_i64);
1319 }
1320 else
1321 {
1322 return T(Ice::IceType_i32);
1323 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04001324 }
1325
Nicolas Capens13ac2322016-10-13 14:52:12 -04001326 Value *Nucleus::createNullValue(Type *Ty)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001327 {
Nicolas Capens73dd7a22016-10-20 13:20:34 -04001328 if(Ice::isVectorType(T(Ty)))
1329 {
Nicolas Capens30385f02017-04-18 13:03:47 -04001330 assert(Ice::typeNumElements(T(Ty)) <= 16);
1331 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 -04001332 return createConstantVector(c, Ty);
1333 }
1334 else
1335 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001336 return V(::context->getConstantZero(T(Ty)));
Nicolas Capens73dd7a22016-10-20 13:20:34 -04001337 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04001338 }
1339
Nicolas Capens13ac2322016-10-13 14:52:12 -04001340 Value *Nucleus::createConstantLong(int64_t i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001341 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001342 return V(::context->getConstantInt64(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001343 }
1344
Nicolas Capens13ac2322016-10-13 14:52:12 -04001345 Value *Nucleus::createConstantInt(int i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001346 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001347 return V(::context->getConstantInt32(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001348 }
1349
Nicolas Capens13ac2322016-10-13 14:52:12 -04001350 Value *Nucleus::createConstantInt(unsigned int i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001351 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001352 return V(::context->getConstantInt32(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001353 }
1354
Nicolas Capens13ac2322016-10-13 14:52:12 -04001355 Value *Nucleus::createConstantBool(bool b)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001356 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001357 return V(::context->getConstantInt1(b));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001358 }
1359
Nicolas Capens13ac2322016-10-13 14:52:12 -04001360 Value *Nucleus::createConstantByte(signed char i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001361 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001362 return V(::context->getConstantInt8(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001363 }
1364
Nicolas Capens13ac2322016-10-13 14:52:12 -04001365 Value *Nucleus::createConstantByte(unsigned char i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001366 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001367 return V(::context->getConstantInt8(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001368 }
1369
Nicolas Capens13ac2322016-10-13 14:52:12 -04001370 Value *Nucleus::createConstantShort(short i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001371 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001372 return V(::context->getConstantInt16(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001373 }
1374
Nicolas Capens13ac2322016-10-13 14:52:12 -04001375 Value *Nucleus::createConstantShort(unsigned short i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001376 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001377 return V(::context->getConstantInt16(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001378 }
1379
Nicolas Capens13ac2322016-10-13 14:52:12 -04001380 Value *Nucleus::createConstantFloat(float x)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001381 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001382 return V(::context->getConstantFloat(x));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001383 }
1384
Nicolas Capens13ac2322016-10-13 14:52:12 -04001385 Value *Nucleus::createNullPointer(Type *Ty)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001386 {
Nicolas Capensa29d6532016-12-05 21:38:09 -05001387 return createNullValue(T(sizeof(void*) == 8 ? Ice::IceType_i64 : Ice::IceType_i32));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001388 }
1389
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001390 Value *Nucleus::createConstantVector(const int64_t *constants, Type *type)
Nicolas Capens13ac2322016-10-13 14:52:12 -04001391 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001392 const int vectorSize = 16;
1393 assert(Ice::typeWidthInBytes(T(type)) == vectorSize);
1394 const int alignment = vectorSize;
1395 auto globalPool = ::function->getGlobalPool();
1396
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001397 const int64_t *i = constants;
1398 const double *f = reinterpret_cast<const double*>(constants);
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001399 Ice::VariableDeclaration::DataInitializer *dataInitializer = nullptr;
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001400
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001401 switch((int)reinterpret_cast<intptr_t>(type))
1402 {
1403 case Ice::IceType_v4i32:
Nicolas Capensa4c30b02016-11-08 15:43:17 -05001404 case Ice::IceType_v4i1:
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001405 {
1406 const int initializer[4] = {(int)i[0], (int)i[1], (int)i[2], (int)i[3]};
1407 static_assert(sizeof(initializer) == vectorSize, "!");
1408 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1409 }
1410 break;
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001411 case Ice::IceType_v4f32:
1412 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001413 const float initializer[4] = {(float)f[0], (float)f[1], (float)f[2], (float)f[3]};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001414 static_assert(sizeof(initializer) == vectorSize, "!");
1415 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1416 }
1417 break;
1418 case Ice::IceType_v8i16:
Nicolas Capensa4c30b02016-11-08 15:43:17 -05001419 case Ice::IceType_v8i1:
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001420 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001421 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 -04001422 static_assert(sizeof(initializer) == vectorSize, "!");
1423 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1424 }
1425 break;
1426 case Ice::IceType_v16i8:
Nicolas Capensa4c30b02016-11-08 15:43:17 -05001427 case Ice::IceType_v16i1:
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001428 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001429 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 -04001430 static_assert(sizeof(initializer) == vectorSize, "!");
1431 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1432 }
1433 break;
1434 case Type_v2i32:
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001435 {
1436 const int initializer[4] = {(int)i[0], (int)i[1], (int)i[0], (int)i[1]};
1437 static_assert(sizeof(initializer) == vectorSize, "!");
1438 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1439 }
1440 break;
Nicolas Capens4cfd4572016-10-20 01:00:19 -04001441 case Type_v2f32:
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001442 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001443 const float initializer[4] = {(float)f[0], (float)f[1], (float)f[0], (float)f[1]};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001444 static_assert(sizeof(initializer) == vectorSize, "!");
1445 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1446 }
1447 break;
1448 case Type_v4i16:
1449 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001450 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 -04001451 static_assert(sizeof(initializer) == vectorSize, "!");
1452 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1453 }
1454 break;
1455 case Type_v8i8:
1456 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001457 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 -04001458 static_assert(sizeof(initializer) == vectorSize, "!");
1459 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1460 }
1461 break;
1462 case Type_v4i8:
1463 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001464 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 -04001465 static_assert(sizeof(initializer) == vectorSize, "!");
1466 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1467 }
1468 break;
1469 default:
1470 assert(false && "Unknown constant vector type" && type);
1471 }
1472
1473 auto name = Ice::GlobalString::createWithoutString(::context);
1474 auto *variableDeclaration = Ice::VariableDeclaration::create(globalPool);
1475 variableDeclaration->setName(name);
1476 variableDeclaration->setAlignment(alignment);
1477 variableDeclaration->setIsConstant(true);
1478 variableDeclaration->addInitializer(dataInitializer);
Nicolas Capens87852e12016-11-24 14:45:06 -05001479
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001480 ::function->addGlobal(variableDeclaration);
1481
1482 constexpr int32_t offset = 0;
1483 Ice::Operand *ptr = ::context->getConstantSym(offset, name);
1484
1485 Ice::Variable *result = ::function->makeVariable(T(type));
1486 auto load = Ice::InstLoad::create(::function, result, ptr, alignment);
1487 ::basicBlock->appendInst(load);
1488
1489 return V(result);
Nicolas Capens13ac2322016-10-13 14:52:12 -04001490 }
1491
1492 Value *Nucleus::createConstantVector(const double *constants, Type *type)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001493 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001494 return createConstantVector((const int64_t*)constants, type);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001495 }
1496
1497 Type *Void::getType()
1498 {
1499 return T(Ice::IceType_void);
1500 }
1501
Nicolas Capens598f8d82016-09-26 15:09:10 -04001502 Bool::Bool(Argument<Bool> argument)
1503 {
1504 storeValue(argument.value);
1505 }
1506
Nicolas Capens598f8d82016-09-26 15:09:10 -04001507 Bool::Bool(bool x)
1508 {
1509 storeValue(Nucleus::createConstantBool(x));
1510 }
1511
1512 Bool::Bool(RValue<Bool> rhs)
1513 {
1514 storeValue(rhs.value);
1515 }
1516
1517 Bool::Bool(const Bool &rhs)
1518 {
1519 Value *value = rhs.loadValue();
1520 storeValue(value);
1521 }
1522
1523 Bool::Bool(const Reference<Bool> &rhs)
1524 {
1525 Value *value = rhs.loadValue();
1526 storeValue(value);
1527 }
1528
Nicolas Capens96d4e092016-11-18 14:22:38 -05001529 RValue<Bool> Bool::operator=(RValue<Bool> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001530 {
1531 storeValue(rhs.value);
1532
1533 return rhs;
1534 }
1535
Nicolas Capens96d4e092016-11-18 14:22:38 -05001536 RValue<Bool> Bool::operator=(const Bool &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001537 {
1538 Value *value = rhs.loadValue();
1539 storeValue(value);
1540
1541 return RValue<Bool>(value);
1542 }
1543
Nicolas Capens96d4e092016-11-18 14:22:38 -05001544 RValue<Bool> Bool::operator=(const Reference<Bool> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001545 {
1546 Value *value = rhs.loadValue();
1547 storeValue(value);
1548
1549 return RValue<Bool>(value);
1550 }
1551
1552 RValue<Bool> operator!(RValue<Bool> val)
1553 {
1554 return RValue<Bool>(Nucleus::createNot(val.value));
1555 }
1556
1557 RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs)
1558 {
1559 return RValue<Bool>(Nucleus::createAnd(lhs.value, rhs.value));
1560 }
1561
1562 RValue<Bool> operator||(RValue<Bool> lhs, RValue<Bool> rhs)
1563 {
1564 return RValue<Bool>(Nucleus::createOr(lhs.value, rhs.value));
1565 }
1566
1567 Type *Bool::getType()
1568 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04001569 return T(Ice::IceType_i1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001570 }
1571
1572 Byte::Byte(Argument<Byte> argument)
1573 {
1574 storeValue(argument.value);
1575 }
1576
1577 Byte::Byte(RValue<Int> cast)
1578 {
1579 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
1580
1581 storeValue(integer);
1582 }
1583
1584 Byte::Byte(RValue<UInt> cast)
1585 {
1586 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
1587
1588 storeValue(integer);
1589 }
1590
1591 Byte::Byte(RValue<UShort> cast)
1592 {
1593 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
1594
1595 storeValue(integer);
1596 }
1597
Nicolas Capens598f8d82016-09-26 15:09:10 -04001598 Byte::Byte(int x)
1599 {
1600 storeValue(Nucleus::createConstantByte((unsigned char)x));
1601 }
1602
1603 Byte::Byte(unsigned char x)
1604 {
1605 storeValue(Nucleus::createConstantByte(x));
1606 }
1607
1608 Byte::Byte(RValue<Byte> rhs)
1609 {
1610 storeValue(rhs.value);
1611 }
1612
1613 Byte::Byte(const Byte &rhs)
1614 {
1615 Value *value = rhs.loadValue();
1616 storeValue(value);
1617 }
1618
1619 Byte::Byte(const Reference<Byte> &rhs)
1620 {
1621 Value *value = rhs.loadValue();
1622 storeValue(value);
1623 }
1624
Nicolas Capens96d4e092016-11-18 14:22:38 -05001625 RValue<Byte> Byte::operator=(RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001626 {
1627 storeValue(rhs.value);
1628
1629 return rhs;
1630 }
1631
Nicolas Capens96d4e092016-11-18 14:22:38 -05001632 RValue<Byte> Byte::operator=(const Byte &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001633 {
1634 Value *value = rhs.loadValue();
1635 storeValue(value);
1636
1637 return RValue<Byte>(value);
1638 }
1639
Nicolas Capens96d4e092016-11-18 14:22:38 -05001640 RValue<Byte> Byte::operator=(const Reference<Byte> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001641 {
1642 Value *value = rhs.loadValue();
1643 storeValue(value);
1644
1645 return RValue<Byte>(value);
1646 }
1647
1648 RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs)
1649 {
1650 return RValue<Byte>(Nucleus::createAdd(lhs.value, rhs.value));
1651 }
1652
1653 RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs)
1654 {
1655 return RValue<Byte>(Nucleus::createSub(lhs.value, rhs.value));
1656 }
1657
1658 RValue<Byte> operator*(RValue<Byte> lhs, RValue<Byte> rhs)
1659 {
1660 return RValue<Byte>(Nucleus::createMul(lhs.value, rhs.value));
1661 }
1662
1663 RValue<Byte> operator/(RValue<Byte> lhs, RValue<Byte> rhs)
1664 {
1665 return RValue<Byte>(Nucleus::createUDiv(lhs.value, rhs.value));
1666 }
1667
1668 RValue<Byte> operator%(RValue<Byte> lhs, RValue<Byte> rhs)
1669 {
1670 return RValue<Byte>(Nucleus::createURem(lhs.value, rhs.value));
1671 }
1672
1673 RValue<Byte> operator&(RValue<Byte> lhs, RValue<Byte> rhs)
1674 {
1675 return RValue<Byte>(Nucleus::createAnd(lhs.value, rhs.value));
1676 }
1677
1678 RValue<Byte> operator|(RValue<Byte> lhs, RValue<Byte> rhs)
1679 {
1680 return RValue<Byte>(Nucleus::createOr(lhs.value, rhs.value));
1681 }
1682
1683 RValue<Byte> operator^(RValue<Byte> lhs, RValue<Byte> rhs)
1684 {
1685 return RValue<Byte>(Nucleus::createXor(lhs.value, rhs.value));
1686 }
1687
1688 RValue<Byte> operator<<(RValue<Byte> lhs, RValue<Byte> rhs)
1689 {
1690 return RValue<Byte>(Nucleus::createShl(lhs.value, rhs.value));
1691 }
1692
1693 RValue<Byte> operator>>(RValue<Byte> lhs, RValue<Byte> rhs)
1694 {
1695 return RValue<Byte>(Nucleus::createLShr(lhs.value, rhs.value));
1696 }
1697
Nicolas Capens96d4e092016-11-18 14:22:38 -05001698 RValue<Byte> operator+=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001699 {
1700 return lhs = lhs + rhs;
1701 }
1702
Nicolas Capens96d4e092016-11-18 14:22:38 -05001703 RValue<Byte> operator-=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001704 {
1705 return lhs = lhs - rhs;
1706 }
1707
Nicolas Capens96d4e092016-11-18 14:22:38 -05001708 RValue<Byte> operator*=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001709 {
1710 return lhs = lhs * rhs;
1711 }
1712
Nicolas Capens96d4e092016-11-18 14:22:38 -05001713 RValue<Byte> operator/=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001714 {
1715 return lhs = lhs / rhs;
1716 }
1717
Nicolas Capens96d4e092016-11-18 14:22:38 -05001718 RValue<Byte> operator%=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001719 {
1720 return lhs = lhs % rhs;
1721 }
1722
Nicolas Capens96d4e092016-11-18 14:22:38 -05001723 RValue<Byte> operator&=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001724 {
1725 return lhs = lhs & rhs;
1726 }
1727
Nicolas Capens96d4e092016-11-18 14:22:38 -05001728 RValue<Byte> operator|=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001729 {
1730 return lhs = lhs | rhs;
1731 }
1732
Nicolas Capens96d4e092016-11-18 14:22:38 -05001733 RValue<Byte> operator^=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001734 {
1735 return lhs = lhs ^ rhs;
1736 }
1737
Nicolas Capens96d4e092016-11-18 14:22:38 -05001738 RValue<Byte> operator<<=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001739 {
1740 return lhs = lhs << rhs;
1741 }
1742
Nicolas Capens96d4e092016-11-18 14:22:38 -05001743 RValue<Byte> operator>>=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001744 {
1745 return lhs = lhs >> rhs;
1746 }
1747
1748 RValue<Byte> operator+(RValue<Byte> val)
1749 {
1750 return val;
1751 }
1752
1753 RValue<Byte> operator-(RValue<Byte> val)
1754 {
1755 return RValue<Byte>(Nucleus::createNeg(val.value));
1756 }
1757
1758 RValue<Byte> operator~(RValue<Byte> val)
1759 {
1760 return RValue<Byte>(Nucleus::createNot(val.value));
1761 }
1762
Nicolas Capens96d4e092016-11-18 14:22:38 -05001763 RValue<Byte> operator++(Byte &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04001764 {
1765 RValue<Byte> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05001766 val += Byte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001767 return res;
1768 }
1769
Nicolas Capens96d4e092016-11-18 14:22:38 -05001770 const Byte &operator++(Byte &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04001771 {
Nicolas Capensd1229402016-11-07 16:05:22 -05001772 val += Byte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001773 return val;
1774 }
1775
Nicolas Capens96d4e092016-11-18 14:22:38 -05001776 RValue<Byte> operator--(Byte &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04001777 {
1778 RValue<Byte> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05001779 val -= Byte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001780 return res;
1781 }
1782
Nicolas Capens96d4e092016-11-18 14:22:38 -05001783 const Byte &operator--(Byte &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04001784 {
Nicolas Capensd1229402016-11-07 16:05:22 -05001785 val -= Byte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001786 return val;
1787 }
1788
1789 RValue<Bool> operator<(RValue<Byte> lhs, RValue<Byte> rhs)
1790 {
1791 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1792 }
1793
1794 RValue<Bool> operator<=(RValue<Byte> lhs, RValue<Byte> rhs)
1795 {
1796 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1797 }
1798
1799 RValue<Bool> operator>(RValue<Byte> lhs, RValue<Byte> rhs)
1800 {
1801 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1802 }
1803
1804 RValue<Bool> operator>=(RValue<Byte> lhs, RValue<Byte> rhs)
1805 {
1806 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1807 }
1808
1809 RValue<Bool> operator!=(RValue<Byte> lhs, RValue<Byte> rhs)
1810 {
1811 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1812 }
1813
1814 RValue<Bool> operator==(RValue<Byte> lhs, RValue<Byte> rhs)
1815 {
1816 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1817 }
1818
1819 Type *Byte::getType()
1820 {
Nicolas Capens6d738712016-09-30 04:15:22 -04001821 return T(Ice::IceType_i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001822 }
1823
1824 SByte::SByte(Argument<SByte> argument)
1825 {
1826 storeValue(argument.value);
1827 }
1828
1829 SByte::SByte(RValue<Int> cast)
1830 {
1831 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1832
1833 storeValue(integer);
1834 }
1835
1836 SByte::SByte(RValue<Short> cast)
1837 {
1838 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1839
1840 storeValue(integer);
1841 }
1842
Nicolas Capens598f8d82016-09-26 15:09:10 -04001843 SByte::SByte(signed char x)
1844 {
1845 storeValue(Nucleus::createConstantByte(x));
1846 }
1847
1848 SByte::SByte(RValue<SByte> rhs)
1849 {
1850 storeValue(rhs.value);
1851 }
1852
1853 SByte::SByte(const SByte &rhs)
1854 {
1855 Value *value = rhs.loadValue();
1856 storeValue(value);
1857 }
1858
1859 SByte::SByte(const Reference<SByte> &rhs)
1860 {
1861 Value *value = rhs.loadValue();
1862 storeValue(value);
1863 }
1864
Nicolas Capens96d4e092016-11-18 14:22:38 -05001865 RValue<SByte> SByte::operator=(RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001866 {
1867 storeValue(rhs.value);
1868
1869 return rhs;
1870 }
1871
Nicolas Capens96d4e092016-11-18 14:22:38 -05001872 RValue<SByte> SByte::operator=(const SByte &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001873 {
1874 Value *value = rhs.loadValue();
1875 storeValue(value);
1876
1877 return RValue<SByte>(value);
1878 }
1879
Nicolas Capens96d4e092016-11-18 14:22:38 -05001880 RValue<SByte> SByte::operator=(const Reference<SByte> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001881 {
1882 Value *value = rhs.loadValue();
1883 storeValue(value);
1884
1885 return RValue<SByte>(value);
1886 }
1887
1888 RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs)
1889 {
1890 return RValue<SByte>(Nucleus::createAdd(lhs.value, rhs.value));
1891 }
1892
1893 RValue<SByte> operator-(RValue<SByte> lhs, RValue<SByte> rhs)
1894 {
1895 return RValue<SByte>(Nucleus::createSub(lhs.value, rhs.value));
1896 }
1897
1898 RValue<SByte> operator*(RValue<SByte> lhs, RValue<SByte> rhs)
1899 {
1900 return RValue<SByte>(Nucleus::createMul(lhs.value, rhs.value));
1901 }
1902
1903 RValue<SByte> operator/(RValue<SByte> lhs, RValue<SByte> rhs)
1904 {
1905 return RValue<SByte>(Nucleus::createSDiv(lhs.value, rhs.value));
1906 }
1907
1908 RValue<SByte> operator%(RValue<SByte> lhs, RValue<SByte> rhs)
1909 {
1910 return RValue<SByte>(Nucleus::createSRem(lhs.value, rhs.value));
1911 }
1912
1913 RValue<SByte> operator&(RValue<SByte> lhs, RValue<SByte> rhs)
1914 {
1915 return RValue<SByte>(Nucleus::createAnd(lhs.value, rhs.value));
1916 }
1917
1918 RValue<SByte> operator|(RValue<SByte> lhs, RValue<SByte> rhs)
1919 {
1920 return RValue<SByte>(Nucleus::createOr(lhs.value, rhs.value));
1921 }
1922
1923 RValue<SByte> operator^(RValue<SByte> lhs, RValue<SByte> rhs)
1924 {
1925 return RValue<SByte>(Nucleus::createXor(lhs.value, rhs.value));
1926 }
1927
1928 RValue<SByte> operator<<(RValue<SByte> lhs, RValue<SByte> rhs)
1929 {
1930 return RValue<SByte>(Nucleus::createShl(lhs.value, rhs.value));
1931 }
1932
1933 RValue<SByte> operator>>(RValue<SByte> lhs, RValue<SByte> rhs)
1934 {
1935 return RValue<SByte>(Nucleus::createAShr(lhs.value, rhs.value));
1936 }
1937
Nicolas Capens96d4e092016-11-18 14:22:38 -05001938 RValue<SByte> operator+=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001939 {
1940 return lhs = lhs + rhs;
1941 }
1942
Nicolas Capens96d4e092016-11-18 14:22:38 -05001943 RValue<SByte> operator-=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001944 {
1945 return lhs = lhs - rhs;
1946 }
1947
Nicolas Capens96d4e092016-11-18 14:22:38 -05001948 RValue<SByte> operator*=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001949 {
1950 return lhs = lhs * rhs;
1951 }
1952
Nicolas Capens96d4e092016-11-18 14:22:38 -05001953 RValue<SByte> operator/=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001954 {
1955 return lhs = lhs / rhs;
1956 }
1957
Nicolas Capens96d4e092016-11-18 14:22:38 -05001958 RValue<SByte> operator%=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001959 {
1960 return lhs = lhs % rhs;
1961 }
1962
Nicolas Capens96d4e092016-11-18 14:22:38 -05001963 RValue<SByte> operator&=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001964 {
1965 return lhs = lhs & rhs;
1966 }
1967
Nicolas Capens96d4e092016-11-18 14:22:38 -05001968 RValue<SByte> operator|=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001969 {
1970 return lhs = lhs | rhs;
1971 }
1972
Nicolas Capens96d4e092016-11-18 14:22:38 -05001973 RValue<SByte> operator^=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001974 {
1975 return lhs = lhs ^ rhs;
1976 }
1977
Nicolas Capens96d4e092016-11-18 14:22:38 -05001978 RValue<SByte> operator<<=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001979 {
1980 return lhs = lhs << rhs;
1981 }
1982
Nicolas Capens96d4e092016-11-18 14:22:38 -05001983 RValue<SByte> operator>>=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001984 {
1985 return lhs = lhs >> rhs;
1986 }
1987
1988 RValue<SByte> operator+(RValue<SByte> val)
1989 {
1990 return val;
1991 }
1992
1993 RValue<SByte> operator-(RValue<SByte> val)
1994 {
1995 return RValue<SByte>(Nucleus::createNeg(val.value));
1996 }
1997
1998 RValue<SByte> operator~(RValue<SByte> val)
1999 {
2000 return RValue<SByte>(Nucleus::createNot(val.value));
2001 }
2002
Nicolas Capens96d4e092016-11-18 14:22:38 -05002003 RValue<SByte> operator++(SByte &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04002004 {
2005 RValue<SByte> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002006 val += SByte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002007 return res;
2008 }
2009
Nicolas Capens96d4e092016-11-18 14:22:38 -05002010 const SByte &operator++(SByte &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04002011 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002012 val += SByte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002013 return val;
2014 }
2015
Nicolas Capens96d4e092016-11-18 14:22:38 -05002016 RValue<SByte> operator--(SByte &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04002017 {
2018 RValue<SByte> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002019 val -= SByte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002020 return res;
2021 }
2022
Nicolas Capens96d4e092016-11-18 14:22:38 -05002023 const SByte &operator--(SByte &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04002024 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002025 val -= SByte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002026 return val;
2027 }
2028
2029 RValue<Bool> operator<(RValue<SByte> lhs, RValue<SByte> rhs)
2030 {
2031 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
2032 }
2033
2034 RValue<Bool> operator<=(RValue<SByte> lhs, RValue<SByte> rhs)
2035 {
2036 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
2037 }
2038
2039 RValue<Bool> operator>(RValue<SByte> lhs, RValue<SByte> rhs)
2040 {
2041 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
2042 }
2043
2044 RValue<Bool> operator>=(RValue<SByte> lhs, RValue<SByte> rhs)
2045 {
2046 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
2047 }
2048
2049 RValue<Bool> operator!=(RValue<SByte> lhs, RValue<SByte> rhs)
2050 {
2051 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
2052 }
2053
2054 RValue<Bool> operator==(RValue<SByte> lhs, RValue<SByte> rhs)
2055 {
2056 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
2057 }
2058
2059 Type *SByte::getType()
2060 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04002061 return T(Ice::IceType_i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002062 }
2063
2064 Short::Short(Argument<Short> argument)
2065 {
2066 storeValue(argument.value);
2067 }
2068
2069 Short::Short(RValue<Int> cast)
2070 {
2071 Value *integer = Nucleus::createTrunc(cast.value, Short::getType());
2072
2073 storeValue(integer);
2074 }
2075
Nicolas Capens598f8d82016-09-26 15:09:10 -04002076 Short::Short(short x)
2077 {
2078 storeValue(Nucleus::createConstantShort(x));
2079 }
2080
2081 Short::Short(RValue<Short> rhs)
2082 {
2083 storeValue(rhs.value);
2084 }
2085
2086 Short::Short(const Short &rhs)
2087 {
2088 Value *value = rhs.loadValue();
2089 storeValue(value);
2090 }
2091
2092 Short::Short(const Reference<Short> &rhs)
2093 {
2094 Value *value = rhs.loadValue();
2095 storeValue(value);
2096 }
2097
Nicolas Capens96d4e092016-11-18 14:22:38 -05002098 RValue<Short> Short::operator=(RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002099 {
2100 storeValue(rhs.value);
2101
2102 return rhs;
2103 }
2104
Nicolas Capens96d4e092016-11-18 14:22:38 -05002105 RValue<Short> Short::operator=(const Short &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002106 {
2107 Value *value = rhs.loadValue();
2108 storeValue(value);
2109
2110 return RValue<Short>(value);
2111 }
2112
Nicolas Capens96d4e092016-11-18 14:22:38 -05002113 RValue<Short> Short::operator=(const Reference<Short> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002114 {
2115 Value *value = rhs.loadValue();
2116 storeValue(value);
2117
2118 return RValue<Short>(value);
2119 }
2120
2121 RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs)
2122 {
2123 return RValue<Short>(Nucleus::createAdd(lhs.value, rhs.value));
2124 }
2125
2126 RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs)
2127 {
2128 return RValue<Short>(Nucleus::createSub(lhs.value, rhs.value));
2129 }
2130
2131 RValue<Short> operator*(RValue<Short> lhs, RValue<Short> rhs)
2132 {
2133 return RValue<Short>(Nucleus::createMul(lhs.value, rhs.value));
2134 }
2135
2136 RValue<Short> operator/(RValue<Short> lhs, RValue<Short> rhs)
2137 {
2138 return RValue<Short>(Nucleus::createSDiv(lhs.value, rhs.value));
2139 }
2140
2141 RValue<Short> operator%(RValue<Short> lhs, RValue<Short> rhs)
2142 {
2143 return RValue<Short>(Nucleus::createSRem(lhs.value, rhs.value));
2144 }
2145
2146 RValue<Short> operator&(RValue<Short> lhs, RValue<Short> rhs)
2147 {
2148 return RValue<Short>(Nucleus::createAnd(lhs.value, rhs.value));
2149 }
2150
2151 RValue<Short> operator|(RValue<Short> lhs, RValue<Short> rhs)
2152 {
2153 return RValue<Short>(Nucleus::createOr(lhs.value, rhs.value));
2154 }
2155
2156 RValue<Short> operator^(RValue<Short> lhs, RValue<Short> rhs)
2157 {
2158 return RValue<Short>(Nucleus::createXor(lhs.value, rhs.value));
2159 }
2160
2161 RValue<Short> operator<<(RValue<Short> lhs, RValue<Short> rhs)
2162 {
2163 return RValue<Short>(Nucleus::createShl(lhs.value, rhs.value));
2164 }
2165
2166 RValue<Short> operator>>(RValue<Short> lhs, RValue<Short> rhs)
2167 {
2168 return RValue<Short>(Nucleus::createAShr(lhs.value, rhs.value));
2169 }
2170
Nicolas Capens96d4e092016-11-18 14:22:38 -05002171 RValue<Short> operator+=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002172 {
2173 return lhs = lhs + rhs;
2174 }
2175
Nicolas Capens96d4e092016-11-18 14:22:38 -05002176 RValue<Short> operator-=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002177 {
2178 return lhs = lhs - rhs;
2179 }
2180
Nicolas Capens96d4e092016-11-18 14:22:38 -05002181 RValue<Short> operator*=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002182 {
2183 return lhs = lhs * rhs;
2184 }
2185
Nicolas Capens96d4e092016-11-18 14:22:38 -05002186 RValue<Short> operator/=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002187 {
2188 return lhs = lhs / rhs;
2189 }
2190
Nicolas Capens96d4e092016-11-18 14:22:38 -05002191 RValue<Short> operator%=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002192 {
2193 return lhs = lhs % rhs;
2194 }
2195
Nicolas Capens96d4e092016-11-18 14:22:38 -05002196 RValue<Short> operator&=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002197 {
2198 return lhs = lhs & rhs;
2199 }
2200
Nicolas Capens96d4e092016-11-18 14:22:38 -05002201 RValue<Short> operator|=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002202 {
2203 return lhs = lhs | rhs;
2204 }
2205
Nicolas Capens96d4e092016-11-18 14:22:38 -05002206 RValue<Short> operator^=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002207 {
2208 return lhs = lhs ^ rhs;
2209 }
2210
Nicolas Capens96d4e092016-11-18 14:22:38 -05002211 RValue<Short> operator<<=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002212 {
2213 return lhs = lhs << rhs;
2214 }
2215
Nicolas Capens96d4e092016-11-18 14:22:38 -05002216 RValue<Short> operator>>=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002217 {
2218 return lhs = lhs >> rhs;
2219 }
2220
2221 RValue<Short> operator+(RValue<Short> val)
2222 {
2223 return val;
2224 }
2225
2226 RValue<Short> operator-(RValue<Short> val)
2227 {
2228 return RValue<Short>(Nucleus::createNeg(val.value));
2229 }
2230
2231 RValue<Short> operator~(RValue<Short> val)
2232 {
2233 return RValue<Short>(Nucleus::createNot(val.value));
2234 }
2235
Nicolas Capens96d4e092016-11-18 14:22:38 -05002236 RValue<Short> operator++(Short &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04002237 {
2238 RValue<Short> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002239 val += Short(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002240 return res;
2241 }
2242
Nicolas Capens96d4e092016-11-18 14:22:38 -05002243 const Short &operator++(Short &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04002244 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002245 val += Short(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002246 return val;
2247 }
2248
Nicolas Capens96d4e092016-11-18 14:22:38 -05002249 RValue<Short> operator--(Short &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04002250 {
2251 RValue<Short> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002252 val -= Short(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002253 return res;
2254 }
2255
Nicolas Capens96d4e092016-11-18 14:22:38 -05002256 const Short &operator--(Short &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04002257 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002258 val -= Short(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002259 return val;
2260 }
2261
2262 RValue<Bool> operator<(RValue<Short> lhs, RValue<Short> rhs)
2263 {
2264 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
2265 }
2266
2267 RValue<Bool> operator<=(RValue<Short> lhs, RValue<Short> rhs)
2268 {
2269 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
2270 }
2271
2272 RValue<Bool> operator>(RValue<Short> lhs, RValue<Short> rhs)
2273 {
2274 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
2275 }
2276
2277 RValue<Bool> operator>=(RValue<Short> lhs, RValue<Short> rhs)
2278 {
2279 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
2280 }
2281
2282 RValue<Bool> operator!=(RValue<Short> lhs, RValue<Short> rhs)
2283 {
2284 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
2285 }
2286
2287 RValue<Bool> operator==(RValue<Short> lhs, RValue<Short> rhs)
2288 {
2289 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
2290 }
2291
2292 Type *Short::getType()
2293 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04002294 return T(Ice::IceType_i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002295 }
2296
2297 UShort::UShort(Argument<UShort> argument)
2298 {
2299 storeValue(argument.value);
2300 }
2301
2302 UShort::UShort(RValue<UInt> cast)
2303 {
2304 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
2305
2306 storeValue(integer);
2307 }
2308
2309 UShort::UShort(RValue<Int> cast)
2310 {
2311 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
2312
2313 storeValue(integer);
2314 }
2315
Nicolas Capens598f8d82016-09-26 15:09:10 -04002316 UShort::UShort(unsigned short x)
2317 {
2318 storeValue(Nucleus::createConstantShort(x));
2319 }
2320
2321 UShort::UShort(RValue<UShort> rhs)
2322 {
2323 storeValue(rhs.value);
2324 }
2325
2326 UShort::UShort(const UShort &rhs)
2327 {
2328 Value *value = rhs.loadValue();
2329 storeValue(value);
2330 }
2331
2332 UShort::UShort(const Reference<UShort> &rhs)
2333 {
2334 Value *value = rhs.loadValue();
2335 storeValue(value);
2336 }
2337
Nicolas Capens96d4e092016-11-18 14:22:38 -05002338 RValue<UShort> UShort::operator=(RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002339 {
2340 storeValue(rhs.value);
2341
2342 return rhs;
2343 }
2344
Nicolas Capens96d4e092016-11-18 14:22:38 -05002345 RValue<UShort> UShort::operator=(const UShort &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002346 {
2347 Value *value = rhs.loadValue();
2348 storeValue(value);
2349
2350 return RValue<UShort>(value);
2351 }
2352
Nicolas Capens96d4e092016-11-18 14:22:38 -05002353 RValue<UShort> UShort::operator=(const Reference<UShort> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002354 {
2355 Value *value = rhs.loadValue();
2356 storeValue(value);
2357
2358 return RValue<UShort>(value);
2359 }
2360
2361 RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs)
2362 {
2363 return RValue<UShort>(Nucleus::createAdd(lhs.value, rhs.value));
2364 }
2365
2366 RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs)
2367 {
2368 return RValue<UShort>(Nucleus::createSub(lhs.value, rhs.value));
2369 }
2370
2371 RValue<UShort> operator*(RValue<UShort> lhs, RValue<UShort> rhs)
2372 {
2373 return RValue<UShort>(Nucleus::createMul(lhs.value, rhs.value));
2374 }
2375
2376 RValue<UShort> operator/(RValue<UShort> lhs, RValue<UShort> rhs)
2377 {
2378 return RValue<UShort>(Nucleus::createUDiv(lhs.value, rhs.value));
2379 }
2380
2381 RValue<UShort> operator%(RValue<UShort> lhs, RValue<UShort> rhs)
2382 {
2383 return RValue<UShort>(Nucleus::createURem(lhs.value, rhs.value));
2384 }
2385
2386 RValue<UShort> operator&(RValue<UShort> lhs, RValue<UShort> rhs)
2387 {
2388 return RValue<UShort>(Nucleus::createAnd(lhs.value, rhs.value));
2389 }
2390
2391 RValue<UShort> operator|(RValue<UShort> lhs, RValue<UShort> rhs)
2392 {
2393 return RValue<UShort>(Nucleus::createOr(lhs.value, rhs.value));
2394 }
2395
2396 RValue<UShort> operator^(RValue<UShort> lhs, RValue<UShort> rhs)
2397 {
2398 return RValue<UShort>(Nucleus::createXor(lhs.value, rhs.value));
2399 }
2400
2401 RValue<UShort> operator<<(RValue<UShort> lhs, RValue<UShort> rhs)
2402 {
2403 return RValue<UShort>(Nucleus::createShl(lhs.value, rhs.value));
2404 }
2405
2406 RValue<UShort> operator>>(RValue<UShort> lhs, RValue<UShort> rhs)
2407 {
2408 return RValue<UShort>(Nucleus::createLShr(lhs.value, rhs.value));
2409 }
2410
Nicolas Capens96d4e092016-11-18 14:22:38 -05002411 RValue<UShort> operator+=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002412 {
2413 return lhs = lhs + rhs;
2414 }
2415
Nicolas Capens96d4e092016-11-18 14:22:38 -05002416 RValue<UShort> operator-=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002417 {
2418 return lhs = lhs - rhs;
2419 }
2420
Nicolas Capens96d4e092016-11-18 14:22:38 -05002421 RValue<UShort> operator*=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002422 {
2423 return lhs = lhs * rhs;
2424 }
2425
Nicolas Capens96d4e092016-11-18 14:22:38 -05002426 RValue<UShort> operator/=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002427 {
2428 return lhs = lhs / rhs;
2429 }
2430
Nicolas Capens96d4e092016-11-18 14:22:38 -05002431 RValue<UShort> operator%=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002432 {
2433 return lhs = lhs % rhs;
2434 }
2435
Nicolas Capens96d4e092016-11-18 14:22:38 -05002436 RValue<UShort> operator&=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002437 {
2438 return lhs = lhs & rhs;
2439 }
2440
Nicolas Capens96d4e092016-11-18 14:22:38 -05002441 RValue<UShort> operator|=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002442 {
2443 return lhs = lhs | rhs;
2444 }
2445
Nicolas Capens96d4e092016-11-18 14:22:38 -05002446 RValue<UShort> operator^=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002447 {
2448 return lhs = lhs ^ rhs;
2449 }
2450
Nicolas Capens96d4e092016-11-18 14:22:38 -05002451 RValue<UShort> operator<<=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002452 {
2453 return lhs = lhs << rhs;
2454 }
2455
Nicolas Capens96d4e092016-11-18 14:22:38 -05002456 RValue<UShort> operator>>=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002457 {
2458 return lhs = lhs >> rhs;
2459 }
2460
2461 RValue<UShort> operator+(RValue<UShort> val)
2462 {
2463 return val;
2464 }
2465
2466 RValue<UShort> operator-(RValue<UShort> val)
2467 {
2468 return RValue<UShort>(Nucleus::createNeg(val.value));
2469 }
2470
2471 RValue<UShort> operator~(RValue<UShort> val)
2472 {
2473 return RValue<UShort>(Nucleus::createNot(val.value));
2474 }
2475
Nicolas Capens96d4e092016-11-18 14:22:38 -05002476 RValue<UShort> operator++(UShort &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04002477 {
2478 RValue<UShort> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002479 val += UShort(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002480 return res;
2481 }
2482
Nicolas Capens96d4e092016-11-18 14:22:38 -05002483 const UShort &operator++(UShort &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04002484 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002485 val += UShort(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002486 return val;
2487 }
2488
Nicolas Capens96d4e092016-11-18 14:22:38 -05002489 RValue<UShort> operator--(UShort &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04002490 {
2491 RValue<UShort> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002492 val -= UShort(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002493 return res;
2494 }
2495
Nicolas Capens96d4e092016-11-18 14:22:38 -05002496 const UShort &operator--(UShort &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04002497 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002498 val -= UShort(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002499 return val;
2500 }
2501
2502 RValue<Bool> operator<(RValue<UShort> lhs, RValue<UShort> rhs)
2503 {
2504 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
2505 }
2506
2507 RValue<Bool> operator<=(RValue<UShort> lhs, RValue<UShort> rhs)
2508 {
2509 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
2510 }
2511
2512 RValue<Bool> operator>(RValue<UShort> lhs, RValue<UShort> rhs)
2513 {
2514 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
2515 }
2516
2517 RValue<Bool> operator>=(RValue<UShort> lhs, RValue<UShort> rhs)
2518 {
2519 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
2520 }
2521
2522 RValue<Bool> operator!=(RValue<UShort> lhs, RValue<UShort> rhs)
2523 {
2524 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
2525 }
2526
2527 RValue<Bool> operator==(RValue<UShort> lhs, RValue<UShort> rhs)
2528 {
2529 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
2530 }
2531
2532 Type *UShort::getType()
2533 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04002534 return T(Ice::IceType_i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002535 }
2536
Nicolas Capens16b5f152016-10-13 13:39:01 -04002537 Byte4::Byte4(RValue<Byte8> cast)
2538 {
Nicolas Capens16b5f152016-10-13 13:39:01 -04002539 storeValue(Nucleus::createBitCast(cast.value, getType()));
2540 }
2541
2542 Byte4::Byte4(const Reference<Byte4> &rhs)
2543 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002544 Value *value = rhs.loadValue();
2545 storeValue(value);
Nicolas Capens16b5f152016-10-13 13:39:01 -04002546 }
2547
Nicolas Capens598f8d82016-09-26 15:09:10 -04002548 Type *Byte4::getType()
2549 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04002550 return T(Type_v4i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002551 }
2552
2553 Type *SByte4::getType()
2554 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04002555 return T(Type_v4i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002556 }
2557
Nicolas Capens598f8d82016-09-26 15:09:10 -04002558 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)
2559 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04002560 int64_t constantVector[8] = {x0, x1, x2, x3, x4, x5, x6, x7};
2561 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002562 }
2563
2564 Byte8::Byte8(RValue<Byte8> rhs)
2565 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002566 storeValue(rhs.value);
2567 }
2568
2569 Byte8::Byte8(const Byte8 &rhs)
2570 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002571 Value *value = rhs.loadValue();
2572 storeValue(value);
2573 }
2574
2575 Byte8::Byte8(const Reference<Byte8> &rhs)
2576 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002577 Value *value = rhs.loadValue();
2578 storeValue(value);
2579 }
2580
Nicolas Capens96d4e092016-11-18 14:22:38 -05002581 RValue<Byte8> Byte8::operator=(RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002582 {
2583 storeValue(rhs.value);
2584
2585 return rhs;
2586 }
2587
Nicolas Capens96d4e092016-11-18 14:22:38 -05002588 RValue<Byte8> Byte8::operator=(const Byte8 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002589 {
2590 Value *value = rhs.loadValue();
2591 storeValue(value);
2592
2593 return RValue<Byte8>(value);
2594 }
2595
Nicolas Capens96d4e092016-11-18 14:22:38 -05002596 RValue<Byte8> Byte8::operator=(const Reference<Byte8> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002597 {
2598 Value *value = rhs.loadValue();
2599 storeValue(value);
2600
2601 return RValue<Byte8>(value);
2602 }
2603
2604 RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs)
2605 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002606 return RValue<Byte8>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002607 }
2608
2609 RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs)
2610 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002611 return RValue<Byte8>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002612 }
2613
2614// RValue<Byte8> operator*(RValue<Byte8> lhs, RValue<Byte8> rhs)
2615// {
2616// return RValue<Byte8>(Nucleus::createMul(lhs.value, rhs.value));
2617// }
2618
2619// RValue<Byte8> operator/(RValue<Byte8> lhs, RValue<Byte8> rhs)
2620// {
2621// return RValue<Byte8>(Nucleus::createUDiv(lhs.value, rhs.value));
2622// }
2623
2624// RValue<Byte8> operator%(RValue<Byte8> lhs, RValue<Byte8> rhs)
2625// {
2626// return RValue<Byte8>(Nucleus::createURem(lhs.value, rhs.value));
2627// }
2628
2629 RValue<Byte8> operator&(RValue<Byte8> lhs, RValue<Byte8> rhs)
2630 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002631 return RValue<Byte8>(Nucleus::createAnd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002632 }
2633
2634 RValue<Byte8> operator|(RValue<Byte8> lhs, RValue<Byte8> rhs)
2635 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002636 return RValue<Byte8>(Nucleus::createOr(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002637 }
2638
2639 RValue<Byte8> operator^(RValue<Byte8> lhs, RValue<Byte8> rhs)
2640 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002641 return RValue<Byte8>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002642 }
2643
2644// RValue<Byte8> operator<<(RValue<Byte8> lhs, unsigned char rhs)
2645// {
Nicolas Capens15060bb2016-12-05 22:17:19 -05002646// return RValue<Byte8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002647// }
2648
2649// RValue<Byte8> operator>>(RValue<Byte8> lhs, unsigned char rhs)
2650// {
Nicolas Capens15060bb2016-12-05 22:17:19 -05002651// return RValue<Byte8>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002652// }
2653
Nicolas Capens96d4e092016-11-18 14:22:38 -05002654 RValue<Byte8> operator+=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002655 {
2656 return lhs = lhs + rhs;
2657 }
2658
Nicolas Capens96d4e092016-11-18 14:22:38 -05002659 RValue<Byte8> operator-=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002660 {
2661 return lhs = lhs - rhs;
2662 }
2663
Nicolas Capens96d4e092016-11-18 14:22:38 -05002664// RValue<Byte8> operator*=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002665// {
2666// return lhs = lhs * rhs;
2667// }
2668
Nicolas Capens96d4e092016-11-18 14:22:38 -05002669// RValue<Byte8> operator/=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002670// {
2671// return lhs = lhs / rhs;
2672// }
2673
Nicolas Capens96d4e092016-11-18 14:22:38 -05002674// RValue<Byte8> operator%=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002675// {
2676// return lhs = lhs % rhs;
2677// }
2678
Nicolas Capens96d4e092016-11-18 14:22:38 -05002679 RValue<Byte8> operator&=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002680 {
2681 return lhs = lhs & rhs;
2682 }
2683
Nicolas Capens96d4e092016-11-18 14:22:38 -05002684 RValue<Byte8> operator|=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002685 {
2686 return lhs = lhs | rhs;
2687 }
2688
Nicolas Capens96d4e092016-11-18 14:22:38 -05002689 RValue<Byte8> operator^=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002690 {
2691 return lhs = lhs ^ rhs;
2692 }
2693
Nicolas Capens96d4e092016-11-18 14:22:38 -05002694// RValue<Byte8> operator<<=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002695// {
2696// return lhs = lhs << rhs;
2697// }
2698
Nicolas Capens96d4e092016-11-18 14:22:38 -05002699// RValue<Byte8> operator>>=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002700// {
2701// return lhs = lhs >> rhs;
2702// }
2703
2704// RValue<Byte8> operator+(RValue<Byte8> val)
2705// {
2706// return val;
2707// }
2708
2709// RValue<Byte8> operator-(RValue<Byte8> val)
2710// {
2711// return RValue<Byte8>(Nucleus::createNeg(val.value));
2712// }
2713
2714 RValue<Byte8> operator~(RValue<Byte8> val)
2715 {
2716 return RValue<Byte8>(Nucleus::createNot(val.value));
2717 }
2718
Nicolas Capensd6cacad2017-07-25 15:32:12 -04002719 RValue<Byte> Extract(RValue<Byte8> val, int i)
2720 {
2721 return RValue<Byte>(Nucleus::createExtractElement(val.value, Byte::getType(), i));
2722 }
2723
2724 RValue<Byte8> Insert(RValue<Byte8> val, RValue<Byte> element, int i)
2725 {
2726 return RValue<Byte8>(Nucleus::createInsertElement(val.value, element.value, i));
2727 }
2728
Nicolas Capens33438a62017-09-27 11:47:35 -04002729 RValue<Byte> SaturateUnsigned(RValue<Short> x)
Nicolas Capens98436732017-07-25 15:32:12 -04002730 {
Nicolas Capens7f301812017-10-02 17:32:34 -04002731 return Byte(IfThenElse(Int(x) > 0xFF, Int(0xFF), IfThenElse(Int(x) < 0, Int(0), Int(x))));
Nicolas Capens98436732017-07-25 15:32:12 -04002732 }
2733
Nicolas Capens598f8d82016-09-26 15:09:10 -04002734 RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y)
2735 {
Nicolas Capens98436732017-07-25 15:32:12 -04002736 if(emulateIntrinsics)
2737 {
2738 Byte8 result;
Nicolas Capens33438a62017-09-27 11:47:35 -04002739 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 0)) + Int(Extract(y, 0)))), 0);
2740 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 1)) + Int(Extract(y, 1)))), 1);
2741 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 2)) + Int(Extract(y, 2)))), 2);
2742 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 3)) + Int(Extract(y, 3)))), 3);
2743 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 4)) + Int(Extract(y, 4)))), 4);
2744 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 5)) + Int(Extract(y, 5)))), 5);
2745 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 6)) + Int(Extract(y, 6)))), 6);
2746 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 7)) + Int(Extract(y, 7)))), 7);
Nicolas Capensc71bed22016-11-07 22:25:14 -05002747
Nicolas Capens98436732017-07-25 15:32:12 -04002748 return result;
2749 }
2750 else
2751 {
2752 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
2753 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2754 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2755 auto paddusb = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
2756 paddusb->addArg(x.value);
2757 paddusb->addArg(y.value);
2758 ::basicBlock->appendInst(paddusb);
2759
2760 return RValue<Byte8>(V(result));
2761 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04002762 }
2763
2764 RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y)
2765 {
Nicolas Capens98436732017-07-25 15:32:12 -04002766 if(emulateIntrinsics)
2767 {
2768 Byte8 result;
Nicolas Capens33438a62017-09-27 11:47:35 -04002769 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 0)) - Int(Extract(y, 0)))), 0);
2770 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 1)) - Int(Extract(y, 1)))), 1);
2771 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 2)) - Int(Extract(y, 2)))), 2);
2772 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 3)) - Int(Extract(y, 3)))), 3);
2773 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 4)) - Int(Extract(y, 4)))), 4);
2774 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 5)) - Int(Extract(y, 5)))), 5);
2775 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 6)) - Int(Extract(y, 6)))), 6);
2776 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 7)) - Int(Extract(y, 7)))), 7);
Nicolas Capensc71bed22016-11-07 22:25:14 -05002777
Nicolas Capens98436732017-07-25 15:32:12 -04002778 return result;
2779 }
2780 else
2781 {
2782 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
2783 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2784 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2785 auto psubusw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
2786 psubusw->addArg(x.value);
2787 psubusw->addArg(y.value);
2788 ::basicBlock->appendInst(psubusw);
2789
2790 return RValue<Byte8>(V(result));
2791 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04002792 }
2793
2794 RValue<Short4> Unpack(RValue<Byte4> x)
2795 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04002796 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 -04002797 return As<Short4>(Nucleus::createShuffleVector(x.value, x.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002798 }
2799
Nicolas Capens411273e2017-01-26 15:13:36 -08002800 RValue<Short4> Unpack(RValue<Byte4> x, RValue<Byte4> y)
2801 {
2802 return UnpackLow(As<Byte8>(x), As<Byte8>(y));
2803 }
2804
Nicolas Capens598f8d82016-09-26 15:09:10 -04002805 RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y)
2806 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04002807 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 -04002808 return As<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002809 }
2810
2811 RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y)
2812 {
Nicolas Capens20e22c42016-10-25 17:32:37 -04002813 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
2814 auto lowHigh = RValue<Byte16>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
2815 return As<Short4>(Swizzle(As<Int4>(lowHigh), 0xEE));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002816 }
2817
Nicolas Capensd6cacad2017-07-25 15:32:12 -04002818 RValue<SByte> Extract(RValue<SByte8> val, int i)
2819 {
2820 return RValue<SByte>(Nucleus::createExtractElement(val.value, SByte::getType(), i));
2821 }
2822
2823 RValue<SByte8> Insert(RValue<SByte8> val, RValue<SByte> element, int i)
2824 {
2825 return RValue<SByte8>(Nucleus::createInsertElement(val.value, element.value, i));
2826 }
2827
2828 RValue<SByte8> operator>>(RValue<SByte8> lhs, unsigned char rhs)
2829 {
2830 if(emulateIntrinsics)
2831 {
2832 SByte8 result;
2833 result = Insert(result, Extract(lhs, 0) >> SByte(rhs), 0);
2834 result = Insert(result, Extract(lhs, 1) >> SByte(rhs), 1);
2835 result = Insert(result, Extract(lhs, 2) >> SByte(rhs), 2);
2836 result = Insert(result, Extract(lhs, 3) >> SByte(rhs), 3);
2837 result = Insert(result, Extract(lhs, 4) >> SByte(rhs), 4);
2838 result = Insert(result, Extract(lhs, 5) >> SByte(rhs), 5);
2839 result = Insert(result, Extract(lhs, 6) >> SByte(rhs), 6);
2840 result = Insert(result, Extract(lhs, 7) >> SByte(rhs), 7);
2841
2842 return result;
2843 }
2844 else
2845 {
2846 #if defined(__i386__) || defined(__x86_64__)
2847 // SSE2 doesn't support byte vector shifts, so shift as shorts and recombine.
Alexis Hetue18c5302017-08-04 11:48:17 -04002848 RValue<Short4> hi = (As<Short4>(lhs) >> rhs) & Short4(0xFF00u);
Nicolas Capensd6cacad2017-07-25 15:32:12 -04002849 RValue<Short4> lo = As<Short4>(As<UShort4>((As<Short4>(lhs) << 8) >> rhs) >> 8);
2850
2851 return As<SByte8>(hi | lo);
2852 #else
2853 return RValue<SByte8>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
2854 #endif
2855 }
2856 }
2857
Nicolas Capens598f8d82016-09-26 15:09:10 -04002858 RValue<Int> SignMask(RValue<Byte8> x)
2859 {
Nicolas Capens091f3502017-10-03 14:56:49 -04002860 if(emulateIntrinsics || CPUID::ARM)
Nicolas Capensd6cacad2017-07-25 15:32:12 -04002861 {
2862 Byte8 xx = As<Byte8>(As<SByte8>(x) >> 7) & Byte8(0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80);
2863 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));
2864 }
2865 else
2866 {
2867 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
2868 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2869 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2870 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
2871 movmsk->addArg(x.value);
2872 ::basicBlock->appendInst(movmsk);
Nicolas Capensc71bed22016-11-07 22:25:14 -05002873
Nicolas Capens0f70a7f2017-07-26 13:50:04 -04002874 return RValue<Int>(V(result)) & 0xFF;
Nicolas Capensd6cacad2017-07-25 15:32:12 -04002875 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04002876 }
2877
2878// RValue<Byte8> CmpGT(RValue<Byte8> x, RValue<Byte8> y)
2879// {
Nicolas Capens2f970b62016-11-08 14:28:59 -05002880// return RValue<Byte8>(createIntCompare(Ice::InstIcmp::Ugt, x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002881// }
2882
2883 RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y)
2884 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05002885 return RValue<Byte8>(Nucleus::createICmpEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002886 }
2887
2888 Type *Byte8::getType()
2889 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04002890 return T(Type_v8i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002891 }
2892
Nicolas Capens598f8d82016-09-26 15:09:10 -04002893 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)
2894 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04002895 int64_t constantVector[8] = { x0, x1, x2, x3, x4, x5, x6, x7 };
2896 Value *vector = V(Nucleus::createConstantVector(constantVector, getType()));
2897
2898 storeValue(Nucleus::createBitCast(vector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002899 }
2900
Nicolas Capens598f8d82016-09-26 15:09:10 -04002901 SByte8::SByte8(RValue<SByte8> rhs)
2902 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002903 storeValue(rhs.value);
2904 }
2905
2906 SByte8::SByte8(const SByte8 &rhs)
2907 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002908 Value *value = rhs.loadValue();
2909 storeValue(value);
2910 }
2911
2912 SByte8::SByte8(const Reference<SByte8> &rhs)
2913 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002914 Value *value = rhs.loadValue();
2915 storeValue(value);
2916 }
2917
Nicolas Capens96d4e092016-11-18 14:22:38 -05002918 RValue<SByte8> SByte8::operator=(RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002919 {
2920 storeValue(rhs.value);
2921
2922 return rhs;
2923 }
2924
Nicolas Capens96d4e092016-11-18 14:22:38 -05002925 RValue<SByte8> SByte8::operator=(const SByte8 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002926 {
2927 Value *value = rhs.loadValue();
2928 storeValue(value);
2929
2930 return RValue<SByte8>(value);
2931 }
2932
Nicolas Capens96d4e092016-11-18 14:22:38 -05002933 RValue<SByte8> SByte8::operator=(const Reference<SByte8> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002934 {
2935 Value *value = rhs.loadValue();
2936 storeValue(value);
2937
2938 return RValue<SByte8>(value);
2939 }
2940
2941 RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs)
2942 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002943 return RValue<SByte8>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002944 }
2945
2946 RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs)
2947 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002948 return RValue<SByte8>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002949 }
2950
2951// RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs)
2952// {
2953// return RValue<SByte8>(Nucleus::createMul(lhs.value, rhs.value));
2954// }
2955
2956// RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs)
2957// {
2958// return RValue<SByte8>(Nucleus::createSDiv(lhs.value, rhs.value));
2959// }
2960
2961// RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs)
2962// {
2963// return RValue<SByte8>(Nucleus::createSRem(lhs.value, rhs.value));
2964// }
2965
2966 RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs)
2967 {
2968 return RValue<SByte8>(Nucleus::createAnd(lhs.value, rhs.value));
2969 }
2970
2971 RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs)
2972 {
2973 return RValue<SByte8>(Nucleus::createOr(lhs.value, rhs.value));
2974 }
2975
2976 RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs)
2977 {
2978 return RValue<SByte8>(Nucleus::createXor(lhs.value, rhs.value));
2979 }
2980
2981// RValue<SByte8> operator<<(RValue<SByte8> lhs, unsigned char rhs)
2982// {
Nicolas Capens15060bb2016-12-05 22:17:19 -05002983// return RValue<SByte8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002984// }
2985
2986// RValue<SByte8> operator>>(RValue<SByte8> lhs, unsigned char rhs)
2987// {
Nicolas Capens15060bb2016-12-05 22:17:19 -05002988// return RValue<SByte8>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002989// }
2990
Nicolas Capens96d4e092016-11-18 14:22:38 -05002991 RValue<SByte8> operator+=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002992 {
2993 return lhs = lhs + rhs;
2994 }
2995
Nicolas Capens96d4e092016-11-18 14:22:38 -05002996 RValue<SByte8> operator-=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002997 {
2998 return lhs = lhs - rhs;
2999 }
3000
Nicolas Capens96d4e092016-11-18 14:22:38 -05003001// RValue<SByte8> operator*=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003002// {
3003// return lhs = lhs * rhs;
3004// }
3005
Nicolas Capens96d4e092016-11-18 14:22:38 -05003006// RValue<SByte8> operator/=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003007// {
3008// return lhs = lhs / rhs;
3009// }
3010
Nicolas Capens96d4e092016-11-18 14:22:38 -05003011// RValue<SByte8> operator%=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003012// {
3013// return lhs = lhs % rhs;
3014// }
3015
Nicolas Capens96d4e092016-11-18 14:22:38 -05003016 RValue<SByte8> operator&=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003017 {
3018 return lhs = lhs & rhs;
3019 }
3020
Nicolas Capens96d4e092016-11-18 14:22:38 -05003021 RValue<SByte8> operator|=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003022 {
3023 return lhs = lhs | rhs;
3024 }
3025
Nicolas Capens96d4e092016-11-18 14:22:38 -05003026 RValue<SByte8> operator^=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003027 {
3028 return lhs = lhs ^ rhs;
3029 }
3030
Nicolas Capens96d4e092016-11-18 14:22:38 -05003031// RValue<SByte8> operator<<=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003032// {
3033// return lhs = lhs << rhs;
3034// }
3035
Nicolas Capens96d4e092016-11-18 14:22:38 -05003036// RValue<SByte8> operator>>=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003037// {
3038// return lhs = lhs >> rhs;
3039// }
3040
3041// RValue<SByte8> operator+(RValue<SByte8> val)
3042// {
3043// return val;
3044// }
3045
3046// RValue<SByte8> operator-(RValue<SByte8> val)
3047// {
3048// return RValue<SByte8>(Nucleus::createNeg(val.value));
3049// }
3050
3051 RValue<SByte8> operator~(RValue<SByte8> val)
3052 {
3053 return RValue<SByte8>(Nucleus::createNot(val.value));
3054 }
3055
Nicolas Capens33438a62017-09-27 11:47:35 -04003056 RValue<SByte> SaturateSigned(RValue<Short> x)
Nicolas Capens98436732017-07-25 15:32:12 -04003057 {
3058 return SByte(IfThenElse(Int(x) > 0x7F, Int(0x7F), IfThenElse(Int(x) < -0x80, Int(0x80), Int(x))));
3059 }
3060
Nicolas Capens598f8d82016-09-26 15:09:10 -04003061 RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y)
3062 {
Nicolas Capens98436732017-07-25 15:32:12 -04003063 if(emulateIntrinsics)
3064 {
3065 SByte8 result;
Nicolas Capens33438a62017-09-27 11:47:35 -04003066 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 0)) + Int(Extract(y, 0)))), 0);
3067 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 1)) + Int(Extract(y, 1)))), 1);
3068 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 2)) + Int(Extract(y, 2)))), 2);
3069 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 3)) + Int(Extract(y, 3)))), 3);
3070 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 4)) + Int(Extract(y, 4)))), 4);
3071 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 5)) + Int(Extract(y, 5)))), 5);
3072 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 6)) + Int(Extract(y, 6)))), 6);
3073 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 7)) + Int(Extract(y, 7)))), 7);
Nicolas Capensc71bed22016-11-07 22:25:14 -05003074
Nicolas Capens98436732017-07-25 15:32:12 -04003075 return result;
3076 }
3077 else
3078 {
3079 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
3080 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3081 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3082 auto paddsb = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3083 paddsb->addArg(x.value);
3084 paddsb->addArg(y.value);
3085 ::basicBlock->appendInst(paddsb);
3086
3087 return RValue<SByte8>(V(result));
3088 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003089 }
3090
3091 RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y)
3092 {
Nicolas Capens98436732017-07-25 15:32:12 -04003093 if(emulateIntrinsics)
3094 {
3095 SByte8 result;
Nicolas Capens33438a62017-09-27 11:47:35 -04003096 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 0)) - Int(Extract(y, 0)))), 0);
3097 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 1)) - Int(Extract(y, 1)))), 1);
3098 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 2)) - Int(Extract(y, 2)))), 2);
3099 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 3)) - Int(Extract(y, 3)))), 3);
3100 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 4)) - Int(Extract(y, 4)))), 4);
3101 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 5)) - Int(Extract(y, 5)))), 5);
3102 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 6)) - Int(Extract(y, 6)))), 6);
3103 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 7)) - Int(Extract(y, 7)))), 7);
Nicolas Capensc71bed22016-11-07 22:25:14 -05003104
Nicolas Capens98436732017-07-25 15:32:12 -04003105 return result;
3106 }
3107 else
3108 {
3109 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
3110 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3111 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3112 auto psubsb = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3113 psubsb->addArg(x.value);
3114 psubsb->addArg(y.value);
3115 ::basicBlock->appendInst(psubsb);
3116
3117 return RValue<SByte8>(V(result));
3118 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003119 }
3120
3121 RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y)
3122 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04003123 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 -04003124 return As<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003125 }
3126
3127 RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y)
3128 {
Nicolas Capens20e22c42016-10-25 17:32:37 -04003129 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
3130 auto lowHigh = RValue<Byte16>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
3131 return As<Short4>(Swizzle(As<Int4>(lowHigh), 0xEE));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003132 }
3133
3134 RValue<Int> SignMask(RValue<SByte8> x)
3135 {
Nicolas Capens091f3502017-10-03 14:56:49 -04003136 if(emulateIntrinsics || CPUID::ARM)
Nicolas Capensd6cacad2017-07-25 15:32:12 -04003137 {
3138 SByte8 xx = (x >> 7) & SByte8(0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80);
3139 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));
3140 }
3141 else
3142 {
3143 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
3144 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3145 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3146 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
3147 movmsk->addArg(x.value);
3148 ::basicBlock->appendInst(movmsk);
Nicolas Capensf2cb9df2016-10-21 17:26:13 -04003149
Nicolas Capens0f70a7f2017-07-26 13:50:04 -04003150 return RValue<Int>(V(result)) & 0xFF;
Nicolas Capensd6cacad2017-07-25 15:32:12 -04003151 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003152 }
3153
3154 RValue<Byte8> CmpGT(RValue<SByte8> x, RValue<SByte8> y)
3155 {
Nicolas Capens2f970b62016-11-08 14:28:59 -05003156 return RValue<Byte8>(createIntCompare(Ice::InstIcmp::Sgt, x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003157 }
3158
3159 RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y)
3160 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05003161 return RValue<Byte8>(Nucleus::createICmpEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003162 }
3163
3164 Type *SByte8::getType()
3165 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04003166 return T(Type_v8i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003167 }
3168
3169 Byte16::Byte16(RValue<Byte16> rhs)
3170 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003171 storeValue(rhs.value);
3172 }
3173
3174 Byte16::Byte16(const Byte16 &rhs)
3175 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003176 Value *value = rhs.loadValue();
3177 storeValue(value);
3178 }
3179
3180 Byte16::Byte16(const Reference<Byte16> &rhs)
3181 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003182 Value *value = rhs.loadValue();
3183 storeValue(value);
3184 }
3185
Nicolas Capens96d4e092016-11-18 14:22:38 -05003186 RValue<Byte16> Byte16::operator=(RValue<Byte16> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003187 {
3188 storeValue(rhs.value);
3189
3190 return rhs;
3191 }
3192
Nicolas Capens96d4e092016-11-18 14:22:38 -05003193 RValue<Byte16> Byte16::operator=(const Byte16 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003194 {
3195 Value *value = rhs.loadValue();
3196 storeValue(value);
3197
3198 return RValue<Byte16>(value);
3199 }
3200
Nicolas Capens96d4e092016-11-18 14:22:38 -05003201 RValue<Byte16> Byte16::operator=(const Reference<Byte16> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003202 {
3203 Value *value = rhs.loadValue();
3204 storeValue(value);
3205
3206 return RValue<Byte16>(value);
3207 }
3208
3209 Type *Byte16::getType()
3210 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04003211 return T(Ice::IceType_v16i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003212 }
3213
3214 Type *SByte16::getType()
3215 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04003216 return T(Ice::IceType_v16i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003217 }
3218
Nicolas Capens16b5f152016-10-13 13:39:01 -04003219 Short2::Short2(RValue<Short4> cast)
3220 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05003221 storeValue(Nucleus::createBitCast(cast.value, getType()));
Nicolas Capens16b5f152016-10-13 13:39:01 -04003222 }
3223
3224 Type *Short2::getType()
3225 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04003226 return T(Type_v2i16);
Nicolas Capens16b5f152016-10-13 13:39:01 -04003227 }
3228
3229 UShort2::UShort2(RValue<UShort4> cast)
3230 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05003231 storeValue(Nucleus::createBitCast(cast.value, getType()));
Nicolas Capens16b5f152016-10-13 13:39:01 -04003232 }
3233
3234 Type *UShort2::getType()
3235 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04003236 return T(Type_v2i16);
Nicolas Capens16b5f152016-10-13 13:39:01 -04003237 }
3238
Nicolas Capens598f8d82016-09-26 15:09:10 -04003239 Short4::Short4(RValue<Int> cast)
3240 {
Nicolas Capensd4227962016-11-09 14:24:25 -05003241 Value *vector = loadValue();
Nicolas Capensbf22bbf2017-01-13 17:37:45 -05003242 Value *element = Nucleus::createTrunc(cast.value, Short::getType());
3243 Value *insert = Nucleus::createInsertElement(vector, element, 0);
Nicolas Capensd4227962016-11-09 14:24:25 -05003244 Value *swizzle = Swizzle(RValue<Short4>(insert), 0x00).value;
Nicolas Capens598f8d82016-09-26 15:09:10 -04003245
3246 storeValue(swizzle);
3247 }
3248
3249 Short4::Short4(RValue<Int4> cast)
3250 {
Nicolas Capensf8beb4b2017-01-27 02:55:44 -08003251 int select[8] = {0, 2, 4, 6, 0, 2, 4, 6};
3252 Value *short8 = Nucleus::createBitCast(cast.value, Short8::getType());
3253 Value *packed = Nucleus::createShuffleVector(short8, short8, select);
Nicolas Capensd4227962016-11-09 14:24:25 -05003254
Nicolas Capensbea4dce2017-07-24 16:54:44 -04003255 Value *int2 = RValue<Int2>(Int2(As<Int4>(packed))).value;
Nicolas Capensd4227962016-11-09 14:24:25 -05003256 Value *short4 = Nucleus::createBitCast(int2, Short4::getType());
3257
3258 storeValue(short4);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003259 }
3260
3261// Short4::Short4(RValue<Float> cast)
3262// {
3263// }
3264
3265 Short4::Short4(RValue<Float4> cast)
3266 {
3267 assert(false && "UNIMPLEMENTED");
3268 }
3269
Nicolas Capens598f8d82016-09-26 15:09:10 -04003270 Short4::Short4(short xyzw)
3271 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04003272 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
3273 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003274 }
3275
3276 Short4::Short4(short x, short y, short z, short w)
3277 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04003278 int64_t constantVector[4] = {x, y, z, w};
3279 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003280 }
3281
3282 Short4::Short4(RValue<Short4> rhs)
3283 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003284 storeValue(rhs.value);
3285 }
3286
3287 Short4::Short4(const Short4 &rhs)
3288 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003289 Value *value = rhs.loadValue();
3290 storeValue(value);
3291 }
3292
3293 Short4::Short4(const Reference<Short4> &rhs)
3294 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003295 Value *value = rhs.loadValue();
3296 storeValue(value);
3297 }
3298
3299 Short4::Short4(RValue<UShort4> rhs)
3300 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003301 storeValue(rhs.value);
3302 }
3303
3304 Short4::Short4(const UShort4 &rhs)
3305 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003306 storeValue(rhs.loadValue());
3307 }
3308
3309 Short4::Short4(const Reference<UShort4> &rhs)
3310 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003311 storeValue(rhs.loadValue());
3312 }
3313
Nicolas Capens96d4e092016-11-18 14:22:38 -05003314 RValue<Short4> Short4::operator=(RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003315 {
3316 storeValue(rhs.value);
3317
3318 return rhs;
3319 }
3320
Nicolas Capens96d4e092016-11-18 14:22:38 -05003321 RValue<Short4> Short4::operator=(const Short4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003322 {
3323 Value *value = rhs.loadValue();
3324 storeValue(value);
3325
3326 return RValue<Short4>(value);
3327 }
3328
Nicolas Capens96d4e092016-11-18 14:22:38 -05003329 RValue<Short4> Short4::operator=(const Reference<Short4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003330 {
3331 Value *value = rhs.loadValue();
3332 storeValue(value);
3333
3334 return RValue<Short4>(value);
3335 }
3336
Nicolas Capens96d4e092016-11-18 14:22:38 -05003337 RValue<Short4> Short4::operator=(RValue<UShort4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003338 {
3339 storeValue(rhs.value);
3340
3341 return RValue<Short4>(rhs);
3342 }
3343
Nicolas Capens96d4e092016-11-18 14:22:38 -05003344 RValue<Short4> Short4::operator=(const UShort4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003345 {
3346 Value *value = rhs.loadValue();
3347 storeValue(value);
3348
3349 return RValue<Short4>(value);
3350 }
3351
Nicolas Capens96d4e092016-11-18 14:22:38 -05003352 RValue<Short4> Short4::operator=(const Reference<UShort4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003353 {
3354 Value *value = rhs.loadValue();
3355 storeValue(value);
3356
3357 return RValue<Short4>(value);
3358 }
3359
3360 RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs)
3361 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003362 return RValue<Short4>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003363 }
3364
3365 RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs)
3366 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003367 return RValue<Short4>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003368 }
3369
3370 RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs)
3371 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003372 return RValue<Short4>(Nucleus::createMul(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003373 }
3374
3375// RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs)
3376// {
3377// return RValue<Short4>(Nucleus::createSDiv(lhs.value, rhs.value));
3378// }
3379
3380// RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs)
3381// {
3382// return RValue<Short4>(Nucleus::createSRem(lhs.value, rhs.value));
3383// }
3384
3385 RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs)
3386 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003387 return RValue<Short4>(Nucleus::createAnd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003388 }
3389
3390 RValue<Short4> operator|(RValue<Short4> lhs, RValue<Short4> rhs)
3391 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003392 return RValue<Short4>(Nucleus::createOr(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003393 }
3394
3395 RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs)
3396 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003397 return RValue<Short4>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003398 }
3399
3400 RValue<Short4> operator<<(RValue<Short4> lhs, unsigned char rhs)
3401 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04003402 if(emulateIntrinsics)
3403 {
3404 Short4 result;
3405 result = Insert(result, Extract(lhs, 0) << Short(rhs), 0);
3406 result = Insert(result, Extract(lhs, 1) << Short(rhs), 1);
3407 result = Insert(result, Extract(lhs, 2) << Short(rhs), 2);
3408 result = Insert(result, Extract(lhs, 3) << Short(rhs), 3);
3409
3410 return result;
3411 }
3412 else
3413 {
3414 return RValue<Short4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
3415 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003416 }
3417
3418 RValue<Short4> operator>>(RValue<Short4> lhs, unsigned char rhs)
3419 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04003420 if(emulateIntrinsics)
3421 {
3422 Short4 result;
3423 result = Insert(result, Extract(lhs, 0) >> Short(rhs), 0);
3424 result = Insert(result, Extract(lhs, 1) >> Short(rhs), 1);
3425 result = Insert(result, Extract(lhs, 2) >> Short(rhs), 2);
3426 result = Insert(result, Extract(lhs, 3) >> Short(rhs), 3);
3427
3428 return result;
3429 }
3430 else
3431 {
3432 return RValue<Short4>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
3433 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003434 }
3435
Nicolas Capens96d4e092016-11-18 14:22:38 -05003436 RValue<Short4> operator+=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003437 {
3438 return lhs = lhs + rhs;
3439 }
3440
Nicolas Capens96d4e092016-11-18 14:22:38 -05003441 RValue<Short4> operator-=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003442 {
3443 return lhs = lhs - rhs;
3444 }
3445
Nicolas Capens96d4e092016-11-18 14:22:38 -05003446 RValue<Short4> operator*=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003447 {
3448 return lhs = lhs * rhs;
3449 }
3450
Nicolas Capens96d4e092016-11-18 14:22:38 -05003451// RValue<Short4> operator/=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003452// {
3453// return lhs = lhs / rhs;
3454// }
3455
Nicolas Capens96d4e092016-11-18 14:22:38 -05003456// RValue<Short4> operator%=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003457// {
3458// return lhs = lhs % rhs;
3459// }
3460
Nicolas Capens96d4e092016-11-18 14:22:38 -05003461 RValue<Short4> operator&=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003462 {
3463 return lhs = lhs & rhs;
3464 }
3465
Nicolas Capens96d4e092016-11-18 14:22:38 -05003466 RValue<Short4> operator|=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003467 {
3468 return lhs = lhs | rhs;
3469 }
3470
Nicolas Capens96d4e092016-11-18 14:22:38 -05003471 RValue<Short4> operator^=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003472 {
3473 return lhs = lhs ^ rhs;
3474 }
3475
Nicolas Capens96d4e092016-11-18 14:22:38 -05003476 RValue<Short4> operator<<=(Short4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003477 {
3478 return lhs = lhs << rhs;
3479 }
3480
Nicolas Capens96d4e092016-11-18 14:22:38 -05003481 RValue<Short4> operator>>=(Short4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003482 {
3483 return lhs = lhs >> rhs;
3484 }
3485
Nicolas Capens598f8d82016-09-26 15:09:10 -04003486// RValue<Short4> operator+(RValue<Short4> val)
3487// {
3488// return val;
3489// }
3490
3491 RValue<Short4> operator-(RValue<Short4> val)
3492 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -05003493 return RValue<Short4>(Nucleus::createNeg(val.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003494 }
3495
3496 RValue<Short4> operator~(RValue<Short4> val)
3497 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -05003498 return RValue<Short4>(Nucleus::createNot(val.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003499 }
3500
3501 RValue<Short4> RoundShort4(RValue<Float4> cast)
3502 {
Nicolas Capensd4227962016-11-09 14:24:25 -05003503 RValue<Int4> int4 = RoundInt(cast);
Nicolas Capens33438a62017-09-27 11:47:35 -04003504 return As<Short4>(PackSigned(int4, int4));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003505 }
3506
3507 RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y)
3508 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04003509 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3510 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sle, condition, x.value, y.value);
3511 ::basicBlock->appendInst(cmp);
3512
3513 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3514 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3515 ::basicBlock->appendInst(select);
3516
3517 return RValue<Short4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003518 }
3519
3520 RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y)
3521 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04003522 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3523 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sgt, condition, x.value, y.value);
3524 ::basicBlock->appendInst(cmp);
3525
3526 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3527 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3528 ::basicBlock->appendInst(select);
3529
3530 return RValue<Short4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003531 }
3532
Nicolas Capens33438a62017-09-27 11:47:35 -04003533 RValue<Short> SaturateSigned(RValue<Int> x)
Nicolas Capens98436732017-07-25 15:32:12 -04003534 {
3535 return Short(IfThenElse(x > 0x7FFF, Int(0x7FFF), IfThenElse(x < -0x8000, Int(0x8000), x)));
3536 }
3537
Nicolas Capens598f8d82016-09-26 15:09:10 -04003538 RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y)
3539 {
Nicolas Capens98436732017-07-25 15:32:12 -04003540 if(emulateIntrinsics)
3541 {
3542 Short4 result;
Nicolas Capens33438a62017-09-27 11:47:35 -04003543 result = Insert(result, SaturateSigned(Int(Extract(x, 0)) + Int(Extract(y, 0))), 0);
3544 result = Insert(result, SaturateSigned(Int(Extract(x, 1)) + Int(Extract(y, 1))), 1);
3545 result = Insert(result, SaturateSigned(Int(Extract(x, 2)) + Int(Extract(y, 2))), 2);
3546 result = Insert(result, SaturateSigned(Int(Extract(x, 3)) + Int(Extract(y, 3))), 3);
Nicolas Capensc71bed22016-11-07 22:25:14 -05003547
Nicolas Capens98436732017-07-25 15:32:12 -04003548 return result;
3549 }
3550 else
3551 {
3552 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3553 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3554 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3555 auto paddsw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3556 paddsw->addArg(x.value);
3557 paddsw->addArg(y.value);
3558 ::basicBlock->appendInst(paddsw);
3559
3560 return RValue<Short4>(V(result));
3561 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003562 }
3563
3564 RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y)
3565 {
Nicolas Capens98436732017-07-25 15:32:12 -04003566 if(emulateIntrinsics)
3567 {
3568 Short4 result;
Nicolas Capens33438a62017-09-27 11:47:35 -04003569 result = Insert(result, SaturateSigned(Int(Extract(x, 0)) - Int(Extract(y, 0))), 0);
3570 result = Insert(result, SaturateSigned(Int(Extract(x, 1)) - Int(Extract(y, 1))), 1);
3571 result = Insert(result, SaturateSigned(Int(Extract(x, 2)) - Int(Extract(y, 2))), 2);
3572 result = Insert(result, SaturateSigned(Int(Extract(x, 3)) - Int(Extract(y, 3))), 3);
Nicolas Capensc71bed22016-11-07 22:25:14 -05003573
Nicolas Capens98436732017-07-25 15:32:12 -04003574 return result;
3575 }
3576 else
3577 {
3578 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3579 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3580 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3581 auto psubsw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3582 psubsw->addArg(x.value);
3583 psubsw->addArg(y.value);
3584 ::basicBlock->appendInst(psubsw);
3585
3586 return RValue<Short4>(V(result));
3587 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003588 }
3589
3590 RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y)
3591 {
Nicolas Capens6c157442017-07-25 15:32:12 -04003592 if(emulateIntrinsics)
3593 {
3594 Short4 result;
3595 result = Insert(result, Short((Int(Extract(x, 0)) * Int(Extract(y, 0))) >> 16), 0);
3596 result = Insert(result, Short((Int(Extract(x, 1)) * Int(Extract(y, 1))) >> 16), 1);
3597 result = Insert(result, Short((Int(Extract(x, 2)) * Int(Extract(y, 2))) >> 16), 2);
3598 result = Insert(result, Short((Int(Extract(x, 3)) * Int(Extract(y, 3))) >> 16), 3);
Nicolas Capensc71bed22016-11-07 22:25:14 -05003599
Nicolas Capens6c157442017-07-25 15:32:12 -04003600 return result;
3601 }
3602 else
3603 {
3604 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3605 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::MultiplyHighSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3606 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3607 auto pmulhw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3608 pmulhw->addArg(x.value);
3609 pmulhw->addArg(y.value);
3610 ::basicBlock->appendInst(pmulhw);
3611
3612 return RValue<Short4>(V(result));
3613 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003614 }
3615
3616 RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y)
3617 {
Nicolas Capensafe27e92017-07-25 15:32:12 -04003618 if(emulateIntrinsics)
3619 {
3620 Int2 result;
3621 result = Insert(result, Int(Extract(x, 0)) * Int(Extract(y, 0)) + Int(Extract(x, 1)) * Int(Extract(y, 1)), 0);
3622 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 -05003623
Nicolas Capensafe27e92017-07-25 15:32:12 -04003624 return result;
3625 }
3626 else
3627 {
3628 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3629 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::MultiplyAddPairs, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3630 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3631 auto pmaddwd = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3632 pmaddwd->addArg(x.value);
3633 pmaddwd->addArg(y.value);
3634 ::basicBlock->appendInst(pmaddwd);
3635
3636 return As<Int2>(V(result));
3637 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003638 }
3639
Nicolas Capens33438a62017-09-27 11:47:35 -04003640 RValue<SByte8> PackSigned(RValue<Short4> x, RValue<Short4> y)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003641 {
Nicolas Capens8960fbf2017-07-25 15:32:12 -04003642 if(emulateIntrinsics)
3643 {
3644 SByte8 result;
Nicolas Capens33438a62017-09-27 11:47:35 -04003645 result = Insert(result, SaturateSigned(Extract(x, 0)), 0);
3646 result = Insert(result, SaturateSigned(Extract(x, 1)), 1);
3647 result = Insert(result, SaturateSigned(Extract(x, 2)), 2);
3648 result = Insert(result, SaturateSigned(Extract(x, 3)), 3);
3649 result = Insert(result, SaturateSigned(Extract(y, 0)), 4);
3650 result = Insert(result, SaturateSigned(Extract(y, 1)), 5);
3651 result = Insert(result, SaturateSigned(Extract(y, 2)), 6);
3652 result = Insert(result, SaturateSigned(Extract(y, 3)), 7);
Nicolas Capensec54a172016-10-25 17:32:37 -04003653
Nicolas Capens8960fbf2017-07-25 15:32:12 -04003654 return result;
3655 }
3656 else
3657 {
3658 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
3659 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3660 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3661 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3662 pack->addArg(x.value);
3663 pack->addArg(y.value);
3664 ::basicBlock->appendInst(pack);
3665
3666 return As<SByte8>(Swizzle(As<Int4>(V(result)), 0x88));
3667 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003668 }
3669
Nicolas Capens33438a62017-09-27 11:47:35 -04003670 RValue<Byte8> PackUnsigned(RValue<Short4> x, RValue<Short4> y)
3671 {
3672 if(emulateIntrinsics)
3673 {
3674 Byte8 result;
3675 result = Insert(result, SaturateUnsigned(Extract(x, 0)), 0);
3676 result = Insert(result, SaturateUnsigned(Extract(x, 1)), 1);
3677 result = Insert(result, SaturateUnsigned(Extract(x, 2)), 2);
3678 result = Insert(result, SaturateUnsigned(Extract(x, 3)), 3);
3679 result = Insert(result, SaturateUnsigned(Extract(y, 0)), 4);
3680 result = Insert(result, SaturateUnsigned(Extract(y, 1)), 5);
3681 result = Insert(result, SaturateUnsigned(Extract(y, 2)), 6);
3682 result = Insert(result, SaturateUnsigned(Extract(y, 3)), 7);
3683
3684 return result;
3685 }
3686 else
3687 {
3688 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
3689 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3690 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3691 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3692 pack->addArg(x.value);
3693 pack->addArg(y.value);
3694 ::basicBlock->appendInst(pack);
3695
3696 return As<Byte8>(Swizzle(As<Int4>(V(result)), 0x88));
3697 }
3698 }
3699
Nicolas Capens598f8d82016-09-26 15:09:10 -04003700 RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y)
3701 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04003702 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11}; // Real type is v8i16
Nicolas Capensbea4dce2017-07-24 16:54:44 -04003703 return As<Int2>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003704 }
3705
3706 RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y)
3707 {
Nicolas Capens20e22c42016-10-25 17:32:37 -04003708 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11}; // Real type is v8i16
3709 auto lowHigh = RValue<Short8>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
3710 return As<Int2>(Swizzle(As<Int4>(lowHigh), 0xEE));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003711 }
3712
3713 RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select)
3714 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04003715 // Real type is v8i16
3716 int shuffle[8] =
3717 {
3718 (select >> 0) & 0x03,
3719 (select >> 2) & 0x03,
3720 (select >> 4) & 0x03,
3721 (select >> 6) & 0x03,
3722 (select >> 0) & 0x03,
3723 (select >> 2) & 0x03,
3724 (select >> 4) & 0x03,
3725 (select >> 6) & 0x03,
3726 };
3727
3728 return RValue<Short4>(Nucleus::createShuffleVector(x.value, x.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003729 }
3730
3731 RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i)
3732 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05003733 return RValue<Short4>(Nucleus::createInsertElement(val.value, element.value, i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003734 }
3735
3736 RValue<Short> Extract(RValue<Short4> val, int i)
3737 {
Nicolas Capens0133d0f2017-01-16 16:25:08 -05003738 return RValue<Short>(Nucleus::createExtractElement(val.value, Short::getType(), i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003739 }
3740
3741 RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y)
3742 {
Nicolas Capens2f970b62016-11-08 14:28:59 -05003743 return RValue<Short4>(createIntCompare(Ice::InstIcmp::Sgt, x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003744 }
3745
3746 RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y)
3747 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05003748 return RValue<Short4>(Nucleus::createICmpEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003749 }
3750
3751 Type *Short4::getType()
3752 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04003753 return T(Type_v4i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003754 }
3755
3756 UShort4::UShort4(RValue<Int4> cast)
3757 {
3758 *this = Short4(cast);
3759 }
3760
3761 UShort4::UShort4(RValue<Float4> cast, bool saturate)
3762 {
Nicolas Capensd4227962016-11-09 14:24:25 -05003763 if(saturate)
3764 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05003765 if(CPUID::SSE4_1)
Nicolas Capensd4227962016-11-09 14:24:25 -05003766 {
Nicolas Capens091f3502017-10-03 14:56:49 -04003767 // x86 produces 0x80000000 on 32-bit integer overflow/underflow.
3768 // PackUnsigned takes care of 0x0000 saturation.
3769 Int4 int4(Min(cast, Float4(0xFFFF)));
3770 *this = As<UShort4>(PackUnsigned(int4, int4));
3771 }
3772 else if(CPUID::ARM)
3773 {
3774 // ARM saturates the 32-bit integer result on overflow/undeflow.
3775 Int4 int4(cast);
Nicolas Capens33438a62017-09-27 11:47:35 -04003776 *this = As<UShort4>(PackUnsigned(int4, int4));
Nicolas Capensd4227962016-11-09 14:24:25 -05003777 }
3778 else
3779 {
3780 *this = Short4(Int4(Max(Min(cast, Float4(0xFFFF)), Float4(0x0000))));
3781 }
3782 }
3783 else
3784 {
3785 *this = Short4(Int4(cast));
3786 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003787 }
3788
Nicolas Capens598f8d82016-09-26 15:09:10 -04003789 UShort4::UShort4(unsigned short xyzw)
3790 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04003791 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
3792 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003793 }
3794
3795 UShort4::UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w)
3796 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04003797 int64_t constantVector[4] = {x, y, z, w};
3798 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003799 }
3800
3801 UShort4::UShort4(RValue<UShort4> rhs)
3802 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003803 storeValue(rhs.value);
3804 }
3805
3806 UShort4::UShort4(const UShort4 &rhs)
3807 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003808 Value *value = rhs.loadValue();
3809 storeValue(value);
3810 }
3811
3812 UShort4::UShort4(const Reference<UShort4> &rhs)
3813 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003814 Value *value = rhs.loadValue();
3815 storeValue(value);
3816 }
3817
3818 UShort4::UShort4(RValue<Short4> rhs)
3819 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003820 storeValue(rhs.value);
3821 }
3822
3823 UShort4::UShort4(const Short4 &rhs)
3824 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003825 Value *value = rhs.loadValue();
3826 storeValue(value);
3827 }
3828
3829 UShort4::UShort4(const Reference<Short4> &rhs)
3830 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003831 Value *value = rhs.loadValue();
3832 storeValue(value);
3833 }
3834
Nicolas Capens96d4e092016-11-18 14:22:38 -05003835 RValue<UShort4> UShort4::operator=(RValue<UShort4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003836 {
3837 storeValue(rhs.value);
3838
3839 return rhs;
3840 }
3841
Nicolas Capens96d4e092016-11-18 14:22:38 -05003842 RValue<UShort4> UShort4::operator=(const UShort4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003843 {
3844 Value *value = rhs.loadValue();
3845 storeValue(value);
3846
3847 return RValue<UShort4>(value);
3848 }
3849
Nicolas Capens96d4e092016-11-18 14:22:38 -05003850 RValue<UShort4> UShort4::operator=(const Reference<UShort4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003851 {
3852 Value *value = rhs.loadValue();
3853 storeValue(value);
3854
3855 return RValue<UShort4>(value);
3856 }
3857
Nicolas Capens96d4e092016-11-18 14:22:38 -05003858 RValue<UShort4> UShort4::operator=(RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003859 {
3860 storeValue(rhs.value);
3861
3862 return RValue<UShort4>(rhs);
3863 }
3864
Nicolas Capens96d4e092016-11-18 14:22:38 -05003865 RValue<UShort4> UShort4::operator=(const Short4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003866 {
3867 Value *value = rhs.loadValue();
3868 storeValue(value);
3869
3870 return RValue<UShort4>(value);
3871 }
3872
Nicolas Capens96d4e092016-11-18 14:22:38 -05003873 RValue<UShort4> UShort4::operator=(const Reference<Short4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003874 {
3875 Value *value = rhs.loadValue();
3876 storeValue(value);
3877
3878 return RValue<UShort4>(value);
3879 }
3880
3881 RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs)
3882 {
Nicolas Capens5b41ba32016-12-08 14:34:00 -05003883 return RValue<UShort4>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003884 }
3885
3886 RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs)
3887 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003888 return RValue<UShort4>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003889 }
3890
3891 RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs)
3892 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003893 return RValue<UShort4>(Nucleus::createMul(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003894 }
3895
Nicolas Capens16b5f152016-10-13 13:39:01 -04003896 RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs)
3897 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003898 return RValue<UShort4>(Nucleus::createAnd(lhs.value, rhs.value));
Nicolas Capens16b5f152016-10-13 13:39:01 -04003899 }
3900
3901 RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs)
3902 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003903 return RValue<UShort4>(Nucleus::createOr(lhs.value, rhs.value));
Nicolas Capens16b5f152016-10-13 13:39:01 -04003904 }
3905
3906 RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs)
3907 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003908 return RValue<UShort4>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens16b5f152016-10-13 13:39:01 -04003909 }
3910
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04003911 RValue<UShort> Extract(RValue<UShort4> val, int i)
3912 {
3913 return RValue<UShort>(Nucleus::createExtractElement(val.value, UShort::getType(), i));
3914 }
3915
3916 RValue<UShort4> Insert(RValue<UShort4> val, RValue<UShort> element, int i)
3917 {
3918 return RValue<UShort4>(Nucleus::createInsertElement(val.value, element.value, i));
3919 }
3920
Nicolas Capens598f8d82016-09-26 15:09:10 -04003921 RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs)
3922 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04003923 if(emulateIntrinsics)
3924 {
3925 UShort4 result;
3926 result = Insert(result, Extract(lhs, 0) << UShort(rhs), 0);
3927 result = Insert(result, Extract(lhs, 1) << UShort(rhs), 1);
3928 result = Insert(result, Extract(lhs, 2) << UShort(rhs), 2);
3929 result = Insert(result, Extract(lhs, 3) << UShort(rhs), 3);
3930
3931 return result;
3932 }
3933 else
3934 {
3935 return RValue<UShort4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
3936 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003937 }
3938
3939 RValue<UShort4> operator>>(RValue<UShort4> lhs, unsigned char rhs)
3940 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04003941 if(emulateIntrinsics)
3942 {
3943 UShort4 result;
3944 result = Insert(result, Extract(lhs, 0) >> UShort(rhs), 0);
3945 result = Insert(result, Extract(lhs, 1) >> UShort(rhs), 1);
3946 result = Insert(result, Extract(lhs, 2) >> UShort(rhs), 2);
3947 result = Insert(result, Extract(lhs, 3) >> UShort(rhs), 3);
3948
3949 return result;
3950 }
3951 else
3952 {
3953 return RValue<UShort4>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
3954 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003955 }
3956
Nicolas Capens96d4e092016-11-18 14:22:38 -05003957 RValue<UShort4> operator<<=(UShort4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003958 {
3959 return lhs = lhs << rhs;
3960 }
3961
Nicolas Capens96d4e092016-11-18 14:22:38 -05003962 RValue<UShort4> operator>>=(UShort4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003963 {
3964 return lhs = lhs >> rhs;
3965 }
3966
Nicolas Capens598f8d82016-09-26 15:09:10 -04003967 RValue<UShort4> operator~(RValue<UShort4> val)
3968 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -05003969 return RValue<UShort4>(Nucleus::createNot(val.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003970 }
3971
3972 RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y)
3973 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04003974 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3975 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ule, condition, x.value, y.value);
3976 ::basicBlock->appendInst(cmp);
3977
3978 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3979 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3980 ::basicBlock->appendInst(select);
3981
3982 return RValue<UShort4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003983 }
3984
3985 RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y)
3986 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04003987 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3988 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ugt, condition, x.value, y.value);
3989 ::basicBlock->appendInst(cmp);
3990
3991 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3992 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3993 ::basicBlock->appendInst(select);
3994
3995 return RValue<UShort4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003996 }
3997
Nicolas Capens7f301812017-10-02 17:32:34 -04003998 RValue<UShort> SaturateUnsigned(RValue<Int> x)
Nicolas Capens98436732017-07-25 15:32:12 -04003999 {
4000 return UShort(IfThenElse(x > 0xFFFF, Int(0xFFFF), IfThenElse(x < 0, Int(0), x)));
4001 }
4002
Nicolas Capens598f8d82016-09-26 15:09:10 -04004003 RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y)
4004 {
Nicolas Capens98436732017-07-25 15:32:12 -04004005 if(emulateIntrinsics)
4006 {
4007 UShort4 result;
Nicolas Capens7f301812017-10-02 17:32:34 -04004008 result = Insert(result, SaturateUnsigned(Int(Extract(x, 0)) + Int(Extract(y, 0))), 0);
4009 result = Insert(result, SaturateUnsigned(Int(Extract(x, 1)) + Int(Extract(y, 1))), 1);
4010 result = Insert(result, SaturateUnsigned(Int(Extract(x, 2)) + Int(Extract(y, 2))), 2);
4011 result = Insert(result, SaturateUnsigned(Int(Extract(x, 3)) + Int(Extract(y, 3))), 3);
Nicolas Capensc71bed22016-11-07 22:25:14 -05004012
Nicolas Capens98436732017-07-25 15:32:12 -04004013 return result;
4014 }
4015 else
4016 {
4017 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
4018 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
4019 auto target = ::context->getConstantUndef(Ice::IceType_i32);
4020 auto paddusw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
4021 paddusw->addArg(x.value);
4022 paddusw->addArg(y.value);
4023 ::basicBlock->appendInst(paddusw);
4024
4025 return RValue<UShort4>(V(result));
4026 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04004027 }
4028
4029 RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y)
4030 {
Nicolas Capens98436732017-07-25 15:32:12 -04004031 if(emulateIntrinsics)
4032 {
4033 UShort4 result;
Nicolas Capens7f301812017-10-02 17:32:34 -04004034 result = Insert(result, SaturateUnsigned(Int(Extract(x, 0)) - Int(Extract(y, 0))), 0);
4035 result = Insert(result, SaturateUnsigned(Int(Extract(x, 1)) - Int(Extract(y, 1))), 1);
4036 result = Insert(result, SaturateUnsigned(Int(Extract(x, 2)) - Int(Extract(y, 2))), 2);
4037 result = Insert(result, SaturateUnsigned(Int(Extract(x, 3)) - Int(Extract(y, 3))), 3);
Nicolas Capensc71bed22016-11-07 22:25:14 -05004038
Nicolas Capens98436732017-07-25 15:32:12 -04004039 return result;
4040 }
4041 else
4042 {
4043 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
4044 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
4045 auto target = ::context->getConstantUndef(Ice::IceType_i32);
4046 auto psubusw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
4047 psubusw->addArg(x.value);
4048 psubusw->addArg(y.value);
4049 ::basicBlock->appendInst(psubusw);
4050
4051 return RValue<UShort4>(V(result));
4052 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04004053 }
4054
4055 RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y)
4056 {
Nicolas Capens6c157442017-07-25 15:32:12 -04004057 if(emulateIntrinsics)
4058 {
4059 UShort4 result;
4060 result = Insert(result, UShort((UInt(Extract(x, 0)) * UInt(Extract(y, 0))) >> 16), 0);
4061 result = Insert(result, UShort((UInt(Extract(x, 1)) * UInt(Extract(y, 1))) >> 16), 1);
4062 result = Insert(result, UShort((UInt(Extract(x, 2)) * UInt(Extract(y, 2))) >> 16), 2);
4063 result = Insert(result, UShort((UInt(Extract(x, 3)) * UInt(Extract(y, 3))) >> 16), 3);
Nicolas Capensc71bed22016-11-07 22:25:14 -05004064
Nicolas Capens6c157442017-07-25 15:32:12 -04004065 return result;
4066 }
4067 else
4068 {
4069 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
4070 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::MultiplyHighUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
4071 auto target = ::context->getConstantUndef(Ice::IceType_i32);
4072 auto pmulhuw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
4073 pmulhuw->addArg(x.value);
4074 pmulhuw->addArg(y.value);
4075 ::basicBlock->appendInst(pmulhuw);
4076
4077 return RValue<UShort4>(V(result));
4078 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04004079 }
4080
4081 RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y)
4082 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004083 assert(false && "UNIMPLEMENTED"); return RValue<UShort4>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004084 }
4085
Nicolas Capens598f8d82016-09-26 15:09:10 -04004086 Type *UShort4::getType()
4087 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04004088 return T(Type_v4i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004089 }
4090
Nicolas Capens3e7062b2017-01-17 14:01:33 -05004091 Short8::Short8(short c)
4092 {
4093 int64_t constantVector[8] = {c, c, c, c, c, c, c, c};
4094 storeValue(Nucleus::createConstantVector(constantVector, getType()));
4095 }
4096
Nicolas Capens598f8d82016-09-26 15:09:10 -04004097 Short8::Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7)
4098 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04004099 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
4100 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004101 }
4102
4103 Short8::Short8(RValue<Short8> rhs)
4104 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004105 storeValue(rhs.value);
4106 }
4107
4108 Short8::Short8(const Reference<Short8> &rhs)
4109 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004110 Value *value = rhs.loadValue();
4111 storeValue(value);
4112 }
4113
4114 Short8::Short8(RValue<Short4> lo, RValue<Short4> hi)
4115 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05004116 int shuffle[8] = {0, 1, 2, 3, 8, 9, 10, 11}; // Real type is v8i16
4117 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
4118
4119 storeValue(packed);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004120 }
4121
4122 RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs)
4123 {
4124 return RValue<Short8>(Nucleus::createAdd(lhs.value, rhs.value));
4125 }
4126
4127 RValue<Short8> operator&(RValue<Short8> lhs, RValue<Short8> rhs)
4128 {
4129 return RValue<Short8>(Nucleus::createAnd(lhs.value, rhs.value));
4130 }
4131
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04004132 RValue<Short> Extract(RValue<Short8> val, int i)
4133 {
4134 return RValue<Short>(Nucleus::createExtractElement(val.value, Short::getType(), i));
4135 }
4136
4137 RValue<Short8> Insert(RValue<Short8> val, RValue<Short> element, int i)
4138 {
4139 return RValue<Short8>(Nucleus::createInsertElement(val.value, element.value, i));
4140 }
4141
Nicolas Capens598f8d82016-09-26 15:09:10 -04004142 RValue<Short8> operator<<(RValue<Short8> lhs, unsigned char rhs)
4143 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04004144 if(emulateIntrinsics)
4145 {
4146 Short8 result;
4147 result = Insert(result, Extract(lhs, 0) << Short(rhs), 0);
4148 result = Insert(result, Extract(lhs, 1) << Short(rhs), 1);
4149 result = Insert(result, Extract(lhs, 2) << Short(rhs), 2);
4150 result = Insert(result, Extract(lhs, 3) << Short(rhs), 3);
4151 result = Insert(result, Extract(lhs, 4) << Short(rhs), 4);
4152 result = Insert(result, Extract(lhs, 5) << Short(rhs), 5);
4153 result = Insert(result, Extract(lhs, 6) << Short(rhs), 6);
4154 result = Insert(result, Extract(lhs, 7) << Short(rhs), 7);
4155
4156 return result;
4157 }
4158 else
4159 {
4160 return RValue<Short8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
4161 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04004162 }
4163
4164 RValue<Short8> operator>>(RValue<Short8> lhs, unsigned char rhs)
4165 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04004166 if(emulateIntrinsics)
4167 {
4168 Short8 result;
4169 result = Insert(result, Extract(lhs, 0) >> Short(rhs), 0);
4170 result = Insert(result, Extract(lhs, 1) >> Short(rhs), 1);
4171 result = Insert(result, Extract(lhs, 2) >> Short(rhs), 2);
4172 result = Insert(result, Extract(lhs, 3) >> Short(rhs), 3);
4173 result = Insert(result, Extract(lhs, 4) >> Short(rhs), 4);
4174 result = Insert(result, Extract(lhs, 5) >> Short(rhs), 5);
4175 result = Insert(result, Extract(lhs, 6) >> Short(rhs), 6);
4176 result = Insert(result, Extract(lhs, 7) >> Short(rhs), 7);
4177
4178 return result;
4179 }
4180 else
4181 {
4182 return RValue<Short8>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
4183 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04004184 }
4185
4186 RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y)
4187 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004188 assert(false && "UNIMPLEMENTED"); return RValue<Int4>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004189 }
4190
4191 RValue<Int4> Abs(RValue<Int4> x)
4192 {
Nicolas Capens84272242016-11-09 13:31:06 -05004193 auto negative = x >> 31;
4194 return (x ^ negative) - negative;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004195 }
4196
4197 RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y)
4198 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004199 assert(false && "UNIMPLEMENTED"); return RValue<Short8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004200 }
4201
4202 Type *Short8::getType()
4203 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04004204 return T(Ice::IceType_v8i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004205 }
4206
Nicolas Capens3e7062b2017-01-17 14:01:33 -05004207 UShort8::UShort8(unsigned short c)
4208 {
4209 int64_t constantVector[8] = {c, c, c, c, c, c, c, c};
4210 storeValue(Nucleus::createConstantVector(constantVector, getType()));
4211 }
4212
Nicolas Capens598f8d82016-09-26 15:09:10 -04004213 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)
4214 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04004215 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
4216 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004217 }
4218
4219 UShort8::UShort8(RValue<UShort8> rhs)
4220 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004221 storeValue(rhs.value);
4222 }
4223
4224 UShort8::UShort8(const Reference<UShort8> &rhs)
4225 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004226 Value *value = rhs.loadValue();
4227 storeValue(value);
4228 }
4229
4230 UShort8::UShort8(RValue<UShort4> lo, RValue<UShort4> hi)
4231 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05004232 int shuffle[8] = {0, 1, 2, 3, 8, 9, 10, 11}; // Real type is v8i16
4233 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
4234
4235 storeValue(packed);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004236 }
4237
Nicolas Capens96d4e092016-11-18 14:22:38 -05004238 RValue<UShort8> UShort8::operator=(RValue<UShort8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004239 {
4240 storeValue(rhs.value);
4241
4242 return rhs;
4243 }
4244
Nicolas Capens96d4e092016-11-18 14:22:38 -05004245 RValue<UShort8> UShort8::operator=(const UShort8 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004246 {
4247 Value *value = rhs.loadValue();
4248 storeValue(value);
4249
4250 return RValue<UShort8>(value);
4251 }
4252
Nicolas Capens96d4e092016-11-18 14:22:38 -05004253 RValue<UShort8> UShort8::operator=(const Reference<UShort8> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004254 {
4255 Value *value = rhs.loadValue();
4256 storeValue(value);
4257
4258 return RValue<UShort8>(value);
4259 }
4260
4261 RValue<UShort8> operator&(RValue<UShort8> lhs, RValue<UShort8> rhs)
4262 {
4263 return RValue<UShort8>(Nucleus::createAnd(lhs.value, rhs.value));
4264 }
4265
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04004266 RValue<UShort> Extract(RValue<UShort8> val, int i)
4267 {
4268 return RValue<UShort>(Nucleus::createExtractElement(val.value, UShort::getType(), i));
4269 }
4270
4271 RValue<UShort8> Insert(RValue<UShort8> val, RValue<UShort> element, int i)
4272 {
4273 return RValue<UShort8>(Nucleus::createInsertElement(val.value, element.value, i));
4274 }
4275
Nicolas Capens598f8d82016-09-26 15:09:10 -04004276 RValue<UShort8> operator<<(RValue<UShort8> lhs, unsigned char rhs)
4277 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04004278 if(emulateIntrinsics)
4279 {
4280 UShort8 result;
4281 result = Insert(result, Extract(lhs, 0) << UShort(rhs), 0);
4282 result = Insert(result, Extract(lhs, 1) << UShort(rhs), 1);
4283 result = Insert(result, Extract(lhs, 2) << UShort(rhs), 2);
4284 result = Insert(result, Extract(lhs, 3) << UShort(rhs), 3);
4285 result = Insert(result, Extract(lhs, 4) << UShort(rhs), 4);
4286 result = Insert(result, Extract(lhs, 5) << UShort(rhs), 5);
4287 result = Insert(result, Extract(lhs, 6) << UShort(rhs), 6);
4288 result = Insert(result, Extract(lhs, 7) << UShort(rhs), 7);
4289
4290 return result;
4291 }
4292 else
4293 {
4294 return RValue<UShort8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
4295 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04004296 }
4297
4298 RValue<UShort8> operator>>(RValue<UShort8> lhs, unsigned char rhs)
4299 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04004300 if(emulateIntrinsics)
4301 {
4302 UShort8 result;
4303 result = Insert(result, Extract(lhs, 0) >> UShort(rhs), 0);
4304 result = Insert(result, Extract(lhs, 1) >> UShort(rhs), 1);
4305 result = Insert(result, Extract(lhs, 2) >> UShort(rhs), 2);
4306 result = Insert(result, Extract(lhs, 3) >> UShort(rhs), 3);
4307 result = Insert(result, Extract(lhs, 4) >> UShort(rhs), 4);
4308 result = Insert(result, Extract(lhs, 5) >> UShort(rhs), 5);
4309 result = Insert(result, Extract(lhs, 6) >> UShort(rhs), 6);
4310 result = Insert(result, Extract(lhs, 7) >> UShort(rhs), 7);
4311
4312 return result;
4313 }
4314 else
4315 {
4316 return RValue<UShort8>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
4317 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04004318 }
4319
4320 RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs)
4321 {
4322 return RValue<UShort8>(Nucleus::createAdd(lhs.value, rhs.value));
4323 }
4324
4325 RValue<UShort8> operator*(RValue<UShort8> lhs, RValue<UShort8> rhs)
4326 {
4327 return RValue<UShort8>(Nucleus::createMul(lhs.value, rhs.value));
4328 }
4329
Nicolas Capens96d4e092016-11-18 14:22:38 -05004330 RValue<UShort8> operator+=(UShort8 &lhs, RValue<UShort8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004331 {
4332 return lhs = lhs + rhs;
4333 }
4334
4335 RValue<UShort8> operator~(RValue<UShort8> val)
4336 {
4337 return RValue<UShort8>(Nucleus::createNot(val.value));
4338 }
4339
4340 RValue<UShort8> Swizzle(RValue<UShort8> x, char select0, char select1, char select2, char select3, char select4, char select5, char select6, char select7)
4341 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004342 assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004343 }
4344
4345 RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y)
4346 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004347 assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004348 }
4349
4350 // FIXME: Implement as Shuffle(x, y, Select(i0, ..., i16)) and Shuffle(x, y, SELECT_PACK_REPEAT(element))
4351// RValue<UShort8> PackRepeat(RValue<Byte16> x, RValue<Byte16> y, int element)
4352// {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004353// assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004354// }
4355
4356 Type *UShort8::getType()
4357 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04004358 return T(Ice::IceType_v8i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004359 }
4360
4361 Int::Int(Argument<Int> argument)
4362 {
4363 storeValue(argument.value);
4364 }
4365
4366 Int::Int(RValue<Byte> cast)
4367 {
4368 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
4369
4370 storeValue(integer);
4371 }
4372
4373 Int::Int(RValue<SByte> cast)
4374 {
4375 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
4376
4377 storeValue(integer);
4378 }
4379
4380 Int::Int(RValue<Short> cast)
4381 {
4382 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
4383
4384 storeValue(integer);
4385 }
4386
4387 Int::Int(RValue<UShort> cast)
4388 {
4389 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
4390
4391 storeValue(integer);
4392 }
4393
4394 Int::Int(RValue<Int2> cast)
4395 {
4396 *this = Extract(cast, 0);
4397 }
4398
4399 Int::Int(RValue<Long> cast)
4400 {
4401 Value *integer = Nucleus::createTrunc(cast.value, Int::getType());
4402
4403 storeValue(integer);
4404 }
4405
4406 Int::Int(RValue<Float> cast)
4407 {
4408 Value *integer = Nucleus::createFPToSI(cast.value, Int::getType());
4409
4410 storeValue(integer);
4411 }
4412
Nicolas Capens598f8d82016-09-26 15:09:10 -04004413 Int::Int(int x)
4414 {
4415 storeValue(Nucleus::createConstantInt(x));
4416 }
4417
4418 Int::Int(RValue<Int> rhs)
4419 {
4420 storeValue(rhs.value);
4421 }
4422
4423 Int::Int(RValue<UInt> rhs)
4424 {
4425 storeValue(rhs.value);
4426 }
4427
4428 Int::Int(const Int &rhs)
4429 {
4430 Value *value = rhs.loadValue();
4431 storeValue(value);
4432 }
4433
4434 Int::Int(const Reference<Int> &rhs)
4435 {
4436 Value *value = rhs.loadValue();
4437 storeValue(value);
4438 }
4439
4440 Int::Int(const UInt &rhs)
4441 {
4442 Value *value = rhs.loadValue();
4443 storeValue(value);
4444 }
4445
4446 Int::Int(const Reference<UInt> &rhs)
4447 {
4448 Value *value = rhs.loadValue();
4449 storeValue(value);
4450 }
4451
Nicolas Capens96d4e092016-11-18 14:22:38 -05004452 RValue<Int> Int::operator=(int rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004453 {
4454 return RValue<Int>(storeValue(Nucleus::createConstantInt(rhs)));
4455 }
4456
Nicolas Capens96d4e092016-11-18 14:22:38 -05004457 RValue<Int> Int::operator=(RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004458 {
4459 storeValue(rhs.value);
4460
4461 return rhs;
4462 }
4463
Nicolas Capens96d4e092016-11-18 14:22:38 -05004464 RValue<Int> Int::operator=(RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004465 {
4466 storeValue(rhs.value);
4467
4468 return RValue<Int>(rhs);
4469 }
4470
Nicolas Capens96d4e092016-11-18 14:22:38 -05004471 RValue<Int> Int::operator=(const Int &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004472 {
4473 Value *value = rhs.loadValue();
4474 storeValue(value);
4475
4476 return RValue<Int>(value);
4477 }
4478
Nicolas Capens96d4e092016-11-18 14:22:38 -05004479 RValue<Int> Int::operator=(const Reference<Int> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004480 {
4481 Value *value = rhs.loadValue();
4482 storeValue(value);
4483
4484 return RValue<Int>(value);
4485 }
4486
Nicolas Capens96d4e092016-11-18 14:22:38 -05004487 RValue<Int> Int::operator=(const UInt &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004488 {
4489 Value *value = rhs.loadValue();
4490 storeValue(value);
4491
4492 return RValue<Int>(value);
4493 }
4494
Nicolas Capens96d4e092016-11-18 14:22:38 -05004495 RValue<Int> Int::operator=(const Reference<UInt> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004496 {
4497 Value *value = rhs.loadValue();
4498 storeValue(value);
4499
4500 return RValue<Int>(value);
4501 }
4502
4503 RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs)
4504 {
4505 return RValue<Int>(Nucleus::createAdd(lhs.value, rhs.value));
4506 }
4507
4508 RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs)
4509 {
4510 return RValue<Int>(Nucleus::createSub(lhs.value, rhs.value));
4511 }
4512
4513 RValue<Int> operator*(RValue<Int> lhs, RValue<Int> rhs)
4514 {
4515 return RValue<Int>(Nucleus::createMul(lhs.value, rhs.value));
4516 }
4517
4518 RValue<Int> operator/(RValue<Int> lhs, RValue<Int> rhs)
4519 {
4520 return RValue<Int>(Nucleus::createSDiv(lhs.value, rhs.value));
4521 }
4522
4523 RValue<Int> operator%(RValue<Int> lhs, RValue<Int> rhs)
4524 {
4525 return RValue<Int>(Nucleus::createSRem(lhs.value, rhs.value));
4526 }
4527
4528 RValue<Int> operator&(RValue<Int> lhs, RValue<Int> rhs)
4529 {
4530 return RValue<Int>(Nucleus::createAnd(lhs.value, rhs.value));
4531 }
4532
4533 RValue<Int> operator|(RValue<Int> lhs, RValue<Int> rhs)
4534 {
4535 return RValue<Int>(Nucleus::createOr(lhs.value, rhs.value));
4536 }
4537
4538 RValue<Int> operator^(RValue<Int> lhs, RValue<Int> rhs)
4539 {
4540 return RValue<Int>(Nucleus::createXor(lhs.value, rhs.value));
4541 }
4542
4543 RValue<Int> operator<<(RValue<Int> lhs, RValue<Int> rhs)
4544 {
4545 return RValue<Int>(Nucleus::createShl(lhs.value, rhs.value));
4546 }
4547
4548 RValue<Int> operator>>(RValue<Int> lhs, RValue<Int> rhs)
4549 {
4550 return RValue<Int>(Nucleus::createAShr(lhs.value, rhs.value));
4551 }
4552
Nicolas Capens96d4e092016-11-18 14:22:38 -05004553 RValue<Int> operator+=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004554 {
4555 return lhs = lhs + rhs;
4556 }
4557
Nicolas Capens96d4e092016-11-18 14:22:38 -05004558 RValue<Int> operator-=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004559 {
4560 return lhs = lhs - rhs;
4561 }
4562
Nicolas Capens96d4e092016-11-18 14:22:38 -05004563 RValue<Int> operator*=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004564 {
4565 return lhs = lhs * rhs;
4566 }
4567
Nicolas Capens96d4e092016-11-18 14:22:38 -05004568 RValue<Int> operator/=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004569 {
4570 return lhs = lhs / rhs;
4571 }
4572
Nicolas Capens96d4e092016-11-18 14:22:38 -05004573 RValue<Int> operator%=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004574 {
4575 return lhs = lhs % rhs;
4576 }
4577
Nicolas Capens96d4e092016-11-18 14:22:38 -05004578 RValue<Int> operator&=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004579 {
4580 return lhs = lhs & rhs;
4581 }
4582
Nicolas Capens96d4e092016-11-18 14:22:38 -05004583 RValue<Int> operator|=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004584 {
4585 return lhs = lhs | rhs;
4586 }
4587
Nicolas Capens96d4e092016-11-18 14:22:38 -05004588 RValue<Int> operator^=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004589 {
4590 return lhs = lhs ^ rhs;
4591 }
4592
Nicolas Capens96d4e092016-11-18 14:22:38 -05004593 RValue<Int> operator<<=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004594 {
4595 return lhs = lhs << rhs;
4596 }
4597
Nicolas Capens96d4e092016-11-18 14:22:38 -05004598 RValue<Int> operator>>=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004599 {
4600 return lhs = lhs >> rhs;
4601 }
4602
4603 RValue<Int> operator+(RValue<Int> val)
4604 {
4605 return val;
4606 }
4607
4608 RValue<Int> operator-(RValue<Int> val)
4609 {
4610 return RValue<Int>(Nucleus::createNeg(val.value));
4611 }
4612
4613 RValue<Int> operator~(RValue<Int> val)
4614 {
4615 return RValue<Int>(Nucleus::createNot(val.value));
4616 }
4617
Nicolas Capens96d4e092016-11-18 14:22:38 -05004618 RValue<Int> operator++(Int &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04004619 {
Nicolas Capens5b41ba32016-12-08 14:34:00 -05004620 RValue<Int> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05004621 val += 1;
4622 return res;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004623 }
4624
Nicolas Capens96d4e092016-11-18 14:22:38 -05004625 const Int &operator++(Int &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04004626 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004627 val += 1;
4628 return val;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004629 }
4630
Nicolas Capens96d4e092016-11-18 14:22:38 -05004631 RValue<Int> operator--(Int &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04004632 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004633 RValue<Int> res = val;
4634 val -= 1;
4635 return res;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004636 }
4637
Nicolas Capens96d4e092016-11-18 14:22:38 -05004638 const Int &operator--(Int &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04004639 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004640 val -= 1;
4641 return val;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004642 }
4643
4644 RValue<Bool> operator<(RValue<Int> lhs, RValue<Int> rhs)
4645 {
4646 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
4647 }
4648
4649 RValue<Bool> operator<=(RValue<Int> lhs, RValue<Int> rhs)
4650 {
4651 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
4652 }
4653
4654 RValue<Bool> operator>(RValue<Int> lhs, RValue<Int> rhs)
4655 {
4656 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
4657 }
4658
4659 RValue<Bool> operator>=(RValue<Int> lhs, RValue<Int> rhs)
4660 {
4661 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
4662 }
4663
4664 RValue<Bool> operator!=(RValue<Int> lhs, RValue<Int> rhs)
4665 {
4666 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
4667 }
4668
4669 RValue<Bool> operator==(RValue<Int> lhs, RValue<Int> rhs)
4670 {
4671 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
4672 }
4673
4674 RValue<Int> Max(RValue<Int> x, RValue<Int> y)
4675 {
4676 return IfThenElse(x > y, x, y);
4677 }
4678
4679 RValue<Int> Min(RValue<Int> x, RValue<Int> y)
4680 {
4681 return IfThenElse(x < y, x, y);
4682 }
4683
4684 RValue<Int> Clamp(RValue<Int> x, RValue<Int> min, RValue<Int> max)
4685 {
4686 return Min(Max(x, min), max);
4687 }
4688
4689 RValue<Int> RoundInt(RValue<Float> cast)
4690 {
Nicolas Capens091f3502017-10-03 14:56:49 -04004691 if(emulateIntrinsics || CPUID::ARM)
Nicolas Capensf7b75882017-04-26 09:30:47 -04004692 {
4693 // Push the fractional part off the mantissa. Accurate up to +/-2^22.
4694 return Int((cast + Float(0x00C00000)) - Float(0x00C00000));
4695 }
4696 else
4697 {
4698 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
4699 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Nearbyint, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
4700 auto target = ::context->getConstantUndef(Ice::IceType_i32);
4701 auto nearbyint = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
4702 nearbyint->addArg(cast.value);
4703 ::basicBlock->appendInst(nearbyint);
Nicolas Capensa8086512016-11-07 17:32:17 -05004704
Nicolas Capensf7b75882017-04-26 09:30:47 -04004705 return RValue<Int>(V(result));
4706 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04004707 }
4708
4709 Type *Int::getType()
4710 {
4711 return T(Ice::IceType_i32);
4712 }
4713
4714 Long::Long(RValue<Int> cast)
4715 {
4716 Value *integer = Nucleus::createSExt(cast.value, Long::getType());
4717
4718 storeValue(integer);
4719 }
4720
4721 Long::Long(RValue<UInt> cast)
4722 {
4723 Value *integer = Nucleus::createZExt(cast.value, Long::getType());
4724
4725 storeValue(integer);
4726 }
4727
Nicolas Capens598f8d82016-09-26 15:09:10 -04004728 Long::Long(RValue<Long> rhs)
4729 {
4730 storeValue(rhs.value);
4731 }
4732
Nicolas Capens96d4e092016-11-18 14:22:38 -05004733 RValue<Long> Long::operator=(int64_t rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004734 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04004735 return RValue<Long>(storeValue(Nucleus::createConstantLong(rhs)));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004736 }
4737
Nicolas Capens96d4e092016-11-18 14:22:38 -05004738 RValue<Long> Long::operator=(RValue<Long> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004739 {
4740 storeValue(rhs.value);
4741
4742 return rhs;
4743 }
4744
Nicolas Capens96d4e092016-11-18 14:22:38 -05004745 RValue<Long> Long::operator=(const Long &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004746 {
4747 Value *value = rhs.loadValue();
4748 storeValue(value);
4749
4750 return RValue<Long>(value);
4751 }
4752
Nicolas Capens96d4e092016-11-18 14:22:38 -05004753 RValue<Long> Long::operator=(const Reference<Long> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004754 {
4755 Value *value = rhs.loadValue();
4756 storeValue(value);
4757
4758 return RValue<Long>(value);
4759 }
4760
4761 RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs)
4762 {
4763 return RValue<Long>(Nucleus::createAdd(lhs.value, rhs.value));
4764 }
4765
4766 RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs)
4767 {
4768 return RValue<Long>(Nucleus::createSub(lhs.value, rhs.value));
4769 }
4770
Nicolas Capens96d4e092016-11-18 14:22:38 -05004771 RValue<Long> operator+=(Long &lhs, RValue<Long> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004772 {
4773 return lhs = lhs + rhs;
4774 }
4775
Nicolas Capens96d4e092016-11-18 14:22:38 -05004776 RValue<Long> operator-=(Long &lhs, RValue<Long> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004777 {
4778 return lhs = lhs - rhs;
4779 }
4780
4781 RValue<Long> AddAtomic(RValue<Pointer<Long> > x, RValue<Long> y)
4782 {
4783 return RValue<Long>(Nucleus::createAtomicAdd(x.value, y.value));
4784 }
4785
4786 Type *Long::getType()
4787 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04004788 return T(Ice::IceType_i64);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004789 }
4790
Nicolas Capens598f8d82016-09-26 15:09:10 -04004791 UInt::UInt(Argument<UInt> argument)
4792 {
4793 storeValue(argument.value);
4794 }
4795
4796 UInt::UInt(RValue<UShort> cast)
4797 {
4798 Value *integer = Nucleus::createZExt(cast.value, UInt::getType());
4799
4800 storeValue(integer);
4801 }
4802
4803 UInt::UInt(RValue<Long> cast)
4804 {
4805 Value *integer = Nucleus::createTrunc(cast.value, UInt::getType());
4806
4807 storeValue(integer);
4808 }
4809
4810 UInt::UInt(RValue<Float> cast)
4811 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05004812 // Smallest positive value representable in UInt, but not in Int
4813 const unsigned int ustart = 0x80000000u;
4814 const float ustartf = float(ustart);
4815
4816 // If the value is negative, store 0, otherwise store the result of the conversion
4817 storeValue((~(As<Int>(cast) >> 31) &
4818 // Check if the value can be represented as an Int
4819 IfThenElse(cast >= ustartf,
4820 // If the value is too large, subtract ustart and re-add it after conversion.
4821 As<Int>(As<UInt>(Int(cast - Float(ustartf))) + UInt(ustart)),
4822 // Otherwise, just convert normally
4823 Int(cast))).value);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004824 }
4825
Nicolas Capens598f8d82016-09-26 15:09:10 -04004826 UInt::UInt(int x)
4827 {
4828 storeValue(Nucleus::createConstantInt(x));
4829 }
4830
4831 UInt::UInt(unsigned int x)
4832 {
4833 storeValue(Nucleus::createConstantInt(x));
4834 }
4835
4836 UInt::UInt(RValue<UInt> rhs)
4837 {
4838 storeValue(rhs.value);
4839 }
4840
4841 UInt::UInt(RValue<Int> rhs)
4842 {
4843 storeValue(rhs.value);
4844 }
4845
4846 UInt::UInt(const UInt &rhs)
4847 {
4848 Value *value = rhs.loadValue();
4849 storeValue(value);
4850 }
4851
4852 UInt::UInt(const Reference<UInt> &rhs)
4853 {
4854 Value *value = rhs.loadValue();
4855 storeValue(value);
4856 }
4857
4858 UInt::UInt(const Int &rhs)
4859 {
4860 Value *value = rhs.loadValue();
4861 storeValue(value);
4862 }
4863
4864 UInt::UInt(const Reference<Int> &rhs)
4865 {
4866 Value *value = rhs.loadValue();
4867 storeValue(value);
4868 }
4869
Nicolas Capens96d4e092016-11-18 14:22:38 -05004870 RValue<UInt> UInt::operator=(unsigned int rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004871 {
4872 return RValue<UInt>(storeValue(Nucleus::createConstantInt(rhs)));
4873 }
4874
Nicolas Capens96d4e092016-11-18 14:22:38 -05004875 RValue<UInt> UInt::operator=(RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004876 {
4877 storeValue(rhs.value);
4878
4879 return rhs;
4880 }
4881
Nicolas Capens96d4e092016-11-18 14:22:38 -05004882 RValue<UInt> UInt::operator=(RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004883 {
4884 storeValue(rhs.value);
4885
4886 return RValue<UInt>(rhs);
4887 }
4888
Nicolas Capens96d4e092016-11-18 14:22:38 -05004889 RValue<UInt> UInt::operator=(const UInt &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004890 {
4891 Value *value = rhs.loadValue();
4892 storeValue(value);
4893
4894 return RValue<UInt>(value);
4895 }
4896
Nicolas Capens96d4e092016-11-18 14:22:38 -05004897 RValue<UInt> UInt::operator=(const Reference<UInt> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004898 {
4899 Value *value = rhs.loadValue();
4900 storeValue(value);
4901
4902 return RValue<UInt>(value);
4903 }
4904
Nicolas Capens96d4e092016-11-18 14:22:38 -05004905 RValue<UInt> UInt::operator=(const Int &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004906 {
4907 Value *value = rhs.loadValue();
4908 storeValue(value);
4909
4910 return RValue<UInt>(value);
4911 }
4912
Nicolas Capens96d4e092016-11-18 14:22:38 -05004913 RValue<UInt> UInt::operator=(const Reference<Int> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004914 {
4915 Value *value = rhs.loadValue();
4916 storeValue(value);
4917
4918 return RValue<UInt>(value);
4919 }
4920
4921 RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs)
4922 {
4923 return RValue<UInt>(Nucleus::createAdd(lhs.value, rhs.value));
4924 }
4925
4926 RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs)
4927 {
4928 return RValue<UInt>(Nucleus::createSub(lhs.value, rhs.value));
4929 }
4930
4931 RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs)
4932 {
4933 return RValue<UInt>(Nucleus::createMul(lhs.value, rhs.value));
4934 }
4935
4936 RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs)
4937 {
4938 return RValue<UInt>(Nucleus::createUDiv(lhs.value, rhs.value));
4939 }
4940
4941 RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs)
4942 {
4943 return RValue<UInt>(Nucleus::createURem(lhs.value, rhs.value));
4944 }
4945
4946 RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs)
4947 {
4948 return RValue<UInt>(Nucleus::createAnd(lhs.value, rhs.value));
4949 }
4950
4951 RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs)
4952 {
4953 return RValue<UInt>(Nucleus::createOr(lhs.value, rhs.value));
4954 }
4955
4956 RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs)
4957 {
4958 return RValue<UInt>(Nucleus::createXor(lhs.value, rhs.value));
4959 }
4960
4961 RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs)
4962 {
4963 return RValue<UInt>(Nucleus::createShl(lhs.value, rhs.value));
4964 }
4965
4966 RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs)
4967 {
4968 return RValue<UInt>(Nucleus::createLShr(lhs.value, rhs.value));
4969 }
4970
Nicolas Capens96d4e092016-11-18 14:22:38 -05004971 RValue<UInt> operator+=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004972 {
4973 return lhs = lhs + rhs;
4974 }
4975
Nicolas Capens96d4e092016-11-18 14:22:38 -05004976 RValue<UInt> operator-=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004977 {
4978 return lhs = lhs - rhs;
4979 }
4980
Nicolas Capens96d4e092016-11-18 14:22:38 -05004981 RValue<UInt> operator*=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004982 {
4983 return lhs = lhs * rhs;
4984 }
4985
Nicolas Capens96d4e092016-11-18 14:22:38 -05004986 RValue<UInt> operator/=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004987 {
4988 return lhs = lhs / rhs;
4989 }
4990
Nicolas Capens96d4e092016-11-18 14:22:38 -05004991 RValue<UInt> operator%=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004992 {
4993 return lhs = lhs % rhs;
4994 }
4995
Nicolas Capens96d4e092016-11-18 14:22:38 -05004996 RValue<UInt> operator&=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004997 {
4998 return lhs = lhs & rhs;
4999 }
5000
Nicolas Capens96d4e092016-11-18 14:22:38 -05005001 RValue<UInt> operator|=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005002 {
5003 return lhs = lhs | rhs;
5004 }
5005
Nicolas Capens96d4e092016-11-18 14:22:38 -05005006 RValue<UInt> operator^=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005007 {
5008 return lhs = lhs ^ rhs;
5009 }
5010
Nicolas Capens96d4e092016-11-18 14:22:38 -05005011 RValue<UInt> operator<<=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005012 {
5013 return lhs = lhs << rhs;
5014 }
5015
Nicolas Capens96d4e092016-11-18 14:22:38 -05005016 RValue<UInt> operator>>=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005017 {
5018 return lhs = lhs >> rhs;
5019 }
5020
5021 RValue<UInt> operator+(RValue<UInt> val)
5022 {
5023 return val;
5024 }
5025
5026 RValue<UInt> operator-(RValue<UInt> val)
5027 {
5028 return RValue<UInt>(Nucleus::createNeg(val.value));
5029 }
5030
5031 RValue<UInt> operator~(RValue<UInt> val)
5032 {
5033 return RValue<UInt>(Nucleus::createNot(val.value));
5034 }
5035
Nicolas Capens96d4e092016-11-18 14:22:38 -05005036 RValue<UInt> operator++(UInt &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04005037 {
Nicolas Capensd1229402016-11-07 16:05:22 -05005038 RValue<UInt> res = val;
5039 val += 1;
5040 return res;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005041 }
5042
Nicolas Capens96d4e092016-11-18 14:22:38 -05005043 const UInt &operator++(UInt &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04005044 {
Nicolas Capensd1229402016-11-07 16:05:22 -05005045 val += 1;
5046 return val;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005047 }
5048
Nicolas Capens96d4e092016-11-18 14:22:38 -05005049 RValue<UInt> operator--(UInt &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04005050 {
Nicolas Capensd1229402016-11-07 16:05:22 -05005051 RValue<UInt> res = val;
5052 val -= 1;
5053 return res;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005054 }
5055
Nicolas Capens96d4e092016-11-18 14:22:38 -05005056 const UInt &operator--(UInt &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04005057 {
Nicolas Capensd1229402016-11-07 16:05:22 -05005058 val -= 1;
5059 return val;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005060 }
5061
5062 RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y)
5063 {
5064 return IfThenElse(x > y, x, y);
5065 }
5066
5067 RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y)
5068 {
5069 return IfThenElse(x < y, x, y);
5070 }
5071
5072 RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max)
5073 {
5074 return Min(Max(x, min), max);
5075 }
5076
5077 RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs)
5078 {
5079 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
5080 }
5081
5082 RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs)
5083 {
5084 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
5085 }
5086
5087 RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs)
5088 {
5089 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
5090 }
5091
5092 RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs)
5093 {
5094 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
5095 }
5096
5097 RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs)
5098 {
5099 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
5100 }
5101
5102 RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs)
5103 {
5104 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
5105 }
5106
5107// RValue<UInt> RoundUInt(RValue<Float> cast)
5108// {
Nicolas Capensc37252c2016-09-28 16:11:54 -04005109// assert(false && "UNIMPLEMENTED"); return RValue<UInt>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005110// }
5111
5112 Type *UInt::getType()
5113 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04005114 return T(Ice::IceType_i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005115 }
5116
5117// Int2::Int2(RValue<Int> cast)
5118// {
5119// Value *extend = Nucleus::createZExt(cast.value, Long::getType());
5120// Value *vector = Nucleus::createBitCast(extend, Int2::getType());
5121//
5122// Constant *shuffle[2];
5123// shuffle[0] = Nucleus::createConstantInt(0);
5124// shuffle[1] = Nucleus::createConstantInt(0);
5125//
5126// Value *replicate = Nucleus::createShuffleVector(vector, UndefValue::get(Int2::getType()), Nucleus::createConstantVector(shuffle, 2));
5127//
5128// storeValue(replicate);
5129// }
5130
5131 Int2::Int2(RValue<Int4> cast)
5132 {
Nicolas Capens22008782016-10-20 01:11:47 -04005133 storeValue(Nucleus::createBitCast(cast.value, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005134 }
5135
Nicolas Capens598f8d82016-09-26 15:09:10 -04005136 Int2::Int2(int x, int y)
5137 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04005138 int64_t constantVector[2] = {x, y};
5139 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005140 }
5141
5142 Int2::Int2(RValue<Int2> rhs)
5143 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005144 storeValue(rhs.value);
5145 }
5146
5147 Int2::Int2(const Int2 &rhs)
5148 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005149 Value *value = rhs.loadValue();
5150 storeValue(value);
5151 }
5152
5153 Int2::Int2(const Reference<Int2> &rhs)
5154 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005155 Value *value = rhs.loadValue();
5156 storeValue(value);
5157 }
5158
5159 Int2::Int2(RValue<Int> lo, RValue<Int> hi)
5160 {
Nicolas Capensd4227962016-11-09 14:24:25 -05005161 int shuffle[4] = {0, 4, 1, 5};
5162 Value *packed = Nucleus::createShuffleVector(Int4(lo).loadValue(), Int4(hi).loadValue(), shuffle);
5163
5164 storeValue(Nucleus::createBitCast(packed, Int2::getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005165 }
5166
Nicolas Capens96d4e092016-11-18 14:22:38 -05005167 RValue<Int2> Int2::operator=(RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005168 {
5169 storeValue(rhs.value);
5170
5171 return rhs;
5172 }
5173
Nicolas Capens96d4e092016-11-18 14:22:38 -05005174 RValue<Int2> Int2::operator=(const Int2 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005175 {
5176 Value *value = rhs.loadValue();
5177 storeValue(value);
5178
5179 return RValue<Int2>(value);
5180 }
5181
Nicolas Capens96d4e092016-11-18 14:22:38 -05005182 RValue<Int2> Int2::operator=(const Reference<Int2> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005183 {
5184 Value *value = rhs.loadValue();
5185 storeValue(value);
5186
5187 return RValue<Int2>(value);
5188 }
5189
5190 RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs)
5191 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005192 return RValue<Int2>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005193 }
5194
5195 RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs)
5196 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005197 return RValue<Int2>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005198 }
5199
5200// RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs)
5201// {
5202// return RValue<Int2>(Nucleus::createMul(lhs.value, rhs.value));
5203// }
5204
5205// RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs)
5206// {
5207// return RValue<Int2>(Nucleus::createSDiv(lhs.value, rhs.value));
5208// }
5209
5210// RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs)
5211// {
5212// return RValue<Int2>(Nucleus::createSRem(lhs.value, rhs.value));
5213// }
5214
5215 RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs)
5216 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005217 return RValue<Int2>(Nucleus::createAnd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005218 }
5219
5220 RValue<Int2> operator|(RValue<Int2> lhs, RValue<Int2> rhs)
5221 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005222 return RValue<Int2>(Nucleus::createOr(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005223 }
5224
5225 RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs)
5226 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005227 return RValue<Int2>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005228 }
5229
5230 RValue<Int2> operator<<(RValue<Int2> lhs, unsigned char rhs)
5231 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005232 if(emulateIntrinsics)
5233 {
5234 Int2 result;
5235 result = Insert(result, Extract(lhs, 0) << Int(rhs), 0);
5236 result = Insert(result, Extract(lhs, 1) << Int(rhs), 1);
5237
5238 return result;
5239 }
5240 else
5241 {
5242 return RValue<Int2>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
5243 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005244 }
5245
5246 RValue<Int2> operator>>(RValue<Int2> lhs, unsigned char rhs)
5247 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005248 if(emulateIntrinsics)
5249 {
5250 Int2 result;
5251 result = Insert(result, Extract(lhs, 0) >> Int(rhs), 0);
5252 result = Insert(result, Extract(lhs, 1) >> Int(rhs), 1);
5253
5254 return result;
5255 }
5256 else
5257 {
5258 return RValue<Int2>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
5259 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005260 }
5261
Nicolas Capens96d4e092016-11-18 14:22:38 -05005262 RValue<Int2> operator+=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005263 {
5264 return lhs = lhs + rhs;
5265 }
5266
Nicolas Capens96d4e092016-11-18 14:22:38 -05005267 RValue<Int2> operator-=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005268 {
5269 return lhs = lhs - rhs;
5270 }
5271
Nicolas Capens96d4e092016-11-18 14:22:38 -05005272// RValue<Int2> operator*=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005273// {
5274// return lhs = lhs * rhs;
5275// }
5276
Nicolas Capens96d4e092016-11-18 14:22:38 -05005277// RValue<Int2> operator/=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005278// {
5279// return lhs = lhs / rhs;
5280// }
5281
Nicolas Capens96d4e092016-11-18 14:22:38 -05005282// RValue<Int2> operator%=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005283// {
5284// return lhs = lhs % rhs;
5285// }
5286
Nicolas Capens96d4e092016-11-18 14:22:38 -05005287 RValue<Int2> operator&=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005288 {
5289 return lhs = lhs & rhs;
5290 }
5291
Nicolas Capens96d4e092016-11-18 14:22:38 -05005292 RValue<Int2> operator|=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005293 {
5294 return lhs = lhs | rhs;
5295 }
5296
Nicolas Capens96d4e092016-11-18 14:22:38 -05005297 RValue<Int2> operator^=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005298 {
5299 return lhs = lhs ^ rhs;
5300 }
5301
Nicolas Capens96d4e092016-11-18 14:22:38 -05005302 RValue<Int2> operator<<=(Int2 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005303 {
5304 return lhs = lhs << rhs;
5305 }
5306
Nicolas Capens96d4e092016-11-18 14:22:38 -05005307 RValue<Int2> operator>>=(Int2 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005308 {
5309 return lhs = lhs >> rhs;
5310 }
5311
Nicolas Capens598f8d82016-09-26 15:09:10 -04005312// RValue<Int2> operator+(RValue<Int2> val)
5313// {
5314// return val;
5315// }
5316
5317// RValue<Int2> operator-(RValue<Int2> val)
5318// {
5319// return RValue<Int2>(Nucleus::createNeg(val.value));
5320// }
5321
5322 RValue<Int2> operator~(RValue<Int2> val)
5323 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -05005324 return RValue<Int2>(Nucleus::createNot(val.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005325 }
5326
Nicolas Capens45f187a2016-12-02 15:30:56 -05005327 RValue<Short4> UnpackLow(RValue<Int2> x, RValue<Int2> y)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005328 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05005329 int shuffle[4] = {0, 4, 1, 5}; // Real type is v4i32
5330 return As<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005331 }
5332
Nicolas Capens45f187a2016-12-02 15:30:56 -05005333 RValue<Short4> UnpackHigh(RValue<Int2> x, RValue<Int2> y)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005334 {
Nicolas Capensf8beb4b2017-01-27 02:55:44 -08005335 int shuffle[4] = {0, 4, 1, 5}; // Real type is v4i32
Nicolas Capensc70a1162016-12-03 00:16:14 -05005336 auto lowHigh = RValue<Int4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
5337 return As<Short4>(Swizzle(lowHigh, 0xEE));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005338 }
5339
5340 RValue<Int> Extract(RValue<Int2> val, int i)
5341 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05005342 return RValue<Int>(Nucleus::createExtractElement(val.value, Int::getType(), i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005343 }
5344
5345 RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i)
5346 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05005347 return RValue<Int2>(Nucleus::createInsertElement(val.value, element.value, i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005348 }
5349
5350 Type *Int2::getType()
5351 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04005352 return T(Type_v2i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005353 }
5354
Nicolas Capens598f8d82016-09-26 15:09:10 -04005355 UInt2::UInt2(unsigned int x, unsigned int y)
5356 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04005357 int64_t constantVector[2] = {x, y};
5358 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005359 }
5360
5361 UInt2::UInt2(RValue<UInt2> rhs)
5362 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005363 storeValue(rhs.value);
5364 }
5365
5366 UInt2::UInt2(const UInt2 &rhs)
5367 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005368 Value *value = rhs.loadValue();
5369 storeValue(value);
5370 }
5371
5372 UInt2::UInt2(const Reference<UInt2> &rhs)
5373 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005374 Value *value = rhs.loadValue();
5375 storeValue(value);
5376 }
5377
Nicolas Capens96d4e092016-11-18 14:22:38 -05005378 RValue<UInt2> UInt2::operator=(RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005379 {
5380 storeValue(rhs.value);
5381
5382 return rhs;
5383 }
5384
Nicolas Capens96d4e092016-11-18 14:22:38 -05005385 RValue<UInt2> UInt2::operator=(const UInt2 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005386 {
5387 Value *value = rhs.loadValue();
5388 storeValue(value);
5389
5390 return RValue<UInt2>(value);
5391 }
5392
Nicolas Capens96d4e092016-11-18 14:22:38 -05005393 RValue<UInt2> UInt2::operator=(const Reference<UInt2> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005394 {
5395 Value *value = rhs.loadValue();
5396 storeValue(value);
5397
5398 return RValue<UInt2>(value);
5399 }
5400
5401 RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs)
5402 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005403 return RValue<UInt2>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005404 }
5405
5406 RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs)
5407 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005408 return RValue<UInt2>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005409 }
5410
5411// RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs)
5412// {
5413// return RValue<UInt2>(Nucleus::createMul(lhs.value, rhs.value));
5414// }
5415
5416// RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs)
5417// {
5418// return RValue<UInt2>(Nucleus::createUDiv(lhs.value, rhs.value));
5419// }
5420
5421// RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs)
5422// {
5423// return RValue<UInt2>(Nucleus::createURem(lhs.value, rhs.value));
5424// }
5425
5426 RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs)
5427 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005428 return RValue<UInt2>(Nucleus::createAnd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005429 }
5430
5431 RValue<UInt2> operator|(RValue<UInt2> lhs, RValue<UInt2> rhs)
5432 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005433 return RValue<UInt2>(Nucleus::createOr(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005434 }
5435
5436 RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs)
5437 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005438 return RValue<UInt2>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005439 }
5440
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005441 RValue<UInt> Extract(RValue<UInt2> val, int i)
5442 {
5443 return RValue<UInt>(Nucleus::createExtractElement(val.value, UInt::getType(), i));
5444 }
5445
5446 RValue<UInt2> Insert(RValue<UInt2> val, RValue<UInt> element, int i)
5447 {
5448 return RValue<UInt2>(Nucleus::createInsertElement(val.value, element.value, i));
5449 }
5450
Nicolas Capens598f8d82016-09-26 15:09:10 -04005451 RValue<UInt2> operator<<(RValue<UInt2> lhs, unsigned char rhs)
5452 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005453 if(emulateIntrinsics)
5454 {
5455 UInt2 result;
5456 result = Insert(result, Extract(lhs, 0) << UInt(rhs), 0);
5457 result = Insert(result, Extract(lhs, 1) << UInt(rhs), 1);
5458
5459 return result;
5460 }
5461 else
5462 {
5463 return RValue<UInt2>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
5464 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005465 }
5466
5467 RValue<UInt2> operator>>(RValue<UInt2> lhs, unsigned char rhs)
5468 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005469 if(emulateIntrinsics)
5470 {
5471 UInt2 result;
5472 result = Insert(result, Extract(lhs, 0) >> UInt(rhs), 0);
5473 result = Insert(result, Extract(lhs, 1) >> UInt(rhs), 1);
5474
5475 return result;
5476 }
5477 else
5478 {
5479 return RValue<UInt2>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
5480 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005481 }
5482
Nicolas Capens96d4e092016-11-18 14:22:38 -05005483 RValue<UInt2> operator+=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005484 {
5485 return lhs = lhs + rhs;
5486 }
5487
Nicolas Capens96d4e092016-11-18 14:22:38 -05005488 RValue<UInt2> operator-=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005489 {
5490 return lhs = lhs - rhs;
5491 }
5492
Nicolas Capens96d4e092016-11-18 14:22:38 -05005493// RValue<UInt2> operator*=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005494// {
5495// return lhs = lhs * rhs;
5496// }
5497
Nicolas Capens96d4e092016-11-18 14:22:38 -05005498// RValue<UInt2> operator/=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005499// {
5500// return lhs = lhs / rhs;
5501// }
5502
Nicolas Capens96d4e092016-11-18 14:22:38 -05005503// RValue<UInt2> operator%=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005504// {
5505// return lhs = lhs % rhs;
5506// }
5507
Nicolas Capens96d4e092016-11-18 14:22:38 -05005508 RValue<UInt2> operator&=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005509 {
5510 return lhs = lhs & rhs;
5511 }
5512
Nicolas Capens96d4e092016-11-18 14:22:38 -05005513 RValue<UInt2> operator|=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005514 {
5515 return lhs = lhs | rhs;
5516 }
5517
Nicolas Capens96d4e092016-11-18 14:22:38 -05005518 RValue<UInt2> operator^=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005519 {
5520 return lhs = lhs ^ rhs;
5521 }
5522
Nicolas Capens96d4e092016-11-18 14:22:38 -05005523 RValue<UInt2> operator<<=(UInt2 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005524 {
5525 return lhs = lhs << rhs;
5526 }
5527
Nicolas Capens96d4e092016-11-18 14:22:38 -05005528 RValue<UInt2> operator>>=(UInt2 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005529 {
5530 return lhs = lhs >> rhs;
5531 }
5532
Nicolas Capens598f8d82016-09-26 15:09:10 -04005533// RValue<UInt2> operator+(RValue<UInt2> val)
5534// {
5535// return val;
5536// }
5537
5538// RValue<UInt2> operator-(RValue<UInt2> val)
5539// {
5540// return RValue<UInt2>(Nucleus::createNeg(val.value));
5541// }
5542
5543 RValue<UInt2> operator~(RValue<UInt2> val)
5544 {
5545 return RValue<UInt2>(Nucleus::createNot(val.value));
5546 }
5547
5548 Type *UInt2::getType()
5549 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04005550 return T(Type_v2i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005551 }
5552
Nicolas Capenscb986762017-01-20 11:34:37 -05005553 Int4::Int4() : XYZW(this)
5554 {
5555 }
5556
5557 Int4::Int4(RValue<Byte4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005558 {
Nicolas Capensd4227962016-11-09 14:24:25 -05005559 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
5560 Value *a = Nucleus::createInsertElement(loadValue(), x, 0);
5561
5562 Value *e;
5563 int swizzle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23};
5564 Value *b = Nucleus::createBitCast(a, Byte16::getType());
5565 Value *c = Nucleus::createShuffleVector(b, V(Nucleus::createNullValue(Byte16::getType())), swizzle);
5566
5567 int swizzle2[8] = {0, 8, 1, 9, 2, 10, 3, 11};
5568 Value *d = Nucleus::createBitCast(c, Short8::getType());
5569 e = Nucleus::createShuffleVector(d, V(Nucleus::createNullValue(Short8::getType())), swizzle2);
5570
5571 Value *f = Nucleus::createBitCast(e, Int4::getType());
5572 storeValue(f);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005573 }
5574
Nicolas Capenscb986762017-01-20 11:34:37 -05005575 Int4::Int4(RValue<SByte4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005576 {
Nicolas Capensd4227962016-11-09 14:24:25 -05005577 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
5578 Value *a = Nucleus::createInsertElement(loadValue(), x, 0);
5579
Nicolas Capensd4227962016-11-09 14:24:25 -05005580 int swizzle[16] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7};
5581 Value *b = Nucleus::createBitCast(a, Byte16::getType());
5582 Value *c = Nucleus::createShuffleVector(b, b, swizzle);
5583
5584 int swizzle2[8] = {0, 0, 1, 1, 2, 2, 3, 3};
5585 Value *d = Nucleus::createBitCast(c, Short8::getType());
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005586 Value *e = Nucleus::createShuffleVector(d, d, swizzle2);
Nicolas Capensd4227962016-11-09 14:24:25 -05005587
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005588 *this = As<Int4>(e) >> 24;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005589 }
5590
Nicolas Capenscb986762017-01-20 11:34:37 -05005591 Int4::Int4(RValue<Float4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005592 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005593 Value *xyzw = Nucleus::createFPToSI(cast.value, Int4::getType());
5594
5595 storeValue(xyzw);
5596 }
5597
Nicolas Capenscb986762017-01-20 11:34:37 -05005598 Int4::Int4(RValue<Short4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005599 {
Nicolas Capensd4227962016-11-09 14:24:25 -05005600 int swizzle[8] = {0, 0, 1, 1, 2, 2, 3, 3};
5601 Value *c = Nucleus::createShuffleVector(cast.value, cast.value, swizzle);
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005602
5603 *this = As<Int4>(c) >> 16;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005604 }
5605
Nicolas Capenscb986762017-01-20 11:34:37 -05005606 Int4::Int4(RValue<UShort4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005607 {
Nicolas Capensd4227962016-11-09 14:24:25 -05005608 int swizzle[8] = {0, 8, 1, 9, 2, 10, 3, 11};
5609 Value *c = Nucleus::createShuffleVector(cast.value, Short8(0, 0, 0, 0, 0, 0, 0, 0).loadValue(), swizzle);
5610 Value *d = Nucleus::createBitCast(c, Int4::getType());
5611 storeValue(d);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005612 }
5613
Nicolas Capenscb986762017-01-20 11:34:37 -05005614 Int4::Int4(int xyzw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005615 {
5616 constant(xyzw, xyzw, xyzw, xyzw);
5617 }
5618
Nicolas Capenscb986762017-01-20 11:34:37 -05005619 Int4::Int4(int x, int yzw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005620 {
5621 constant(x, yzw, yzw, yzw);
5622 }
5623
Nicolas Capenscb986762017-01-20 11:34:37 -05005624 Int4::Int4(int x, int y, int zw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005625 {
5626 constant(x, y, zw, zw);
5627 }
5628
Nicolas Capenscb986762017-01-20 11:34:37 -05005629 Int4::Int4(int x, int y, int z, int w) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005630 {
5631 constant(x, y, z, w);
5632 }
5633
5634 void Int4::constant(int x, int y, int z, int w)
5635 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04005636 int64_t constantVector[4] = {x, y, z, w};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04005637 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005638 }
5639
Nicolas Capenscb986762017-01-20 11:34:37 -05005640 Int4::Int4(RValue<Int4> rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005641 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005642 storeValue(rhs.value);
5643 }
5644
Nicolas Capenscb986762017-01-20 11:34:37 -05005645 Int4::Int4(const Int4 &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005646 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005647 Value *value = rhs.loadValue();
5648 storeValue(value);
5649 }
5650
Nicolas Capenscb986762017-01-20 11:34:37 -05005651 Int4::Int4(const Reference<Int4> &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005652 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005653 Value *value = rhs.loadValue();
5654 storeValue(value);
5655 }
5656
Nicolas Capenscb986762017-01-20 11:34:37 -05005657 Int4::Int4(RValue<UInt4> rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005658 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005659 storeValue(rhs.value);
5660 }
5661
Nicolas Capenscb986762017-01-20 11:34:37 -05005662 Int4::Int4(const UInt4 &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005663 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005664 Value *value = rhs.loadValue();
5665 storeValue(value);
5666 }
5667
Nicolas Capenscb986762017-01-20 11:34:37 -05005668 Int4::Int4(const Reference<UInt4> &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005669 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005670 Value *value = rhs.loadValue();
5671 storeValue(value);
5672 }
5673
Nicolas Capenscb986762017-01-20 11:34:37 -05005674 Int4::Int4(RValue<Int2> lo, RValue<Int2> hi) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005675 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05005676 int shuffle[4] = {0, 1, 4, 5}; // Real type is v4i32
5677 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
5678
5679 storeValue(packed);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005680 }
5681
Nicolas Capenscb986762017-01-20 11:34:37 -05005682 Int4::Int4(RValue<Int> rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005683 {
Nicolas Capensf8beb4b2017-01-27 02:55:44 -08005684 Value *vector = Nucleus::createBitCast(rhs.value, Int4::getType());
Nicolas Capensd4227962016-11-09 14:24:25 -05005685
5686 int swizzle[4] = {0, 0, 0, 0};
Nicolas Capensf8beb4b2017-01-27 02:55:44 -08005687 Value *replicate = Nucleus::createShuffleVector(vector, vector, swizzle);
Nicolas Capensd4227962016-11-09 14:24:25 -05005688
5689 storeValue(replicate);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005690 }
5691
Nicolas Capenscb986762017-01-20 11:34:37 -05005692 Int4::Int4(const Int &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005693 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005694 *this = RValue<Int>(rhs.loadValue());
5695 }
5696
Nicolas Capenscb986762017-01-20 11:34:37 -05005697 Int4::Int4(const Reference<Int> &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005698 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005699 *this = RValue<Int>(rhs.loadValue());
5700 }
5701
Nicolas Capens96d4e092016-11-18 14:22:38 -05005702 RValue<Int4> Int4::operator=(RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005703 {
5704 storeValue(rhs.value);
5705
5706 return rhs;
5707 }
5708
Nicolas Capens96d4e092016-11-18 14:22:38 -05005709 RValue<Int4> Int4::operator=(const Int4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005710 {
5711 Value *value = rhs.loadValue();
5712 storeValue(value);
5713
5714 return RValue<Int4>(value);
5715 }
5716
Nicolas Capens96d4e092016-11-18 14:22:38 -05005717 RValue<Int4> Int4::operator=(const Reference<Int4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005718 {
5719 Value *value = rhs.loadValue();
5720 storeValue(value);
5721
5722 return RValue<Int4>(value);
5723 }
5724
5725 RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs)
5726 {
5727 return RValue<Int4>(Nucleus::createAdd(lhs.value, rhs.value));
5728 }
5729
5730 RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs)
5731 {
5732 return RValue<Int4>(Nucleus::createSub(lhs.value, rhs.value));
5733 }
5734
5735 RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs)
5736 {
5737 return RValue<Int4>(Nucleus::createMul(lhs.value, rhs.value));
5738 }
5739
5740 RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs)
5741 {
5742 return RValue<Int4>(Nucleus::createSDiv(lhs.value, rhs.value));
5743 }
5744
5745 RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs)
5746 {
5747 return RValue<Int4>(Nucleus::createSRem(lhs.value, rhs.value));
5748 }
5749
5750 RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs)
5751 {
5752 return RValue<Int4>(Nucleus::createAnd(lhs.value, rhs.value));
5753 }
5754
5755 RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs)
5756 {
5757 return RValue<Int4>(Nucleus::createOr(lhs.value, rhs.value));
5758 }
5759
5760 RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs)
5761 {
5762 return RValue<Int4>(Nucleus::createXor(lhs.value, rhs.value));
5763 }
5764
5765 RValue<Int4> operator<<(RValue<Int4> lhs, unsigned char rhs)
5766 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005767 if(emulateIntrinsics)
5768 {
5769 Int4 result;
5770 result = Insert(result, Extract(lhs, 0) << Int(rhs), 0);
5771 result = Insert(result, Extract(lhs, 1) << Int(rhs), 1);
5772 result = Insert(result, Extract(lhs, 2) << Int(rhs), 2);
5773 result = Insert(result, Extract(lhs, 3) << Int(rhs), 3);
5774
5775 return result;
5776 }
5777 else
5778 {
5779 return RValue<Int4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
5780 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005781 }
5782
5783 RValue<Int4> operator>>(RValue<Int4> lhs, unsigned char rhs)
5784 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005785 if(emulateIntrinsics)
5786 {
5787 Int4 result;
5788 result = Insert(result, Extract(lhs, 0) >> Int(rhs), 0);
5789 result = Insert(result, Extract(lhs, 1) >> Int(rhs), 1);
5790 result = Insert(result, Extract(lhs, 2) >> Int(rhs), 2);
5791 result = Insert(result, Extract(lhs, 3) >> Int(rhs), 3);
5792
5793 return result;
5794 }
5795 else
5796 {
5797 return RValue<Int4>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
5798 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005799 }
5800
5801 RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs)
5802 {
5803 return RValue<Int4>(Nucleus::createShl(lhs.value, rhs.value));
5804 }
5805
5806 RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs)
5807 {
5808 return RValue<Int4>(Nucleus::createAShr(lhs.value, rhs.value));
5809 }
5810
Nicolas Capens96d4e092016-11-18 14:22:38 -05005811 RValue<Int4> operator+=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005812 {
5813 return lhs = lhs + rhs;
5814 }
5815
Nicolas Capens96d4e092016-11-18 14:22:38 -05005816 RValue<Int4> operator-=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005817 {
5818 return lhs = lhs - rhs;
5819 }
5820
Nicolas Capens96d4e092016-11-18 14:22:38 -05005821 RValue<Int4> operator*=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005822 {
5823 return lhs = lhs * rhs;
5824 }
5825
Nicolas Capens96d4e092016-11-18 14:22:38 -05005826// RValue<Int4> operator/=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005827// {
5828// return lhs = lhs / rhs;
5829// }
5830
Nicolas Capens96d4e092016-11-18 14:22:38 -05005831// RValue<Int4> operator%=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005832// {
5833// return lhs = lhs % rhs;
5834// }
5835
Nicolas Capens96d4e092016-11-18 14:22:38 -05005836 RValue<Int4> operator&=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005837 {
5838 return lhs = lhs & rhs;
5839 }
5840
Nicolas Capens96d4e092016-11-18 14:22:38 -05005841 RValue<Int4> operator|=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005842 {
5843 return lhs = lhs | rhs;
5844 }
5845
Nicolas Capens96d4e092016-11-18 14:22:38 -05005846 RValue<Int4> operator^=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005847 {
5848 return lhs = lhs ^ rhs;
5849 }
5850
Nicolas Capens96d4e092016-11-18 14:22:38 -05005851 RValue<Int4> operator<<=(Int4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005852 {
5853 return lhs = lhs << rhs;
5854 }
5855
Nicolas Capens96d4e092016-11-18 14:22:38 -05005856 RValue<Int4> operator>>=(Int4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005857 {
5858 return lhs = lhs >> rhs;
5859 }
5860
5861 RValue<Int4> operator+(RValue<Int4> val)
5862 {
5863 return val;
5864 }
5865
5866 RValue<Int4> operator-(RValue<Int4> val)
5867 {
5868 return RValue<Int4>(Nucleus::createNeg(val.value));
5869 }
5870
5871 RValue<Int4> operator~(RValue<Int4> val)
5872 {
5873 return RValue<Int4>(Nucleus::createNot(val.value));
5874 }
5875
5876 RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y)
5877 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005878 return RValue<Int4>(Nucleus::createICmpEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005879 }
5880
5881 RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y)
5882 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005883 return RValue<Int4>(Nucleus::createICmpSLT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005884 }
5885
5886 RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y)
5887 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005888 return RValue<Int4>(Nucleus::createICmpSLE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005889 }
5890
5891 RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y)
5892 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005893 return RValue<Int4>(Nucleus::createICmpNE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005894 }
5895
5896 RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y)
5897 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005898 return RValue<Int4>(Nucleus::createICmpSGE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005899 }
5900
5901 RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y)
5902 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005903 return RValue<Int4>(Nucleus::createICmpSGT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005904 }
5905
5906 RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y)
5907 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04005908 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
5909 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sle, condition, x.value, y.value);
5910 ::basicBlock->appendInst(cmp);
5911
5912 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5913 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
5914 ::basicBlock->appendInst(select);
5915
5916 return RValue<Int4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005917 }
5918
5919 RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y)
5920 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04005921 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
5922 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sgt, condition, x.value, y.value);
5923 ::basicBlock->appendInst(cmp);
5924
5925 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5926 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
5927 ::basicBlock->appendInst(select);
5928
5929 return RValue<Int4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005930 }
5931
5932 RValue<Int4> RoundInt(RValue<Float4> cast)
5933 {
Nicolas Capens091f3502017-10-03 14:56:49 -04005934 if(emulateIntrinsics || CPUID::ARM)
Nicolas Capensf7b75882017-04-26 09:30:47 -04005935 {
5936 // Push the fractional part off the mantissa. Accurate up to +/-2^22.
5937 return Int4((cast + Float4(0x00C00000)) - Float4(0x00C00000));
5938 }
5939 else
5940 {
5941 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5942 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Nearbyint, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5943 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5944 auto nearbyint = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
5945 nearbyint->addArg(cast.value);
5946 ::basicBlock->appendInst(nearbyint);
Nicolas Capensa8086512016-11-07 17:32:17 -05005947
Nicolas Capensf7b75882017-04-26 09:30:47 -04005948 return RValue<Int4>(V(result));
5949 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005950 }
5951
Nicolas Capens33438a62017-09-27 11:47:35 -04005952 RValue<Short8> PackSigned(RValue<Int4> x, RValue<Int4> y)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005953 {
Nicolas Capens8960fbf2017-07-25 15:32:12 -04005954 if(emulateIntrinsics)
5955 {
5956 Short8 result;
Nicolas Capens33438a62017-09-27 11:47:35 -04005957 result = Insert(result, SaturateSigned(Extract(x, 0)), 0);
5958 result = Insert(result, SaturateSigned(Extract(x, 1)), 1);
5959 result = Insert(result, SaturateSigned(Extract(x, 2)), 2);
5960 result = Insert(result, SaturateSigned(Extract(x, 3)), 3);
5961 result = Insert(result, SaturateSigned(Extract(y, 0)), 4);
5962 result = Insert(result, SaturateSigned(Extract(y, 1)), 5);
5963 result = Insert(result, SaturateSigned(Extract(y, 2)), 6);
5964 result = Insert(result, SaturateSigned(Extract(y, 3)), 7);
Nicolas Capensec54a172016-10-25 17:32:37 -04005965
Nicolas Capens8960fbf2017-07-25 15:32:12 -04005966 return result;
5967 }
5968 else
5969 {
5970 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
5971 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5972 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5973 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
5974 pack->addArg(x.value);
5975 pack->addArg(y.value);
5976 ::basicBlock->appendInst(pack);
5977
5978 return RValue<Short8>(V(result));
5979 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005980 }
5981
Nicolas Capens33438a62017-09-27 11:47:35 -04005982 RValue<UShort8> PackUnsigned(RValue<Int4> x, RValue<Int4> y)
5983 {
Nicolas Capens091f3502017-10-03 14:56:49 -04005984 if(emulateIntrinsics || !(CPUID::SSE4_1 || CPUID::ARM))
5985 {
5986 RValue<Int4> sx = As<Int4>(x);
5987 RValue<Int4> bx = (sx & ~(sx >> 31)) - Int4(0x8000);
5988
5989 RValue<Int4> sy = As<Int4>(y);
5990 RValue<Int4> by = (sy & ~(sy >> 31)) - Int4(0x8000);
5991
5992 return As<UShort8>(PackSigned(bx, by) + Short8(0x8000u));
5993 }
5994 else
Nicolas Capens33438a62017-09-27 11:47:35 -04005995 {
5996 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
5997 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5998 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5999 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
6000 pack->addArg(x.value);
6001 pack->addArg(y.value);
6002 ::basicBlock->appendInst(pack);
6003
6004 return RValue<UShort8>(V(result));
6005 }
Nicolas Capens33438a62017-09-27 11:47:35 -04006006 }
6007
Nicolas Capens598f8d82016-09-26 15:09:10 -04006008 RValue<Int> Extract(RValue<Int4> x, int i)
6009 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006010 return RValue<Int>(Nucleus::createExtractElement(x.value, Int::getType(), i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006011 }
6012
6013 RValue<Int4> Insert(RValue<Int4> x, RValue<Int> element, int i)
6014 {
6015 return RValue<Int4>(Nucleus::createInsertElement(x.value, element.value, i));
6016 }
6017
6018 RValue<Int> SignMask(RValue<Int4> x)
6019 {
Nicolas Capens091f3502017-10-03 14:56:49 -04006020 if(emulateIntrinsics || CPUID::ARM)
Nicolas Capensd6cacad2017-07-25 15:32:12 -04006021 {
6022 Int4 xx = (x >> 31) & Int4(0x00000001, 0x00000002, 0x00000004, 0x00000008);
6023 return Extract(xx, 0) | Extract(xx, 1) | Extract(xx, 2) | Extract(xx, 3);
6024 }
6025 else
6026 {
6027 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
6028 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6029 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6030 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
6031 movmsk->addArg(x.value);
6032 ::basicBlock->appendInst(movmsk);
Nicolas Capensf2cb9df2016-10-21 17:26:13 -04006033
Nicolas Capensd6cacad2017-07-25 15:32:12 -04006034 return RValue<Int>(V(result));
6035 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04006036 }
6037
6038 RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select)
6039 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006040 return RValue<Int4>(createSwizzle4(x.value, select));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006041 }
6042
6043 Type *Int4::getType()
6044 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04006045 return T(Ice::IceType_v4i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006046 }
6047
Nicolas Capenscb986762017-01-20 11:34:37 -05006048 UInt4::UInt4() : XYZW(this)
6049 {
6050 }
6051
6052 UInt4::UInt4(RValue<Float4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006053 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05006054 // Smallest positive value representable in UInt, but not in Int
6055 const unsigned int ustart = 0x80000000u;
6056 const float ustartf = float(ustart);
6057
6058 // Check if the value can be represented as an Int
6059 Int4 uiValue = CmpNLT(cast, Float4(ustartf));
6060 // If the value is too large, subtract ustart and re-add it after conversion.
6061 uiValue = (uiValue & As<Int4>(As<UInt4>(Int4(cast - Float4(ustartf))) + UInt4(ustart))) |
6062 // Otherwise, just convert normally
6063 (~uiValue & Int4(cast));
6064 // If the value is negative, store 0, otherwise store the result of the conversion
6065 storeValue((~(As<Int4>(cast) >> 31) & uiValue).value);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006066 }
6067
Nicolas Capenscb986762017-01-20 11:34:37 -05006068 UInt4::UInt4(int xyzw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006069 {
6070 constant(xyzw, xyzw, xyzw, xyzw);
6071 }
6072
Nicolas Capenscb986762017-01-20 11:34:37 -05006073 UInt4::UInt4(int x, int yzw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006074 {
6075 constant(x, yzw, yzw, yzw);
6076 }
6077
Nicolas Capenscb986762017-01-20 11:34:37 -05006078 UInt4::UInt4(int x, int y, int zw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006079 {
6080 constant(x, y, zw, zw);
6081 }
6082
Nicolas Capenscb986762017-01-20 11:34:37 -05006083 UInt4::UInt4(int x, int y, int z, int w) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006084 {
6085 constant(x, y, z, w);
6086 }
6087
6088 void UInt4::constant(int x, int y, int z, int w)
6089 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04006090 int64_t constantVector[4] = {x, y, z, w};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04006091 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006092 }
6093
Nicolas Capenscb986762017-01-20 11:34:37 -05006094 UInt4::UInt4(RValue<UInt4> rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006095 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006096 storeValue(rhs.value);
6097 }
6098
Nicolas Capenscb986762017-01-20 11:34:37 -05006099 UInt4::UInt4(const UInt4 &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006100 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006101 Value *value = rhs.loadValue();
6102 storeValue(value);
6103 }
6104
Nicolas Capenscb986762017-01-20 11:34:37 -05006105 UInt4::UInt4(const Reference<UInt4> &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006106 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006107 Value *value = rhs.loadValue();
6108 storeValue(value);
6109 }
6110
Nicolas Capenscb986762017-01-20 11:34:37 -05006111 UInt4::UInt4(RValue<Int4> rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006112 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006113 storeValue(rhs.value);
6114 }
6115
Nicolas Capenscb986762017-01-20 11:34:37 -05006116 UInt4::UInt4(const Int4 &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006117 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006118 Value *value = rhs.loadValue();
6119 storeValue(value);
6120 }
6121
Nicolas Capenscb986762017-01-20 11:34:37 -05006122 UInt4::UInt4(const Reference<Int4> &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006123 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006124 Value *value = rhs.loadValue();
6125 storeValue(value);
6126 }
6127
Nicolas Capenscb986762017-01-20 11:34:37 -05006128 UInt4::UInt4(RValue<UInt2> lo, RValue<UInt2> hi) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006129 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05006130 int shuffle[4] = {0, 1, 4, 5}; // Real type is v4i32
6131 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
6132
6133 storeValue(packed);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006134 }
6135
Nicolas Capens96d4e092016-11-18 14:22:38 -05006136 RValue<UInt4> UInt4::operator=(RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006137 {
6138 storeValue(rhs.value);
6139
6140 return rhs;
6141 }
6142
Nicolas Capens96d4e092016-11-18 14:22:38 -05006143 RValue<UInt4> UInt4::operator=(const UInt4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006144 {
6145 Value *value = rhs.loadValue();
6146 storeValue(value);
6147
6148 return RValue<UInt4>(value);
6149 }
6150
Nicolas Capens96d4e092016-11-18 14:22:38 -05006151 RValue<UInt4> UInt4::operator=(const Reference<UInt4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006152 {
6153 Value *value = rhs.loadValue();
6154 storeValue(value);
6155
6156 return RValue<UInt4>(value);
6157 }
6158
6159 RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs)
6160 {
6161 return RValue<UInt4>(Nucleus::createAdd(lhs.value, rhs.value));
6162 }
6163
6164 RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs)
6165 {
6166 return RValue<UInt4>(Nucleus::createSub(lhs.value, rhs.value));
6167 }
6168
6169 RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs)
6170 {
6171 return RValue<UInt4>(Nucleus::createMul(lhs.value, rhs.value));
6172 }
6173
6174 RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs)
6175 {
6176 return RValue<UInt4>(Nucleus::createUDiv(lhs.value, rhs.value));
6177 }
6178
6179 RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs)
6180 {
6181 return RValue<UInt4>(Nucleus::createURem(lhs.value, rhs.value));
6182 }
6183
6184 RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs)
6185 {
6186 return RValue<UInt4>(Nucleus::createAnd(lhs.value, rhs.value));
6187 }
6188
6189 RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs)
6190 {
6191 return RValue<UInt4>(Nucleus::createOr(lhs.value, rhs.value));
6192 }
6193
6194 RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs)
6195 {
6196 return RValue<UInt4>(Nucleus::createXor(lhs.value, rhs.value));
6197 }
6198
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04006199 RValue<UInt> Extract(RValue<UInt4> x, int i)
6200 {
6201 return RValue<UInt>(Nucleus::createExtractElement(x.value, UInt::getType(), i));
6202 }
6203
6204 RValue<UInt4> Insert(RValue<UInt4> x, RValue<UInt> element, int i)
6205 {
6206 return RValue<UInt4>(Nucleus::createInsertElement(x.value, element.value, i));
6207 }
6208
Nicolas Capens598f8d82016-09-26 15:09:10 -04006209 RValue<UInt4> operator<<(RValue<UInt4> lhs, unsigned char rhs)
6210 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04006211 if(emulateIntrinsics)
6212 {
6213 UInt4 result;
6214 result = Insert(result, Extract(lhs, 0) << UInt(rhs), 0);
6215 result = Insert(result, Extract(lhs, 1) << UInt(rhs), 1);
6216 result = Insert(result, Extract(lhs, 2) << UInt(rhs), 2);
6217 result = Insert(result, Extract(lhs, 3) << UInt(rhs), 3);
6218
6219 return result;
6220 }
6221 else
6222 {
6223 return RValue<UInt4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
6224 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04006225 }
6226
6227 RValue<UInt4> operator>>(RValue<UInt4> lhs, unsigned char rhs)
6228 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04006229 if(emulateIntrinsics)
6230 {
6231 UInt4 result;
6232 result = Insert(result, Extract(lhs, 0) >> UInt(rhs), 0);
6233 result = Insert(result, Extract(lhs, 1) >> UInt(rhs), 1);
6234 result = Insert(result, Extract(lhs, 2) >> UInt(rhs), 2);
6235 result = Insert(result, Extract(lhs, 3) >> UInt(rhs), 3);
6236
6237 return result;
6238 }
6239 else
6240 {
6241 return RValue<UInt4>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
6242 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04006243 }
6244
6245 RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs)
6246 {
6247 return RValue<UInt4>(Nucleus::createShl(lhs.value, rhs.value));
6248 }
6249
6250 RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs)
6251 {
6252 return RValue<UInt4>(Nucleus::createLShr(lhs.value, rhs.value));
6253 }
6254
Nicolas Capens96d4e092016-11-18 14:22:38 -05006255 RValue<UInt4> operator+=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006256 {
6257 return lhs = lhs + rhs;
6258 }
6259
Nicolas Capens96d4e092016-11-18 14:22:38 -05006260 RValue<UInt4> operator-=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006261 {
6262 return lhs = lhs - rhs;
6263 }
6264
Nicolas Capens96d4e092016-11-18 14:22:38 -05006265 RValue<UInt4> operator*=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006266 {
6267 return lhs = lhs * rhs;
6268 }
6269
Nicolas Capens96d4e092016-11-18 14:22:38 -05006270// RValue<UInt4> operator/=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006271// {
6272// return lhs = lhs / rhs;
6273// }
6274
Nicolas Capens96d4e092016-11-18 14:22:38 -05006275// RValue<UInt4> operator%=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006276// {
6277// return lhs = lhs % rhs;
6278// }
6279
Nicolas Capens96d4e092016-11-18 14:22:38 -05006280 RValue<UInt4> operator&=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006281 {
6282 return lhs = lhs & rhs;
6283 }
6284
Nicolas Capens96d4e092016-11-18 14:22:38 -05006285 RValue<UInt4> operator|=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006286 {
6287 return lhs = lhs | rhs;
6288 }
6289
Nicolas Capens96d4e092016-11-18 14:22:38 -05006290 RValue<UInt4> operator^=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006291 {
6292 return lhs = lhs ^ rhs;
6293 }
6294
Nicolas Capens96d4e092016-11-18 14:22:38 -05006295 RValue<UInt4> operator<<=(UInt4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006296 {
6297 return lhs = lhs << rhs;
6298 }
6299
Nicolas Capens96d4e092016-11-18 14:22:38 -05006300 RValue<UInt4> operator>>=(UInt4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006301 {
6302 return lhs = lhs >> rhs;
6303 }
6304
6305 RValue<UInt4> operator+(RValue<UInt4> val)
6306 {
6307 return val;
6308 }
6309
6310 RValue<UInt4> operator-(RValue<UInt4> val)
6311 {
6312 return RValue<UInt4>(Nucleus::createNeg(val.value));
6313 }
6314
6315 RValue<UInt4> operator~(RValue<UInt4> val)
6316 {
6317 return RValue<UInt4>(Nucleus::createNot(val.value));
6318 }
6319
6320 RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y)
6321 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006322 return RValue<UInt4>(Nucleus::createICmpEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006323 }
6324
6325 RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y)
6326 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006327 return RValue<UInt4>(Nucleus::createICmpULT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006328 }
6329
6330 RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y)
6331 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006332 return RValue<UInt4>(Nucleus::createICmpULE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006333 }
6334
6335 RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y)
6336 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006337 return RValue<UInt4>(Nucleus::createICmpNE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006338 }
6339
6340 RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y)
6341 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006342 return RValue<UInt4>(Nucleus::createICmpUGE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006343 }
6344
6345 RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y)
6346 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006347 return RValue<UInt4>(Nucleus::createICmpUGT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006348 }
6349
6350 RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y)
6351 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006352 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
6353 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ule, condition, x.value, y.value);
6354 ::basicBlock->appendInst(cmp);
6355
6356 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
6357 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
6358 ::basicBlock->appendInst(select);
6359
6360 return RValue<UInt4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006361 }
6362
6363 RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y)
6364 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006365 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
6366 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ugt, condition, x.value, y.value);
6367 ::basicBlock->appendInst(cmp);
6368
6369 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
6370 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
6371 ::basicBlock->appendInst(select);
6372
6373 return RValue<UInt4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006374 }
6375
Nicolas Capens598f8d82016-09-26 15:09:10 -04006376 Type *UInt4::getType()
6377 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04006378 return T(Ice::IceType_v4i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006379 }
6380
6381 Float::Float(RValue<Int> cast)
6382 {
6383 Value *integer = Nucleus::createSIToFP(cast.value, Float::getType());
6384
6385 storeValue(integer);
6386 }
6387
Alexis Hetucfd96322017-07-24 14:44:33 -04006388 Float::Float(RValue<UInt> cast)
6389 {
6390 RValue<Float> result = Float(Int(cast & UInt(0x7FFFFFFF))) +
6391 As<Float>((As<Int>(cast) >> 31) & As<Int>(Float(0x80000000u)));
6392
6393 storeValue(result.value);
6394 }
6395
Nicolas Capens598f8d82016-09-26 15:09:10 -04006396 Float::Float(float x)
6397 {
6398 storeValue(Nucleus::createConstantFloat(x));
6399 }
6400
6401 Float::Float(RValue<Float> rhs)
6402 {
6403 storeValue(rhs.value);
6404 }
6405
6406 Float::Float(const Float &rhs)
6407 {
6408 Value *value = rhs.loadValue();
6409 storeValue(value);
6410 }
6411
6412 Float::Float(const Reference<Float> &rhs)
6413 {
6414 Value *value = rhs.loadValue();
6415 storeValue(value);
6416 }
6417
Nicolas Capens96d4e092016-11-18 14:22:38 -05006418 RValue<Float> Float::operator=(RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006419 {
6420 storeValue(rhs.value);
6421
6422 return rhs;
6423 }
6424
Nicolas Capens96d4e092016-11-18 14:22:38 -05006425 RValue<Float> Float::operator=(const Float &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006426 {
6427 Value *value = rhs.loadValue();
6428 storeValue(value);
6429
6430 return RValue<Float>(value);
6431 }
6432
Nicolas Capens96d4e092016-11-18 14:22:38 -05006433 RValue<Float> Float::operator=(const Reference<Float> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006434 {
6435 Value *value = rhs.loadValue();
6436 storeValue(value);
6437
6438 return RValue<Float>(value);
6439 }
6440
6441 RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs)
6442 {
6443 return RValue<Float>(Nucleus::createFAdd(lhs.value, rhs.value));
6444 }
6445
6446 RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs)
6447 {
6448 return RValue<Float>(Nucleus::createFSub(lhs.value, rhs.value));
6449 }
6450
6451 RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs)
6452 {
6453 return RValue<Float>(Nucleus::createFMul(lhs.value, rhs.value));
6454 }
6455
6456 RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs)
6457 {
6458 return RValue<Float>(Nucleus::createFDiv(lhs.value, rhs.value));
6459 }
6460
Nicolas Capens96d4e092016-11-18 14:22:38 -05006461 RValue<Float> operator+=(Float &lhs, RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006462 {
6463 return lhs = lhs + rhs;
6464 }
6465
Nicolas Capens96d4e092016-11-18 14:22:38 -05006466 RValue<Float> operator-=(Float &lhs, RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006467 {
6468 return lhs = lhs - rhs;
6469 }
6470
Nicolas Capens96d4e092016-11-18 14:22:38 -05006471 RValue<Float> operator*=(Float &lhs, RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006472 {
6473 return lhs = lhs * rhs;
6474 }
6475
Nicolas Capens96d4e092016-11-18 14:22:38 -05006476 RValue<Float> operator/=(Float &lhs, RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006477 {
6478 return lhs = lhs / rhs;
6479 }
6480
6481 RValue<Float> operator+(RValue<Float> val)
6482 {
6483 return val;
6484 }
6485
6486 RValue<Float> operator-(RValue<Float> val)
6487 {
6488 return RValue<Float>(Nucleus::createFNeg(val.value));
6489 }
6490
6491 RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs)
6492 {
6493 return RValue<Bool>(Nucleus::createFCmpOLT(lhs.value, rhs.value));
6494 }
6495
6496 RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs)
6497 {
6498 return RValue<Bool>(Nucleus::createFCmpOLE(lhs.value, rhs.value));
6499 }
6500
6501 RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs)
6502 {
6503 return RValue<Bool>(Nucleus::createFCmpOGT(lhs.value, rhs.value));
6504 }
6505
6506 RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs)
6507 {
6508 return RValue<Bool>(Nucleus::createFCmpOGE(lhs.value, rhs.value));
6509 }
6510
6511 RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs)
6512 {
6513 return RValue<Bool>(Nucleus::createFCmpONE(lhs.value, rhs.value));
6514 }
6515
6516 RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs)
6517 {
6518 return RValue<Bool>(Nucleus::createFCmpOEQ(lhs.value, rhs.value));
6519 }
6520
6521 RValue<Float> Abs(RValue<Float> x)
6522 {
6523 return IfThenElse(x > 0.0f, x, -x);
6524 }
6525
6526 RValue<Float> Max(RValue<Float> x, RValue<Float> y)
6527 {
6528 return IfThenElse(x > y, x, y);
6529 }
6530
6531 RValue<Float> Min(RValue<Float> x, RValue<Float> y)
6532 {
6533 return IfThenElse(x < y, x, y);
6534 }
6535
6536 RValue<Float> Rcp_pp(RValue<Float> x, bool exactAtPow2)
6537 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04006538 return 1.0f / x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04006539 }
6540
6541 RValue<Float> RcpSqrt_pp(RValue<Float> x)
6542 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04006543 return Rcp_pp(Sqrt(x));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006544 }
6545
6546 RValue<Float> Sqrt(RValue<Float> x)
6547 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04006548 Ice::Variable *result = ::function->makeVariable(Ice::IceType_f32);
6549 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Sqrt, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6550 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6551 auto sqrt = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
6552 sqrt->addArg(x.value);
6553 ::basicBlock->appendInst(sqrt);
6554
6555 return RValue<Float>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006556 }
6557
6558 RValue<Float> Round(RValue<Float> x)
6559 {
Nicolas Capensa8086512016-11-07 17:32:17 -05006560 return Float4(Round(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04006561 }
6562
6563 RValue<Float> Trunc(RValue<Float> x)
6564 {
Nicolas Capensa8086512016-11-07 17:32:17 -05006565 return Float4(Trunc(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04006566 }
6567
6568 RValue<Float> Frac(RValue<Float> x)
6569 {
Nicolas Capensa8086512016-11-07 17:32:17 -05006570 return Float4(Frac(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04006571 }
6572
6573 RValue<Float> Floor(RValue<Float> x)
6574 {
Nicolas Capensa8086512016-11-07 17:32:17 -05006575 return Float4(Floor(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04006576 }
6577
6578 RValue<Float> Ceil(RValue<Float> x)
6579 {
Nicolas Capensa8086512016-11-07 17:32:17 -05006580 return Float4(Ceil(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04006581 }
6582
6583 Type *Float::getType()
6584 {
Nicolas Capens9709d4f2016-09-30 11:44:14 -04006585 return T(Ice::IceType_f32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006586 }
6587
6588 Float2::Float2(RValue<Float4> cast)
6589 {
Nicolas Capens22008782016-10-20 01:11:47 -04006590 storeValue(Nucleus::createBitCast(cast.value, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006591 }
6592
6593 Type *Float2::getType()
6594 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04006595 return T(Type_v2f32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006596 }
6597
Nicolas Capenscb986762017-01-20 11:34:37 -05006598 Float4::Float4(RValue<Byte4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006599 {
Nicolas Capensd4227962016-11-09 14:24:25 -05006600 Value *a = Int4(cast).loadValue();
6601 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
6602
6603 storeValue(xyzw);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006604 }
6605
Nicolas Capenscb986762017-01-20 11:34:37 -05006606 Float4::Float4(RValue<SByte4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006607 {
Nicolas Capensd4227962016-11-09 14:24:25 -05006608 Value *a = Int4(cast).loadValue();
6609 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
6610
6611 storeValue(xyzw);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006612 }
6613
Nicolas Capenscb986762017-01-20 11:34:37 -05006614 Float4::Float4(RValue<Short4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006615 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006616 Int4 c(cast);
6617 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
6618 }
6619
Nicolas Capenscb986762017-01-20 11:34:37 -05006620 Float4::Float4(RValue<UShort4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006621 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006622 Int4 c(cast);
6623 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
6624 }
6625
Nicolas Capenscb986762017-01-20 11:34:37 -05006626 Float4::Float4(RValue<Int4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006627 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006628 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType());
6629
6630 storeValue(xyzw);
6631 }
6632
Nicolas Capenscb986762017-01-20 11:34:37 -05006633 Float4::Float4(RValue<UInt4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006634 {
Nicolas Capens96445fe2016-12-15 14:45:13 -05006635 RValue<Float4> result = Float4(Int4(cast & UInt4(0x7FFFFFFF))) +
6636 As<Float4>((As<Int4>(cast) >> 31) & As<Int4>(Float4(0x80000000u)));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006637
Nicolas Capens96445fe2016-12-15 14:45:13 -05006638 storeValue(result.value);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006639 }
6640
Nicolas Capenscb986762017-01-20 11:34:37 -05006641 Float4::Float4() : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006642 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006643 }
6644
Nicolas Capenscb986762017-01-20 11:34:37 -05006645 Float4::Float4(float xyzw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006646 {
6647 constant(xyzw, xyzw, xyzw, xyzw);
6648 }
6649
Nicolas Capenscb986762017-01-20 11:34:37 -05006650 Float4::Float4(float x, float yzw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006651 {
6652 constant(x, yzw, yzw, yzw);
6653 }
6654
Nicolas Capenscb986762017-01-20 11:34:37 -05006655 Float4::Float4(float x, float y, float zw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006656 {
6657 constant(x, y, zw, zw);
6658 }
6659
Nicolas Capenscb986762017-01-20 11:34:37 -05006660 Float4::Float4(float x, float y, float z, float w) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006661 {
6662 constant(x, y, z, w);
6663 }
6664
6665 void Float4::constant(float x, float y, float z, float w)
6666 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04006667 double constantVector[4] = {x, y, z, w};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04006668 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006669 }
6670
Nicolas Capenscb986762017-01-20 11:34:37 -05006671 Float4::Float4(RValue<Float4> rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006672 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006673 storeValue(rhs.value);
6674 }
6675
Nicolas Capenscb986762017-01-20 11:34:37 -05006676 Float4::Float4(const Float4 &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006677 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006678 Value *value = rhs.loadValue();
6679 storeValue(value);
6680 }
6681
Nicolas Capenscb986762017-01-20 11:34:37 -05006682 Float4::Float4(const Reference<Float4> &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006683 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006684 Value *value = rhs.loadValue();
6685 storeValue(value);
6686 }
6687
Nicolas Capenscb986762017-01-20 11:34:37 -05006688 Float4::Float4(RValue<Float> rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006689 {
Nicolas Capensf8beb4b2017-01-27 02:55:44 -08006690 Value *vector = Nucleus::createBitCast(rhs.value, Float4::getType());
Nicolas Capensd4227962016-11-09 14:24:25 -05006691
6692 int swizzle[4] = {0, 0, 0, 0};
Nicolas Capensf8beb4b2017-01-27 02:55:44 -08006693 Value *replicate = Nucleus::createShuffleVector(vector, vector, swizzle);
Nicolas Capensd4227962016-11-09 14:24:25 -05006694
6695 storeValue(replicate);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006696 }
6697
Nicolas Capenscb986762017-01-20 11:34:37 -05006698 Float4::Float4(const Float &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006699 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006700 *this = RValue<Float>(rhs.loadValue());
6701 }
6702
Nicolas Capenscb986762017-01-20 11:34:37 -05006703 Float4::Float4(const Reference<Float> &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006704 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006705 *this = RValue<Float>(rhs.loadValue());
6706 }
6707
Nicolas Capens96d4e092016-11-18 14:22:38 -05006708 RValue<Float4> Float4::operator=(float x)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006709 {
6710 return *this = Float4(x, x, x, x);
6711 }
6712
Nicolas Capens96d4e092016-11-18 14:22:38 -05006713 RValue<Float4> Float4::operator=(RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006714 {
6715 storeValue(rhs.value);
6716
6717 return rhs;
6718 }
6719
Nicolas Capens96d4e092016-11-18 14:22:38 -05006720 RValue<Float4> Float4::operator=(const Float4 &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006721 {
6722 Value *value = rhs.loadValue();
6723 storeValue(value);
6724
6725 return RValue<Float4>(value);
6726 }
6727
Nicolas Capens96d4e092016-11-18 14:22:38 -05006728 RValue<Float4> Float4::operator=(const Reference<Float4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006729 {
6730 Value *value = rhs.loadValue();
6731 storeValue(value);
6732
6733 return RValue<Float4>(value);
6734 }
6735
Nicolas Capens96d4e092016-11-18 14:22:38 -05006736 RValue<Float4> Float4::operator=(RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006737 {
6738 return *this = Float4(rhs);
6739 }
6740
Nicolas Capens96d4e092016-11-18 14:22:38 -05006741 RValue<Float4> Float4::operator=(const Float &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006742 {
6743 return *this = Float4(rhs);
6744 }
6745
Nicolas Capens96d4e092016-11-18 14:22:38 -05006746 RValue<Float4> Float4::operator=(const Reference<Float> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006747 {
6748 return *this = Float4(rhs);
6749 }
6750
6751 RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs)
6752 {
6753 return RValue<Float4>(Nucleus::createFAdd(lhs.value, rhs.value));
6754 }
6755
6756 RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs)
6757 {
6758 return RValue<Float4>(Nucleus::createFSub(lhs.value, rhs.value));
6759 }
6760
6761 RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs)
6762 {
6763 return RValue<Float4>(Nucleus::createFMul(lhs.value, rhs.value));
6764 }
6765
6766 RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs)
6767 {
6768 return RValue<Float4>(Nucleus::createFDiv(lhs.value, rhs.value));
6769 }
6770
6771 RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs)
6772 {
6773 return RValue<Float4>(Nucleus::createFRem(lhs.value, rhs.value));
6774 }
6775
Nicolas Capens96d4e092016-11-18 14:22:38 -05006776 RValue<Float4> operator+=(Float4 &lhs, RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006777 {
6778 return lhs = lhs + rhs;
6779 }
6780
Nicolas Capens96d4e092016-11-18 14:22:38 -05006781 RValue<Float4> operator-=(Float4 &lhs, RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006782 {
6783 return lhs = lhs - rhs;
6784 }
6785
Nicolas Capens96d4e092016-11-18 14:22:38 -05006786 RValue<Float4> operator*=(Float4 &lhs, RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006787 {
6788 return lhs = lhs * rhs;
6789 }
6790
Nicolas Capens96d4e092016-11-18 14:22:38 -05006791 RValue<Float4> operator/=(Float4 &lhs, RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006792 {
6793 return lhs = lhs / rhs;
6794 }
6795
Nicolas Capens96d4e092016-11-18 14:22:38 -05006796 RValue<Float4> operator%=(Float4 &lhs, RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006797 {
6798 return lhs = lhs % rhs;
6799 }
6800
6801 RValue<Float4> operator+(RValue<Float4> val)
6802 {
6803 return val;
6804 }
6805
6806 RValue<Float4> operator-(RValue<Float4> val)
6807 {
6808 return RValue<Float4>(Nucleus::createFNeg(val.value));
6809 }
6810
6811 RValue<Float4> Abs(RValue<Float4> x)
6812 {
Nicolas Capens84272242016-11-09 13:31:06 -05006813 Value *vector = Nucleus::createBitCast(x.value, Int4::getType());
6814 int64_t constantVector[4] = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF};
6815 Value *result = Nucleus::createAnd(vector, V(Nucleus::createConstantVector(constantVector, Int4::getType())));
6816
6817 return As<Float4>(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006818 }
6819
6820 RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y)
6821 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006822 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
Nicolas Capens5cdb91a2017-02-13 12:39:18 -05006823 auto cmp = Ice::InstFcmp::create(::function, Ice::InstFcmp::Ogt, condition, x.value, y.value);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006824 ::basicBlock->appendInst(cmp);
6825
6826 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
Nicolas Capens5cdb91a2017-02-13 12:39:18 -05006827 auto select = Ice::InstSelect::create(::function, result, condition, x.value, y.value);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006828 ::basicBlock->appendInst(select);
6829
6830 return RValue<Float4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006831 }
6832
6833 RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y)
6834 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006835 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
Nicolas Capens5cdb91a2017-02-13 12:39:18 -05006836 auto cmp = Ice::InstFcmp::create(::function, Ice::InstFcmp::Olt, condition, x.value, y.value);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006837 ::basicBlock->appendInst(cmp);
6838
6839 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
Nicolas Capens5cdb91a2017-02-13 12:39:18 -05006840 auto select = Ice::InstSelect::create(::function, result, condition, x.value, y.value);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006841 ::basicBlock->appendInst(select);
6842
6843 return RValue<Float4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006844 }
6845
6846 RValue<Float4> Rcp_pp(RValue<Float4> x, bool exactAtPow2)
6847 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04006848 return Float4(1.0f) / x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04006849 }
6850
6851 RValue<Float4> RcpSqrt_pp(RValue<Float4> x)
6852 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04006853 return Rcp_pp(Sqrt(x));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006854 }
6855
6856 RValue<Float4> Sqrt(RValue<Float4> x)
6857 {
Nicolas Capens091f3502017-10-03 14:56:49 -04006858 if(emulateIntrinsics || CPUID::ARM)
Nicolas Capens9f737d32017-07-25 17:26:14 -04006859 {
6860 Float4 result;
6861 result.x = Sqrt(Float(Float4(x).x));
6862 result.y = Sqrt(Float(Float4(x).y));
6863 result.z = Sqrt(Float(Float4(x).z));
6864 result.w = Sqrt(Float(Float4(x).w));
Nicolas Capensd52e9362016-10-31 23:23:15 -04006865
Nicolas Capens9f737d32017-07-25 17:26:14 -04006866 return result;
6867 }
6868 else
6869 {
6870 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6871 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Sqrt, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6872 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6873 auto sqrt = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
6874 sqrt->addArg(x.value);
6875 ::basicBlock->appendInst(sqrt);
6876
6877 return RValue<Float4>(V(result));
6878 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04006879 }
6880
Nicolas Capensc94ab742016-11-08 15:15:31 -05006881 RValue<Float4> Insert(RValue<Float4> x, RValue<Float> element, int i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006882 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05006883 return RValue<Float4>(Nucleus::createInsertElement(x.value, element.value, i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006884 }
6885
6886 RValue<Float> Extract(RValue<Float4> x, int i)
6887 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006888 return RValue<Float>(Nucleus::createExtractElement(x.value, Float::getType(), i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006889 }
6890
6891 RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select)
6892 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006893 return RValue<Float4>(createSwizzle4(x.value, select));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006894 }
6895
6896 RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
6897 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04006898 int shuffle[4] =
6899 {
6900 ((imm >> 0) & 0x03) + 0,
6901 ((imm >> 2) & 0x03) + 0,
6902 ((imm >> 4) & 0x03) + 4,
6903 ((imm >> 6) & 0x03) + 4,
6904 };
6905
6906 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006907 }
6908
6909 RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y)
6910 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04006911 int shuffle[4] = {0, 4, 1, 5};
6912 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006913 }
6914
6915 RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y)
6916 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04006917 int shuffle[4] = {2, 6, 3, 7};
6918 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006919 }
6920
6921 RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select)
6922 {
6923 Value *vector = lhs.loadValue();
Nicolas Capensa4c30b02016-11-08 15:43:17 -05006924 Value *result = createMask4(vector, rhs.value, select);
6925 lhs.storeValue(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006926
Nicolas Capensa4c30b02016-11-08 15:43:17 -05006927 return RValue<Float4>(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006928 }
6929
6930 RValue<Int> SignMask(RValue<Float4> x)
6931 {
Nicolas Capens091f3502017-10-03 14:56:49 -04006932 if(emulateIntrinsics || CPUID::ARM)
Nicolas Capensd6cacad2017-07-25 15:32:12 -04006933 {
6934 Int4 xx = (As<Int4>(x) >> 31) & Int4(0x00000001, 0x00000002, 0x00000004, 0x00000008);
6935 return Extract(xx, 0) | Extract(xx, 1) | Extract(xx, 2) | Extract(xx, 3);
6936 }
6937 else
6938 {
6939 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
6940 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6941 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6942 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
6943 movmsk->addArg(x.value);
6944 ::basicBlock->appendInst(movmsk);
Nicolas Capensf2cb9df2016-10-21 17:26:13 -04006945
Nicolas Capensd6cacad2017-07-25 15:32:12 -04006946 return RValue<Int>(V(result));
6947 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04006948 }
6949
6950 RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y)
6951 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006952 return RValue<Int4>(Nucleus::createFCmpOEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006953 }
6954
6955 RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y)
6956 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006957 return RValue<Int4>(Nucleus::createFCmpOLT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006958 }
6959
6960 RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y)
6961 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006962 return RValue<Int4>(Nucleus::createFCmpOLE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006963 }
6964
6965 RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y)
6966 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006967 return RValue<Int4>(Nucleus::createFCmpONE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006968 }
6969
6970 RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y)
6971 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006972 return RValue<Int4>(Nucleus::createFCmpOGE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006973 }
6974
6975 RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y)
6976 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006977 return RValue<Int4>(Nucleus::createFCmpOGT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006978 }
6979
Alexis Hetu8ef6d102017-11-09 15:49:09 -05006980 RValue<Int4> IsInf(RValue<Float4> x)
6981 {
6982 return CmpEQ(As<Int4>(x) & Int4(0x7FFFFFFF), Int4(0x7F800000));
6983 }
6984
6985 RValue<Int4> IsNan(RValue<Float4> x)
6986 {
6987 return ~CmpEQ(x, x);
6988 }
6989
Nicolas Capens598f8d82016-09-26 15:09:10 -04006990 RValue<Float4> Round(RValue<Float4> x)
6991 {
Nicolas Capens091f3502017-10-03 14:56:49 -04006992 if(emulateIntrinsics || CPUID::ARM)
Nicolas Capensf7b75882017-04-26 09:30:47 -04006993 {
6994 // Push the fractional part off the mantissa. Accurate up to +/-2^22.
6995 return (x + Float4(0x00C00000)) - Float4(0x00C00000);
6996 }
6997 else if(CPUID::SSE4_1)
Nicolas Capens9ca48d52017-01-14 12:52:55 -05006998 {
6999 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
7000 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
7001 auto target = ::context->getConstantUndef(Ice::IceType_i32);
7002 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
7003 round->addArg(x.value);
7004 round->addArg(::context->getConstantInt32(0));
7005 ::basicBlock->appendInst(round);
Nicolas Capensa8086512016-11-07 17:32:17 -05007006
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007007 return RValue<Float4>(V(result));
7008 }
7009 else
7010 {
7011 return Float4(RoundInt(x));
7012 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04007013 }
7014
7015 RValue<Float4> Trunc(RValue<Float4> x)
7016 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007017 if(CPUID::SSE4_1)
7018 {
7019 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
7020 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
7021 auto target = ::context->getConstantUndef(Ice::IceType_i32);
7022 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
7023 round->addArg(x.value);
7024 round->addArg(::context->getConstantInt32(3));
7025 ::basicBlock->appendInst(round);
Nicolas Capensa8086512016-11-07 17:32:17 -05007026
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007027 return RValue<Float4>(V(result));
7028 }
7029 else
7030 {
7031 return Float4(Int4(x));
7032 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04007033 }
7034
7035 RValue<Float4> Frac(RValue<Float4> x)
7036 {
Nicolas Capensb9230422017-07-17 10:27:33 -04007037 Float4 frc;
7038
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007039 if(CPUID::SSE4_1)
7040 {
Nicolas Capensb9230422017-07-17 10:27:33 -04007041 frc = x - Floor(x);
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007042 }
7043 else
7044 {
Nicolas Capensb9230422017-07-17 10:27:33 -04007045 frc = x - Float4(Int4(x)); // Signed fractional part.
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007046
Nicolas Capensb9230422017-07-17 10:27:33 -04007047 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 -05007048 }
Nicolas Capensb9230422017-07-17 10:27:33 -04007049
7050 // x - floor(x) can be 1.0 for very small negative x.
7051 // Clamp against the value just below 1.0.
7052 return Min(frc, As<Float4>(Int4(0x3F7FFFFF)));
Nicolas Capens598f8d82016-09-26 15:09:10 -04007053 }
7054
7055 RValue<Float4> Floor(RValue<Float4> x)
7056 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007057 if(CPUID::SSE4_1)
7058 {
7059 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
7060 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
7061 auto target = ::context->getConstantUndef(Ice::IceType_i32);
7062 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
7063 round->addArg(x.value);
7064 round->addArg(::context->getConstantInt32(1));
7065 ::basicBlock->appendInst(round);
Nicolas Capensa8086512016-11-07 17:32:17 -05007066
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007067 return RValue<Float4>(V(result));
7068 }
7069 else
7070 {
7071 return x - Frac(x);
7072 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04007073 }
7074
7075 RValue<Float4> Ceil(RValue<Float4> x)
7076 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007077 if(CPUID::SSE4_1)
7078 {
7079 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
7080 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
7081 auto target = ::context->getConstantUndef(Ice::IceType_i32);
7082 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
7083 round->addArg(x.value);
7084 round->addArg(::context->getConstantInt32(2));
7085 ::basicBlock->appendInst(round);
Nicolas Capensa8086512016-11-07 17:32:17 -05007086
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007087 return RValue<Float4>(V(result));
7088 }
7089 else
7090 {
7091 return -Floor(-x);
7092 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04007093 }
7094
7095 Type *Float4::getType()
7096 {
Nicolas Capens9709d4f2016-09-30 11:44:14 -04007097 return T(Ice::IceType_v4f32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04007098 }
7099
7100 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset)
7101 {
Nicolas Capens8820f642016-09-30 04:42:43 -04007102 return lhs + RValue<Int>(Nucleus::createConstantInt(offset));
Nicolas Capens598f8d82016-09-26 15:09:10 -04007103 }
7104
7105 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
7106 {
Nicolas Capensd294def2017-01-26 17:44:37 -08007107 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value, false));
Nicolas Capens598f8d82016-09-26 15:09:10 -04007108 }
7109
7110 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
7111 {
Nicolas Capensd294def2017-01-26 17:44:37 -08007112 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value, true));
Nicolas Capens598f8d82016-09-26 15:09:10 -04007113 }
7114
Nicolas Capens96d4e092016-11-18 14:22:38 -05007115 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, int offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04007116 {
7117 return lhs = lhs + offset;
7118 }
7119
Nicolas Capens96d4e092016-11-18 14:22:38 -05007120 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<Int> offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04007121 {
7122 return lhs = lhs + offset;
7123 }
7124
Nicolas Capens96d4e092016-11-18 14:22:38 -05007125 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<UInt> offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04007126 {
7127 return lhs = lhs + offset;
7128 }
7129
7130 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset)
7131 {
7132 return lhs + -offset;
7133 }
7134
7135 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
7136 {
7137 return lhs + -offset;
7138 }
7139
7140 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
7141 {
7142 return lhs + -offset;
7143 }
7144
Nicolas Capens96d4e092016-11-18 14:22:38 -05007145 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, int offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04007146 {
7147 return lhs = lhs - offset;
7148 }
7149
Nicolas Capens96d4e092016-11-18 14:22:38 -05007150 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<Int> offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04007151 {
7152 return lhs = lhs - offset;
7153 }
7154
Nicolas Capens96d4e092016-11-18 14:22:38 -05007155 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<UInt> offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04007156 {
7157 return lhs = lhs - offset;
7158 }
7159
7160 void Return()
7161 {
7162 Nucleus::createRetVoid();
7163 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
7164 Nucleus::createUnreachable();
7165 }
7166
Nicolas Capenseb253d02016-11-18 14:40:40 -05007167 void Return(RValue<Int> ret)
Nicolas Capens598f8d82016-09-26 15:09:10 -04007168 {
Nicolas Capenseb253d02016-11-18 14:40:40 -05007169 Nucleus::createRet(ret.value);
Nicolas Capensfdcca2d2016-10-20 11:31:36 -04007170 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
7171 Nucleus::createUnreachable();
Nicolas Capens598f8d82016-09-26 15:09:10 -04007172 }
7173
Nicolas Capensf4eec2f2017-05-24 15:46:48 -04007174 void branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB)
Nicolas Capens598f8d82016-09-26 15:09:10 -04007175 {
7176 Nucleus::createCondBr(cmp.value, bodyBB, endBB);
7177 Nucleus::setInsertBlock(bodyBB);
Nicolas Capens598f8d82016-09-26 15:09:10 -04007178 }
7179
Nicolas Capens598f8d82016-09-26 15:09:10 -04007180 RValue<Long> Ticks()
7181 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04007182 assert(false && "UNIMPLEMENTED"); return RValue<Long>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04007183 }
7184}