blob: 76f5a729d2c92251ea6ff0bbd3d736236d908b2c [file] [log] [blame]
Nicolas Capens598f8d82016-09-26 15:09:10 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Nicolas Capens598f8d82016-09-26 15:09:10 -040015#include "Reactor.hpp"
Nicolas Capens598f8d82016-09-26 15:09:10 -040016
Nicolas Capens2ae9d742016-11-24 14:43:05 -050017#include "Optimizer.hpp"
Nicolas Capens1a3ce872018-10-10 10:42:36 -040018#include "ExecutableMemory.hpp"
Nicolas Capensa062f322018-09-06 15:34:46 -040019
Nicolas Capens598f8d82016-09-26 15:09:10 -040020#include "src/IceTypes.h"
21#include "src/IceCfg.h"
22#include "src/IceELFStreamer.h"
23#include "src/IceGlobalContext.h"
24#include "src/IceCfgNode.h"
25#include "src/IceELFObjectWriter.h"
Nicolas Capens8dfd9a72016-10-13 17:44:51 -040026#include "src/IceGlobalInits.h"
Nicolas Capens598f8d82016-09-26 15:09:10 -040027
28#include "llvm/Support/FileSystem.h"
29#include "llvm/Support/raw_os_ostream.h"
Nicolas Capens6a990f82018-07-06 15:54:07 -040030#include "llvm/Support/Compiler.h"
31
32#if __has_feature(memory_sanitizer)
33#include <sanitizer/msan_interface.h>
34#endif
Nicolas Capens598f8d82016-09-26 15:09:10 -040035
Nicolas Capensbd65da92017-01-05 16:31:06 -050036#if defined(_WIN32)
Alexis Hetu113e33a2017-01-19 10:49:19 -050037#ifndef WIN32_LEAN_AND_MEAN
Nicolas Capens598f8d82016-09-26 15:09:10 -040038#define WIN32_LEAN_AND_MEAN
Alexis Hetu113e33a2017-01-19 10:49:19 -050039#endif // !WIN32_LEAN_AND_MEAN
40#ifndef NOMINMAX
Nicolas Capens598f8d82016-09-26 15:09:10 -040041#define NOMINMAX
Alexis Hetu113e33a2017-01-19 10:49:19 -050042#endif // !NOMINMAX
Nicolas Capens598f8d82016-09-26 15:09:10 -040043#include <Windows.h>
Nicolas Capensbd65da92017-01-05 16:31:06 -050044#else
45#include <sys/mman.h>
Nicolas Capens411273e2017-01-26 15:13:36 -080046#if !defined(MAP_ANONYMOUS)
47#define MAP_ANONYMOUS MAP_ANON
Nicolas Capens8b275742017-01-20 17:11:41 -050048#endif
Nicolas Capensbd65da92017-01-05 16:31:06 -050049#endif
Nicolas Capens598f8d82016-09-26 15:09:10 -040050
Nicolas Capensc07dc4b2018-08-06 14:20:45 -040051#include <mutex>
Nicolas Capens598f8d82016-09-26 15:09:10 -040052#include <limits>
53#include <iostream>
54#include <cassert>
55
56namespace
57{
58 Ice::GlobalContext *context = nullptr;
59 Ice::Cfg *function = nullptr;
60 Ice::CfgNode *basicBlock = nullptr;
61 Ice::CfgLocalAllocatorScope *allocator = nullptr;
Nicolas Capens48461502018-08-06 14:20:45 -040062 rr::Routine *routine = nullptr;
Nicolas Capens598f8d82016-09-26 15:09:10 -040063
64 std::mutex codegenMutex;
65
66 Ice::ELFFileStreamer *elfFile = nullptr;
67 Ice::Fdstream *out = nullptr;
68}
69
Nicolas Capensccd5ecb2017-01-14 12:52:55 -050070namespace
71{
Nicolas Capens47dc8672017-04-25 12:54:39 -040072 #if !defined(__i386__) && defined(_M_IX86)
73 #define __i386__ 1
74 #endif
75
76 #if !defined(__x86_64__) && (defined(_M_AMD64) || defined (_M_X64))
77 #define __x86_64__ 1
78 #endif
79
Nicolas Capensccd5ecb2017-01-14 12:52:55 -050080 class CPUID
81 {
82 public:
Nicolas Capensf7b75882017-04-26 09:30:47 -040083 const static bool ARM;
Nicolas Capensccd5ecb2017-01-14 12:52:55 -050084 const static bool SSE4_1;
85
86 private:
87 static void cpuid(int registers[4], int info)
88 {
Nicolas Capens47dc8672017-04-25 12:54:39 -040089 #if defined(__i386__) || defined(__x86_64__)
90 #if defined(_WIN32)
91 __cpuid(registers, info);
92 #else
93 __asm volatile("cpuid": "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]): "a" (info));
94 #endif
Nicolas Capensccd5ecb2017-01-14 12:52:55 -050095 #else
Nicolas Capens47dc8672017-04-25 12:54:39 -040096 registers[0] = 0;
97 registers[1] = 0;
98 registers[2] = 0;
99 registers[3] = 0;
Nicolas Capensccd5ecb2017-01-14 12:52:55 -0500100 #endif
101 }
102
Nicolas Capensf7b75882017-04-26 09:30:47 -0400103 static bool detectARM()
104 {
Stephen Lanhamfe796492018-09-07 11:59:54 -0700105 #if defined(__arm__) || defined(__aarch64__)
Nicolas Capensf7b75882017-04-26 09:30:47 -0400106 return true;
107 #elif defined(__i386__) || defined(__x86_64__)
108 return false;
Gordana Cmiljanovic082dfec2018-10-19 11:36:15 +0200109 #elif defined(__mips__)
110 return false;
Nicolas Capensf7b75882017-04-26 09:30:47 -0400111 #else
112 #error "Unknown architecture"
113 #endif
114 }
115
Nicolas Capensccd5ecb2017-01-14 12:52:55 -0500116 static bool detectSSE4_1()
117 {
Nicolas Capens47dc8672017-04-25 12:54:39 -0400118 #if defined(__i386__) || defined(__x86_64__)
119 int registers[4];
120 cpuid(registers, 1);
121 return (registers[2] & 0x00080000) != 0;
122 #else
123 return false;
124 #endif
Nicolas Capensccd5ecb2017-01-14 12:52:55 -0500125 }
126 };
127
Nicolas Capensf7b75882017-04-26 09:30:47 -0400128 const bool CPUID::ARM = CPUID::detectARM();
Nicolas Capensccd5ecb2017-01-14 12:52:55 -0500129 const bool CPUID::SSE4_1 = CPUID::detectSSE4_1();
Nicolas Capens091f3502017-10-03 14:56:49 -0400130 const bool emulateIntrinsics = false;
Nicolas Capens2d8c3702017-07-25 13:56:46 -0400131 const bool emulateMismatchedBitCast = CPUID::ARM;
Nicolas Capensccd5ecb2017-01-14 12:52:55 -0500132}
133
Nicolas Capens48461502018-08-06 14:20:45 -0400134namespace rr
Nicolas Capens598f8d82016-09-26 15:09:10 -0400135{
Nicolas Capens23d99a42016-09-30 14:57:16 -0400136 enum EmulatedType
137 {
138 EmulatedShift = 16,
139 EmulatedV2 = 2 << EmulatedShift,
140 EmulatedV4 = 4 << EmulatedShift,
141 EmulatedV8 = 8 << EmulatedShift,
142 EmulatedBits = EmulatedV2 | EmulatedV4 | EmulatedV8,
143
144 Type_v2i32 = Ice::IceType_v4i32 | EmulatedV2,
145 Type_v4i16 = Ice::IceType_v8i16 | EmulatedV4,
146 Type_v2i16 = Ice::IceType_v8i16 | EmulatedV2,
147 Type_v8i8 = Ice::IceType_v16i8 | EmulatedV8,
148 Type_v4i8 = Ice::IceType_v16i8 | EmulatedV4,
Nicolas Capens4cfd4572016-10-20 01:00:19 -0400149 Type_v2f32 = Ice::IceType_v4f32 | EmulatedV2,
Nicolas Capens23d99a42016-09-30 14:57:16 -0400150 };
151
Nicolas Capens15060bb2016-12-05 22:17:19 -0500152 class Value : public Ice::Operand {};
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500153 class SwitchCases : public Ice::InstSwitch {};
Nicolas Capens598f8d82016-09-26 15:09:10 -0400154 class BasicBlock : public Ice::CfgNode {};
155
156 Ice::Type T(Type *t)
157 {
Alexis Hetu113e33a2017-01-19 10:49:19 -0500158 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 -0400159 return (Ice::Type)(reinterpret_cast<std::intptr_t>(t) & ~EmulatedBits);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400160 }
161
162 Type *T(Ice::Type t)
163 {
164 return reinterpret_cast<Type*>(t);
165 }
166
Nicolas Capens23d99a42016-09-30 14:57:16 -0400167 Type *T(EmulatedType t)
168 {
169 return reinterpret_cast<Type*>(t);
170 }
171
Nicolas Capens15060bb2016-12-05 22:17:19 -0500172 Value *V(Ice::Operand *v)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400173 {
174 return reinterpret_cast<Value*>(v);
175 }
176
Nicolas Capens611642a2016-09-28 16:45:04 -0400177 BasicBlock *B(Ice::CfgNode *b)
178 {
179 return reinterpret_cast<BasicBlock*>(b);
180 }
181
Nicolas Capens584088c2017-01-26 16:05:18 -0800182 static size_t typeSize(Type *type)
183 {
184 if(reinterpret_cast<std::intptr_t>(type) & EmulatedBits)
185 {
186 switch(reinterpret_cast<std::intptr_t>(type))
187 {
188 case Type_v2i32: return 8;
189 case Type_v4i16: return 8;
190 case Type_v2i16: return 4;
191 case Type_v8i8: return 8;
192 case Type_v4i8: return 4;
193 case Type_v2f32: return 8;
194 default: assert(false);
195 }
196 }
197
198 return Ice::typeWidthInBytes(T(type));
199 }
200
Nicolas Capens598f8d82016-09-26 15:09:10 -0400201 Optimization optimization[10] = {InstructionCombining, Disabled};
202
Nicolas Capens66478362016-10-13 15:36:36 -0400203 using ElfHeader = std::conditional<sizeof(void*) == 8, Elf64_Ehdr, Elf32_Ehdr>::type;
204 using SectionHeader = std::conditional<sizeof(void*) == 8, Elf64_Shdr, Elf32_Shdr>::type;
205
206 inline const SectionHeader *sectionHeader(const ElfHeader *elfHeader)
207 {
208 return reinterpret_cast<const SectionHeader*>((intptr_t)elfHeader + elfHeader->e_shoff);
209 }
Nicolas Capens87852e12016-11-24 14:45:06 -0500210
Nicolas Capens66478362016-10-13 15:36:36 -0400211 inline const SectionHeader *elfSection(const ElfHeader *elfHeader, int index)
212 {
213 return &sectionHeader(elfHeader)[index];
214 }
215
216 static void *relocateSymbol(const ElfHeader *elfHeader, const Elf32_Rel &relocation, const SectionHeader &relocationTable)
217 {
218 const SectionHeader *target = elfSection(elfHeader, relocationTable.sh_info);
Nicolas Capens87852e12016-11-24 14:45:06 -0500219
Nicolas Capens66478362016-10-13 15:36:36 -0400220 intptr_t address = (intptr_t)elfHeader + target->sh_offset;
221 int32_t *patchSite = (int*)(address + relocation.r_offset);
222 uint32_t index = relocation.getSymbol();
223 int table = relocationTable.sh_link;
224 void *symbolValue = nullptr;
Nicolas Capens87852e12016-11-24 14:45:06 -0500225
Nicolas Capens66478362016-10-13 15:36:36 -0400226 if(index != SHN_UNDEF)
227 {
228 if(table == SHN_UNDEF) return nullptr;
229 const SectionHeader *symbolTable = elfSection(elfHeader, table);
Nicolas Capens87852e12016-11-24 14:45:06 -0500230
Nicolas Capens66478362016-10-13 15:36:36 -0400231 uint32_t symtab_entries = symbolTable->sh_size / symbolTable->sh_entsize;
232 if(index >= symtab_entries)
233 {
234 assert(index < symtab_entries && "Symbol Index out of range");
235 return nullptr;
236 }
Nicolas Capens87852e12016-11-24 14:45:06 -0500237
Nicolas Capens66478362016-10-13 15:36:36 -0400238 intptr_t symbolAddress = (intptr_t)elfHeader + symbolTable->sh_offset;
239 Elf32_Sym &symbol = ((Elf32_Sym*)symbolAddress)[index];
240 uint16_t section = symbol.st_shndx;
241
242 if(section != SHN_UNDEF && section < SHN_LORESERVE)
243 {
244 const SectionHeader *target = elfSection(elfHeader, symbol.st_shndx);
245 symbolValue = reinterpret_cast<void*>((intptr_t)elfHeader + symbol.st_value + target->sh_offset);
246 }
247 else
248 {
249 return nullptr;
250 }
251 }
252
Nicolas Capensf110e4d2017-05-03 15:33:49 -0400253 if(CPUID::ARM)
254 {
255 switch(relocation.getType())
256 {
257 case R_ARM_NONE:
258 // No relocation
259 break;
260 case R_ARM_MOVW_ABS_NC:
261 {
262 uint32_t thumb = 0; // Calls to Thumb code not supported.
263 uint32_t lo = (uint32_t)(intptr_t)symbolValue | thumb;
264 *patchSite = (*patchSite & 0xFFF0F000) | ((lo & 0xF000) << 4) | (lo & 0x0FFF);
265 }
266 break;
267 case R_ARM_MOVT_ABS:
268 {
269 uint32_t hi = (uint32_t)(intptr_t)(symbolValue) >> 16;
270 *patchSite = (*patchSite & 0xFFF0F000) | ((hi & 0xF000) << 4) | (hi & 0x0FFF);
271 }
272 break;
273 default:
274 assert(false && "Unsupported relocation type");
275 return nullptr;
276 }
277 }
278 else
279 {
Nicolas Capens30cd7d42017-04-25 15:17:25 -0400280 switch(relocation.getType())
281 {
282 case R_386_NONE:
283 // No relocation
284 break;
285 case R_386_32:
286 *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite);
287 break;
288 // case R_386_PC32:
289 // *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite - (intptr_t)patchSite);
290 // break;
291 default:
292 assert(false && "Unsupported relocation type");
293 return nullptr;
294 }
Nicolas Capensf110e4d2017-05-03 15:33:49 -0400295 }
296
Nicolas Capens66478362016-10-13 15:36:36 -0400297 return symbolValue;
298 }
299
300 static void *relocateSymbol(const ElfHeader *elfHeader, const Elf64_Rela &relocation, const SectionHeader &relocationTable)
301 {
302 const SectionHeader *target = elfSection(elfHeader, relocationTable.sh_info);
Nicolas Capens87852e12016-11-24 14:45:06 -0500303
Nicolas Capens66478362016-10-13 15:36:36 -0400304 intptr_t address = (intptr_t)elfHeader + target->sh_offset;
305 int32_t *patchSite = (int*)(address + relocation.r_offset);
306 uint32_t index = relocation.getSymbol();
307 int table = relocationTable.sh_link;
308 void *symbolValue = nullptr;
309
310 if(index != SHN_UNDEF)
311 {
312 if(table == SHN_UNDEF) return nullptr;
313 const SectionHeader *symbolTable = elfSection(elfHeader, table);
Nicolas Capens87852e12016-11-24 14:45:06 -0500314
Nicolas Capens66478362016-10-13 15:36:36 -0400315 uint32_t symtab_entries = symbolTable->sh_size / symbolTable->sh_entsize;
316 if(index >= symtab_entries)
317 {
318 assert(index < symtab_entries && "Symbol Index out of range");
319 return nullptr;
320 }
Nicolas Capens87852e12016-11-24 14:45:06 -0500321
Nicolas Capens66478362016-10-13 15:36:36 -0400322 intptr_t symbolAddress = (intptr_t)elfHeader + symbolTable->sh_offset;
323 Elf64_Sym &symbol = ((Elf64_Sym*)symbolAddress)[index];
324 uint16_t section = symbol.st_shndx;
325
326 if(section != SHN_UNDEF && section < SHN_LORESERVE)
327 {
328 const SectionHeader *target = elfSection(elfHeader, symbol.st_shndx);
329 symbolValue = reinterpret_cast<void*>((intptr_t)elfHeader + symbol.st_value + target->sh_offset);
330 }
331 else
332 {
333 return nullptr;
334 }
335 }
336
Nicolas Capensf110e4d2017-05-03 15:33:49 -0400337 switch(relocation.getType())
338 {
339 case R_X86_64_NONE:
340 // No relocation
341 break;
342 case R_X86_64_64:
343 *(int64_t*)patchSite = (int64_t)((intptr_t)symbolValue + *(int64_t*)patchSite) + relocation.r_addend;
344 break;
345 case R_X86_64_PC32:
346 *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite - (intptr_t)patchSite) + relocation.r_addend;
347 break;
348 case R_X86_64_32S:
349 *patchSite = (int32_t)((intptr_t)symbolValue + *patchSite) + relocation.r_addend;
350 break;
351 default:
352 assert(false && "Unsupported relocation type");
353 return nullptr;
354 }
Nicolas Capens66478362016-10-13 15:36:36 -0400355
356 return symbolValue;
357 }
358
Nicolas Capens1cc44382017-04-25 10:52:16 -0400359 void *loadImage(uint8_t *const elfImage, size_t &codeSize)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400360 {
Nicolas Capens598f8d82016-09-26 15:09:10 -0400361 ElfHeader *elfHeader = (ElfHeader*)elfImage;
362
363 if(!elfHeader->checkMagic())
364 {
365 return nullptr;
366 }
367
Nicolas Capens66478362016-10-13 15:36:36 -0400368 // Expect ELF bitness to match platform
Nicolas Capens65047112016-11-07 13:01:07 -0500369 assert(sizeof(void*) == 8 ? elfHeader->getFileClass() == ELFCLASS64 : elfHeader->getFileClass() == ELFCLASS32);
Nicolas Capens30cd7d42017-04-25 15:17:25 -0400370 #if defined(__i386__)
371 assert(sizeof(void*) == 4 && elfHeader->e_machine == EM_386);
372 #elif defined(__x86_64__)
373 assert(sizeof(void*) == 8 && elfHeader->e_machine == EM_X86_64);
374 #elif defined(__arm__)
375 assert(sizeof(void*) == 4 && elfHeader->e_machine == EM_ARM);
Stephen Lanhamfe796492018-09-07 11:59:54 -0700376 #elif defined(__aarch64__)
377 assert(sizeof(void*) == 8 && elfHeader->e_machine == EM_AARCH64);
Gordana Cmiljanovic082dfec2018-10-19 11:36:15 +0200378 #elif defined(__mips__)
379 assert(sizeof(void*) == 4 && elfHeader->e_machine == EM_MIPS);
Nicolas Capens30cd7d42017-04-25 15:17:25 -0400380 #else
381 #error "Unsupported platform"
382 #endif
Nicolas Capens66478362016-10-13 15:36:36 -0400383
Nicolas Capens598f8d82016-09-26 15:09:10 -0400384 SectionHeader *sectionHeader = (SectionHeader*)(elfImage + elfHeader->e_shoff);
385 void *entry = nullptr;
386
387 for(int i = 0; i < elfHeader->e_shnum; i++)
388 {
Nicolas Capens66478362016-10-13 15:36:36 -0400389 if(sectionHeader[i].sh_type == SHT_PROGBITS)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400390 {
Nicolas Capens66478362016-10-13 15:36:36 -0400391 if(sectionHeader[i].sh_flags & SHF_EXECINSTR)
392 {
393 entry = elfImage + sectionHeader[i].sh_offset;
Nicolas Capens1cc44382017-04-25 10:52:16 -0400394 codeSize = sectionHeader[i].sh_size;
Nicolas Capens66478362016-10-13 15:36:36 -0400395 }
396 }
397 else if(sectionHeader[i].sh_type == SHT_REL)
398 {
399 assert(sizeof(void*) == 4 && "UNIMPLEMENTED"); // Only expected/implemented for 32-bit code
400
Alexis Hetu113e33a2017-01-19 10:49:19 -0500401 for(Elf32_Word index = 0; index < sectionHeader[i].sh_size / sectionHeader[i].sh_entsize; index++)
Nicolas Capens66478362016-10-13 15:36:36 -0400402 {
403 const Elf32_Rel &relocation = ((const Elf32_Rel*)(elfImage + sectionHeader[i].sh_offset))[index];
Alexis Hetu113e33a2017-01-19 10:49:19 -0500404 relocateSymbol(elfHeader, relocation, sectionHeader[i]);
Nicolas Capens66478362016-10-13 15:36:36 -0400405 }
406 }
407 else if(sectionHeader[i].sh_type == SHT_RELA)
408 {
409 assert(sizeof(void*) == 8 && "UNIMPLEMENTED"); // Only expected/implemented for 64-bit code
410
Alexis Hetu113e33a2017-01-19 10:49:19 -0500411 for(Elf32_Word index = 0; index < sectionHeader[i].sh_size / sectionHeader[i].sh_entsize; index++)
Nicolas Capens66478362016-10-13 15:36:36 -0400412 {
413 const Elf64_Rela &relocation = ((const Elf64_Rela*)(elfImage + sectionHeader[i].sh_offset))[index];
Alexis Hetu113e33a2017-01-19 10:49:19 -0500414 relocateSymbol(elfHeader, relocation, sectionHeader[i]);
Nicolas Capens66478362016-10-13 15:36:36 -0400415 }
Nicolas Capens598f8d82016-09-26 15:09:10 -0400416 }
417 }
418
419 return entry;
420 }
421
422 template<typename T>
423 struct ExecutableAllocator
424 {
425 ExecutableAllocator() {};
426 template<class U> ExecutableAllocator(const ExecutableAllocator<U> &other) {};
427
428 using value_type = T;
429 using size_type = std::size_t;
430
431 T *allocate(size_type n)
432 {
Nicolas Capensc07dc4b2018-08-06 14:20:45 -0400433 return (T*)allocateExecutable(sizeof(T) * n);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400434 }
435
436 void deallocate(T *p, size_type n)
437 {
Nicolas Capensc07dc4b2018-08-06 14:20:45 -0400438 deallocateExecutable(p, sizeof(T) * n);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400439 }
440 };
441
442 class ELFMemoryStreamer : public Ice::ELFStreamer, public Routine
443 {
444 ELFMemoryStreamer(const ELFMemoryStreamer &) = delete;
445 ELFMemoryStreamer &operator=(const ELFMemoryStreamer &) = delete;
446
447 public:
Nicolas Capens58274b52016-10-19 23:45:19 -0400448 ELFMemoryStreamer() : Routine(), entry(nullptr)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400449 {
450 position = 0;
451 buffer.reserve(0x1000);
452 }
453
Nicolas Capens81aa97b2017-06-27 17:08:08 -0400454 ~ELFMemoryStreamer() override
Nicolas Capens598f8d82016-09-26 15:09:10 -0400455 {
Nicolas Capensbd65da92017-01-05 16:31:06 -0500456 #if defined(_WIN32)
457 if(buffer.size() != 0)
458 {
459 DWORD exeProtection;
460 VirtualProtect(&buffer[0], buffer.size(), oldProtection, &exeProtection);
461 }
462 #endif
Nicolas Capens598f8d82016-09-26 15:09:10 -0400463 }
464
465 void write8(uint8_t Value) override
466 {
467 if(position == (uint64_t)buffer.size())
468 {
469 buffer.push_back(Value);
470 position++;
471 }
472 else if(position < (uint64_t)buffer.size())
473 {
474 buffer[position] = Value;
475 position++;
476 }
477 else assert(false && "UNIMPLEMENTED");
478 }
479
480 void writeBytes(llvm::StringRef Bytes) override
481 {
482 std::size_t oldSize = buffer.size();
483 buffer.resize(oldSize + Bytes.size());
484 memcpy(&buffer[oldSize], Bytes.begin(), Bytes.size());
485 position += Bytes.size();
486 }
487
488 uint64_t tell() const override { return position; }
489
490 void seek(uint64_t Off) override { position = Off; }
491
492 const void *getEntry() override
493 {
Nicolas Capens58274b52016-10-19 23:45:19 -0400494 if(!entry)
495 {
Nicolas Capensbd65da92017-01-05 16:31:06 -0500496 position = std::numeric_limits<std::size_t>::max(); // Can't stream more data after this
Nicolas Capens598f8d82016-09-26 15:09:10 -0400497
Nicolas Capens1cc44382017-04-25 10:52:16 -0400498 size_t codeSize = 0;
499 entry = loadImage(&buffer[0], codeSize);
500
501 #if defined(_WIN32)
Nicolas Capense745f5a2017-05-29 10:00:32 -0400502 VirtualProtect(&buffer[0], buffer.size(), PAGE_EXECUTE_READ, &oldProtection);
Nicolas Capens1cc44382017-04-25 10:52:16 -0400503 FlushInstructionCache(GetCurrentProcess(), NULL, 0);
504 #else
Nicolas Capense745f5a2017-05-29 10:00:32 -0400505 mprotect(&buffer[0], buffer.size(), PROT_READ | PROT_EXEC);
Nicolas Capens1cc44382017-04-25 10:52:16 -0400506 __builtin___clear_cache((char*)entry, (char*)entry + codeSize);
507 #endif
Nicolas Capens58274b52016-10-19 23:45:19 -0400508 }
509
510 return entry;
Nicolas Capens598f8d82016-09-26 15:09:10 -0400511 }
512
513 private:
Nicolas Capens58274b52016-10-19 23:45:19 -0400514 void *entry;
Nicolas Capens598f8d82016-09-26 15:09:10 -0400515 std::vector<uint8_t, ExecutableAllocator<uint8_t>> buffer;
516 std::size_t position;
Nicolas Capensbd65da92017-01-05 16:31:06 -0500517
518 #if defined(_WIN32)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400519 DWORD oldProtection;
Nicolas Capensbd65da92017-01-05 16:31:06 -0500520 #endif
Nicolas Capens598f8d82016-09-26 15:09:10 -0400521 };
522
523 Nucleus::Nucleus()
524 {
525 ::codegenMutex.lock(); // Reactor is currently not thread safe
526
Nicolas Capens66478362016-10-13 15:36:36 -0400527 Ice::ClFlags &Flags = Ice::ClFlags::Flags;
528 Ice::ClFlags::getParsedClFlags(Flags);
529
Nicolas Capens30cd7d42017-04-25 15:17:25 -0400530 #if defined(__arm__)
531 Flags.setTargetArch(Ice::Target_ARM32);
532 Flags.setTargetInstructionSet(Ice::ARM32InstructionSet_HWDivArm);
Gordana Cmiljanovic082dfec2018-10-19 11:36:15 +0200533 #elif defined(__mips__)
534 Flags.setTargetArch(Ice::Target_MIPS32);
535 Flags.setTargetInstructionSet(Ice::BaseInstructionSet);
Nicolas Capens30cd7d42017-04-25 15:17:25 -0400536 #else // x86
537 Flags.setTargetArch(sizeof(void*) == 8 ? Ice::Target_X8664 : Ice::Target_X8632);
538 Flags.setTargetInstructionSet(CPUID::SSE4_1 ? Ice::X86InstructionSet_SSE4_1 : Ice::X86InstructionSet_SSE2);
539 #endif
Nicolas Capens66478362016-10-13 15:36:36 -0400540 Flags.setOutFileType(Ice::FT_Elf);
541 Flags.setOptLevel(Ice::Opt_2);
542 Flags.setApplicationBinaryInterface(Ice::ABI_Platform);
Nicolas Capens30cd7d42017-04-25 15:17:25 -0400543 Flags.setVerbose(false ? Ice::IceV_Most : Ice::IceV_None);
544 Flags.setDisableHybridAssembly(true);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400545
Nicolas Capens65047112016-11-07 13:01:07 -0500546 static llvm::raw_os_ostream cout(std::cout);
547 static llvm::raw_os_ostream cerr(std::cerr);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400548
549 if(false) // Write out to a file
550 {
551 std::error_code errorCode;
552 ::out = new Ice::Fdstream("out.o", errorCode, llvm::sys::fs::F_None);
553 ::elfFile = new Ice::ELFFileStreamer(*out);
Nicolas Capens65047112016-11-07 13:01:07 -0500554 ::context = new Ice::GlobalContext(&cout, &cout, &cerr, elfFile);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400555 }
556 else
557 {
558 ELFMemoryStreamer *elfMemory = new ELFMemoryStreamer();
Nicolas Capens65047112016-11-07 13:01:07 -0500559 ::context = new Ice::GlobalContext(&cout, &cout, &cerr, elfMemory);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400560 ::routine = elfMemory;
561 }
562 }
563
564 Nucleus::~Nucleus()
565 {
Nicolas Capens619a8c52017-07-05 14:10:46 -0400566 delete ::routine;
567
Nicolas Capens598f8d82016-09-26 15:09:10 -0400568 delete ::allocator;
569 delete ::function;
570 delete ::context;
571
572 delete ::elfFile;
573 delete ::out;
574
575 ::codegenMutex.unlock();
576 }
577
578 Routine *Nucleus::acquireRoutine(const wchar_t *name, bool runOptimizations)
579 {
580 if(basicBlock->getInsts().empty() || basicBlock->getInsts().back().getKind() != Ice::Inst::Ret)
581 {
582 createRetVoid();
583 }
584
585 std::wstring wideName(name);
586 std::string asciiName(wideName.begin(), wideName.end());
587 ::function->setFunctionName(Ice::GlobalString::createWithString(::context, asciiName));
588
Nicolas Capens2ae9d742016-11-24 14:43:05 -0500589 optimize();
590
Nicolas Capens598f8d82016-09-26 15:09:10 -0400591 ::function->translate();
Nicolas Capensde19f392016-10-19 10:29:49 -0400592 assert(!::function->hasError());
593
Nicolas Capens83a6bb92017-07-05 15:04:00 -0400594 auto globals = ::function->getGlobalInits();
Nicolas Capens66478362016-10-13 15:36:36 -0400595
596 if(globals && !globals->empty())
597 {
Nicolas Capens83a6bb92017-07-05 15:04:00 -0400598 ::context->getGlobals()->merge(globals.get());
Nicolas Capens66478362016-10-13 15:36:36 -0400599 }
Nicolas Capens598f8d82016-09-26 15:09:10 -0400600
601 ::context->emitFileHeader();
602 ::function->emitIAS();
603 auto assembler = ::function->releaseAssembler();
Nicolas Capens66478362016-10-13 15:36:36 -0400604 auto objectWriter = ::context->getObjectWriter();
605 assembler->alignFunction();
606 objectWriter->writeFunctionCode(::function->getFunctionName(), false, assembler.get());
607 ::context->lowerGlobals("last");
Nicolas Capens73dd7a22016-10-20 13:20:34 -0400608 ::context->lowerConstants();
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500609 ::context->lowerJumpTables();
Nicolas Capens66478362016-10-13 15:36:36 -0400610 objectWriter->setUndefinedSyms(::context->getConstantExternSyms());
611 objectWriter->writeNonUserSections();
Nicolas Capens598f8d82016-09-26 15:09:10 -0400612
Nicolas Capens619a8c52017-07-05 14:10:46 -0400613 Routine *handoffRoutine = ::routine;
614 ::routine = nullptr;
615
616 return handoffRoutine;
Nicolas Capens598f8d82016-09-26 15:09:10 -0400617 }
618
619 void Nucleus::optimize()
620 {
Nicolas Capens48461502018-08-06 14:20:45 -0400621 rr::optimize(::function);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400622 }
623
624 Value *Nucleus::allocateStackVariable(Type *t, int arraySize)
625 {
626 Ice::Type type = T(t);
Nicolas Capensa8f98632016-10-20 11:25:55 -0400627 int typeSize = Ice::typeWidthInBytes(type);
628 int totalSize = typeSize * (arraySize ? arraySize : 1);
Nicolas Capense12780d2016-09-27 14:18:07 -0400629
Nicolas Capensa8f98632016-10-20 11:25:55 -0400630 auto bytes = Ice::ConstantInteger32::create(::context, type, totalSize);
Nicolas Capense12780d2016-09-27 14:18:07 -0400631 auto address = ::function->makeVariable(T(getPointerType(t)));
Nicolas Capensa8f98632016-10-20 11:25:55 -0400632 auto alloca = Ice::InstAlloca::create(::function, address, bytes, typeSize);
Nicolas Capense12780d2016-09-27 14:18:07 -0400633 ::function->getEntryNode()->getInsts().push_front(alloca);
634
635 return V(address);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400636 }
637
638 BasicBlock *Nucleus::createBasicBlock()
639 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400640 return B(::function->makeNode());
Nicolas Capens598f8d82016-09-26 15:09:10 -0400641 }
642
643 BasicBlock *Nucleus::getInsertBlock()
644 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400645 return B(::basicBlock);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400646 }
647
648 void Nucleus::setInsertBlock(BasicBlock *basicBlock)
649 {
Nicolas Capens9ed1a182016-10-24 09:52:23 -0400650 // assert(::basicBlock->getInsts().back().getTerminatorEdges().size() >= 0 && "Previous basic block must have a terminator");
Nicolas Capens611642a2016-09-28 16:45:04 -0400651 ::basicBlock = basicBlock;
Nicolas Capens598f8d82016-09-26 15:09:10 -0400652 }
653
Nicolas Capens598f8d82016-09-26 15:09:10 -0400654 void Nucleus::createFunction(Type *ReturnType, std::vector<Type*> &Params)
655 {
656 uint32_t sequenceNumber = 0;
657 ::function = Ice::Cfg::create(::context, sequenceNumber).release();
658 ::allocator = new Ice::CfgLocalAllocatorScope(::function);
659
660 for(Type *type : Params)
661 {
662 Ice::Variable *arg = ::function->makeVariable(T(type));
663 ::function->addArg(arg);
664 }
665
666 Ice::CfgNode *node = ::function->makeNode();
667 ::function->setEntryNode(node);
668 ::basicBlock = node;
669 }
670
671 Value *Nucleus::getArgument(unsigned int index)
672 {
673 return V(::function->getArgs()[index]);
674 }
675
676 void Nucleus::createRetVoid()
677 {
Nicolas Capensfdcca2d2016-10-20 11:31:36 -0400678 Ice::InstRet *ret = Ice::InstRet::create(::function);
679 ::basicBlock->appendInst(ret);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400680 }
681
682 void Nucleus::createRet(Value *v)
683 {
Nicolas Capensfdcca2d2016-10-20 11:31:36 -0400684 Ice::InstRet *ret = Ice::InstRet::create(::function, v);
685 ::basicBlock->appendInst(ret);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400686 }
687
688 void Nucleus::createBr(BasicBlock *dest)
689 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400690 auto br = Ice::InstBr::create(::function, dest);
691 ::basicBlock->appendInst(br);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400692 }
693
694 void Nucleus::createCondBr(Value *cond, BasicBlock *ifTrue, BasicBlock *ifFalse)
695 {
Nicolas Capens611642a2016-09-28 16:45:04 -0400696 auto br = Ice::InstBr::create(::function, cond, ifTrue, ifFalse);
697 ::basicBlock->appendInst(br);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400698 }
699
Nicolas Capensf8360ba2017-01-25 11:35:00 -0800700 static bool isCommutative(Ice::InstArithmetic::OpKind op)
701 {
702 switch(op)
703 {
704 case Ice::InstArithmetic::Add:
705 case Ice::InstArithmetic::Fadd:
706 case Ice::InstArithmetic::Mul:
707 case Ice::InstArithmetic::Fmul:
708 case Ice::InstArithmetic::And:
709 case Ice::InstArithmetic::Or:
710 case Ice::InstArithmetic::Xor:
711 return true;
712 default:
713 return false;
714 }
715 }
716
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400717 static Value *createArithmetic(Ice::InstArithmetic::OpKind op, Value *lhs, Value *rhs)
718 {
Nicolas Capensb64e0ce2018-01-26 01:24:57 +0000719 assert(lhs->getType() == rhs->getType() || llvm::isa<Ice::Constant>(rhs));
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400720
Nicolas Capensf8360ba2017-01-25 11:35:00 -0800721 bool swapOperands = llvm::isa<Ice::Constant>(lhs) && isCommutative(op);
722
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400723 Ice::Variable *result = ::function->makeVariable(lhs->getType());
Nicolas Capensf8360ba2017-01-25 11:35:00 -0800724 Ice::InstArithmetic *arithmetic = Ice::InstArithmetic::create(::function, op, result, swapOperands ? rhs : lhs, swapOperands ? lhs : rhs);
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400725 ::basicBlock->appendInst(arithmetic);
726
727 return V(result);
728 }
729
Nicolas Capens598f8d82016-09-26 15:09:10 -0400730 Value *Nucleus::createAdd(Value *lhs, Value *rhs)
731 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400732 return createArithmetic(Ice::InstArithmetic::Add, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400733 }
734
735 Value *Nucleus::createSub(Value *lhs, Value *rhs)
736 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400737 return createArithmetic(Ice::InstArithmetic::Sub, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400738 }
739
740 Value *Nucleus::createMul(Value *lhs, Value *rhs)
741 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400742 return createArithmetic(Ice::InstArithmetic::Mul, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400743 }
744
745 Value *Nucleus::createUDiv(Value *lhs, Value *rhs)
746 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400747 return createArithmetic(Ice::InstArithmetic::Udiv, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400748 }
749
750 Value *Nucleus::createSDiv(Value *lhs, Value *rhs)
751 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400752 return createArithmetic(Ice::InstArithmetic::Sdiv, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400753 }
754
755 Value *Nucleus::createFAdd(Value *lhs, Value *rhs)
756 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400757 return createArithmetic(Ice::InstArithmetic::Fadd, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400758 }
759
760 Value *Nucleus::createFSub(Value *lhs, Value *rhs)
761 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400762 return createArithmetic(Ice::InstArithmetic::Fsub, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400763 }
764
765 Value *Nucleus::createFMul(Value *lhs, Value *rhs)
766 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400767 return createArithmetic(Ice::InstArithmetic::Fmul, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400768 }
769
770 Value *Nucleus::createFDiv(Value *lhs, Value *rhs)
771 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400772 return createArithmetic(Ice::InstArithmetic::Fdiv, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400773 }
774
775 Value *Nucleus::createURem(Value *lhs, Value *rhs)
776 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400777 return createArithmetic(Ice::InstArithmetic::Urem, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400778 }
779
780 Value *Nucleus::createSRem(Value *lhs, Value *rhs)
781 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400782 return createArithmetic(Ice::InstArithmetic::Srem, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400783 }
784
785 Value *Nucleus::createFRem(Value *lhs, Value *rhs)
786 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400787 return createArithmetic(Ice::InstArithmetic::Frem, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400788 }
789
790 Value *Nucleus::createShl(Value *lhs, Value *rhs)
791 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400792 return createArithmetic(Ice::InstArithmetic::Shl, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400793 }
794
795 Value *Nucleus::createLShr(Value *lhs, Value *rhs)
796 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400797 return createArithmetic(Ice::InstArithmetic::Lshr, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400798 }
799
800 Value *Nucleus::createAShr(Value *lhs, Value *rhs)
801 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400802 return createArithmetic(Ice::InstArithmetic::Ashr, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400803 }
804
805 Value *Nucleus::createAnd(Value *lhs, Value *rhs)
806 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400807 return createArithmetic(Ice::InstArithmetic::And, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400808 }
809
810 Value *Nucleus::createOr(Value *lhs, Value *rhs)
811 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400812 return createArithmetic(Ice::InstArithmetic::Or, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400813 }
814
815 Value *Nucleus::createXor(Value *lhs, Value *rhs)
816 {
Nicolas Capens7d9f76d2016-09-29 13:39:44 -0400817 return createArithmetic(Ice::InstArithmetic::Xor, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400818 }
819
820 Value *Nucleus::createNeg(Value *v)
821 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500822 return createSub(createNullValue(T(v->getType())), v);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400823 }
824
825 Value *Nucleus::createFNeg(Value *v)
826 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500827 double c[4] = {-0.0, -0.0, -0.0, -0.0};
828 Value *negativeZero = Ice::isVectorType(v->getType()) ?
829 createConstantVector(c, T(v->getType())) :
Nicolas Capens15060bb2016-12-05 22:17:19 -0500830 V(::context->getConstantFloat(-0.0f));
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500831
832 return createFSub(negativeZero, v);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400833 }
834
835 Value *Nucleus::createNot(Value *v)
836 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500837 if(Ice::isScalarIntegerType(v->getType()))
838 {
Nicolas Capens15060bb2016-12-05 22:17:19 -0500839 return createXor(v, V(::context->getConstantInt(v->getType(), -1)));
Nicolas Capensc5c0c332016-11-08 11:37:01 -0500840 }
841 else // Vector
842 {
Nicolas Capensf34d1ac2017-05-08 17:06:11 -0400843 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 -0500844 return createXor(v, createConstantVector(c, T(v->getType())));
845 }
Nicolas Capens598f8d82016-09-26 15:09:10 -0400846 }
847
Nicolas Capense12780d2016-09-27 14:18:07 -0400848 Value *Nucleus::createLoad(Value *ptr, Type *type, bool isVolatile, unsigned int align)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400849 {
Nicolas Capens23d99a42016-09-30 14:57:16 -0400850 int valueType = (int)reinterpret_cast<intptr_t>(type);
851 Ice::Variable *result = ::function->makeVariable(T(type));
852
Nicolas Capensf4c4eca2017-10-03 14:26:07 -0400853 if((valueType & EmulatedBits) && (align != 0)) // Narrow vector not stored on stack.
Nicolas Capens23d99a42016-09-30 14:57:16 -0400854 {
Nicolas Capens070d9f42017-04-26 13:36:33 -0400855 if(emulateIntrinsics)
856 {
857 if(typeSize(type) == 4)
858 {
859 auto pointer = RValue<Pointer<Byte>>(ptr);
Nicolas Capens1894cfa2017-07-27 14:21:46 -0400860 Int x = *Pointer<Int>(pointer);
Nicolas Capens070d9f42017-04-26 13:36:33 -0400861
862 Int4 vector;
863 vector = Insert(vector, x, 0);
864
865 auto bitcast = Ice::InstCast::create(::function, Ice::InstCast::Bitcast, result, vector.loadValue());
866 ::basicBlock->appendInst(bitcast);
867 }
868 else if(typeSize(type) == 8)
869 {
870 auto pointer = RValue<Pointer<Byte>>(ptr);
Nicolas Capens1894cfa2017-07-27 14:21:46 -0400871 Int x = *Pointer<Int>(pointer);
Nicolas Capens070d9f42017-04-26 13:36:33 -0400872 Int y = *Pointer<Int>(pointer + 4);
873
874 Int4 vector;
875 vector = Insert(vector, x, 0);
876 vector = Insert(vector, y, 1);
877
878 auto bitcast = Ice::InstCast::create(::function, Ice::InstCast::Bitcast, result, vector.loadValue());
879 ::basicBlock->appendInst(bitcast);
880 }
881 else assert(false);
882 }
883 else
884 {
885 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::LoadSubVector, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
886 auto target = ::context->getConstantUndef(Ice::IceType_i32);
887 auto load = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
888 load->addArg(ptr);
889 load->addArg(::context->getConstantInt32(typeSize(type)));
890 ::basicBlock->appendInst(load);
891 }
Nicolas Capens23d99a42016-09-30 14:57:16 -0400892 }
893 else
894 {
895 auto load = Ice::InstLoad::create(::function, result, ptr, align);
896 ::basicBlock->appendInst(load);
897 }
898
899 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -0400900 }
901
Nicolas Capens6d738712016-09-30 04:15:22 -0400902 Value *Nucleus::createStore(Value *value, Value *ptr, Type *type, bool isVolatile, unsigned int align)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400903 {
Nicolas Capens6a990f82018-07-06 15:54:07 -0400904 #if __has_feature(memory_sanitizer)
905 // Mark all (non-stack) memory writes as initialized by calling __msan_unpoison
906 if(align != 0)
907 {
908 auto call = Ice::InstCall::create(::function, 2, nullptr, ::context->getConstantInt64(reinterpret_cast<intptr_t>(__msan_unpoison)), false);
909 call->addArg(ptr);
910 call->addArg(::context->getConstantInt64(typeSize(type)));
911 ::basicBlock->appendInst(call);
912 }
913 #endif
914
Nicolas Capens23d99a42016-09-30 14:57:16 -0400915 int valueType = (int)reinterpret_cast<intptr_t>(type);
916
Nicolas Capensf4c4eca2017-10-03 14:26:07 -0400917 if((valueType & EmulatedBits) && (align != 0)) // Narrow vector not stored on stack.
Nicolas Capens23d99a42016-09-30 14:57:16 -0400918 {
Nicolas Capens070d9f42017-04-26 13:36:33 -0400919 if(emulateIntrinsics)
920 {
921 if(typeSize(type) == 4)
922 {
923 Ice::Variable *vector = ::function->makeVariable(Ice::IceType_v4i32);
924 auto bitcast = Ice::InstCast::create(::function, Ice::InstCast::Bitcast, vector, value);
925 ::basicBlock->appendInst(bitcast);
926
927 RValue<Int4> v(V(vector));
928
929 auto pointer = RValue<Pointer<Byte>>(ptr);
930 Int x = Extract(v, 0);
931 *Pointer<Int>(pointer) = x;
932 }
933 else if(typeSize(type) == 8)
934 {
935 Ice::Variable *vector = ::function->makeVariable(Ice::IceType_v4i32);
936 auto bitcast = Ice::InstCast::create(::function, Ice::InstCast::Bitcast, vector, value);
937 ::basicBlock->appendInst(bitcast);
938
939 RValue<Int4> v(V(vector));
940
941 auto pointer = RValue<Pointer<Byte>>(ptr);
942 Int x = Extract(v, 0);
943 *Pointer<Int>(pointer) = x;
944 Int y = Extract(v, 1);
945 *Pointer<Int>(pointer + 4) = y;
946 }
947 else assert(false);
948 }
949 else
950 {
951 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::StoreSubVector, Ice::Intrinsics::SideEffects_T, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_T};
952 auto target = ::context->getConstantUndef(Ice::IceType_i32);
953 auto store = Ice::InstIntrinsicCall::create(::function, 3, nullptr, target, intrinsic);
954 store->addArg(value);
955 store->addArg(ptr);
956 store->addArg(::context->getConstantInt32(typeSize(type)));
957 ::basicBlock->appendInst(store);
958 }
Nicolas Capens23d99a42016-09-30 14:57:16 -0400959 }
960 else
961 {
Nicolas Capensf4c4eca2017-10-03 14:26:07 -0400962 assert(value->getType() == T(type));
Nicolas Capens23d99a42016-09-30 14:57:16 -0400963
964 auto store = Ice::InstStore::create(::function, value, ptr, align);
965 ::basicBlock->appendInst(store);
966 }
967
Nicolas Capens598f8d82016-09-26 15:09:10 -0400968 return value;
969 }
970
Nicolas Capensd294def2017-01-26 17:44:37 -0800971 Value *Nucleus::createGEP(Value *ptr, Type *type, Value *index, bool unsignedIndex)
Nicolas Capens598f8d82016-09-26 15:09:10 -0400972 {
Nicolas Capens8820f642016-09-30 04:42:43 -0400973 assert(index->getType() == Ice::IceType_i32);
974
Nicolas Capens15060bb2016-12-05 22:17:19 -0500975 if(auto *constant = llvm::dyn_cast<Ice::ConstantInteger32>(index))
976 {
Nicolas Capens584088c2017-01-26 16:05:18 -0800977 int32_t offset = constant->getValue() * (int)typeSize(type);
Nicolas Capens15060bb2016-12-05 22:17:19 -0500978
979 if(offset == 0)
980 {
981 return ptr;
982 }
983
984 return createAdd(ptr, createConstantInt(offset));
985 }
986
Nicolas Capens8820f642016-09-30 04:42:43 -0400987 if(!Ice::isByteSizedType(T(type)))
988 {
Nicolas Capens584088c2017-01-26 16:05:18 -0800989 index = createMul(index, createConstantInt((int)typeSize(type)));
Nicolas Capens8820f642016-09-30 04:42:43 -0400990 }
991
992 if(sizeof(void*) == 8)
993 {
Nicolas Capensd294def2017-01-26 17:44:37 -0800994 if(unsignedIndex)
995 {
996 index = createZExt(index, T(Ice::IceType_i64));
997 }
998 else
999 {
1000 index = createSExt(index, T(Ice::IceType_i64));
1001 }
Nicolas Capens8820f642016-09-30 04:42:43 -04001002 }
1003
1004 return createAdd(ptr, index);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001005 }
1006
1007 Value *Nucleus::createAtomicAdd(Value *ptr, Value *value)
1008 {
1009 assert(false && "UNIMPLEMENTED"); return nullptr;
1010 }
1011
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001012 static Value *createCast(Ice::InstCast::OpKind op, Value *v, Type *destType)
1013 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04001014 if(v->getType() == T(destType))
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001015 {
1016 return v;
1017 }
1018
1019 Ice::Variable *result = ::function->makeVariable(T(destType));
1020 Ice::InstCast *cast = Ice::InstCast::create(::function, op, result, v);
1021 ::basicBlock->appendInst(cast);
1022
1023 return V(result);
1024 }
1025
Nicolas Capens598f8d82016-09-26 15:09:10 -04001026 Value *Nucleus::createTrunc(Value *v, Type *destType)
1027 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001028 return createCast(Ice::InstCast::Trunc, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001029 }
1030
1031 Value *Nucleus::createZExt(Value *v, Type *destType)
1032 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001033 return createCast(Ice::InstCast::Zext, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001034 }
1035
1036 Value *Nucleus::createSExt(Value *v, Type *destType)
1037 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001038 return createCast(Ice::InstCast::Sext, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001039 }
1040
1041 Value *Nucleus::createFPToSI(Value *v, Type *destType)
1042 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001043 return createCast(Ice::InstCast::Fptosi, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001044 }
1045
Nicolas Capens598f8d82016-09-26 15:09:10 -04001046 Value *Nucleus::createSIToFP(Value *v, Type *destType)
1047 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001048 return createCast(Ice::InstCast::Sitofp, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001049 }
1050
1051 Value *Nucleus::createFPTrunc(Value *v, Type *destType)
1052 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001053 return createCast(Ice::InstCast::Fptrunc, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001054 }
1055
1056 Value *Nucleus::createFPExt(Value *v, Type *destType)
1057 {
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001058 return createCast(Ice::InstCast::Fpext, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001059 }
1060
1061 Value *Nucleus::createBitCast(Value *v, Type *destType)
1062 {
Nicolas Capens2d8c3702017-07-25 13:56:46 -04001063 // Bitcasts must be between types of the same logical size. But with emulated narrow vectors we need
1064 // support for casting between scalars and wide vectors. For platforms where this is not supported,
1065 // emulate them by writing to the stack and reading back as the destination type.
1066 if(emulateMismatchedBitCast)
1067 {
1068 if(!Ice::isVectorType(v->getType()) && Ice::isVectorType(T(destType)))
1069 {
1070 Value *address = allocateStackVariable(destType);
1071 createStore(v, address, T(v->getType()));
1072 return createLoad(address, destType);
1073 }
1074 else if(Ice::isVectorType(v->getType()) && !Ice::isVectorType(T(destType)))
1075 {
1076 Value *address = allocateStackVariable(T(v->getType()));
1077 createStore(v, address, T(v->getType()));
1078 return createLoad(address, destType);
1079 }
1080 }
1081
Nicolas Capensa0c2fc52016-09-30 05:04:21 -04001082 return createCast(Ice::InstCast::Bitcast, v, destType);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001083 }
1084
Nicolas Capens43dc6292016-10-20 00:01:38 -04001085 static Value *createIntCompare(Ice::InstIcmp::ICond condition, Value *lhs, Value *rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001086 {
Nicolas Capens611642a2016-09-28 16:45:04 -04001087 assert(lhs->getType() == rhs->getType());
1088
Nicolas Capens43dc6292016-10-20 00:01:38 -04001089 auto result = ::function->makeVariable(Ice::isScalarIntegerType(lhs->getType()) ? Ice::IceType_i1 : lhs->getType());
1090 auto cmp = Ice::InstIcmp::create(::function, condition, result, lhs, rhs);
Nicolas Capens611642a2016-09-28 16:45:04 -04001091 ::basicBlock->appendInst(cmp);
1092
1093 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001094 }
1095
Nicolas Capens43dc6292016-10-20 00:01:38 -04001096 Value *Nucleus::createICmpEQ(Value *lhs, Value *rhs)
1097 {
1098 return createIntCompare(Ice::InstIcmp::Eq, lhs, rhs);
1099 }
1100
1101 Value *Nucleus::createICmpNE(Value *lhs, Value *rhs)
1102 {
1103 return createIntCompare(Ice::InstIcmp::Ne, lhs, rhs);
1104 }
1105
1106 Value *Nucleus::createICmpUGT(Value *lhs, Value *rhs)
1107 {
1108 return createIntCompare(Ice::InstIcmp::Ugt, lhs, rhs);
1109 }
1110
1111 Value *Nucleus::createICmpUGE(Value *lhs, Value *rhs)
1112 {
1113 return createIntCompare(Ice::InstIcmp::Uge, lhs, rhs);
1114 }
1115
1116 Value *Nucleus::createICmpULT(Value *lhs, Value *rhs)
1117 {
1118 return createIntCompare(Ice::InstIcmp::Ult, lhs, rhs);
1119 }
1120
1121 Value *Nucleus::createICmpULE(Value *lhs, Value *rhs)
1122 {
1123 return createIntCompare(Ice::InstIcmp::Ule, lhs, rhs);
1124 }
1125
1126 Value *Nucleus::createICmpSGT(Value *lhs, Value *rhs)
1127 {
1128 return createIntCompare(Ice::InstIcmp::Sgt, lhs, rhs);
1129 }
1130
1131 Value *Nucleus::createICmpSGE(Value *lhs, Value *rhs)
1132 {
1133 return createIntCompare(Ice::InstIcmp::Sge, lhs, rhs);
1134 }
1135
1136 Value *Nucleus::createICmpSLT(Value *lhs, Value *rhs)
1137 {
1138 return createIntCompare(Ice::InstIcmp::Slt, lhs, rhs);
1139 }
1140
Nicolas Capens598f8d82016-09-26 15:09:10 -04001141 Value *Nucleus::createICmpSLE(Value *lhs, Value *rhs)
1142 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001143 return createIntCompare(Ice::InstIcmp::Sle, lhs, rhs);
1144 }
1145
1146 static Value *createFloatCompare(Ice::InstFcmp::FCond condition, Value *lhs, Value *rhs)
1147 {
1148 assert(lhs->getType() == rhs->getType());
1149 assert(Ice::isScalarFloatingType(lhs->getType()) || lhs->getType() == Ice::IceType_v4f32);
1150
1151 auto result = ::function->makeVariable(Ice::isScalarFloatingType(lhs->getType()) ? Ice::IceType_i1 : Ice::IceType_v4i32);
1152 auto cmp = Ice::InstFcmp::create(::function, condition, result, lhs, rhs);
1153 ::basicBlock->appendInst(cmp);
1154
1155 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001156 }
1157
1158 Value *Nucleus::createFCmpOEQ(Value *lhs, Value *rhs)
1159 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001160 return createFloatCompare(Ice::InstFcmp::Oeq, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001161 }
1162
1163 Value *Nucleus::createFCmpOGT(Value *lhs, Value *rhs)
1164 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001165 return createFloatCompare(Ice::InstFcmp::Ogt, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001166 }
1167
1168 Value *Nucleus::createFCmpOGE(Value *lhs, Value *rhs)
1169 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001170 return createFloatCompare(Ice::InstFcmp::Oge, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001171 }
1172
1173 Value *Nucleus::createFCmpOLT(Value *lhs, Value *rhs)
1174 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001175 return createFloatCompare(Ice::InstFcmp::Olt, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001176 }
1177
1178 Value *Nucleus::createFCmpOLE(Value *lhs, Value *rhs)
1179 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001180 return createFloatCompare(Ice::InstFcmp::Ole, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001181 }
1182
1183 Value *Nucleus::createFCmpONE(Value *lhs, Value *rhs)
1184 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001185 return createFloatCompare(Ice::InstFcmp::One, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001186 }
1187
1188 Value *Nucleus::createFCmpORD(Value *lhs, Value *rhs)
1189 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001190 return createFloatCompare(Ice::InstFcmp::Ord, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001191 }
1192
1193 Value *Nucleus::createFCmpUNO(Value *lhs, Value *rhs)
1194 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001195 return createFloatCompare(Ice::InstFcmp::Uno, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001196 }
1197
1198 Value *Nucleus::createFCmpUEQ(Value *lhs, Value *rhs)
1199 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001200 return createFloatCompare(Ice::InstFcmp::Ueq, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001201 }
1202
1203 Value *Nucleus::createFCmpUGT(Value *lhs, Value *rhs)
1204 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001205 return createFloatCompare(Ice::InstFcmp::Ugt, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001206 }
1207
1208 Value *Nucleus::createFCmpUGE(Value *lhs, Value *rhs)
1209 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001210 return createFloatCompare(Ice::InstFcmp::Uge, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001211 }
1212
1213 Value *Nucleus::createFCmpULT(Value *lhs, Value *rhs)
1214 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001215 return createFloatCompare(Ice::InstFcmp::Ult, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001216 }
1217
1218 Value *Nucleus::createFCmpULE(Value *lhs, Value *rhs)
1219 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001220 return createFloatCompare(Ice::InstFcmp::Ule, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001221 }
1222
1223 Value *Nucleus::createFCmpUNE(Value *lhs, Value *rhs)
1224 {
Nicolas Capens43dc6292016-10-20 00:01:38 -04001225 return createFloatCompare(Ice::InstFcmp::Une, lhs, rhs);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001226 }
1227
Nicolas Capense95d5342016-09-30 11:37:28 -04001228 Value *Nucleus::createExtractElement(Value *vector, Type *type, int index)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001229 {
Nicolas Capens9709d4f2016-09-30 11:44:14 -04001230 auto result = ::function->makeVariable(T(type));
1231 auto extract = Ice::InstExtractElement::create(::function, result, vector, ::context->getConstantInt32(index));
1232 ::basicBlock->appendInst(extract);
1233
1234 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001235 }
1236
1237 Value *Nucleus::createInsertElement(Value *vector, Value *element, int index)
1238 {
Nicolas Capens9709d4f2016-09-30 11:44:14 -04001239 auto result = ::function->makeVariable(vector->getType());
1240 auto insert = Ice::InstInsertElement::create(::function, result, vector, element, ::context->getConstantInt32(index));
1241 ::basicBlock->appendInst(insert);
1242
1243 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001244 }
1245
Nicolas Capense89cd582016-09-30 14:23:47 -04001246 Value *Nucleus::createShuffleVector(Value *V1, Value *V2, const int *select)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001247 {
Nicolas Capens619c0ab2016-09-30 14:46:24 -04001248 assert(V1->getType() == V2->getType());
1249
1250 int size = Ice::typeNumElements(V1->getType());
1251 auto result = ::function->makeVariable(V1->getType());
1252 auto shuffle = Ice::InstShuffleVector::create(::function, result, V1, V2);
1253
1254 for(int i = 0; i < size; i++)
1255 {
1256 shuffle->addIndex(llvm::cast<Ice::ConstantInteger32>(::context->getConstantInt32(select[i])));
1257 }
1258
1259 ::basicBlock->appendInst(shuffle);
1260
1261 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001262 }
1263
1264 Value *Nucleus::createSelect(Value *C, Value *ifTrue, Value *ifFalse)
1265 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04001266 assert(ifTrue->getType() == ifFalse->getType());
1267
1268 auto result = ::function->makeVariable(ifTrue->getType());
1269 auto *select = Ice::InstSelect::create(::function, result, C, ifTrue, ifFalse);
1270 ::basicBlock->appendInst(select);
1271
1272 return V(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001273 }
1274
Nicolas Capensb98fe5c2016-11-09 12:24:06 -05001275 SwitchCases *Nucleus::createSwitch(Value *control, BasicBlock *defaultBranch, unsigned numCases)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001276 {
Nicolas Capensb98fe5c2016-11-09 12:24:06 -05001277 auto switchInst = Ice::InstSwitch::create(::function, numCases, control, defaultBranch);
1278 ::basicBlock->appendInst(switchInst);
1279
1280 return reinterpret_cast<SwitchCases*>(switchInst);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001281 }
1282
Nicolas Capensb98fe5c2016-11-09 12:24:06 -05001283 void Nucleus::addSwitchCase(SwitchCases *switchCases, int label, BasicBlock *branch)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001284 {
Nicolas Capensb98fe5c2016-11-09 12:24:06 -05001285 switchCases->addBranch(label, label, branch);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001286 }
1287
1288 void Nucleus::createUnreachable()
1289 {
Nicolas Capensfdcca2d2016-10-20 11:31:36 -04001290 Ice::InstUnreachable *unreachable = Ice::InstUnreachable::create(::function);
1291 ::basicBlock->appendInst(unreachable);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001292 }
1293
Nicolas Capense95d5342016-09-30 11:37:28 -04001294 static Value *createSwizzle4(Value *val, unsigned char select)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001295 {
Nicolas Capens619c0ab2016-09-30 14:46:24 -04001296 int swizzle[4] =
1297 {
1298 (select >> 0) & 0x03,
1299 (select >> 2) & 0x03,
1300 (select >> 4) & 0x03,
1301 (select >> 6) & 0x03,
1302 };
Nicolas Capens9709d4f2016-09-30 11:44:14 -04001303
Nicolas Capens619c0ab2016-09-30 14:46:24 -04001304 return Nucleus::createShuffleVector(val, val, swizzle);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001305 }
1306
Nicolas Capense95d5342016-09-30 11:37:28 -04001307 static Value *createMask4(Value *lhs, Value *rhs, unsigned char select)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001308 {
Nicolas Capensa4c30b02016-11-08 15:43:17 -05001309 int64_t mask[4] = {0, 0, 0, 0};
1310
1311 mask[(select >> 0) & 0x03] = -1;
1312 mask[(select >> 2) & 0x03] = -1;
1313 mask[(select >> 4) & 0x03] = -1;
1314 mask[(select >> 6) & 0x03] = -1;
1315
1316 Value *condition = Nucleus::createConstantVector(mask, T(Ice::IceType_v4i1));
1317 Value *result = Nucleus::createSelect(condition, rhs, lhs);
1318
1319 return result;
Nicolas Capens598f8d82016-09-26 15:09:10 -04001320 }
1321
Nicolas Capens598f8d82016-09-26 15:09:10 -04001322 Type *Nucleus::getPointerType(Type *ElementType)
1323 {
Nicolas Capense12780d2016-09-27 14:18:07 -04001324 if(sizeof(void*) == 8)
1325 {
1326 return T(Ice::IceType_i64);
1327 }
1328 else
1329 {
1330 return T(Ice::IceType_i32);
1331 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04001332 }
1333
Nicolas Capens13ac2322016-10-13 14:52:12 -04001334 Value *Nucleus::createNullValue(Type *Ty)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001335 {
Nicolas Capens73dd7a22016-10-20 13:20:34 -04001336 if(Ice::isVectorType(T(Ty)))
1337 {
Nicolas Capens30385f02017-04-18 13:03:47 -04001338 assert(Ice::typeNumElements(T(Ty)) <= 16);
1339 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 -04001340 return createConstantVector(c, Ty);
1341 }
1342 else
1343 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001344 return V(::context->getConstantZero(T(Ty)));
Nicolas Capens73dd7a22016-10-20 13:20:34 -04001345 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04001346 }
1347
Nicolas Capens13ac2322016-10-13 14:52:12 -04001348 Value *Nucleus::createConstantLong(int64_t i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001349 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001350 return V(::context->getConstantInt64(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001351 }
1352
Nicolas Capens13ac2322016-10-13 14:52:12 -04001353 Value *Nucleus::createConstantInt(int i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001354 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001355 return V(::context->getConstantInt32(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001356 }
1357
Nicolas Capens13ac2322016-10-13 14:52:12 -04001358 Value *Nucleus::createConstantInt(unsigned int i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001359 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001360 return V(::context->getConstantInt32(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001361 }
1362
Nicolas Capens13ac2322016-10-13 14:52:12 -04001363 Value *Nucleus::createConstantBool(bool b)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001364 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001365 return V(::context->getConstantInt1(b));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001366 }
1367
Nicolas Capens13ac2322016-10-13 14:52:12 -04001368 Value *Nucleus::createConstantByte(signed char i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001369 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001370 return V(::context->getConstantInt8(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001371 }
1372
Nicolas Capens13ac2322016-10-13 14:52:12 -04001373 Value *Nucleus::createConstantByte(unsigned char i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001374 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001375 return V(::context->getConstantInt8(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001376 }
1377
Nicolas Capens13ac2322016-10-13 14:52:12 -04001378 Value *Nucleus::createConstantShort(short i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001379 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001380 return V(::context->getConstantInt16(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001381 }
1382
Nicolas Capens13ac2322016-10-13 14:52:12 -04001383 Value *Nucleus::createConstantShort(unsigned short i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001384 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001385 return V(::context->getConstantInt16(i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001386 }
1387
Nicolas Capens13ac2322016-10-13 14:52:12 -04001388 Value *Nucleus::createConstantFloat(float x)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001389 {
Nicolas Capens15060bb2016-12-05 22:17:19 -05001390 return V(::context->getConstantFloat(x));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001391 }
1392
Nicolas Capens13ac2322016-10-13 14:52:12 -04001393 Value *Nucleus::createNullPointer(Type *Ty)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001394 {
Nicolas Capensa29d6532016-12-05 21:38:09 -05001395 return createNullValue(T(sizeof(void*) == 8 ? Ice::IceType_i64 : Ice::IceType_i32));
Nicolas Capens598f8d82016-09-26 15:09:10 -04001396 }
1397
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001398 Value *Nucleus::createConstantVector(const int64_t *constants, Type *type)
Nicolas Capens13ac2322016-10-13 14:52:12 -04001399 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001400 const int vectorSize = 16;
1401 assert(Ice::typeWidthInBytes(T(type)) == vectorSize);
1402 const int alignment = vectorSize;
1403 auto globalPool = ::function->getGlobalPool();
1404
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001405 const int64_t *i = constants;
1406 const double *f = reinterpret_cast<const double*>(constants);
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001407 Ice::VariableDeclaration::DataInitializer *dataInitializer = nullptr;
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001408
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001409 switch((int)reinterpret_cast<intptr_t>(type))
1410 {
1411 case Ice::IceType_v4i32:
Nicolas Capensa4c30b02016-11-08 15:43:17 -05001412 case Ice::IceType_v4i1:
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001413 {
1414 const int initializer[4] = {(int)i[0], (int)i[1], (int)i[2], (int)i[3]};
1415 static_assert(sizeof(initializer) == vectorSize, "!");
1416 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1417 }
1418 break;
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001419 case Ice::IceType_v4f32:
1420 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001421 const float initializer[4] = {(float)f[0], (float)f[1], (float)f[2], (float)f[3]};
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_v8i16:
Nicolas Capensa4c30b02016-11-08 15:43:17 -05001427 case Ice::IceType_v8i1:
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001428 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001429 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 -04001430 static_assert(sizeof(initializer) == vectorSize, "!");
1431 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1432 }
1433 break;
1434 case Ice::IceType_v16i8:
Nicolas Capensa4c30b02016-11-08 15:43:17 -05001435 case Ice::IceType_v16i1:
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001436 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001437 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 -04001438 static_assert(sizeof(initializer) == vectorSize, "!");
1439 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1440 }
1441 break;
1442 case Type_v2i32:
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001443 {
1444 const int initializer[4] = {(int)i[0], (int)i[1], (int)i[0], (int)i[1]};
1445 static_assert(sizeof(initializer) == vectorSize, "!");
1446 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1447 }
1448 break;
Nicolas Capens4cfd4572016-10-20 01:00:19 -04001449 case Type_v2f32:
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001450 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001451 const float initializer[4] = {(float)f[0], (float)f[1], (float)f[0], (float)f[1]};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001452 static_assert(sizeof(initializer) == vectorSize, "!");
1453 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1454 }
1455 break;
1456 case Type_v4i16:
1457 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001458 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 -04001459 static_assert(sizeof(initializer) == vectorSize, "!");
1460 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1461 }
1462 break;
1463 case Type_v8i8:
1464 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001465 const char initializer[16] = {(char)i[0], (char)i[1], (char)i[2], (char)i[3], (char)i[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 -04001466 static_assert(sizeof(initializer) == vectorSize, "!");
1467 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1468 }
1469 break;
1470 case Type_v4i8:
1471 {
Nicolas Capens7f3f69c2016-10-20 01:29:33 -04001472 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 -04001473 static_assert(sizeof(initializer) == vectorSize, "!");
1474 dataInitializer = Ice::VariableDeclaration::DataInitializer::create(globalPool, (const char*)initializer, vectorSize);
1475 }
1476 break;
1477 default:
1478 assert(false && "Unknown constant vector type" && type);
1479 }
1480
1481 auto name = Ice::GlobalString::createWithoutString(::context);
1482 auto *variableDeclaration = Ice::VariableDeclaration::create(globalPool);
1483 variableDeclaration->setName(name);
1484 variableDeclaration->setAlignment(alignment);
1485 variableDeclaration->setIsConstant(true);
1486 variableDeclaration->addInitializer(dataInitializer);
Nicolas Capens87852e12016-11-24 14:45:06 -05001487
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001488 ::function->addGlobal(variableDeclaration);
1489
1490 constexpr int32_t offset = 0;
1491 Ice::Operand *ptr = ::context->getConstantSym(offset, name);
1492
1493 Ice::Variable *result = ::function->makeVariable(T(type));
1494 auto load = Ice::InstLoad::create(::function, result, ptr, alignment);
1495 ::basicBlock->appendInst(load);
1496
1497 return V(result);
Nicolas Capens13ac2322016-10-13 14:52:12 -04001498 }
1499
1500 Value *Nucleus::createConstantVector(const double *constants, Type *type)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001501 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04001502 return createConstantVector((const int64_t*)constants, type);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001503 }
1504
1505 Type *Void::getType()
1506 {
1507 return T(Ice::IceType_void);
1508 }
1509
Nicolas Capens598f8d82016-09-26 15:09:10 -04001510 Bool::Bool(Argument<Bool> argument)
1511 {
1512 storeValue(argument.value);
1513 }
1514
Nicolas Capens598f8d82016-09-26 15:09:10 -04001515 Bool::Bool(bool x)
1516 {
1517 storeValue(Nucleus::createConstantBool(x));
1518 }
1519
1520 Bool::Bool(RValue<Bool> rhs)
1521 {
1522 storeValue(rhs.value);
1523 }
1524
1525 Bool::Bool(const Bool &rhs)
1526 {
1527 Value *value = rhs.loadValue();
1528 storeValue(value);
1529 }
1530
1531 Bool::Bool(const Reference<Bool> &rhs)
1532 {
1533 Value *value = rhs.loadValue();
1534 storeValue(value);
1535 }
1536
Nicolas Capens96d4e092016-11-18 14:22:38 -05001537 RValue<Bool> Bool::operator=(RValue<Bool> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001538 {
1539 storeValue(rhs.value);
1540
1541 return rhs;
1542 }
1543
Nicolas Capens96d4e092016-11-18 14:22:38 -05001544 RValue<Bool> Bool::operator=(const 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
Nicolas Capens96d4e092016-11-18 14:22:38 -05001552 RValue<Bool> Bool::operator=(const Reference<Bool> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001553 {
1554 Value *value = rhs.loadValue();
1555 storeValue(value);
1556
1557 return RValue<Bool>(value);
1558 }
1559
1560 RValue<Bool> operator!(RValue<Bool> val)
1561 {
1562 return RValue<Bool>(Nucleus::createNot(val.value));
1563 }
1564
1565 RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs)
1566 {
1567 return RValue<Bool>(Nucleus::createAnd(lhs.value, rhs.value));
1568 }
1569
1570 RValue<Bool> operator||(RValue<Bool> lhs, RValue<Bool> rhs)
1571 {
1572 return RValue<Bool>(Nucleus::createOr(lhs.value, rhs.value));
1573 }
1574
1575 Type *Bool::getType()
1576 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04001577 return T(Ice::IceType_i1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001578 }
1579
1580 Byte::Byte(Argument<Byte> argument)
1581 {
1582 storeValue(argument.value);
1583 }
1584
1585 Byte::Byte(RValue<Int> cast)
1586 {
1587 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
1588
1589 storeValue(integer);
1590 }
1591
1592 Byte::Byte(RValue<UInt> cast)
1593 {
1594 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
1595
1596 storeValue(integer);
1597 }
1598
1599 Byte::Byte(RValue<UShort> cast)
1600 {
1601 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
1602
1603 storeValue(integer);
1604 }
1605
Nicolas Capens598f8d82016-09-26 15:09:10 -04001606 Byte::Byte(int x)
1607 {
1608 storeValue(Nucleus::createConstantByte((unsigned char)x));
1609 }
1610
1611 Byte::Byte(unsigned char x)
1612 {
1613 storeValue(Nucleus::createConstantByte(x));
1614 }
1615
1616 Byte::Byte(RValue<Byte> rhs)
1617 {
1618 storeValue(rhs.value);
1619 }
1620
1621 Byte::Byte(const Byte &rhs)
1622 {
1623 Value *value = rhs.loadValue();
1624 storeValue(value);
1625 }
1626
1627 Byte::Byte(const Reference<Byte> &rhs)
1628 {
1629 Value *value = rhs.loadValue();
1630 storeValue(value);
1631 }
1632
Nicolas Capens96d4e092016-11-18 14:22:38 -05001633 RValue<Byte> Byte::operator=(RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001634 {
1635 storeValue(rhs.value);
1636
1637 return rhs;
1638 }
1639
Nicolas Capens96d4e092016-11-18 14:22:38 -05001640 RValue<Byte> Byte::operator=(const 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
Nicolas Capens96d4e092016-11-18 14:22:38 -05001648 RValue<Byte> Byte::operator=(const Reference<Byte> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001649 {
1650 Value *value = rhs.loadValue();
1651 storeValue(value);
1652
1653 return RValue<Byte>(value);
1654 }
1655
1656 RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs)
1657 {
1658 return RValue<Byte>(Nucleus::createAdd(lhs.value, rhs.value));
1659 }
1660
1661 RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs)
1662 {
1663 return RValue<Byte>(Nucleus::createSub(lhs.value, rhs.value));
1664 }
1665
1666 RValue<Byte> operator*(RValue<Byte> lhs, RValue<Byte> rhs)
1667 {
1668 return RValue<Byte>(Nucleus::createMul(lhs.value, rhs.value));
1669 }
1670
1671 RValue<Byte> operator/(RValue<Byte> lhs, RValue<Byte> rhs)
1672 {
1673 return RValue<Byte>(Nucleus::createUDiv(lhs.value, rhs.value));
1674 }
1675
1676 RValue<Byte> operator%(RValue<Byte> lhs, RValue<Byte> rhs)
1677 {
1678 return RValue<Byte>(Nucleus::createURem(lhs.value, rhs.value));
1679 }
1680
1681 RValue<Byte> operator&(RValue<Byte> lhs, RValue<Byte> rhs)
1682 {
1683 return RValue<Byte>(Nucleus::createAnd(lhs.value, rhs.value));
1684 }
1685
1686 RValue<Byte> operator|(RValue<Byte> lhs, RValue<Byte> rhs)
1687 {
1688 return RValue<Byte>(Nucleus::createOr(lhs.value, rhs.value));
1689 }
1690
1691 RValue<Byte> operator^(RValue<Byte> lhs, RValue<Byte> rhs)
1692 {
1693 return RValue<Byte>(Nucleus::createXor(lhs.value, rhs.value));
1694 }
1695
1696 RValue<Byte> operator<<(RValue<Byte> lhs, RValue<Byte> rhs)
1697 {
1698 return RValue<Byte>(Nucleus::createShl(lhs.value, rhs.value));
1699 }
1700
1701 RValue<Byte> operator>>(RValue<Byte> lhs, RValue<Byte> rhs)
1702 {
1703 return RValue<Byte>(Nucleus::createLShr(lhs.value, rhs.value));
1704 }
1705
Nicolas Capens96d4e092016-11-18 14:22:38 -05001706 RValue<Byte> operator+=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001707 {
1708 return lhs = lhs + rhs;
1709 }
1710
Nicolas Capens96d4e092016-11-18 14:22:38 -05001711 RValue<Byte> operator-=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001712 {
1713 return lhs = lhs - rhs;
1714 }
1715
Nicolas Capens96d4e092016-11-18 14:22:38 -05001716 RValue<Byte> operator*=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001717 {
1718 return lhs = lhs * rhs;
1719 }
1720
Nicolas Capens96d4e092016-11-18 14:22:38 -05001721 RValue<Byte> operator/=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001722 {
1723 return lhs = lhs / rhs;
1724 }
1725
Nicolas Capens96d4e092016-11-18 14:22:38 -05001726 RValue<Byte> operator%=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001727 {
1728 return lhs = lhs % rhs;
1729 }
1730
Nicolas Capens96d4e092016-11-18 14:22:38 -05001731 RValue<Byte> operator&=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001732 {
1733 return lhs = lhs & rhs;
1734 }
1735
Nicolas Capens96d4e092016-11-18 14:22:38 -05001736 RValue<Byte> operator|=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001737 {
1738 return lhs = lhs | rhs;
1739 }
1740
Nicolas Capens96d4e092016-11-18 14:22:38 -05001741 RValue<Byte> operator^=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001742 {
1743 return lhs = lhs ^ rhs;
1744 }
1745
Nicolas Capens96d4e092016-11-18 14:22:38 -05001746 RValue<Byte> operator<<=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001747 {
1748 return lhs = lhs << rhs;
1749 }
1750
Nicolas Capens96d4e092016-11-18 14:22:38 -05001751 RValue<Byte> operator>>=(Byte &lhs, RValue<Byte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001752 {
1753 return lhs = lhs >> rhs;
1754 }
1755
1756 RValue<Byte> operator+(RValue<Byte> val)
1757 {
1758 return val;
1759 }
1760
1761 RValue<Byte> operator-(RValue<Byte> val)
1762 {
1763 return RValue<Byte>(Nucleus::createNeg(val.value));
1764 }
1765
1766 RValue<Byte> operator~(RValue<Byte> val)
1767 {
1768 return RValue<Byte>(Nucleus::createNot(val.value));
1769 }
1770
Nicolas Capens96d4e092016-11-18 14:22:38 -05001771 RValue<Byte> operator++(Byte &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04001772 {
1773 RValue<Byte> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05001774 val += Byte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001775 return res;
1776 }
1777
Nicolas Capens96d4e092016-11-18 14:22:38 -05001778 const Byte &operator++(Byte &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04001779 {
Nicolas Capensd1229402016-11-07 16:05:22 -05001780 val += Byte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001781 return val;
1782 }
1783
Nicolas Capens96d4e092016-11-18 14:22:38 -05001784 RValue<Byte> operator--(Byte &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04001785 {
1786 RValue<Byte> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05001787 val -= Byte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001788 return res;
1789 }
1790
Nicolas Capens96d4e092016-11-18 14:22:38 -05001791 const Byte &operator--(Byte &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04001792 {
Nicolas Capensd1229402016-11-07 16:05:22 -05001793 val -= Byte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001794 return val;
1795 }
1796
1797 RValue<Bool> operator<(RValue<Byte> lhs, RValue<Byte> rhs)
1798 {
1799 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1800 }
1801
1802 RValue<Bool> operator<=(RValue<Byte> lhs, RValue<Byte> rhs)
1803 {
1804 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1805 }
1806
1807 RValue<Bool> operator>(RValue<Byte> lhs, RValue<Byte> rhs)
1808 {
1809 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1810 }
1811
1812 RValue<Bool> operator>=(RValue<Byte> lhs, RValue<Byte> rhs)
1813 {
1814 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1815 }
1816
1817 RValue<Bool> operator!=(RValue<Byte> lhs, RValue<Byte> rhs)
1818 {
1819 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1820 }
1821
1822 RValue<Bool> operator==(RValue<Byte> lhs, RValue<Byte> rhs)
1823 {
1824 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1825 }
1826
1827 Type *Byte::getType()
1828 {
Nicolas Capens6d738712016-09-30 04:15:22 -04001829 return T(Ice::IceType_i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04001830 }
1831
1832 SByte::SByte(Argument<SByte> argument)
1833 {
1834 storeValue(argument.value);
1835 }
1836
1837 SByte::SByte(RValue<Int> cast)
1838 {
1839 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1840
1841 storeValue(integer);
1842 }
1843
1844 SByte::SByte(RValue<Short> cast)
1845 {
1846 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1847
1848 storeValue(integer);
1849 }
1850
Nicolas Capens598f8d82016-09-26 15:09:10 -04001851 SByte::SByte(signed char x)
1852 {
1853 storeValue(Nucleus::createConstantByte(x));
1854 }
1855
1856 SByte::SByte(RValue<SByte> rhs)
1857 {
1858 storeValue(rhs.value);
1859 }
1860
1861 SByte::SByte(const SByte &rhs)
1862 {
1863 Value *value = rhs.loadValue();
1864 storeValue(value);
1865 }
1866
1867 SByte::SByte(const Reference<SByte> &rhs)
1868 {
1869 Value *value = rhs.loadValue();
1870 storeValue(value);
1871 }
1872
Nicolas Capens96d4e092016-11-18 14:22:38 -05001873 RValue<SByte> SByte::operator=(RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001874 {
1875 storeValue(rhs.value);
1876
1877 return rhs;
1878 }
1879
Nicolas Capens96d4e092016-11-18 14:22:38 -05001880 RValue<SByte> SByte::operator=(const 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
Nicolas Capens96d4e092016-11-18 14:22:38 -05001888 RValue<SByte> SByte::operator=(const Reference<SByte> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001889 {
1890 Value *value = rhs.loadValue();
1891 storeValue(value);
1892
1893 return RValue<SByte>(value);
1894 }
1895
1896 RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs)
1897 {
1898 return RValue<SByte>(Nucleus::createAdd(lhs.value, rhs.value));
1899 }
1900
1901 RValue<SByte> operator-(RValue<SByte> lhs, RValue<SByte> rhs)
1902 {
1903 return RValue<SByte>(Nucleus::createSub(lhs.value, rhs.value));
1904 }
1905
1906 RValue<SByte> operator*(RValue<SByte> lhs, RValue<SByte> rhs)
1907 {
1908 return RValue<SByte>(Nucleus::createMul(lhs.value, rhs.value));
1909 }
1910
1911 RValue<SByte> operator/(RValue<SByte> lhs, RValue<SByte> rhs)
1912 {
1913 return RValue<SByte>(Nucleus::createSDiv(lhs.value, rhs.value));
1914 }
1915
1916 RValue<SByte> operator%(RValue<SByte> lhs, RValue<SByte> rhs)
1917 {
1918 return RValue<SByte>(Nucleus::createSRem(lhs.value, rhs.value));
1919 }
1920
1921 RValue<SByte> operator&(RValue<SByte> lhs, RValue<SByte> rhs)
1922 {
1923 return RValue<SByte>(Nucleus::createAnd(lhs.value, rhs.value));
1924 }
1925
1926 RValue<SByte> operator|(RValue<SByte> lhs, RValue<SByte> rhs)
1927 {
1928 return RValue<SByte>(Nucleus::createOr(lhs.value, rhs.value));
1929 }
1930
1931 RValue<SByte> operator^(RValue<SByte> lhs, RValue<SByte> rhs)
1932 {
1933 return RValue<SByte>(Nucleus::createXor(lhs.value, rhs.value));
1934 }
1935
1936 RValue<SByte> operator<<(RValue<SByte> lhs, RValue<SByte> rhs)
1937 {
1938 return RValue<SByte>(Nucleus::createShl(lhs.value, rhs.value));
1939 }
1940
1941 RValue<SByte> operator>>(RValue<SByte> lhs, RValue<SByte> rhs)
1942 {
1943 return RValue<SByte>(Nucleus::createAShr(lhs.value, rhs.value));
1944 }
1945
Nicolas Capens96d4e092016-11-18 14:22:38 -05001946 RValue<SByte> operator+=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001947 {
1948 return lhs = lhs + rhs;
1949 }
1950
Nicolas Capens96d4e092016-11-18 14:22:38 -05001951 RValue<SByte> operator-=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001952 {
1953 return lhs = lhs - rhs;
1954 }
1955
Nicolas Capens96d4e092016-11-18 14:22:38 -05001956 RValue<SByte> operator*=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001957 {
1958 return lhs = lhs * rhs;
1959 }
1960
Nicolas Capens96d4e092016-11-18 14:22:38 -05001961 RValue<SByte> operator/=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001962 {
1963 return lhs = lhs / rhs;
1964 }
1965
Nicolas Capens96d4e092016-11-18 14:22:38 -05001966 RValue<SByte> operator%=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001967 {
1968 return lhs = lhs % rhs;
1969 }
1970
Nicolas Capens96d4e092016-11-18 14:22:38 -05001971 RValue<SByte> operator&=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001972 {
1973 return lhs = lhs & rhs;
1974 }
1975
Nicolas Capens96d4e092016-11-18 14:22:38 -05001976 RValue<SByte> operator|=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001977 {
1978 return lhs = lhs | rhs;
1979 }
1980
Nicolas Capens96d4e092016-11-18 14:22:38 -05001981 RValue<SByte> operator^=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001982 {
1983 return lhs = lhs ^ rhs;
1984 }
1985
Nicolas Capens96d4e092016-11-18 14:22:38 -05001986 RValue<SByte> operator<<=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001987 {
1988 return lhs = lhs << rhs;
1989 }
1990
Nicolas Capens96d4e092016-11-18 14:22:38 -05001991 RValue<SByte> operator>>=(SByte &lhs, RValue<SByte> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04001992 {
1993 return lhs = lhs >> rhs;
1994 }
1995
1996 RValue<SByte> operator+(RValue<SByte> val)
1997 {
1998 return val;
1999 }
2000
2001 RValue<SByte> operator-(RValue<SByte> val)
2002 {
2003 return RValue<SByte>(Nucleus::createNeg(val.value));
2004 }
2005
2006 RValue<SByte> operator~(RValue<SByte> val)
2007 {
2008 return RValue<SByte>(Nucleus::createNot(val.value));
2009 }
2010
Nicolas Capens96d4e092016-11-18 14:22:38 -05002011 RValue<SByte> operator++(SByte &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04002012 {
2013 RValue<SByte> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002014 val += SByte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002015 return res;
2016 }
2017
Nicolas Capens96d4e092016-11-18 14:22:38 -05002018 const SByte &operator++(SByte &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04002019 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002020 val += SByte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002021 return val;
2022 }
2023
Nicolas Capens96d4e092016-11-18 14:22:38 -05002024 RValue<SByte> operator--(SByte &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04002025 {
2026 RValue<SByte> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002027 val -= SByte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002028 return res;
2029 }
2030
Nicolas Capens96d4e092016-11-18 14:22:38 -05002031 const SByte &operator--(SByte &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04002032 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002033 val -= SByte(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002034 return val;
2035 }
2036
2037 RValue<Bool> operator<(RValue<SByte> lhs, RValue<SByte> rhs)
2038 {
2039 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
2040 }
2041
2042 RValue<Bool> operator<=(RValue<SByte> lhs, RValue<SByte> rhs)
2043 {
2044 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
2045 }
2046
2047 RValue<Bool> operator>(RValue<SByte> lhs, RValue<SByte> rhs)
2048 {
2049 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
2050 }
2051
2052 RValue<Bool> operator>=(RValue<SByte> lhs, RValue<SByte> rhs)
2053 {
2054 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
2055 }
2056
2057 RValue<Bool> operator!=(RValue<SByte> lhs, RValue<SByte> rhs)
2058 {
2059 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
2060 }
2061
2062 RValue<Bool> operator==(RValue<SByte> lhs, RValue<SByte> rhs)
2063 {
2064 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
2065 }
2066
2067 Type *SByte::getType()
2068 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04002069 return T(Ice::IceType_i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002070 }
2071
2072 Short::Short(Argument<Short> argument)
2073 {
2074 storeValue(argument.value);
2075 }
2076
2077 Short::Short(RValue<Int> cast)
2078 {
2079 Value *integer = Nucleus::createTrunc(cast.value, Short::getType());
2080
2081 storeValue(integer);
2082 }
2083
Nicolas Capens598f8d82016-09-26 15:09:10 -04002084 Short::Short(short x)
2085 {
2086 storeValue(Nucleus::createConstantShort(x));
2087 }
2088
2089 Short::Short(RValue<Short> rhs)
2090 {
2091 storeValue(rhs.value);
2092 }
2093
2094 Short::Short(const Short &rhs)
2095 {
2096 Value *value = rhs.loadValue();
2097 storeValue(value);
2098 }
2099
2100 Short::Short(const Reference<Short> &rhs)
2101 {
2102 Value *value = rhs.loadValue();
2103 storeValue(value);
2104 }
2105
Nicolas Capens96d4e092016-11-18 14:22:38 -05002106 RValue<Short> Short::operator=(RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002107 {
2108 storeValue(rhs.value);
2109
2110 return rhs;
2111 }
2112
Nicolas Capens96d4e092016-11-18 14:22:38 -05002113 RValue<Short> Short::operator=(const 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
Nicolas Capens96d4e092016-11-18 14:22:38 -05002121 RValue<Short> Short::operator=(const Reference<Short> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002122 {
2123 Value *value = rhs.loadValue();
2124 storeValue(value);
2125
2126 return RValue<Short>(value);
2127 }
2128
2129 RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs)
2130 {
2131 return RValue<Short>(Nucleus::createAdd(lhs.value, rhs.value));
2132 }
2133
2134 RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs)
2135 {
2136 return RValue<Short>(Nucleus::createSub(lhs.value, rhs.value));
2137 }
2138
2139 RValue<Short> operator*(RValue<Short> lhs, RValue<Short> rhs)
2140 {
2141 return RValue<Short>(Nucleus::createMul(lhs.value, rhs.value));
2142 }
2143
2144 RValue<Short> operator/(RValue<Short> lhs, RValue<Short> rhs)
2145 {
2146 return RValue<Short>(Nucleus::createSDiv(lhs.value, rhs.value));
2147 }
2148
2149 RValue<Short> operator%(RValue<Short> lhs, RValue<Short> rhs)
2150 {
2151 return RValue<Short>(Nucleus::createSRem(lhs.value, rhs.value));
2152 }
2153
2154 RValue<Short> operator&(RValue<Short> lhs, RValue<Short> rhs)
2155 {
2156 return RValue<Short>(Nucleus::createAnd(lhs.value, rhs.value));
2157 }
2158
2159 RValue<Short> operator|(RValue<Short> lhs, RValue<Short> rhs)
2160 {
2161 return RValue<Short>(Nucleus::createOr(lhs.value, rhs.value));
2162 }
2163
2164 RValue<Short> operator^(RValue<Short> lhs, RValue<Short> rhs)
2165 {
2166 return RValue<Short>(Nucleus::createXor(lhs.value, rhs.value));
2167 }
2168
2169 RValue<Short> operator<<(RValue<Short> lhs, RValue<Short> rhs)
2170 {
2171 return RValue<Short>(Nucleus::createShl(lhs.value, rhs.value));
2172 }
2173
2174 RValue<Short> operator>>(RValue<Short> lhs, RValue<Short> rhs)
2175 {
2176 return RValue<Short>(Nucleus::createAShr(lhs.value, rhs.value));
2177 }
2178
Nicolas Capens96d4e092016-11-18 14:22:38 -05002179 RValue<Short> operator+=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002180 {
2181 return lhs = lhs + rhs;
2182 }
2183
Nicolas Capens96d4e092016-11-18 14:22:38 -05002184 RValue<Short> operator-=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002185 {
2186 return lhs = lhs - rhs;
2187 }
2188
Nicolas Capens96d4e092016-11-18 14:22:38 -05002189 RValue<Short> operator*=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002190 {
2191 return lhs = lhs * rhs;
2192 }
2193
Nicolas Capens96d4e092016-11-18 14:22:38 -05002194 RValue<Short> operator/=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002195 {
2196 return lhs = lhs / rhs;
2197 }
2198
Nicolas Capens96d4e092016-11-18 14:22:38 -05002199 RValue<Short> operator%=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002200 {
2201 return lhs = lhs % rhs;
2202 }
2203
Nicolas Capens96d4e092016-11-18 14:22:38 -05002204 RValue<Short> operator&=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002205 {
2206 return lhs = lhs & rhs;
2207 }
2208
Nicolas Capens96d4e092016-11-18 14:22:38 -05002209 RValue<Short> operator|=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002210 {
2211 return lhs = lhs | rhs;
2212 }
2213
Nicolas Capens96d4e092016-11-18 14:22:38 -05002214 RValue<Short> operator^=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002215 {
2216 return lhs = lhs ^ rhs;
2217 }
2218
Nicolas Capens96d4e092016-11-18 14:22:38 -05002219 RValue<Short> operator<<=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002220 {
2221 return lhs = lhs << rhs;
2222 }
2223
Nicolas Capens96d4e092016-11-18 14:22:38 -05002224 RValue<Short> operator>>=(Short &lhs, RValue<Short> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002225 {
2226 return lhs = lhs >> rhs;
2227 }
2228
2229 RValue<Short> operator+(RValue<Short> val)
2230 {
2231 return val;
2232 }
2233
2234 RValue<Short> operator-(RValue<Short> val)
2235 {
2236 return RValue<Short>(Nucleus::createNeg(val.value));
2237 }
2238
2239 RValue<Short> operator~(RValue<Short> val)
2240 {
2241 return RValue<Short>(Nucleus::createNot(val.value));
2242 }
2243
Nicolas Capens96d4e092016-11-18 14:22:38 -05002244 RValue<Short> operator++(Short &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04002245 {
2246 RValue<Short> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002247 val += Short(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002248 return res;
2249 }
2250
Nicolas Capens96d4e092016-11-18 14:22:38 -05002251 const Short &operator++(Short &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04002252 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002253 val += Short(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002254 return val;
2255 }
2256
Nicolas Capens96d4e092016-11-18 14:22:38 -05002257 RValue<Short> operator--(Short &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04002258 {
2259 RValue<Short> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002260 val -= Short(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002261 return res;
2262 }
2263
Nicolas Capens96d4e092016-11-18 14:22:38 -05002264 const Short &operator--(Short &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04002265 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002266 val -= Short(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002267 return val;
2268 }
2269
2270 RValue<Bool> operator<(RValue<Short> lhs, RValue<Short> rhs)
2271 {
2272 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
2273 }
2274
2275 RValue<Bool> operator<=(RValue<Short> lhs, RValue<Short> rhs)
2276 {
2277 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
2278 }
2279
2280 RValue<Bool> operator>(RValue<Short> lhs, RValue<Short> rhs)
2281 {
2282 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
2283 }
2284
2285 RValue<Bool> operator>=(RValue<Short> lhs, RValue<Short> rhs)
2286 {
2287 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
2288 }
2289
2290 RValue<Bool> operator!=(RValue<Short> lhs, RValue<Short> rhs)
2291 {
2292 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
2293 }
2294
2295 RValue<Bool> operator==(RValue<Short> lhs, RValue<Short> rhs)
2296 {
2297 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
2298 }
2299
2300 Type *Short::getType()
2301 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04002302 return T(Ice::IceType_i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002303 }
2304
2305 UShort::UShort(Argument<UShort> argument)
2306 {
2307 storeValue(argument.value);
2308 }
2309
2310 UShort::UShort(RValue<UInt> cast)
2311 {
2312 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
2313
2314 storeValue(integer);
2315 }
2316
2317 UShort::UShort(RValue<Int> cast)
2318 {
2319 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
2320
2321 storeValue(integer);
2322 }
2323
Nicolas Capens598f8d82016-09-26 15:09:10 -04002324 UShort::UShort(unsigned short x)
2325 {
2326 storeValue(Nucleus::createConstantShort(x));
2327 }
2328
2329 UShort::UShort(RValue<UShort> rhs)
2330 {
2331 storeValue(rhs.value);
2332 }
2333
2334 UShort::UShort(const UShort &rhs)
2335 {
2336 Value *value = rhs.loadValue();
2337 storeValue(value);
2338 }
2339
2340 UShort::UShort(const Reference<UShort> &rhs)
2341 {
2342 Value *value = rhs.loadValue();
2343 storeValue(value);
2344 }
2345
Nicolas Capens96d4e092016-11-18 14:22:38 -05002346 RValue<UShort> UShort::operator=(RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002347 {
2348 storeValue(rhs.value);
2349
2350 return rhs;
2351 }
2352
Nicolas Capens96d4e092016-11-18 14:22:38 -05002353 RValue<UShort> UShort::operator=(const 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
Nicolas Capens96d4e092016-11-18 14:22:38 -05002361 RValue<UShort> UShort::operator=(const Reference<UShort> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002362 {
2363 Value *value = rhs.loadValue();
2364 storeValue(value);
2365
2366 return RValue<UShort>(value);
2367 }
2368
2369 RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs)
2370 {
2371 return RValue<UShort>(Nucleus::createAdd(lhs.value, rhs.value));
2372 }
2373
2374 RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs)
2375 {
2376 return RValue<UShort>(Nucleus::createSub(lhs.value, rhs.value));
2377 }
2378
2379 RValue<UShort> operator*(RValue<UShort> lhs, RValue<UShort> rhs)
2380 {
2381 return RValue<UShort>(Nucleus::createMul(lhs.value, rhs.value));
2382 }
2383
2384 RValue<UShort> operator/(RValue<UShort> lhs, RValue<UShort> rhs)
2385 {
2386 return RValue<UShort>(Nucleus::createUDiv(lhs.value, rhs.value));
2387 }
2388
2389 RValue<UShort> operator%(RValue<UShort> lhs, RValue<UShort> rhs)
2390 {
2391 return RValue<UShort>(Nucleus::createURem(lhs.value, rhs.value));
2392 }
2393
2394 RValue<UShort> operator&(RValue<UShort> lhs, RValue<UShort> rhs)
2395 {
2396 return RValue<UShort>(Nucleus::createAnd(lhs.value, rhs.value));
2397 }
2398
2399 RValue<UShort> operator|(RValue<UShort> lhs, RValue<UShort> rhs)
2400 {
2401 return RValue<UShort>(Nucleus::createOr(lhs.value, rhs.value));
2402 }
2403
2404 RValue<UShort> operator^(RValue<UShort> lhs, RValue<UShort> rhs)
2405 {
2406 return RValue<UShort>(Nucleus::createXor(lhs.value, rhs.value));
2407 }
2408
2409 RValue<UShort> operator<<(RValue<UShort> lhs, RValue<UShort> rhs)
2410 {
2411 return RValue<UShort>(Nucleus::createShl(lhs.value, rhs.value));
2412 }
2413
2414 RValue<UShort> operator>>(RValue<UShort> lhs, RValue<UShort> rhs)
2415 {
2416 return RValue<UShort>(Nucleus::createLShr(lhs.value, rhs.value));
2417 }
2418
Nicolas Capens96d4e092016-11-18 14:22:38 -05002419 RValue<UShort> operator+=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002420 {
2421 return lhs = lhs + rhs;
2422 }
2423
Nicolas Capens96d4e092016-11-18 14:22:38 -05002424 RValue<UShort> operator-=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002425 {
2426 return lhs = lhs - rhs;
2427 }
2428
Nicolas Capens96d4e092016-11-18 14:22:38 -05002429 RValue<UShort> operator*=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002430 {
2431 return lhs = lhs * rhs;
2432 }
2433
Nicolas Capens96d4e092016-11-18 14:22:38 -05002434 RValue<UShort> operator/=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002435 {
2436 return lhs = lhs / rhs;
2437 }
2438
Nicolas Capens96d4e092016-11-18 14:22:38 -05002439 RValue<UShort> operator%=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002440 {
2441 return lhs = lhs % rhs;
2442 }
2443
Nicolas Capens96d4e092016-11-18 14:22:38 -05002444 RValue<UShort> operator&=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002445 {
2446 return lhs = lhs & rhs;
2447 }
2448
Nicolas Capens96d4e092016-11-18 14:22:38 -05002449 RValue<UShort> operator|=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002450 {
2451 return lhs = lhs | rhs;
2452 }
2453
Nicolas Capens96d4e092016-11-18 14:22:38 -05002454 RValue<UShort> operator^=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002455 {
2456 return lhs = lhs ^ rhs;
2457 }
2458
Nicolas Capens96d4e092016-11-18 14:22:38 -05002459 RValue<UShort> operator<<=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002460 {
2461 return lhs = lhs << rhs;
2462 }
2463
Nicolas Capens96d4e092016-11-18 14:22:38 -05002464 RValue<UShort> operator>>=(UShort &lhs, RValue<UShort> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002465 {
2466 return lhs = lhs >> rhs;
2467 }
2468
2469 RValue<UShort> operator+(RValue<UShort> val)
2470 {
2471 return val;
2472 }
2473
2474 RValue<UShort> operator-(RValue<UShort> val)
2475 {
2476 return RValue<UShort>(Nucleus::createNeg(val.value));
2477 }
2478
2479 RValue<UShort> operator~(RValue<UShort> val)
2480 {
2481 return RValue<UShort>(Nucleus::createNot(val.value));
2482 }
2483
Nicolas Capens96d4e092016-11-18 14:22:38 -05002484 RValue<UShort> operator++(UShort &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04002485 {
2486 RValue<UShort> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002487 val += UShort(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002488 return res;
2489 }
2490
Nicolas Capens96d4e092016-11-18 14:22:38 -05002491 const UShort &operator++(UShort &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04002492 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002493 val += UShort(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002494 return val;
2495 }
2496
Nicolas Capens96d4e092016-11-18 14:22:38 -05002497 RValue<UShort> operator--(UShort &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04002498 {
2499 RValue<UShort> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05002500 val -= UShort(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002501 return res;
2502 }
2503
Nicolas Capens96d4e092016-11-18 14:22:38 -05002504 const UShort &operator--(UShort &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04002505 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002506 val -= UShort(1);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002507 return val;
2508 }
2509
2510 RValue<Bool> operator<(RValue<UShort> lhs, RValue<UShort> rhs)
2511 {
2512 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
2513 }
2514
2515 RValue<Bool> operator<=(RValue<UShort> lhs, RValue<UShort> rhs)
2516 {
2517 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
2518 }
2519
2520 RValue<Bool> operator>(RValue<UShort> lhs, RValue<UShort> rhs)
2521 {
2522 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
2523 }
2524
2525 RValue<Bool> operator>=(RValue<UShort> lhs, RValue<UShort> rhs)
2526 {
2527 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
2528 }
2529
2530 RValue<Bool> operator!=(RValue<UShort> lhs, RValue<UShort> rhs)
2531 {
2532 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
2533 }
2534
2535 RValue<Bool> operator==(RValue<UShort> lhs, RValue<UShort> rhs)
2536 {
2537 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
2538 }
2539
2540 Type *UShort::getType()
2541 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04002542 return T(Ice::IceType_i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002543 }
2544
Nicolas Capens16b5f152016-10-13 13:39:01 -04002545 Byte4::Byte4(RValue<Byte8> cast)
2546 {
Nicolas Capens16b5f152016-10-13 13:39:01 -04002547 storeValue(Nucleus::createBitCast(cast.value, getType()));
2548 }
2549
2550 Byte4::Byte4(const Reference<Byte4> &rhs)
2551 {
Nicolas Capensd1229402016-11-07 16:05:22 -05002552 Value *value = rhs.loadValue();
2553 storeValue(value);
Nicolas Capens16b5f152016-10-13 13:39:01 -04002554 }
2555
Nicolas Capens598f8d82016-09-26 15:09:10 -04002556 Type *Byte4::getType()
2557 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04002558 return T(Type_v4i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002559 }
2560
2561 Type *SByte4::getType()
2562 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04002563 return T(Type_v4i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002564 }
2565
Nicolas Capens598f8d82016-09-26 15:09:10 -04002566 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)
2567 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04002568 int64_t constantVector[8] = {x0, x1, x2, x3, x4, x5, x6, x7};
2569 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002570 }
2571
2572 Byte8::Byte8(RValue<Byte8> rhs)
2573 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002574 storeValue(rhs.value);
2575 }
2576
2577 Byte8::Byte8(const Byte8 &rhs)
2578 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002579 Value *value = rhs.loadValue();
2580 storeValue(value);
2581 }
2582
2583 Byte8::Byte8(const Reference<Byte8> &rhs)
2584 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002585 Value *value = rhs.loadValue();
2586 storeValue(value);
2587 }
2588
Nicolas Capens96d4e092016-11-18 14:22:38 -05002589 RValue<Byte8> Byte8::operator=(RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002590 {
2591 storeValue(rhs.value);
2592
2593 return rhs;
2594 }
2595
Nicolas Capens96d4e092016-11-18 14:22:38 -05002596 RValue<Byte8> Byte8::operator=(const 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
Nicolas Capens96d4e092016-11-18 14:22:38 -05002604 RValue<Byte8> Byte8::operator=(const Reference<Byte8> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002605 {
2606 Value *value = rhs.loadValue();
2607 storeValue(value);
2608
2609 return RValue<Byte8>(value);
2610 }
2611
2612 RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs)
2613 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002614 return RValue<Byte8>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002615 }
2616
2617 RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs)
2618 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002619 return RValue<Byte8>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002620 }
2621
2622// RValue<Byte8> operator*(RValue<Byte8> lhs, RValue<Byte8> rhs)
2623// {
2624// return RValue<Byte8>(Nucleus::createMul(lhs.value, rhs.value));
2625// }
2626
2627// RValue<Byte8> operator/(RValue<Byte8> lhs, RValue<Byte8> rhs)
2628// {
2629// return RValue<Byte8>(Nucleus::createUDiv(lhs.value, rhs.value));
2630// }
2631
2632// RValue<Byte8> operator%(RValue<Byte8> lhs, RValue<Byte8> rhs)
2633// {
2634// return RValue<Byte8>(Nucleus::createURem(lhs.value, rhs.value));
2635// }
2636
2637 RValue<Byte8> operator&(RValue<Byte8> lhs, RValue<Byte8> rhs)
2638 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002639 return RValue<Byte8>(Nucleus::createAnd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002640 }
2641
2642 RValue<Byte8> operator|(RValue<Byte8> lhs, RValue<Byte8> rhs)
2643 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002644 return RValue<Byte8>(Nucleus::createOr(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002645 }
2646
2647 RValue<Byte8> operator^(RValue<Byte8> lhs, RValue<Byte8> rhs)
2648 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002649 return RValue<Byte8>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002650 }
2651
2652// RValue<Byte8> operator<<(RValue<Byte8> lhs, unsigned char rhs)
2653// {
Nicolas Capens15060bb2016-12-05 22:17:19 -05002654// return RValue<Byte8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002655// }
2656
2657// RValue<Byte8> operator>>(RValue<Byte8> lhs, unsigned char rhs)
2658// {
Nicolas Capens15060bb2016-12-05 22:17:19 -05002659// return RValue<Byte8>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002660// }
2661
Nicolas Capens96d4e092016-11-18 14:22:38 -05002662 RValue<Byte8> operator+=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002663 {
2664 return lhs = lhs + rhs;
2665 }
2666
Nicolas Capens96d4e092016-11-18 14:22:38 -05002667 RValue<Byte8> operator-=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002668 {
2669 return lhs = lhs - rhs;
2670 }
2671
Nicolas Capens96d4e092016-11-18 14:22:38 -05002672// RValue<Byte8> operator*=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002673// {
2674// return lhs = lhs * rhs;
2675// }
2676
Nicolas Capens96d4e092016-11-18 14:22:38 -05002677// RValue<Byte8> operator/=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002678// {
2679// return lhs = lhs / rhs;
2680// }
2681
Nicolas Capens96d4e092016-11-18 14:22:38 -05002682// RValue<Byte8> operator%=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002683// {
2684// return lhs = lhs % rhs;
2685// }
2686
Nicolas Capens96d4e092016-11-18 14:22:38 -05002687 RValue<Byte8> operator&=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002688 {
2689 return lhs = lhs & rhs;
2690 }
2691
Nicolas Capens96d4e092016-11-18 14:22:38 -05002692 RValue<Byte8> operator|=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002693 {
2694 return lhs = lhs | rhs;
2695 }
2696
Nicolas Capens96d4e092016-11-18 14:22:38 -05002697 RValue<Byte8> operator^=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002698 {
2699 return lhs = lhs ^ rhs;
2700 }
2701
Nicolas Capens96d4e092016-11-18 14:22:38 -05002702// RValue<Byte8> operator<<=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002703// {
2704// return lhs = lhs << rhs;
2705// }
2706
Nicolas Capens96d4e092016-11-18 14:22:38 -05002707// RValue<Byte8> operator>>=(Byte8 &lhs, RValue<Byte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002708// {
2709// return lhs = lhs >> rhs;
2710// }
2711
2712// RValue<Byte8> operator+(RValue<Byte8> val)
2713// {
2714// return val;
2715// }
2716
2717// RValue<Byte8> operator-(RValue<Byte8> val)
2718// {
2719// return RValue<Byte8>(Nucleus::createNeg(val.value));
2720// }
2721
2722 RValue<Byte8> operator~(RValue<Byte8> val)
2723 {
2724 return RValue<Byte8>(Nucleus::createNot(val.value));
2725 }
2726
Nicolas Capensd6cacad2017-07-25 15:32:12 -04002727 RValue<Byte> Extract(RValue<Byte8> val, int i)
2728 {
2729 return RValue<Byte>(Nucleus::createExtractElement(val.value, Byte::getType(), i));
2730 }
2731
2732 RValue<Byte8> Insert(RValue<Byte8> val, RValue<Byte> element, int i)
2733 {
2734 return RValue<Byte8>(Nucleus::createInsertElement(val.value, element.value, i));
2735 }
2736
Nicolas Capens33438a62017-09-27 11:47:35 -04002737 RValue<Byte> SaturateUnsigned(RValue<Short> x)
Nicolas Capens98436732017-07-25 15:32:12 -04002738 {
Nicolas Capens7f301812017-10-02 17:32:34 -04002739 return Byte(IfThenElse(Int(x) > 0xFF, Int(0xFF), IfThenElse(Int(x) < 0, Int(0), Int(x))));
Nicolas Capens98436732017-07-25 15:32:12 -04002740 }
2741
Nicolas Capens598f8d82016-09-26 15:09:10 -04002742 RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y)
2743 {
Nicolas Capens98436732017-07-25 15:32:12 -04002744 if(emulateIntrinsics)
2745 {
2746 Byte8 result;
Nicolas Capens33438a62017-09-27 11:47:35 -04002747 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 0)) + Int(Extract(y, 0)))), 0);
2748 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 1)) + Int(Extract(y, 1)))), 1);
2749 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 2)) + Int(Extract(y, 2)))), 2);
2750 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 3)) + Int(Extract(y, 3)))), 3);
2751 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 4)) + Int(Extract(y, 4)))), 4);
2752 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 5)) + Int(Extract(y, 5)))), 5);
2753 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 6)) + Int(Extract(y, 6)))), 6);
2754 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 7)) + Int(Extract(y, 7)))), 7);
Nicolas Capensc71bed22016-11-07 22:25:14 -05002755
Nicolas Capens98436732017-07-25 15:32:12 -04002756 return result;
2757 }
2758 else
2759 {
2760 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
2761 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2762 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2763 auto paddusb = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
2764 paddusb->addArg(x.value);
2765 paddusb->addArg(y.value);
2766 ::basicBlock->appendInst(paddusb);
2767
2768 return RValue<Byte8>(V(result));
2769 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04002770 }
2771
2772 RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y)
2773 {
Nicolas Capens98436732017-07-25 15:32:12 -04002774 if(emulateIntrinsics)
2775 {
2776 Byte8 result;
Nicolas Capens33438a62017-09-27 11:47:35 -04002777 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 0)) - Int(Extract(y, 0)))), 0);
2778 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 1)) - Int(Extract(y, 1)))), 1);
2779 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 2)) - Int(Extract(y, 2)))), 2);
2780 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 3)) - Int(Extract(y, 3)))), 3);
2781 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 4)) - Int(Extract(y, 4)))), 4);
2782 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 5)) - Int(Extract(y, 5)))), 5);
2783 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 6)) - Int(Extract(y, 6)))), 6);
2784 result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 7)) - Int(Extract(y, 7)))), 7);
Nicolas Capensc71bed22016-11-07 22:25:14 -05002785
Nicolas Capens98436732017-07-25 15:32:12 -04002786 return result;
2787 }
2788 else
2789 {
2790 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
2791 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2792 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2793 auto psubusw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
2794 psubusw->addArg(x.value);
2795 psubusw->addArg(y.value);
2796 ::basicBlock->appendInst(psubusw);
2797
2798 return RValue<Byte8>(V(result));
2799 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04002800 }
2801
2802 RValue<Short4> Unpack(RValue<Byte4> x)
2803 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04002804 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 -04002805 return As<Short4>(Nucleus::createShuffleVector(x.value, x.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002806 }
2807
Nicolas Capens411273e2017-01-26 15:13:36 -08002808 RValue<Short4> Unpack(RValue<Byte4> x, RValue<Byte4> y)
2809 {
2810 return UnpackLow(As<Byte8>(x), As<Byte8>(y));
2811 }
2812
Nicolas Capens598f8d82016-09-26 15:09:10 -04002813 RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y)
2814 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04002815 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 -04002816 return As<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002817 }
2818
2819 RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y)
2820 {
Nicolas Capens20e22c42016-10-25 17:32:37 -04002821 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
2822 auto lowHigh = RValue<Byte16>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
2823 return As<Short4>(Swizzle(As<Int4>(lowHigh), 0xEE));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002824 }
2825
Nicolas Capensd6cacad2017-07-25 15:32:12 -04002826 RValue<SByte> Extract(RValue<SByte8> val, int i)
2827 {
2828 return RValue<SByte>(Nucleus::createExtractElement(val.value, SByte::getType(), i));
2829 }
2830
2831 RValue<SByte8> Insert(RValue<SByte8> val, RValue<SByte> element, int i)
2832 {
2833 return RValue<SByte8>(Nucleus::createInsertElement(val.value, element.value, i));
2834 }
2835
2836 RValue<SByte8> operator>>(RValue<SByte8> lhs, unsigned char rhs)
2837 {
2838 if(emulateIntrinsics)
2839 {
2840 SByte8 result;
2841 result = Insert(result, Extract(lhs, 0) >> SByte(rhs), 0);
2842 result = Insert(result, Extract(lhs, 1) >> SByte(rhs), 1);
2843 result = Insert(result, Extract(lhs, 2) >> SByte(rhs), 2);
2844 result = Insert(result, Extract(lhs, 3) >> SByte(rhs), 3);
2845 result = Insert(result, Extract(lhs, 4) >> SByte(rhs), 4);
2846 result = Insert(result, Extract(lhs, 5) >> SByte(rhs), 5);
2847 result = Insert(result, Extract(lhs, 6) >> SByte(rhs), 6);
2848 result = Insert(result, Extract(lhs, 7) >> SByte(rhs), 7);
2849
2850 return result;
2851 }
2852 else
2853 {
2854 #if defined(__i386__) || defined(__x86_64__)
2855 // SSE2 doesn't support byte vector shifts, so shift as shorts and recombine.
Alexis Hetue18c5302017-08-04 11:48:17 -04002856 RValue<Short4> hi = (As<Short4>(lhs) >> rhs) & Short4(0xFF00u);
Nicolas Capensd6cacad2017-07-25 15:32:12 -04002857 RValue<Short4> lo = As<Short4>(As<UShort4>((As<Short4>(lhs) << 8) >> rhs) >> 8);
2858
2859 return As<SByte8>(hi | lo);
2860 #else
2861 return RValue<SByte8>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
2862 #endif
2863 }
2864 }
2865
Nicolas Capens598f8d82016-09-26 15:09:10 -04002866 RValue<Int> SignMask(RValue<Byte8> x)
2867 {
Nicolas Capens091f3502017-10-03 14:56:49 -04002868 if(emulateIntrinsics || CPUID::ARM)
Nicolas Capensd6cacad2017-07-25 15:32:12 -04002869 {
2870 Byte8 xx = As<Byte8>(As<SByte8>(x) >> 7) & Byte8(0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80);
2871 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));
2872 }
2873 else
2874 {
2875 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
2876 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
2877 auto target = ::context->getConstantUndef(Ice::IceType_i32);
2878 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
2879 movmsk->addArg(x.value);
2880 ::basicBlock->appendInst(movmsk);
Nicolas Capensc71bed22016-11-07 22:25:14 -05002881
Nicolas Capens0f70a7f2017-07-26 13:50:04 -04002882 return RValue<Int>(V(result)) & 0xFF;
Nicolas Capensd6cacad2017-07-25 15:32:12 -04002883 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04002884 }
2885
2886// RValue<Byte8> CmpGT(RValue<Byte8> x, RValue<Byte8> y)
2887// {
Nicolas Capens2f970b62016-11-08 14:28:59 -05002888// return RValue<Byte8>(createIntCompare(Ice::InstIcmp::Ugt, x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002889// }
2890
2891 RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y)
2892 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05002893 return RValue<Byte8>(Nucleus::createICmpEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002894 }
2895
2896 Type *Byte8::getType()
2897 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04002898 return T(Type_v8i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04002899 }
2900
Nicolas Capens598f8d82016-09-26 15:09:10 -04002901 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)
2902 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04002903 int64_t constantVector[8] = { x0, x1, x2, x3, x4, x5, x6, x7 };
2904 Value *vector = V(Nucleus::createConstantVector(constantVector, getType()));
2905
2906 storeValue(Nucleus::createBitCast(vector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002907 }
2908
Nicolas Capens598f8d82016-09-26 15:09:10 -04002909 SByte8::SByte8(RValue<SByte8> rhs)
2910 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002911 storeValue(rhs.value);
2912 }
2913
2914 SByte8::SByte8(const SByte8 &rhs)
2915 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002916 Value *value = rhs.loadValue();
2917 storeValue(value);
2918 }
2919
2920 SByte8::SByte8(const Reference<SByte8> &rhs)
2921 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04002922 Value *value = rhs.loadValue();
2923 storeValue(value);
2924 }
2925
Nicolas Capens96d4e092016-11-18 14:22:38 -05002926 RValue<SByte8> SByte8::operator=(RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002927 {
2928 storeValue(rhs.value);
2929
2930 return rhs;
2931 }
2932
Nicolas Capens96d4e092016-11-18 14:22:38 -05002933 RValue<SByte8> SByte8::operator=(const 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
Nicolas Capens96d4e092016-11-18 14:22:38 -05002941 RValue<SByte8> SByte8::operator=(const Reference<SByte8> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04002942 {
2943 Value *value = rhs.loadValue();
2944 storeValue(value);
2945
2946 return RValue<SByte8>(value);
2947 }
2948
2949 RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs)
2950 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002951 return RValue<SByte8>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002952 }
2953
2954 RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs)
2955 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04002956 return RValue<SByte8>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002957 }
2958
2959// RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs)
2960// {
2961// return RValue<SByte8>(Nucleus::createMul(lhs.value, rhs.value));
2962// }
2963
2964// RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs)
2965// {
2966// return RValue<SByte8>(Nucleus::createSDiv(lhs.value, rhs.value));
2967// }
2968
2969// RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs)
2970// {
2971// return RValue<SByte8>(Nucleus::createSRem(lhs.value, rhs.value));
2972// }
2973
2974 RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs)
2975 {
2976 return RValue<SByte8>(Nucleus::createAnd(lhs.value, rhs.value));
2977 }
2978
2979 RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs)
2980 {
2981 return RValue<SByte8>(Nucleus::createOr(lhs.value, rhs.value));
2982 }
2983
2984 RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs)
2985 {
2986 return RValue<SByte8>(Nucleus::createXor(lhs.value, rhs.value));
2987 }
2988
2989// RValue<SByte8> operator<<(RValue<SByte8> lhs, unsigned char rhs)
2990// {
Nicolas Capens15060bb2016-12-05 22:17:19 -05002991// return RValue<SByte8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002992// }
2993
2994// RValue<SByte8> operator>>(RValue<SByte8> lhs, unsigned char rhs)
2995// {
Nicolas Capens15060bb2016-12-05 22:17:19 -05002996// return RValue<SByte8>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
Nicolas Capens598f8d82016-09-26 15:09:10 -04002997// }
2998
Nicolas Capens96d4e092016-11-18 14:22:38 -05002999 RValue<SByte8> operator+=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003000 {
3001 return lhs = lhs + rhs;
3002 }
3003
Nicolas Capens96d4e092016-11-18 14:22:38 -05003004 RValue<SByte8> operator-=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003005 {
3006 return lhs = lhs - rhs;
3007 }
3008
Nicolas Capens96d4e092016-11-18 14:22:38 -05003009// RValue<SByte8> operator*=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003010// {
3011// return lhs = lhs * rhs;
3012// }
3013
Nicolas Capens96d4e092016-11-18 14:22:38 -05003014// RValue<SByte8> operator/=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003015// {
3016// return lhs = lhs / rhs;
3017// }
3018
Nicolas Capens96d4e092016-11-18 14:22:38 -05003019// RValue<SByte8> operator%=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003020// {
3021// return lhs = lhs % rhs;
3022// }
3023
Nicolas Capens96d4e092016-11-18 14:22:38 -05003024 RValue<SByte8> operator&=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003025 {
3026 return lhs = lhs & rhs;
3027 }
3028
Nicolas Capens96d4e092016-11-18 14:22:38 -05003029 RValue<SByte8> operator|=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003030 {
3031 return lhs = lhs | rhs;
3032 }
3033
Nicolas Capens96d4e092016-11-18 14:22:38 -05003034 RValue<SByte8> operator^=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003035 {
3036 return lhs = lhs ^ rhs;
3037 }
3038
Nicolas Capens96d4e092016-11-18 14:22:38 -05003039// RValue<SByte8> operator<<=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003040// {
3041// return lhs = lhs << rhs;
3042// }
3043
Nicolas Capens96d4e092016-11-18 14:22:38 -05003044// RValue<SByte8> operator>>=(SByte8 &lhs, RValue<SByte8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003045// {
3046// return lhs = lhs >> rhs;
3047// }
3048
3049// RValue<SByte8> operator+(RValue<SByte8> val)
3050// {
3051// return val;
3052// }
3053
3054// RValue<SByte8> operator-(RValue<SByte8> val)
3055// {
3056// return RValue<SByte8>(Nucleus::createNeg(val.value));
3057// }
3058
3059 RValue<SByte8> operator~(RValue<SByte8> val)
3060 {
3061 return RValue<SByte8>(Nucleus::createNot(val.value));
3062 }
3063
Nicolas Capens33438a62017-09-27 11:47:35 -04003064 RValue<SByte> SaturateSigned(RValue<Short> x)
Nicolas Capens98436732017-07-25 15:32:12 -04003065 {
3066 return SByte(IfThenElse(Int(x) > 0x7F, Int(0x7F), IfThenElse(Int(x) < -0x80, Int(0x80), Int(x))));
3067 }
3068
Nicolas Capens598f8d82016-09-26 15:09:10 -04003069 RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y)
3070 {
Nicolas Capens98436732017-07-25 15:32:12 -04003071 if(emulateIntrinsics)
3072 {
3073 SByte8 result;
Nicolas Capens33438a62017-09-27 11:47:35 -04003074 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 0)) + Int(Extract(y, 0)))), 0);
3075 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 1)) + Int(Extract(y, 1)))), 1);
3076 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 2)) + Int(Extract(y, 2)))), 2);
3077 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 3)) + Int(Extract(y, 3)))), 3);
3078 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 4)) + Int(Extract(y, 4)))), 4);
3079 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 5)) + Int(Extract(y, 5)))), 5);
3080 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 6)) + Int(Extract(y, 6)))), 6);
3081 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 7)) + Int(Extract(y, 7)))), 7);
Nicolas Capensc71bed22016-11-07 22:25:14 -05003082
Nicolas Capens98436732017-07-25 15:32:12 -04003083 return result;
3084 }
3085 else
3086 {
3087 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
3088 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3089 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3090 auto paddsb = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3091 paddsb->addArg(x.value);
3092 paddsb->addArg(y.value);
3093 ::basicBlock->appendInst(paddsb);
3094
3095 return RValue<SByte8>(V(result));
3096 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003097 }
3098
3099 RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y)
3100 {
Nicolas Capens98436732017-07-25 15:32:12 -04003101 if(emulateIntrinsics)
3102 {
3103 SByte8 result;
Nicolas Capens33438a62017-09-27 11:47:35 -04003104 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 0)) - Int(Extract(y, 0)))), 0);
3105 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 1)) - Int(Extract(y, 1)))), 1);
3106 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 2)) - Int(Extract(y, 2)))), 2);
3107 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 3)) - Int(Extract(y, 3)))), 3);
3108 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 4)) - Int(Extract(y, 4)))), 4);
3109 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 5)) - Int(Extract(y, 5)))), 5);
3110 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 6)) - Int(Extract(y, 6)))), 6);
3111 result = Insert(result, SaturateSigned(Short(Int(Extract(x, 7)) - Int(Extract(y, 7)))), 7);
Nicolas Capensc71bed22016-11-07 22:25:14 -05003112
Nicolas Capens98436732017-07-25 15:32:12 -04003113 return result;
3114 }
3115 else
3116 {
3117 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
3118 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3119 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3120 auto psubsb = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3121 psubsb->addArg(x.value);
3122 psubsb->addArg(y.value);
3123 ::basicBlock->appendInst(psubsb);
3124
3125 return RValue<SByte8>(V(result));
3126 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003127 }
3128
3129 RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y)
3130 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04003131 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 -04003132 return As<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003133 }
3134
3135 RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y)
3136 {
Nicolas Capens20e22c42016-10-25 17:32:37 -04003137 int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}; // Real type is v16i8
3138 auto lowHigh = RValue<Byte16>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
3139 return As<Short4>(Swizzle(As<Int4>(lowHigh), 0xEE));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003140 }
3141
3142 RValue<Int> SignMask(RValue<SByte8> x)
3143 {
Nicolas Capens091f3502017-10-03 14:56:49 -04003144 if(emulateIntrinsics || CPUID::ARM)
Nicolas Capensd6cacad2017-07-25 15:32:12 -04003145 {
3146 SByte8 xx = (x >> 7) & SByte8(0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80);
3147 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));
3148 }
3149 else
3150 {
3151 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
3152 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3153 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3154 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
3155 movmsk->addArg(x.value);
3156 ::basicBlock->appendInst(movmsk);
Nicolas Capensf2cb9df2016-10-21 17:26:13 -04003157
Nicolas Capens0f70a7f2017-07-26 13:50:04 -04003158 return RValue<Int>(V(result)) & 0xFF;
Nicolas Capensd6cacad2017-07-25 15:32:12 -04003159 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003160 }
3161
3162 RValue<Byte8> CmpGT(RValue<SByte8> x, RValue<SByte8> y)
3163 {
Nicolas Capens2f970b62016-11-08 14:28:59 -05003164 return RValue<Byte8>(createIntCompare(Ice::InstIcmp::Sgt, x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003165 }
3166
3167 RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y)
3168 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05003169 return RValue<Byte8>(Nucleus::createICmpEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003170 }
3171
3172 Type *SByte8::getType()
3173 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04003174 return T(Type_v8i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003175 }
3176
3177 Byte16::Byte16(RValue<Byte16> rhs)
3178 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003179 storeValue(rhs.value);
3180 }
3181
3182 Byte16::Byte16(const Byte16 &rhs)
3183 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003184 Value *value = rhs.loadValue();
3185 storeValue(value);
3186 }
3187
3188 Byte16::Byte16(const Reference<Byte16> &rhs)
3189 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003190 Value *value = rhs.loadValue();
3191 storeValue(value);
3192 }
3193
Nicolas Capens96d4e092016-11-18 14:22:38 -05003194 RValue<Byte16> Byte16::operator=(RValue<Byte16> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003195 {
3196 storeValue(rhs.value);
3197
3198 return rhs;
3199 }
3200
Nicolas Capens96d4e092016-11-18 14:22:38 -05003201 RValue<Byte16> Byte16::operator=(const 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
Nicolas Capens96d4e092016-11-18 14:22:38 -05003209 RValue<Byte16> Byte16::operator=(const Reference<Byte16> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003210 {
3211 Value *value = rhs.loadValue();
3212 storeValue(value);
3213
3214 return RValue<Byte16>(value);
3215 }
3216
3217 Type *Byte16::getType()
3218 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04003219 return T(Ice::IceType_v16i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003220 }
3221
3222 Type *SByte16::getType()
3223 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04003224 return T(Ice::IceType_v16i8);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003225 }
3226
Nicolas Capens16b5f152016-10-13 13:39:01 -04003227 Short2::Short2(RValue<Short4> cast)
3228 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05003229 storeValue(Nucleus::createBitCast(cast.value, getType()));
Nicolas Capens16b5f152016-10-13 13:39:01 -04003230 }
3231
3232 Type *Short2::getType()
3233 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04003234 return T(Type_v2i16);
Nicolas Capens16b5f152016-10-13 13:39:01 -04003235 }
3236
3237 UShort2::UShort2(RValue<UShort4> cast)
3238 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05003239 storeValue(Nucleus::createBitCast(cast.value, getType()));
Nicolas Capens16b5f152016-10-13 13:39:01 -04003240 }
3241
3242 Type *UShort2::getType()
3243 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04003244 return T(Type_v2i16);
Nicolas Capens16b5f152016-10-13 13:39:01 -04003245 }
3246
Nicolas Capens598f8d82016-09-26 15:09:10 -04003247 Short4::Short4(RValue<Int> cast)
3248 {
Nicolas Capensd4227962016-11-09 14:24:25 -05003249 Value *vector = loadValue();
Nicolas Capensbf22bbf2017-01-13 17:37:45 -05003250 Value *element = Nucleus::createTrunc(cast.value, Short::getType());
3251 Value *insert = Nucleus::createInsertElement(vector, element, 0);
Nicolas Capensd4227962016-11-09 14:24:25 -05003252 Value *swizzle = Swizzle(RValue<Short4>(insert), 0x00).value;
Nicolas Capens598f8d82016-09-26 15:09:10 -04003253
3254 storeValue(swizzle);
3255 }
3256
3257 Short4::Short4(RValue<Int4> cast)
3258 {
Nicolas Capensf8beb4b2017-01-27 02:55:44 -08003259 int select[8] = {0, 2, 4, 6, 0, 2, 4, 6};
3260 Value *short8 = Nucleus::createBitCast(cast.value, Short8::getType());
3261 Value *packed = Nucleus::createShuffleVector(short8, short8, select);
Nicolas Capensd4227962016-11-09 14:24:25 -05003262
Nicolas Capensbea4dce2017-07-24 16:54:44 -04003263 Value *int2 = RValue<Int2>(Int2(As<Int4>(packed))).value;
Nicolas Capensd4227962016-11-09 14:24:25 -05003264 Value *short4 = Nucleus::createBitCast(int2, Short4::getType());
3265
3266 storeValue(short4);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003267 }
3268
3269// Short4::Short4(RValue<Float> cast)
3270// {
3271// }
3272
3273 Short4::Short4(RValue<Float4> cast)
3274 {
3275 assert(false && "UNIMPLEMENTED");
3276 }
3277
Nicolas Capens598f8d82016-09-26 15:09:10 -04003278 Short4::Short4(short xyzw)
3279 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04003280 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
3281 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003282 }
3283
3284 Short4::Short4(short x, short y, short z, short w)
3285 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04003286 int64_t constantVector[4] = {x, y, z, w};
3287 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003288 }
3289
3290 Short4::Short4(RValue<Short4> rhs)
3291 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003292 storeValue(rhs.value);
3293 }
3294
3295 Short4::Short4(const Short4 &rhs)
3296 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003297 Value *value = rhs.loadValue();
3298 storeValue(value);
3299 }
3300
3301 Short4::Short4(const Reference<Short4> &rhs)
3302 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003303 Value *value = rhs.loadValue();
3304 storeValue(value);
3305 }
3306
3307 Short4::Short4(RValue<UShort4> rhs)
3308 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003309 storeValue(rhs.value);
3310 }
3311
3312 Short4::Short4(const UShort4 &rhs)
3313 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003314 storeValue(rhs.loadValue());
3315 }
3316
3317 Short4::Short4(const Reference<UShort4> &rhs)
3318 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003319 storeValue(rhs.loadValue());
3320 }
3321
Nicolas Capens96d4e092016-11-18 14:22:38 -05003322 RValue<Short4> Short4::operator=(RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003323 {
3324 storeValue(rhs.value);
3325
3326 return rhs;
3327 }
3328
Nicolas Capens96d4e092016-11-18 14:22:38 -05003329 RValue<Short4> Short4::operator=(const 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=(const Reference<Short4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003338 {
3339 Value *value = rhs.loadValue();
3340 storeValue(value);
3341
3342 return RValue<Short4>(value);
3343 }
3344
Nicolas Capens96d4e092016-11-18 14:22:38 -05003345 RValue<Short4> Short4::operator=(RValue<UShort4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003346 {
3347 storeValue(rhs.value);
3348
3349 return RValue<Short4>(rhs);
3350 }
3351
Nicolas Capens96d4e092016-11-18 14:22:38 -05003352 RValue<Short4> Short4::operator=(const 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
Nicolas Capens96d4e092016-11-18 14:22:38 -05003360 RValue<Short4> Short4::operator=(const Reference<UShort4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003361 {
3362 Value *value = rhs.loadValue();
3363 storeValue(value);
3364
3365 return RValue<Short4>(value);
3366 }
3367
3368 RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs)
3369 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003370 return RValue<Short4>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003371 }
3372
3373 RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs)
3374 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003375 return RValue<Short4>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003376 }
3377
3378 RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs)
3379 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003380 return RValue<Short4>(Nucleus::createMul(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003381 }
3382
3383// RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs)
3384// {
3385// return RValue<Short4>(Nucleus::createSDiv(lhs.value, rhs.value));
3386// }
3387
3388// RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs)
3389// {
3390// return RValue<Short4>(Nucleus::createSRem(lhs.value, rhs.value));
3391// }
3392
3393 RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs)
3394 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003395 return RValue<Short4>(Nucleus::createAnd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003396 }
3397
3398 RValue<Short4> operator|(RValue<Short4> lhs, RValue<Short4> rhs)
3399 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003400 return RValue<Short4>(Nucleus::createOr(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003401 }
3402
3403 RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs)
3404 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003405 return RValue<Short4>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003406 }
3407
3408 RValue<Short4> operator<<(RValue<Short4> lhs, unsigned char rhs)
3409 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04003410 if(emulateIntrinsics)
3411 {
3412 Short4 result;
3413 result = Insert(result, Extract(lhs, 0) << Short(rhs), 0);
3414 result = Insert(result, Extract(lhs, 1) << Short(rhs), 1);
3415 result = Insert(result, Extract(lhs, 2) << Short(rhs), 2);
3416 result = Insert(result, Extract(lhs, 3) << Short(rhs), 3);
3417
3418 return result;
3419 }
3420 else
3421 {
3422 return RValue<Short4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
3423 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003424 }
3425
3426 RValue<Short4> operator>>(RValue<Short4> lhs, unsigned char rhs)
3427 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04003428 if(emulateIntrinsics)
3429 {
3430 Short4 result;
3431 result = Insert(result, Extract(lhs, 0) >> Short(rhs), 0);
3432 result = Insert(result, Extract(lhs, 1) >> Short(rhs), 1);
3433 result = Insert(result, Extract(lhs, 2) >> Short(rhs), 2);
3434 result = Insert(result, Extract(lhs, 3) >> Short(rhs), 3);
3435
3436 return result;
3437 }
3438 else
3439 {
3440 return RValue<Short4>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
3441 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003442 }
3443
Nicolas Capens96d4e092016-11-18 14:22:38 -05003444 RValue<Short4> operator+=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003445 {
3446 return lhs = lhs + rhs;
3447 }
3448
Nicolas Capens96d4e092016-11-18 14:22:38 -05003449 RValue<Short4> operator-=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003450 {
3451 return lhs = lhs - rhs;
3452 }
3453
Nicolas Capens96d4e092016-11-18 14:22:38 -05003454 RValue<Short4> operator*=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003455 {
3456 return lhs = lhs * rhs;
3457 }
3458
Nicolas Capens96d4e092016-11-18 14:22:38 -05003459// RValue<Short4> operator/=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003460// {
3461// return lhs = lhs / rhs;
3462// }
3463
Nicolas Capens96d4e092016-11-18 14:22:38 -05003464// RValue<Short4> operator%=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003465// {
3466// return lhs = lhs % rhs;
3467// }
3468
Nicolas Capens96d4e092016-11-18 14:22:38 -05003469 RValue<Short4> operator&=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003470 {
3471 return lhs = lhs & rhs;
3472 }
3473
Nicolas Capens96d4e092016-11-18 14:22:38 -05003474 RValue<Short4> operator|=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003475 {
3476 return lhs = lhs | rhs;
3477 }
3478
Nicolas Capens96d4e092016-11-18 14:22:38 -05003479 RValue<Short4> operator^=(Short4 &lhs, RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003480 {
3481 return lhs = lhs ^ rhs;
3482 }
3483
Nicolas Capens96d4e092016-11-18 14:22:38 -05003484 RValue<Short4> operator<<=(Short4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003485 {
3486 return lhs = lhs << rhs;
3487 }
3488
Nicolas Capens96d4e092016-11-18 14:22:38 -05003489 RValue<Short4> operator>>=(Short4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003490 {
3491 return lhs = lhs >> rhs;
3492 }
3493
Nicolas Capens598f8d82016-09-26 15:09:10 -04003494// RValue<Short4> operator+(RValue<Short4> val)
3495// {
3496// return val;
3497// }
3498
3499 RValue<Short4> operator-(RValue<Short4> val)
3500 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -05003501 return RValue<Short4>(Nucleus::createNeg(val.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003502 }
3503
3504 RValue<Short4> operator~(RValue<Short4> val)
3505 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -05003506 return RValue<Short4>(Nucleus::createNot(val.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003507 }
3508
3509 RValue<Short4> RoundShort4(RValue<Float4> cast)
3510 {
Nicolas Capensd4227962016-11-09 14:24:25 -05003511 RValue<Int4> int4 = RoundInt(cast);
Nicolas Capens33438a62017-09-27 11:47:35 -04003512 return As<Short4>(PackSigned(int4, int4));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003513 }
3514
3515 RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y)
3516 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04003517 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3518 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sle, condition, x.value, y.value);
3519 ::basicBlock->appendInst(cmp);
3520
3521 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3522 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3523 ::basicBlock->appendInst(select);
3524
3525 return RValue<Short4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003526 }
3527
3528 RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y)
3529 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04003530 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3531 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sgt, condition, x.value, y.value);
3532 ::basicBlock->appendInst(cmp);
3533
3534 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3535 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3536 ::basicBlock->appendInst(select);
3537
3538 return RValue<Short4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003539 }
3540
Nicolas Capens33438a62017-09-27 11:47:35 -04003541 RValue<Short> SaturateSigned(RValue<Int> x)
Nicolas Capens98436732017-07-25 15:32:12 -04003542 {
3543 return Short(IfThenElse(x > 0x7FFF, Int(0x7FFF), IfThenElse(x < -0x8000, Int(0x8000), x)));
3544 }
3545
Nicolas Capens598f8d82016-09-26 15:09:10 -04003546 RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y)
3547 {
Nicolas Capens98436732017-07-25 15:32:12 -04003548 if(emulateIntrinsics)
3549 {
3550 Short4 result;
Nicolas Capens33438a62017-09-27 11:47:35 -04003551 result = Insert(result, SaturateSigned(Int(Extract(x, 0)) + Int(Extract(y, 0))), 0);
3552 result = Insert(result, SaturateSigned(Int(Extract(x, 1)) + Int(Extract(y, 1))), 1);
3553 result = Insert(result, SaturateSigned(Int(Extract(x, 2)) + Int(Extract(y, 2))), 2);
3554 result = Insert(result, SaturateSigned(Int(Extract(x, 3)) + Int(Extract(y, 3))), 3);
Nicolas Capensc71bed22016-11-07 22:25:14 -05003555
Nicolas Capens98436732017-07-25 15:32:12 -04003556 return result;
3557 }
3558 else
3559 {
3560 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3561 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3562 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3563 auto paddsw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3564 paddsw->addArg(x.value);
3565 paddsw->addArg(y.value);
3566 ::basicBlock->appendInst(paddsw);
3567
3568 return RValue<Short4>(V(result));
3569 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003570 }
3571
3572 RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y)
3573 {
Nicolas Capens98436732017-07-25 15:32:12 -04003574 if(emulateIntrinsics)
3575 {
3576 Short4 result;
Nicolas Capens33438a62017-09-27 11:47:35 -04003577 result = Insert(result, SaturateSigned(Int(Extract(x, 0)) - Int(Extract(y, 0))), 0);
3578 result = Insert(result, SaturateSigned(Int(Extract(x, 1)) - Int(Extract(y, 1))), 1);
3579 result = Insert(result, SaturateSigned(Int(Extract(x, 2)) - Int(Extract(y, 2))), 2);
3580 result = Insert(result, SaturateSigned(Int(Extract(x, 3)) - Int(Extract(y, 3))), 3);
Nicolas Capensc71bed22016-11-07 22:25:14 -05003581
Nicolas Capens98436732017-07-25 15:32:12 -04003582 return result;
3583 }
3584 else
3585 {
3586 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3587 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3588 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3589 auto psubsw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3590 psubsw->addArg(x.value);
3591 psubsw->addArg(y.value);
3592 ::basicBlock->appendInst(psubsw);
3593
3594 return RValue<Short4>(V(result));
3595 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003596 }
3597
3598 RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y)
3599 {
Nicolas Capens6c157442017-07-25 15:32:12 -04003600 if(emulateIntrinsics)
3601 {
3602 Short4 result;
3603 result = Insert(result, Short((Int(Extract(x, 0)) * Int(Extract(y, 0))) >> 16), 0);
3604 result = Insert(result, Short((Int(Extract(x, 1)) * Int(Extract(y, 1))) >> 16), 1);
3605 result = Insert(result, Short((Int(Extract(x, 2)) * Int(Extract(y, 2))) >> 16), 2);
3606 result = Insert(result, Short((Int(Extract(x, 3)) * Int(Extract(y, 3))) >> 16), 3);
Nicolas Capensc71bed22016-11-07 22:25:14 -05003607
Nicolas Capens6c157442017-07-25 15:32:12 -04003608 return result;
3609 }
3610 else
3611 {
3612 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3613 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::MultiplyHighSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3614 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3615 auto pmulhw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3616 pmulhw->addArg(x.value);
3617 pmulhw->addArg(y.value);
3618 ::basicBlock->appendInst(pmulhw);
3619
3620 return RValue<Short4>(V(result));
3621 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003622 }
3623
3624 RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y)
3625 {
Nicolas Capensafe27e92017-07-25 15:32:12 -04003626 if(emulateIntrinsics)
3627 {
3628 Int2 result;
3629 result = Insert(result, Int(Extract(x, 0)) * Int(Extract(y, 0)) + Int(Extract(x, 1)) * Int(Extract(y, 1)), 0);
3630 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 -05003631
Nicolas Capensafe27e92017-07-25 15:32:12 -04003632 return result;
3633 }
3634 else
3635 {
3636 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3637 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::MultiplyAddPairs, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3638 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3639 auto pmaddwd = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3640 pmaddwd->addArg(x.value);
3641 pmaddwd->addArg(y.value);
3642 ::basicBlock->appendInst(pmaddwd);
3643
3644 return As<Int2>(V(result));
3645 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003646 }
3647
Nicolas Capens33438a62017-09-27 11:47:35 -04003648 RValue<SByte8> PackSigned(RValue<Short4> x, RValue<Short4> y)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003649 {
Nicolas Capens8960fbf2017-07-25 15:32:12 -04003650 if(emulateIntrinsics)
3651 {
3652 SByte8 result;
Nicolas Capens33438a62017-09-27 11:47:35 -04003653 result = Insert(result, SaturateSigned(Extract(x, 0)), 0);
3654 result = Insert(result, SaturateSigned(Extract(x, 1)), 1);
3655 result = Insert(result, SaturateSigned(Extract(x, 2)), 2);
3656 result = Insert(result, SaturateSigned(Extract(x, 3)), 3);
3657 result = Insert(result, SaturateSigned(Extract(y, 0)), 4);
3658 result = Insert(result, SaturateSigned(Extract(y, 1)), 5);
3659 result = Insert(result, SaturateSigned(Extract(y, 2)), 6);
3660 result = Insert(result, SaturateSigned(Extract(y, 3)), 7);
Nicolas Capensec54a172016-10-25 17:32:37 -04003661
Nicolas Capens8960fbf2017-07-25 15:32:12 -04003662 return result;
3663 }
3664 else
3665 {
3666 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
3667 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3668 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3669 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3670 pack->addArg(x.value);
3671 pack->addArg(y.value);
3672 ::basicBlock->appendInst(pack);
3673
3674 return As<SByte8>(Swizzle(As<Int4>(V(result)), 0x88));
3675 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003676 }
3677
Nicolas Capens33438a62017-09-27 11:47:35 -04003678 RValue<Byte8> PackUnsigned(RValue<Short4> x, RValue<Short4> y)
3679 {
3680 if(emulateIntrinsics)
3681 {
3682 Byte8 result;
3683 result = Insert(result, SaturateUnsigned(Extract(x, 0)), 0);
3684 result = Insert(result, SaturateUnsigned(Extract(x, 1)), 1);
3685 result = Insert(result, SaturateUnsigned(Extract(x, 2)), 2);
3686 result = Insert(result, SaturateUnsigned(Extract(x, 3)), 3);
3687 result = Insert(result, SaturateUnsigned(Extract(y, 0)), 4);
3688 result = Insert(result, SaturateUnsigned(Extract(y, 1)), 5);
3689 result = Insert(result, SaturateUnsigned(Extract(y, 2)), 6);
3690 result = Insert(result, SaturateUnsigned(Extract(y, 3)), 7);
3691
3692 return result;
3693 }
3694 else
3695 {
3696 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
3697 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
3698 auto target = ::context->getConstantUndef(Ice::IceType_i32);
3699 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
3700 pack->addArg(x.value);
3701 pack->addArg(y.value);
3702 ::basicBlock->appendInst(pack);
3703
3704 return As<Byte8>(Swizzle(As<Int4>(V(result)), 0x88));
3705 }
3706 }
3707
Nicolas Capens598f8d82016-09-26 15:09:10 -04003708 RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y)
3709 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04003710 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11}; // Real type is v8i16
Nicolas Capensbea4dce2017-07-24 16:54:44 -04003711 return As<Int2>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003712 }
3713
3714 RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y)
3715 {
Nicolas Capens20e22c42016-10-25 17:32:37 -04003716 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11}; // Real type is v8i16
3717 auto lowHigh = RValue<Short8>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
3718 return As<Int2>(Swizzle(As<Int4>(lowHigh), 0xEE));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003719 }
3720
3721 RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select)
3722 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04003723 // Real type is v8i16
3724 int shuffle[8] =
3725 {
3726 (select >> 0) & 0x03,
3727 (select >> 2) & 0x03,
3728 (select >> 4) & 0x03,
3729 (select >> 6) & 0x03,
3730 (select >> 0) & 0x03,
3731 (select >> 2) & 0x03,
3732 (select >> 4) & 0x03,
3733 (select >> 6) & 0x03,
3734 };
3735
3736 return RValue<Short4>(Nucleus::createShuffleVector(x.value, x.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003737 }
3738
3739 RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i)
3740 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05003741 return RValue<Short4>(Nucleus::createInsertElement(val.value, element.value, i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003742 }
3743
3744 RValue<Short> Extract(RValue<Short4> val, int i)
3745 {
Nicolas Capens0133d0f2017-01-16 16:25:08 -05003746 return RValue<Short>(Nucleus::createExtractElement(val.value, Short::getType(), i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003747 }
3748
3749 RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y)
3750 {
Nicolas Capens2f970b62016-11-08 14:28:59 -05003751 return RValue<Short4>(createIntCompare(Ice::InstIcmp::Sgt, x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003752 }
3753
3754 RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y)
3755 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05003756 return RValue<Short4>(Nucleus::createICmpEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003757 }
3758
3759 Type *Short4::getType()
3760 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04003761 return T(Type_v4i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04003762 }
3763
3764 UShort4::UShort4(RValue<Int4> cast)
3765 {
3766 *this = Short4(cast);
3767 }
3768
3769 UShort4::UShort4(RValue<Float4> cast, bool saturate)
3770 {
Nicolas Capensd4227962016-11-09 14:24:25 -05003771 if(saturate)
3772 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05003773 if(CPUID::SSE4_1)
Nicolas Capensd4227962016-11-09 14:24:25 -05003774 {
Nicolas Capens091f3502017-10-03 14:56:49 -04003775 // x86 produces 0x80000000 on 32-bit integer overflow/underflow.
3776 // PackUnsigned takes care of 0x0000 saturation.
3777 Int4 int4(Min(cast, Float4(0xFFFF)));
3778 *this = As<UShort4>(PackUnsigned(int4, int4));
3779 }
3780 else if(CPUID::ARM)
3781 {
3782 // ARM saturates the 32-bit integer result on overflow/undeflow.
3783 Int4 int4(cast);
Nicolas Capens33438a62017-09-27 11:47:35 -04003784 *this = As<UShort4>(PackUnsigned(int4, int4));
Nicolas Capensd4227962016-11-09 14:24:25 -05003785 }
3786 else
3787 {
3788 *this = Short4(Int4(Max(Min(cast, Float4(0xFFFF)), Float4(0x0000))));
3789 }
3790 }
3791 else
3792 {
3793 *this = Short4(Int4(cast));
3794 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003795 }
3796
Nicolas Capens598f8d82016-09-26 15:09:10 -04003797 UShort4::UShort4(unsigned short xyzw)
3798 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04003799 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
3800 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003801 }
3802
3803 UShort4::UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w)
3804 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04003805 int64_t constantVector[4] = {x, y, z, w};
3806 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003807 }
3808
3809 UShort4::UShort4(RValue<UShort4> rhs)
3810 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003811 storeValue(rhs.value);
3812 }
3813
3814 UShort4::UShort4(const UShort4 &rhs)
3815 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003816 Value *value = rhs.loadValue();
3817 storeValue(value);
3818 }
3819
3820 UShort4::UShort4(const Reference<UShort4> &rhs)
3821 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003822 Value *value = rhs.loadValue();
3823 storeValue(value);
3824 }
3825
3826 UShort4::UShort4(RValue<Short4> rhs)
3827 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003828 storeValue(rhs.value);
3829 }
3830
3831 UShort4::UShort4(const Short4 &rhs)
3832 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003833 Value *value = rhs.loadValue();
3834 storeValue(value);
3835 }
3836
3837 UShort4::UShort4(const Reference<Short4> &rhs)
3838 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04003839 Value *value = rhs.loadValue();
3840 storeValue(value);
3841 }
3842
Nicolas Capens96d4e092016-11-18 14:22:38 -05003843 RValue<UShort4> UShort4::operator=(RValue<UShort4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003844 {
3845 storeValue(rhs.value);
3846
3847 return rhs;
3848 }
3849
Nicolas Capens96d4e092016-11-18 14:22:38 -05003850 RValue<UShort4> UShort4::operator=(const 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=(const Reference<UShort4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003859 {
3860 Value *value = rhs.loadValue();
3861 storeValue(value);
3862
3863 return RValue<UShort4>(value);
3864 }
3865
Nicolas Capens96d4e092016-11-18 14:22:38 -05003866 RValue<UShort4> UShort4::operator=(RValue<Short4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003867 {
3868 storeValue(rhs.value);
3869
3870 return RValue<UShort4>(rhs);
3871 }
3872
Nicolas Capens96d4e092016-11-18 14:22:38 -05003873 RValue<UShort4> UShort4::operator=(const 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
Nicolas Capens96d4e092016-11-18 14:22:38 -05003881 RValue<UShort4> UShort4::operator=(const Reference<Short4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003882 {
3883 Value *value = rhs.loadValue();
3884 storeValue(value);
3885
3886 return RValue<UShort4>(value);
3887 }
3888
3889 RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs)
3890 {
Nicolas Capens5b41ba32016-12-08 14:34:00 -05003891 return RValue<UShort4>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003892 }
3893
3894 RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs)
3895 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003896 return RValue<UShort4>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003897 }
3898
3899 RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs)
3900 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003901 return RValue<UShort4>(Nucleus::createMul(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003902 }
3903
Nicolas Capens16b5f152016-10-13 13:39:01 -04003904 RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs)
3905 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003906 return RValue<UShort4>(Nucleus::createAnd(lhs.value, rhs.value));
Nicolas Capens16b5f152016-10-13 13:39:01 -04003907 }
3908
3909 RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs)
3910 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003911 return RValue<UShort4>(Nucleus::createOr(lhs.value, rhs.value));
Nicolas Capens16b5f152016-10-13 13:39:01 -04003912 }
3913
3914 RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs)
3915 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04003916 return RValue<UShort4>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens16b5f152016-10-13 13:39:01 -04003917 }
3918
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04003919 RValue<UShort> Extract(RValue<UShort4> val, int i)
3920 {
3921 return RValue<UShort>(Nucleus::createExtractElement(val.value, UShort::getType(), i));
3922 }
3923
3924 RValue<UShort4> Insert(RValue<UShort4> val, RValue<UShort> element, int i)
3925 {
3926 return RValue<UShort4>(Nucleus::createInsertElement(val.value, element.value, i));
3927 }
3928
Nicolas Capens598f8d82016-09-26 15:09:10 -04003929 RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs)
3930 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04003931 if(emulateIntrinsics)
3932 {
3933 UShort4 result;
3934 result = Insert(result, Extract(lhs, 0) << UShort(rhs), 0);
3935 result = Insert(result, Extract(lhs, 1) << UShort(rhs), 1);
3936 result = Insert(result, Extract(lhs, 2) << UShort(rhs), 2);
3937 result = Insert(result, Extract(lhs, 3) << UShort(rhs), 3);
3938
3939 return result;
3940 }
3941 else
3942 {
3943 return RValue<UShort4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
3944 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003945 }
3946
3947 RValue<UShort4> operator>>(RValue<UShort4> lhs, unsigned char rhs)
3948 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04003949 if(emulateIntrinsics)
3950 {
3951 UShort4 result;
3952 result = Insert(result, Extract(lhs, 0) >> UShort(rhs), 0);
3953 result = Insert(result, Extract(lhs, 1) >> UShort(rhs), 1);
3954 result = Insert(result, Extract(lhs, 2) >> UShort(rhs), 2);
3955 result = Insert(result, Extract(lhs, 3) >> UShort(rhs), 3);
3956
3957 return result;
3958 }
3959 else
3960 {
3961 return RValue<UShort4>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
3962 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04003963 }
3964
Nicolas Capens96d4e092016-11-18 14:22:38 -05003965 RValue<UShort4> operator<<=(UShort4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003966 {
3967 return lhs = lhs << rhs;
3968 }
3969
Nicolas Capens96d4e092016-11-18 14:22:38 -05003970 RValue<UShort4> operator>>=(UShort4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04003971 {
3972 return lhs = lhs >> rhs;
3973 }
3974
Nicolas Capens598f8d82016-09-26 15:09:10 -04003975 RValue<UShort4> operator~(RValue<UShort4> val)
3976 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -05003977 return RValue<UShort4>(Nucleus::createNot(val.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003978 }
3979
3980 RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y)
3981 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04003982 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3983 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ule, condition, x.value, y.value);
3984 ::basicBlock->appendInst(cmp);
3985
3986 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
3987 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
3988 ::basicBlock->appendInst(select);
3989
3990 return RValue<UShort4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04003991 }
3992
3993 RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y)
3994 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04003995 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
3996 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ugt, condition, x.value, y.value);
3997 ::basicBlock->appendInst(cmp);
3998
3999 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
4000 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
4001 ::basicBlock->appendInst(select);
4002
4003 return RValue<UShort4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004004 }
4005
Nicolas Capens7f301812017-10-02 17:32:34 -04004006 RValue<UShort> SaturateUnsigned(RValue<Int> x)
Nicolas Capens98436732017-07-25 15:32:12 -04004007 {
4008 return UShort(IfThenElse(x > 0xFFFF, Int(0xFFFF), IfThenElse(x < 0, Int(0), x)));
4009 }
4010
Nicolas Capens598f8d82016-09-26 15:09:10 -04004011 RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y)
4012 {
Nicolas Capens98436732017-07-25 15:32:12 -04004013 if(emulateIntrinsics)
4014 {
4015 UShort4 result;
Nicolas Capens7f301812017-10-02 17:32:34 -04004016 result = Insert(result, SaturateUnsigned(Int(Extract(x, 0)) + Int(Extract(y, 0))), 0);
4017 result = Insert(result, SaturateUnsigned(Int(Extract(x, 1)) + Int(Extract(y, 1))), 1);
4018 result = Insert(result, SaturateUnsigned(Int(Extract(x, 2)) + Int(Extract(y, 2))), 2);
4019 result = Insert(result, SaturateUnsigned(Int(Extract(x, 3)) + Int(Extract(y, 3))), 3);
Nicolas Capensc71bed22016-11-07 22:25:14 -05004020
Nicolas Capens98436732017-07-25 15:32:12 -04004021 return result;
4022 }
4023 else
4024 {
4025 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
4026 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::AddSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
4027 auto target = ::context->getConstantUndef(Ice::IceType_i32);
4028 auto paddusw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
4029 paddusw->addArg(x.value);
4030 paddusw->addArg(y.value);
4031 ::basicBlock->appendInst(paddusw);
4032
4033 return RValue<UShort4>(V(result));
4034 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04004035 }
4036
4037 RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y)
4038 {
Nicolas Capens98436732017-07-25 15:32:12 -04004039 if(emulateIntrinsics)
4040 {
4041 UShort4 result;
Nicolas Capens7f301812017-10-02 17:32:34 -04004042 result = Insert(result, SaturateUnsigned(Int(Extract(x, 0)) - Int(Extract(y, 0))), 0);
4043 result = Insert(result, SaturateUnsigned(Int(Extract(x, 1)) - Int(Extract(y, 1))), 1);
4044 result = Insert(result, SaturateUnsigned(Int(Extract(x, 2)) - Int(Extract(y, 2))), 2);
4045 result = Insert(result, SaturateUnsigned(Int(Extract(x, 3)) - Int(Extract(y, 3))), 3);
Nicolas Capensc71bed22016-11-07 22:25:14 -05004046
Nicolas Capens98436732017-07-25 15:32:12 -04004047 return result;
4048 }
4049 else
4050 {
4051 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
4052 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SubtractSaturateUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
4053 auto target = ::context->getConstantUndef(Ice::IceType_i32);
4054 auto psubusw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
4055 psubusw->addArg(x.value);
4056 psubusw->addArg(y.value);
4057 ::basicBlock->appendInst(psubusw);
4058
4059 return RValue<UShort4>(V(result));
4060 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04004061 }
4062
4063 RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y)
4064 {
Nicolas Capens6c157442017-07-25 15:32:12 -04004065 if(emulateIntrinsics)
4066 {
4067 UShort4 result;
4068 result = Insert(result, UShort((UInt(Extract(x, 0)) * UInt(Extract(y, 0))) >> 16), 0);
4069 result = Insert(result, UShort((UInt(Extract(x, 1)) * UInt(Extract(y, 1))) >> 16), 1);
4070 result = Insert(result, UShort((UInt(Extract(x, 2)) * UInt(Extract(y, 2))) >> 16), 2);
4071 result = Insert(result, UShort((UInt(Extract(x, 3)) * UInt(Extract(y, 3))) >> 16), 3);
Nicolas Capensc71bed22016-11-07 22:25:14 -05004072
Nicolas Capens6c157442017-07-25 15:32:12 -04004073 return result;
4074 }
4075 else
4076 {
4077 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
4078 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::MultiplyHighUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
4079 auto target = ::context->getConstantUndef(Ice::IceType_i32);
4080 auto pmulhuw = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
4081 pmulhuw->addArg(x.value);
4082 pmulhuw->addArg(y.value);
4083 ::basicBlock->appendInst(pmulhuw);
4084
4085 return RValue<UShort4>(V(result));
4086 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04004087 }
4088
4089 RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y)
4090 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004091 assert(false && "UNIMPLEMENTED"); return RValue<UShort4>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004092 }
4093
Nicolas Capens598f8d82016-09-26 15:09:10 -04004094 Type *UShort4::getType()
4095 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04004096 return T(Type_v4i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004097 }
4098
Nicolas Capens3e7062b2017-01-17 14:01:33 -05004099 Short8::Short8(short c)
4100 {
4101 int64_t constantVector[8] = {c, c, c, c, c, c, c, c};
4102 storeValue(Nucleus::createConstantVector(constantVector, getType()));
4103 }
4104
Nicolas Capens598f8d82016-09-26 15:09:10 -04004105 Short8::Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7)
4106 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04004107 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
4108 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004109 }
4110
4111 Short8::Short8(RValue<Short8> rhs)
4112 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004113 storeValue(rhs.value);
4114 }
4115
4116 Short8::Short8(const Reference<Short8> &rhs)
4117 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004118 Value *value = rhs.loadValue();
4119 storeValue(value);
4120 }
4121
4122 Short8::Short8(RValue<Short4> lo, RValue<Short4> hi)
4123 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05004124 int shuffle[8] = {0, 1, 2, 3, 8, 9, 10, 11}; // Real type is v8i16
4125 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
4126
4127 storeValue(packed);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004128 }
4129
4130 RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs)
4131 {
4132 return RValue<Short8>(Nucleus::createAdd(lhs.value, rhs.value));
4133 }
4134
4135 RValue<Short8> operator&(RValue<Short8> lhs, RValue<Short8> rhs)
4136 {
4137 return RValue<Short8>(Nucleus::createAnd(lhs.value, rhs.value));
4138 }
4139
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04004140 RValue<Short> Extract(RValue<Short8> val, int i)
4141 {
4142 return RValue<Short>(Nucleus::createExtractElement(val.value, Short::getType(), i));
4143 }
4144
4145 RValue<Short8> Insert(RValue<Short8> val, RValue<Short> element, int i)
4146 {
4147 return RValue<Short8>(Nucleus::createInsertElement(val.value, element.value, i));
4148 }
4149
Nicolas Capens598f8d82016-09-26 15:09:10 -04004150 RValue<Short8> operator<<(RValue<Short8> lhs, unsigned char rhs)
4151 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04004152 if(emulateIntrinsics)
4153 {
4154 Short8 result;
4155 result = Insert(result, Extract(lhs, 0) << Short(rhs), 0);
4156 result = Insert(result, Extract(lhs, 1) << Short(rhs), 1);
4157 result = Insert(result, Extract(lhs, 2) << Short(rhs), 2);
4158 result = Insert(result, Extract(lhs, 3) << Short(rhs), 3);
4159 result = Insert(result, Extract(lhs, 4) << Short(rhs), 4);
4160 result = Insert(result, Extract(lhs, 5) << Short(rhs), 5);
4161 result = Insert(result, Extract(lhs, 6) << Short(rhs), 6);
4162 result = Insert(result, Extract(lhs, 7) << Short(rhs), 7);
4163
4164 return result;
4165 }
4166 else
4167 {
4168 return RValue<Short8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
4169 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04004170 }
4171
4172 RValue<Short8> operator>>(RValue<Short8> lhs, unsigned char rhs)
4173 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04004174 if(emulateIntrinsics)
4175 {
4176 Short8 result;
4177 result = Insert(result, Extract(lhs, 0) >> Short(rhs), 0);
4178 result = Insert(result, Extract(lhs, 1) >> Short(rhs), 1);
4179 result = Insert(result, Extract(lhs, 2) >> Short(rhs), 2);
4180 result = Insert(result, Extract(lhs, 3) >> Short(rhs), 3);
4181 result = Insert(result, Extract(lhs, 4) >> Short(rhs), 4);
4182 result = Insert(result, Extract(lhs, 5) >> Short(rhs), 5);
4183 result = Insert(result, Extract(lhs, 6) >> Short(rhs), 6);
4184 result = Insert(result, Extract(lhs, 7) >> Short(rhs), 7);
4185
4186 return result;
4187 }
4188 else
4189 {
4190 return RValue<Short8>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
4191 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04004192 }
4193
4194 RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y)
4195 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004196 assert(false && "UNIMPLEMENTED"); return RValue<Int4>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004197 }
4198
4199 RValue<Int4> Abs(RValue<Int4> x)
4200 {
Nicolas Capens84272242016-11-09 13:31:06 -05004201 auto negative = x >> 31;
4202 return (x ^ negative) - negative;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004203 }
4204
4205 RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y)
4206 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004207 assert(false && "UNIMPLEMENTED"); return RValue<Short8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004208 }
4209
4210 Type *Short8::getType()
4211 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04004212 return T(Ice::IceType_v8i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004213 }
4214
Nicolas Capens3e7062b2017-01-17 14:01:33 -05004215 UShort8::UShort8(unsigned short c)
4216 {
4217 int64_t constantVector[8] = {c, c, c, c, c, c, c, c};
4218 storeValue(Nucleus::createConstantVector(constantVector, getType()));
4219 }
4220
Nicolas Capens598f8d82016-09-26 15:09:10 -04004221 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)
4222 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04004223 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
4224 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004225 }
4226
4227 UShort8::UShort8(RValue<UShort8> rhs)
4228 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004229 storeValue(rhs.value);
4230 }
4231
4232 UShort8::UShort8(const Reference<UShort8> &rhs)
4233 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04004234 Value *value = rhs.loadValue();
4235 storeValue(value);
4236 }
4237
4238 UShort8::UShort8(RValue<UShort4> lo, RValue<UShort4> hi)
4239 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05004240 int shuffle[8] = {0, 1, 2, 3, 8, 9, 10, 11}; // Real type is v8i16
4241 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
4242
4243 storeValue(packed);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004244 }
4245
Nicolas Capens96d4e092016-11-18 14:22:38 -05004246 RValue<UShort8> UShort8::operator=(RValue<UShort8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004247 {
4248 storeValue(rhs.value);
4249
4250 return rhs;
4251 }
4252
Nicolas Capens96d4e092016-11-18 14:22:38 -05004253 RValue<UShort8> UShort8::operator=(const 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
Nicolas Capens96d4e092016-11-18 14:22:38 -05004261 RValue<UShort8> UShort8::operator=(const Reference<UShort8> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004262 {
4263 Value *value = rhs.loadValue();
4264 storeValue(value);
4265
4266 return RValue<UShort8>(value);
4267 }
4268
4269 RValue<UShort8> operator&(RValue<UShort8> lhs, RValue<UShort8> rhs)
4270 {
4271 return RValue<UShort8>(Nucleus::createAnd(lhs.value, rhs.value));
4272 }
4273
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04004274 RValue<UShort> Extract(RValue<UShort8> val, int i)
4275 {
4276 return RValue<UShort>(Nucleus::createExtractElement(val.value, UShort::getType(), i));
4277 }
4278
4279 RValue<UShort8> Insert(RValue<UShort8> val, RValue<UShort> element, int i)
4280 {
4281 return RValue<UShort8>(Nucleus::createInsertElement(val.value, element.value, i));
4282 }
4283
Nicolas Capens598f8d82016-09-26 15:09:10 -04004284 RValue<UShort8> operator<<(RValue<UShort8> lhs, unsigned char rhs)
4285 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04004286 if(emulateIntrinsics)
4287 {
4288 UShort8 result;
4289 result = Insert(result, Extract(lhs, 0) << UShort(rhs), 0);
4290 result = Insert(result, Extract(lhs, 1) << UShort(rhs), 1);
4291 result = Insert(result, Extract(lhs, 2) << UShort(rhs), 2);
4292 result = Insert(result, Extract(lhs, 3) << UShort(rhs), 3);
4293 result = Insert(result, Extract(lhs, 4) << UShort(rhs), 4);
4294 result = Insert(result, Extract(lhs, 5) << UShort(rhs), 5);
4295 result = Insert(result, Extract(lhs, 6) << UShort(rhs), 6);
4296 result = Insert(result, Extract(lhs, 7) << UShort(rhs), 7);
4297
4298 return result;
4299 }
4300 else
4301 {
4302 return RValue<UShort8>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
4303 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04004304 }
4305
4306 RValue<UShort8> operator>>(RValue<UShort8> lhs, unsigned char rhs)
4307 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04004308 if(emulateIntrinsics)
4309 {
4310 UShort8 result;
4311 result = Insert(result, Extract(lhs, 0) >> UShort(rhs), 0);
4312 result = Insert(result, Extract(lhs, 1) >> UShort(rhs), 1);
4313 result = Insert(result, Extract(lhs, 2) >> UShort(rhs), 2);
4314 result = Insert(result, Extract(lhs, 3) >> UShort(rhs), 3);
4315 result = Insert(result, Extract(lhs, 4) >> UShort(rhs), 4);
4316 result = Insert(result, Extract(lhs, 5) >> UShort(rhs), 5);
4317 result = Insert(result, Extract(lhs, 6) >> UShort(rhs), 6);
4318 result = Insert(result, Extract(lhs, 7) >> UShort(rhs), 7);
4319
4320 return result;
4321 }
4322 else
4323 {
4324 return RValue<UShort8>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
4325 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04004326 }
4327
4328 RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs)
4329 {
4330 return RValue<UShort8>(Nucleus::createAdd(lhs.value, rhs.value));
4331 }
4332
4333 RValue<UShort8> operator*(RValue<UShort8> lhs, RValue<UShort8> rhs)
4334 {
4335 return RValue<UShort8>(Nucleus::createMul(lhs.value, rhs.value));
4336 }
4337
Nicolas Capens96d4e092016-11-18 14:22:38 -05004338 RValue<UShort8> operator+=(UShort8 &lhs, RValue<UShort8> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004339 {
4340 return lhs = lhs + rhs;
4341 }
4342
4343 RValue<UShort8> operator~(RValue<UShort8> val)
4344 {
4345 return RValue<UShort8>(Nucleus::createNot(val.value));
4346 }
4347
4348 RValue<UShort8> Swizzle(RValue<UShort8> x, char select0, char select1, char select2, char select3, char select4, char select5, char select6, char select7)
4349 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004350 assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004351 }
4352
4353 RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y)
4354 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004355 assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004356 }
4357
4358 // FIXME: Implement as Shuffle(x, y, Select(i0, ..., i16)) and Shuffle(x, y, SELECT_PACK_REPEAT(element))
4359// RValue<UShort8> PackRepeat(RValue<Byte16> x, RValue<Byte16> y, int element)
4360// {
Nicolas Capensc37252c2016-09-28 16:11:54 -04004361// assert(false && "UNIMPLEMENTED"); return RValue<UShort8>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004362// }
4363
4364 Type *UShort8::getType()
4365 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04004366 return T(Ice::IceType_v8i16);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004367 }
4368
4369 Int::Int(Argument<Int> argument)
4370 {
4371 storeValue(argument.value);
4372 }
4373
4374 Int::Int(RValue<Byte> cast)
4375 {
4376 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
4377
4378 storeValue(integer);
4379 }
4380
4381 Int::Int(RValue<SByte> cast)
4382 {
4383 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
4384
4385 storeValue(integer);
4386 }
4387
4388 Int::Int(RValue<Short> cast)
4389 {
4390 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
4391
4392 storeValue(integer);
4393 }
4394
4395 Int::Int(RValue<UShort> cast)
4396 {
4397 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
4398
4399 storeValue(integer);
4400 }
4401
4402 Int::Int(RValue<Int2> cast)
4403 {
4404 *this = Extract(cast, 0);
4405 }
4406
4407 Int::Int(RValue<Long> cast)
4408 {
4409 Value *integer = Nucleus::createTrunc(cast.value, Int::getType());
4410
4411 storeValue(integer);
4412 }
4413
4414 Int::Int(RValue<Float> cast)
4415 {
4416 Value *integer = Nucleus::createFPToSI(cast.value, Int::getType());
4417
4418 storeValue(integer);
4419 }
4420
Nicolas Capens598f8d82016-09-26 15:09:10 -04004421 Int::Int(int x)
4422 {
4423 storeValue(Nucleus::createConstantInt(x));
4424 }
4425
4426 Int::Int(RValue<Int> rhs)
4427 {
4428 storeValue(rhs.value);
4429 }
4430
4431 Int::Int(RValue<UInt> rhs)
4432 {
4433 storeValue(rhs.value);
4434 }
4435
4436 Int::Int(const Int &rhs)
4437 {
4438 Value *value = rhs.loadValue();
4439 storeValue(value);
4440 }
4441
4442 Int::Int(const Reference<Int> &rhs)
4443 {
4444 Value *value = rhs.loadValue();
4445 storeValue(value);
4446 }
4447
4448 Int::Int(const UInt &rhs)
4449 {
4450 Value *value = rhs.loadValue();
4451 storeValue(value);
4452 }
4453
4454 Int::Int(const Reference<UInt> &rhs)
4455 {
4456 Value *value = rhs.loadValue();
4457 storeValue(value);
4458 }
4459
Nicolas Capens96d4e092016-11-18 14:22:38 -05004460 RValue<Int> Int::operator=(int rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004461 {
4462 return RValue<Int>(storeValue(Nucleus::createConstantInt(rhs)));
4463 }
4464
Nicolas Capens96d4e092016-11-18 14:22:38 -05004465 RValue<Int> Int::operator=(RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004466 {
4467 storeValue(rhs.value);
4468
4469 return rhs;
4470 }
4471
Nicolas Capens96d4e092016-11-18 14:22:38 -05004472 RValue<Int> Int::operator=(RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004473 {
4474 storeValue(rhs.value);
4475
4476 return RValue<Int>(rhs);
4477 }
4478
Nicolas Capens96d4e092016-11-18 14:22:38 -05004479 RValue<Int> Int::operator=(const 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 Reference<Int> &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 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
Nicolas Capens96d4e092016-11-18 14:22:38 -05004503 RValue<Int> Int::operator=(const Reference<UInt> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004504 {
4505 Value *value = rhs.loadValue();
4506 storeValue(value);
4507
4508 return RValue<Int>(value);
4509 }
4510
4511 RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs)
4512 {
4513 return RValue<Int>(Nucleus::createAdd(lhs.value, rhs.value));
4514 }
4515
4516 RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs)
4517 {
4518 return RValue<Int>(Nucleus::createSub(lhs.value, rhs.value));
4519 }
4520
4521 RValue<Int> operator*(RValue<Int> lhs, RValue<Int> rhs)
4522 {
4523 return RValue<Int>(Nucleus::createMul(lhs.value, rhs.value));
4524 }
4525
4526 RValue<Int> operator/(RValue<Int> lhs, RValue<Int> rhs)
4527 {
4528 return RValue<Int>(Nucleus::createSDiv(lhs.value, rhs.value));
4529 }
4530
4531 RValue<Int> operator%(RValue<Int> lhs, RValue<Int> rhs)
4532 {
4533 return RValue<Int>(Nucleus::createSRem(lhs.value, rhs.value));
4534 }
4535
4536 RValue<Int> operator&(RValue<Int> lhs, RValue<Int> rhs)
4537 {
4538 return RValue<Int>(Nucleus::createAnd(lhs.value, rhs.value));
4539 }
4540
4541 RValue<Int> operator|(RValue<Int> lhs, RValue<Int> rhs)
4542 {
4543 return RValue<Int>(Nucleus::createOr(lhs.value, rhs.value));
4544 }
4545
4546 RValue<Int> operator^(RValue<Int> lhs, RValue<Int> rhs)
4547 {
4548 return RValue<Int>(Nucleus::createXor(lhs.value, rhs.value));
4549 }
4550
4551 RValue<Int> operator<<(RValue<Int> lhs, RValue<Int> rhs)
4552 {
4553 return RValue<Int>(Nucleus::createShl(lhs.value, rhs.value));
4554 }
4555
4556 RValue<Int> operator>>(RValue<Int> lhs, RValue<Int> rhs)
4557 {
4558 return RValue<Int>(Nucleus::createAShr(lhs.value, rhs.value));
4559 }
4560
Nicolas Capens96d4e092016-11-18 14:22:38 -05004561 RValue<Int> operator+=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004562 {
4563 return lhs = lhs + rhs;
4564 }
4565
Nicolas Capens96d4e092016-11-18 14:22:38 -05004566 RValue<Int> operator-=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004567 {
4568 return lhs = lhs - rhs;
4569 }
4570
Nicolas Capens96d4e092016-11-18 14:22:38 -05004571 RValue<Int> operator*=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004572 {
4573 return lhs = lhs * rhs;
4574 }
4575
Nicolas Capens96d4e092016-11-18 14:22:38 -05004576 RValue<Int> operator/=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004577 {
4578 return lhs = lhs / rhs;
4579 }
4580
Nicolas Capens96d4e092016-11-18 14:22:38 -05004581 RValue<Int> operator%=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004582 {
4583 return lhs = lhs % rhs;
4584 }
4585
Nicolas Capens96d4e092016-11-18 14:22:38 -05004586 RValue<Int> operator&=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004587 {
4588 return lhs = lhs & rhs;
4589 }
4590
Nicolas Capens96d4e092016-11-18 14:22:38 -05004591 RValue<Int> operator|=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004592 {
4593 return lhs = lhs | rhs;
4594 }
4595
Nicolas Capens96d4e092016-11-18 14:22:38 -05004596 RValue<Int> operator^=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004597 {
4598 return lhs = lhs ^ rhs;
4599 }
4600
Nicolas Capens96d4e092016-11-18 14:22:38 -05004601 RValue<Int> operator<<=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004602 {
4603 return lhs = lhs << rhs;
4604 }
4605
Nicolas Capens96d4e092016-11-18 14:22:38 -05004606 RValue<Int> operator>>=(Int &lhs, RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004607 {
4608 return lhs = lhs >> rhs;
4609 }
4610
4611 RValue<Int> operator+(RValue<Int> val)
4612 {
4613 return val;
4614 }
4615
4616 RValue<Int> operator-(RValue<Int> val)
4617 {
4618 return RValue<Int>(Nucleus::createNeg(val.value));
4619 }
4620
4621 RValue<Int> operator~(RValue<Int> val)
4622 {
4623 return RValue<Int>(Nucleus::createNot(val.value));
4624 }
4625
Nicolas Capens96d4e092016-11-18 14:22:38 -05004626 RValue<Int> operator++(Int &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04004627 {
Nicolas Capens5b41ba32016-12-08 14:34:00 -05004628 RValue<Int> res = val;
Nicolas Capensd1229402016-11-07 16:05:22 -05004629 val += 1;
4630 return res;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004631 }
4632
Nicolas Capens96d4e092016-11-18 14:22:38 -05004633 const Int &operator++(Int &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04004634 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004635 val += 1;
4636 return val;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004637 }
4638
Nicolas Capens96d4e092016-11-18 14:22:38 -05004639 RValue<Int> operator--(Int &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04004640 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004641 RValue<Int> res = val;
4642 val -= 1;
4643 return res;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004644 }
4645
Nicolas Capens96d4e092016-11-18 14:22:38 -05004646 const Int &operator--(Int &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04004647 {
Nicolas Capensd1229402016-11-07 16:05:22 -05004648 val -= 1;
4649 return val;
Nicolas Capens598f8d82016-09-26 15:09:10 -04004650 }
4651
4652 RValue<Bool> operator<(RValue<Int> lhs, RValue<Int> rhs)
4653 {
4654 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
4655 }
4656
4657 RValue<Bool> operator<=(RValue<Int> lhs, RValue<Int> rhs)
4658 {
4659 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
4660 }
4661
4662 RValue<Bool> operator>(RValue<Int> lhs, RValue<Int> rhs)
4663 {
4664 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
4665 }
4666
4667 RValue<Bool> operator>=(RValue<Int> lhs, RValue<Int> rhs)
4668 {
4669 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
4670 }
4671
4672 RValue<Bool> operator!=(RValue<Int> lhs, RValue<Int> rhs)
4673 {
4674 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
4675 }
4676
4677 RValue<Bool> operator==(RValue<Int> lhs, RValue<Int> rhs)
4678 {
4679 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
4680 }
4681
4682 RValue<Int> Max(RValue<Int> x, RValue<Int> y)
4683 {
4684 return IfThenElse(x > y, x, y);
4685 }
4686
4687 RValue<Int> Min(RValue<Int> x, RValue<Int> y)
4688 {
4689 return IfThenElse(x < y, x, y);
4690 }
4691
4692 RValue<Int> Clamp(RValue<Int> x, RValue<Int> min, RValue<Int> max)
4693 {
4694 return Min(Max(x, min), max);
4695 }
4696
4697 RValue<Int> RoundInt(RValue<Float> cast)
4698 {
Nicolas Capens091f3502017-10-03 14:56:49 -04004699 if(emulateIntrinsics || CPUID::ARM)
Nicolas Capensf7b75882017-04-26 09:30:47 -04004700 {
4701 // Push the fractional part off the mantissa. Accurate up to +/-2^22.
4702 return Int((cast + Float(0x00C00000)) - Float(0x00C00000));
4703 }
4704 else
4705 {
4706 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
4707 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Nearbyint, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
4708 auto target = ::context->getConstantUndef(Ice::IceType_i32);
4709 auto nearbyint = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
4710 nearbyint->addArg(cast.value);
4711 ::basicBlock->appendInst(nearbyint);
Nicolas Capensa8086512016-11-07 17:32:17 -05004712
Nicolas Capensf7b75882017-04-26 09:30:47 -04004713 return RValue<Int>(V(result));
4714 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04004715 }
4716
4717 Type *Int::getType()
4718 {
4719 return T(Ice::IceType_i32);
4720 }
4721
4722 Long::Long(RValue<Int> cast)
4723 {
4724 Value *integer = Nucleus::createSExt(cast.value, Long::getType());
4725
4726 storeValue(integer);
4727 }
4728
4729 Long::Long(RValue<UInt> cast)
4730 {
4731 Value *integer = Nucleus::createZExt(cast.value, Long::getType());
4732
4733 storeValue(integer);
4734 }
4735
Nicolas Capens598f8d82016-09-26 15:09:10 -04004736 Long::Long(RValue<Long> rhs)
4737 {
4738 storeValue(rhs.value);
4739 }
4740
Nicolas Capens96d4e092016-11-18 14:22:38 -05004741 RValue<Long> Long::operator=(int64_t rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004742 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04004743 return RValue<Long>(storeValue(Nucleus::createConstantLong(rhs)));
Nicolas Capens598f8d82016-09-26 15:09:10 -04004744 }
4745
Nicolas Capens96d4e092016-11-18 14:22:38 -05004746 RValue<Long> Long::operator=(RValue<Long> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004747 {
4748 storeValue(rhs.value);
4749
4750 return rhs;
4751 }
4752
Nicolas Capens96d4e092016-11-18 14:22:38 -05004753 RValue<Long> Long::operator=(const 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
Nicolas Capens96d4e092016-11-18 14:22:38 -05004761 RValue<Long> Long::operator=(const Reference<Long> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004762 {
4763 Value *value = rhs.loadValue();
4764 storeValue(value);
4765
4766 return RValue<Long>(value);
4767 }
4768
4769 RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs)
4770 {
4771 return RValue<Long>(Nucleus::createAdd(lhs.value, rhs.value));
4772 }
4773
4774 RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs)
4775 {
4776 return RValue<Long>(Nucleus::createSub(lhs.value, rhs.value));
4777 }
4778
Nicolas Capens96d4e092016-11-18 14:22:38 -05004779 RValue<Long> operator+=(Long &lhs, RValue<Long> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004780 {
4781 return lhs = lhs + rhs;
4782 }
4783
Nicolas Capens96d4e092016-11-18 14:22:38 -05004784 RValue<Long> operator-=(Long &lhs, RValue<Long> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004785 {
4786 return lhs = lhs - rhs;
4787 }
4788
4789 RValue<Long> AddAtomic(RValue<Pointer<Long> > x, RValue<Long> y)
4790 {
4791 return RValue<Long>(Nucleus::createAtomicAdd(x.value, y.value));
4792 }
4793
4794 Type *Long::getType()
4795 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04004796 return T(Ice::IceType_i64);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004797 }
4798
Nicolas Capens598f8d82016-09-26 15:09:10 -04004799 UInt::UInt(Argument<UInt> argument)
4800 {
4801 storeValue(argument.value);
4802 }
4803
4804 UInt::UInt(RValue<UShort> cast)
4805 {
4806 Value *integer = Nucleus::createZExt(cast.value, UInt::getType());
4807
4808 storeValue(integer);
4809 }
4810
4811 UInt::UInt(RValue<Long> cast)
4812 {
4813 Value *integer = Nucleus::createTrunc(cast.value, UInt::getType());
4814
4815 storeValue(integer);
4816 }
4817
4818 UInt::UInt(RValue<Float> cast)
4819 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05004820 // Smallest positive value representable in UInt, but not in Int
4821 const unsigned int ustart = 0x80000000u;
4822 const float ustartf = float(ustart);
4823
4824 // If the value is negative, store 0, otherwise store the result of the conversion
4825 storeValue((~(As<Int>(cast) >> 31) &
4826 // Check if the value can be represented as an Int
4827 IfThenElse(cast >= ustartf,
4828 // If the value is too large, subtract ustart and re-add it after conversion.
4829 As<Int>(As<UInt>(Int(cast - Float(ustartf))) + UInt(ustart)),
4830 // Otherwise, just convert normally
4831 Int(cast))).value);
Nicolas Capens598f8d82016-09-26 15:09:10 -04004832 }
4833
Nicolas Capens598f8d82016-09-26 15:09:10 -04004834 UInt::UInt(int x)
4835 {
4836 storeValue(Nucleus::createConstantInt(x));
4837 }
4838
4839 UInt::UInt(unsigned int x)
4840 {
4841 storeValue(Nucleus::createConstantInt(x));
4842 }
4843
4844 UInt::UInt(RValue<UInt> rhs)
4845 {
4846 storeValue(rhs.value);
4847 }
4848
4849 UInt::UInt(RValue<Int> rhs)
4850 {
4851 storeValue(rhs.value);
4852 }
4853
4854 UInt::UInt(const UInt &rhs)
4855 {
4856 Value *value = rhs.loadValue();
4857 storeValue(value);
4858 }
4859
4860 UInt::UInt(const Reference<UInt> &rhs)
4861 {
4862 Value *value = rhs.loadValue();
4863 storeValue(value);
4864 }
4865
4866 UInt::UInt(const Int &rhs)
4867 {
4868 Value *value = rhs.loadValue();
4869 storeValue(value);
4870 }
4871
4872 UInt::UInt(const Reference<Int> &rhs)
4873 {
4874 Value *value = rhs.loadValue();
4875 storeValue(value);
4876 }
4877
Nicolas Capens96d4e092016-11-18 14:22:38 -05004878 RValue<UInt> UInt::operator=(unsigned int rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004879 {
4880 return RValue<UInt>(storeValue(Nucleus::createConstantInt(rhs)));
4881 }
4882
Nicolas Capens96d4e092016-11-18 14:22:38 -05004883 RValue<UInt> UInt::operator=(RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004884 {
4885 storeValue(rhs.value);
4886
4887 return rhs;
4888 }
4889
Nicolas Capens96d4e092016-11-18 14:22:38 -05004890 RValue<UInt> UInt::operator=(RValue<Int> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004891 {
4892 storeValue(rhs.value);
4893
4894 return RValue<UInt>(rhs);
4895 }
4896
Nicolas Capens96d4e092016-11-18 14:22:38 -05004897 RValue<UInt> UInt::operator=(const 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 Reference<UInt> &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 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
Nicolas Capens96d4e092016-11-18 14:22:38 -05004921 RValue<UInt> UInt::operator=(const Reference<Int> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004922 {
4923 Value *value = rhs.loadValue();
4924 storeValue(value);
4925
4926 return RValue<UInt>(value);
4927 }
4928
4929 RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs)
4930 {
4931 return RValue<UInt>(Nucleus::createAdd(lhs.value, rhs.value));
4932 }
4933
4934 RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs)
4935 {
4936 return RValue<UInt>(Nucleus::createSub(lhs.value, rhs.value));
4937 }
4938
4939 RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs)
4940 {
4941 return RValue<UInt>(Nucleus::createMul(lhs.value, rhs.value));
4942 }
4943
4944 RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs)
4945 {
4946 return RValue<UInt>(Nucleus::createUDiv(lhs.value, rhs.value));
4947 }
4948
4949 RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs)
4950 {
4951 return RValue<UInt>(Nucleus::createURem(lhs.value, rhs.value));
4952 }
4953
4954 RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs)
4955 {
4956 return RValue<UInt>(Nucleus::createAnd(lhs.value, rhs.value));
4957 }
4958
4959 RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs)
4960 {
4961 return RValue<UInt>(Nucleus::createOr(lhs.value, rhs.value));
4962 }
4963
4964 RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs)
4965 {
4966 return RValue<UInt>(Nucleus::createXor(lhs.value, rhs.value));
4967 }
4968
4969 RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs)
4970 {
4971 return RValue<UInt>(Nucleus::createShl(lhs.value, rhs.value));
4972 }
4973
4974 RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs)
4975 {
4976 return RValue<UInt>(Nucleus::createLShr(lhs.value, rhs.value));
4977 }
4978
Nicolas Capens96d4e092016-11-18 14:22:38 -05004979 RValue<UInt> operator+=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004980 {
4981 return lhs = lhs + rhs;
4982 }
4983
Nicolas Capens96d4e092016-11-18 14:22:38 -05004984 RValue<UInt> operator-=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004985 {
4986 return lhs = lhs - rhs;
4987 }
4988
Nicolas Capens96d4e092016-11-18 14:22:38 -05004989 RValue<UInt> operator*=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004990 {
4991 return lhs = lhs * rhs;
4992 }
4993
Nicolas Capens96d4e092016-11-18 14:22:38 -05004994 RValue<UInt> operator/=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04004995 {
4996 return lhs = lhs / rhs;
4997 }
4998
Nicolas Capens96d4e092016-11-18 14:22:38 -05004999 RValue<UInt> operator%=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005000 {
5001 return lhs = lhs % rhs;
5002 }
5003
Nicolas Capens96d4e092016-11-18 14:22:38 -05005004 RValue<UInt> operator&=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005005 {
5006 return lhs = lhs & rhs;
5007 }
5008
Nicolas Capens96d4e092016-11-18 14:22:38 -05005009 RValue<UInt> operator|=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005010 {
5011 return lhs = lhs | rhs;
5012 }
5013
Nicolas Capens96d4e092016-11-18 14:22:38 -05005014 RValue<UInt> operator^=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005015 {
5016 return lhs = lhs ^ rhs;
5017 }
5018
Nicolas Capens96d4e092016-11-18 14:22:38 -05005019 RValue<UInt> operator<<=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005020 {
5021 return lhs = lhs << rhs;
5022 }
5023
Nicolas Capens96d4e092016-11-18 14:22:38 -05005024 RValue<UInt> operator>>=(UInt &lhs, RValue<UInt> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005025 {
5026 return lhs = lhs >> rhs;
5027 }
5028
5029 RValue<UInt> operator+(RValue<UInt> val)
5030 {
5031 return val;
5032 }
5033
5034 RValue<UInt> operator-(RValue<UInt> val)
5035 {
5036 return RValue<UInt>(Nucleus::createNeg(val.value));
5037 }
5038
5039 RValue<UInt> operator~(RValue<UInt> val)
5040 {
5041 return RValue<UInt>(Nucleus::createNot(val.value));
5042 }
5043
Nicolas Capens96d4e092016-11-18 14:22:38 -05005044 RValue<UInt> operator++(UInt &val, int) // Post-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04005045 {
Nicolas Capensd1229402016-11-07 16:05:22 -05005046 RValue<UInt> res = val;
5047 val += 1;
5048 return res;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005049 }
5050
Nicolas Capens96d4e092016-11-18 14:22:38 -05005051 const UInt &operator++(UInt &val) // Pre-increment
Nicolas Capens598f8d82016-09-26 15:09:10 -04005052 {
Nicolas Capensd1229402016-11-07 16:05:22 -05005053 val += 1;
5054 return val;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005055 }
5056
Nicolas Capens96d4e092016-11-18 14:22:38 -05005057 RValue<UInt> operator--(UInt &val, int) // Post-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04005058 {
Nicolas Capensd1229402016-11-07 16:05:22 -05005059 RValue<UInt> res = val;
5060 val -= 1;
5061 return res;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005062 }
5063
Nicolas Capens96d4e092016-11-18 14:22:38 -05005064 const UInt &operator--(UInt &val) // Pre-decrement
Nicolas Capens598f8d82016-09-26 15:09:10 -04005065 {
Nicolas Capensd1229402016-11-07 16:05:22 -05005066 val -= 1;
5067 return val;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005068 }
5069
5070 RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y)
5071 {
5072 return IfThenElse(x > y, x, y);
5073 }
5074
5075 RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y)
5076 {
5077 return IfThenElse(x < y, x, y);
5078 }
5079
5080 RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max)
5081 {
5082 return Min(Max(x, min), max);
5083 }
5084
5085 RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs)
5086 {
5087 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
5088 }
5089
5090 RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs)
5091 {
5092 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
5093 }
5094
5095 RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs)
5096 {
5097 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
5098 }
5099
5100 RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs)
5101 {
5102 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
5103 }
5104
5105 RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs)
5106 {
5107 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
5108 }
5109
5110 RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs)
5111 {
5112 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
5113 }
5114
5115// RValue<UInt> RoundUInt(RValue<Float> cast)
5116// {
Nicolas Capensc37252c2016-09-28 16:11:54 -04005117// assert(false && "UNIMPLEMENTED"); return RValue<UInt>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005118// }
5119
5120 Type *UInt::getType()
5121 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04005122 return T(Ice::IceType_i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005123 }
5124
5125// Int2::Int2(RValue<Int> cast)
5126// {
5127// Value *extend = Nucleus::createZExt(cast.value, Long::getType());
5128// Value *vector = Nucleus::createBitCast(extend, Int2::getType());
5129//
5130// Constant *shuffle[2];
5131// shuffle[0] = Nucleus::createConstantInt(0);
5132// shuffle[1] = Nucleus::createConstantInt(0);
5133//
5134// Value *replicate = Nucleus::createShuffleVector(vector, UndefValue::get(Int2::getType()), Nucleus::createConstantVector(shuffle, 2));
5135//
5136// storeValue(replicate);
5137// }
5138
5139 Int2::Int2(RValue<Int4> cast)
5140 {
Nicolas Capens22008782016-10-20 01:11:47 -04005141 storeValue(Nucleus::createBitCast(cast.value, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005142 }
5143
Nicolas Capens598f8d82016-09-26 15:09:10 -04005144 Int2::Int2(int x, int y)
5145 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04005146 int64_t constantVector[2] = {x, y};
5147 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005148 }
5149
5150 Int2::Int2(RValue<Int2> rhs)
5151 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005152 storeValue(rhs.value);
5153 }
5154
5155 Int2::Int2(const Int2 &rhs)
5156 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005157 Value *value = rhs.loadValue();
5158 storeValue(value);
5159 }
5160
5161 Int2::Int2(const Reference<Int2> &rhs)
5162 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005163 Value *value = rhs.loadValue();
5164 storeValue(value);
5165 }
5166
5167 Int2::Int2(RValue<Int> lo, RValue<Int> hi)
5168 {
Nicolas Capensd4227962016-11-09 14:24:25 -05005169 int shuffle[4] = {0, 4, 1, 5};
5170 Value *packed = Nucleus::createShuffleVector(Int4(lo).loadValue(), Int4(hi).loadValue(), shuffle);
5171
5172 storeValue(Nucleus::createBitCast(packed, Int2::getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005173 }
5174
Nicolas Capens96d4e092016-11-18 14:22:38 -05005175 RValue<Int2> Int2::operator=(RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005176 {
5177 storeValue(rhs.value);
5178
5179 return rhs;
5180 }
5181
Nicolas Capens96d4e092016-11-18 14:22:38 -05005182 RValue<Int2> Int2::operator=(const 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
Nicolas Capens96d4e092016-11-18 14:22:38 -05005190 RValue<Int2> Int2::operator=(const Reference<Int2> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005191 {
5192 Value *value = rhs.loadValue();
5193 storeValue(value);
5194
5195 return RValue<Int2>(value);
5196 }
5197
5198 RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs)
5199 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005200 return RValue<Int2>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005201 }
5202
5203 RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs)
5204 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005205 return RValue<Int2>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005206 }
5207
5208// RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs)
5209// {
5210// return RValue<Int2>(Nucleus::createMul(lhs.value, rhs.value));
5211// }
5212
5213// RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs)
5214// {
5215// return RValue<Int2>(Nucleus::createSDiv(lhs.value, rhs.value));
5216// }
5217
5218// RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs)
5219// {
5220// return RValue<Int2>(Nucleus::createSRem(lhs.value, rhs.value));
5221// }
5222
5223 RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs)
5224 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005225 return RValue<Int2>(Nucleus::createAnd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005226 }
5227
5228 RValue<Int2> operator|(RValue<Int2> lhs, RValue<Int2> rhs)
5229 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005230 return RValue<Int2>(Nucleus::createOr(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005231 }
5232
5233 RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs)
5234 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005235 return RValue<Int2>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005236 }
5237
5238 RValue<Int2> operator<<(RValue<Int2> lhs, unsigned char rhs)
5239 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005240 if(emulateIntrinsics)
5241 {
5242 Int2 result;
5243 result = Insert(result, Extract(lhs, 0) << Int(rhs), 0);
5244 result = Insert(result, Extract(lhs, 1) << Int(rhs), 1);
5245
5246 return result;
5247 }
5248 else
5249 {
5250 return RValue<Int2>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
5251 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005252 }
5253
5254 RValue<Int2> operator>>(RValue<Int2> lhs, unsigned char rhs)
5255 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005256 if(emulateIntrinsics)
5257 {
5258 Int2 result;
5259 result = Insert(result, Extract(lhs, 0) >> Int(rhs), 0);
5260 result = Insert(result, Extract(lhs, 1) >> Int(rhs), 1);
5261
5262 return result;
5263 }
5264 else
5265 {
5266 return RValue<Int2>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
5267 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005268 }
5269
Nicolas Capens96d4e092016-11-18 14:22:38 -05005270 RValue<Int2> operator+=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005271 {
5272 return lhs = lhs + rhs;
5273 }
5274
Nicolas Capens96d4e092016-11-18 14:22:38 -05005275 RValue<Int2> operator-=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005276 {
5277 return lhs = lhs - rhs;
5278 }
5279
Nicolas Capens96d4e092016-11-18 14:22:38 -05005280// RValue<Int2> operator*=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005281// {
5282// return lhs = lhs * rhs;
5283// }
5284
Nicolas Capens96d4e092016-11-18 14:22:38 -05005285// RValue<Int2> operator/=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005286// {
5287// return lhs = lhs / rhs;
5288// }
5289
Nicolas Capens96d4e092016-11-18 14:22:38 -05005290// RValue<Int2> operator%=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005291// {
5292// return lhs = lhs % rhs;
5293// }
5294
Nicolas Capens96d4e092016-11-18 14:22:38 -05005295 RValue<Int2> operator&=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005296 {
5297 return lhs = lhs & rhs;
5298 }
5299
Nicolas Capens96d4e092016-11-18 14:22:38 -05005300 RValue<Int2> operator|=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005301 {
5302 return lhs = lhs | rhs;
5303 }
5304
Nicolas Capens96d4e092016-11-18 14:22:38 -05005305 RValue<Int2> operator^=(Int2 &lhs, RValue<Int2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005306 {
5307 return lhs = lhs ^ rhs;
5308 }
5309
Nicolas Capens96d4e092016-11-18 14:22:38 -05005310 RValue<Int2> operator<<=(Int2 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005311 {
5312 return lhs = lhs << rhs;
5313 }
5314
Nicolas Capens96d4e092016-11-18 14:22:38 -05005315 RValue<Int2> operator>>=(Int2 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005316 {
5317 return lhs = lhs >> rhs;
5318 }
5319
Nicolas Capens598f8d82016-09-26 15:09:10 -04005320// RValue<Int2> operator+(RValue<Int2> val)
5321// {
5322// return val;
5323// }
5324
5325// RValue<Int2> operator-(RValue<Int2> val)
5326// {
5327// return RValue<Int2>(Nucleus::createNeg(val.value));
5328// }
5329
5330 RValue<Int2> operator~(RValue<Int2> val)
5331 {
Nicolas Capensc5c0c332016-11-08 11:37:01 -05005332 return RValue<Int2>(Nucleus::createNot(val.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005333 }
5334
Nicolas Capens45f187a2016-12-02 15:30:56 -05005335 RValue<Short4> UnpackLow(RValue<Int2> x, RValue<Int2> y)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005336 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05005337 int shuffle[4] = {0, 4, 1, 5}; // Real type is v4i32
5338 return As<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005339 }
5340
Nicolas Capens45f187a2016-12-02 15:30:56 -05005341 RValue<Short4> UnpackHigh(RValue<Int2> x, RValue<Int2> y)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005342 {
Nicolas Capensf8beb4b2017-01-27 02:55:44 -08005343 int shuffle[4] = {0, 4, 1, 5}; // Real type is v4i32
Nicolas Capensc70a1162016-12-03 00:16:14 -05005344 auto lowHigh = RValue<Int4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
5345 return As<Short4>(Swizzle(lowHigh, 0xEE));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005346 }
5347
5348 RValue<Int> Extract(RValue<Int2> val, int i)
5349 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05005350 return RValue<Int>(Nucleus::createExtractElement(val.value, Int::getType(), i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005351 }
5352
5353 RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i)
5354 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05005355 return RValue<Int2>(Nucleus::createInsertElement(val.value, element.value, i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005356 }
5357
5358 Type *Int2::getType()
5359 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04005360 return T(Type_v2i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005361 }
5362
Nicolas Capens598f8d82016-09-26 15:09:10 -04005363 UInt2::UInt2(unsigned int x, unsigned int y)
5364 {
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04005365 int64_t constantVector[2] = {x, y};
5366 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005367 }
5368
5369 UInt2::UInt2(RValue<UInt2> rhs)
5370 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005371 storeValue(rhs.value);
5372 }
5373
5374 UInt2::UInt2(const UInt2 &rhs)
5375 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005376 Value *value = rhs.loadValue();
5377 storeValue(value);
5378 }
5379
5380 UInt2::UInt2(const Reference<UInt2> &rhs)
5381 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005382 Value *value = rhs.loadValue();
5383 storeValue(value);
5384 }
5385
Nicolas Capens96d4e092016-11-18 14:22:38 -05005386 RValue<UInt2> UInt2::operator=(RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005387 {
5388 storeValue(rhs.value);
5389
5390 return rhs;
5391 }
5392
Nicolas Capens96d4e092016-11-18 14:22:38 -05005393 RValue<UInt2> UInt2::operator=(const 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
Nicolas Capens96d4e092016-11-18 14:22:38 -05005401 RValue<UInt2> UInt2::operator=(const Reference<UInt2> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005402 {
5403 Value *value = rhs.loadValue();
5404 storeValue(value);
5405
5406 return RValue<UInt2>(value);
5407 }
5408
5409 RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs)
5410 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005411 return RValue<UInt2>(Nucleus::createAdd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005412 }
5413
5414 RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs)
5415 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005416 return RValue<UInt2>(Nucleus::createSub(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005417 }
5418
5419// RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs)
5420// {
5421// return RValue<UInt2>(Nucleus::createMul(lhs.value, rhs.value));
5422// }
5423
5424// RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs)
5425// {
5426// return RValue<UInt2>(Nucleus::createUDiv(lhs.value, rhs.value));
5427// }
5428
5429// RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs)
5430// {
5431// return RValue<UInt2>(Nucleus::createURem(lhs.value, rhs.value));
5432// }
5433
5434 RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs)
5435 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005436 return RValue<UInt2>(Nucleus::createAnd(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005437 }
5438
5439 RValue<UInt2> operator|(RValue<UInt2> lhs, RValue<UInt2> rhs)
5440 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005441 return RValue<UInt2>(Nucleus::createOr(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005442 }
5443
5444 RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs)
5445 {
Nicolas Capensc4c431d2016-10-21 15:30:29 -04005446 return RValue<UInt2>(Nucleus::createXor(lhs.value, rhs.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005447 }
5448
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005449 RValue<UInt> Extract(RValue<UInt2> val, int i)
5450 {
5451 return RValue<UInt>(Nucleus::createExtractElement(val.value, UInt::getType(), i));
5452 }
5453
5454 RValue<UInt2> Insert(RValue<UInt2> val, RValue<UInt> element, int i)
5455 {
5456 return RValue<UInt2>(Nucleus::createInsertElement(val.value, element.value, i));
5457 }
5458
Nicolas Capens598f8d82016-09-26 15:09:10 -04005459 RValue<UInt2> operator<<(RValue<UInt2> lhs, unsigned char rhs)
5460 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005461 if(emulateIntrinsics)
5462 {
5463 UInt2 result;
5464 result = Insert(result, Extract(lhs, 0) << UInt(rhs), 0);
5465 result = Insert(result, Extract(lhs, 1) << UInt(rhs), 1);
5466
5467 return result;
5468 }
5469 else
5470 {
5471 return RValue<UInt2>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
5472 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005473 }
5474
5475 RValue<UInt2> operator>>(RValue<UInt2> lhs, unsigned char rhs)
5476 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005477 if(emulateIntrinsics)
5478 {
5479 UInt2 result;
5480 result = Insert(result, Extract(lhs, 0) >> UInt(rhs), 0);
5481 result = Insert(result, Extract(lhs, 1) >> UInt(rhs), 1);
5482
5483 return result;
5484 }
5485 else
5486 {
5487 return RValue<UInt2>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
5488 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005489 }
5490
Nicolas Capens96d4e092016-11-18 14:22:38 -05005491 RValue<UInt2> operator+=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005492 {
5493 return lhs = lhs + rhs;
5494 }
5495
Nicolas Capens96d4e092016-11-18 14:22:38 -05005496 RValue<UInt2> operator-=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005497 {
5498 return lhs = lhs - rhs;
5499 }
5500
Nicolas Capens96d4e092016-11-18 14:22:38 -05005501// RValue<UInt2> operator*=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005502// {
5503// return lhs = lhs * rhs;
5504// }
5505
Nicolas Capens96d4e092016-11-18 14:22:38 -05005506// RValue<UInt2> operator/=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005507// {
5508// return lhs = lhs / rhs;
5509// }
5510
Nicolas Capens96d4e092016-11-18 14:22:38 -05005511// RValue<UInt2> operator%=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005512// {
5513// return lhs = lhs % rhs;
5514// }
5515
Nicolas Capens96d4e092016-11-18 14:22:38 -05005516 RValue<UInt2> operator&=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005517 {
5518 return lhs = lhs & rhs;
5519 }
5520
Nicolas Capens96d4e092016-11-18 14:22:38 -05005521 RValue<UInt2> operator|=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005522 {
5523 return lhs = lhs | rhs;
5524 }
5525
Nicolas Capens96d4e092016-11-18 14:22:38 -05005526 RValue<UInt2> operator^=(UInt2 &lhs, RValue<UInt2> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005527 {
5528 return lhs = lhs ^ rhs;
5529 }
5530
Nicolas Capens96d4e092016-11-18 14:22:38 -05005531 RValue<UInt2> operator<<=(UInt2 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005532 {
5533 return lhs = lhs << rhs;
5534 }
5535
Nicolas Capens96d4e092016-11-18 14:22:38 -05005536 RValue<UInt2> operator>>=(UInt2 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005537 {
5538 return lhs = lhs >> rhs;
5539 }
5540
Nicolas Capens598f8d82016-09-26 15:09:10 -04005541// RValue<UInt2> operator+(RValue<UInt2> val)
5542// {
5543// return val;
5544// }
5545
5546// RValue<UInt2> operator-(RValue<UInt2> val)
5547// {
5548// return RValue<UInt2>(Nucleus::createNeg(val.value));
5549// }
5550
5551 RValue<UInt2> operator~(RValue<UInt2> val)
5552 {
5553 return RValue<UInt2>(Nucleus::createNot(val.value));
5554 }
5555
5556 Type *UInt2::getType()
5557 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04005558 return T(Type_v2i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005559 }
5560
Nicolas Capenscb986762017-01-20 11:34:37 -05005561 Int4::Int4() : XYZW(this)
5562 {
5563 }
5564
5565 Int4::Int4(RValue<Byte4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005566 {
Nicolas Capensd4227962016-11-09 14:24:25 -05005567 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
5568 Value *a = Nucleus::createInsertElement(loadValue(), x, 0);
5569
5570 Value *e;
5571 int swizzle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23};
5572 Value *b = Nucleus::createBitCast(a, Byte16::getType());
5573 Value *c = Nucleus::createShuffleVector(b, V(Nucleus::createNullValue(Byte16::getType())), swizzle);
5574
5575 int swizzle2[8] = {0, 8, 1, 9, 2, 10, 3, 11};
5576 Value *d = Nucleus::createBitCast(c, Short8::getType());
5577 e = Nucleus::createShuffleVector(d, V(Nucleus::createNullValue(Short8::getType())), swizzle2);
5578
5579 Value *f = Nucleus::createBitCast(e, Int4::getType());
5580 storeValue(f);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005581 }
5582
Nicolas Capenscb986762017-01-20 11:34:37 -05005583 Int4::Int4(RValue<SByte4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005584 {
Nicolas Capensd4227962016-11-09 14:24:25 -05005585 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
5586 Value *a = Nucleus::createInsertElement(loadValue(), x, 0);
5587
Nicolas Capensd4227962016-11-09 14:24:25 -05005588 int swizzle[16] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7};
5589 Value *b = Nucleus::createBitCast(a, Byte16::getType());
5590 Value *c = Nucleus::createShuffleVector(b, b, swizzle);
5591
5592 int swizzle2[8] = {0, 0, 1, 1, 2, 2, 3, 3};
5593 Value *d = Nucleus::createBitCast(c, Short8::getType());
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005594 Value *e = Nucleus::createShuffleVector(d, d, swizzle2);
Nicolas Capensd4227962016-11-09 14:24:25 -05005595
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005596 *this = As<Int4>(e) >> 24;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005597 }
5598
Nicolas Capenscb986762017-01-20 11:34:37 -05005599 Int4::Int4(RValue<Float4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005600 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005601 Value *xyzw = Nucleus::createFPToSI(cast.value, Int4::getType());
5602
5603 storeValue(xyzw);
5604 }
5605
Nicolas Capenscb986762017-01-20 11:34:37 -05005606 Int4::Int4(RValue<Short4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005607 {
Nicolas Capensd4227962016-11-09 14:24:25 -05005608 int swizzle[8] = {0, 0, 1, 1, 2, 2, 3, 3};
5609 Value *c = Nucleus::createShuffleVector(cast.value, cast.value, swizzle);
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005610
5611 *this = As<Int4>(c) >> 16;
Nicolas Capens598f8d82016-09-26 15:09:10 -04005612 }
5613
Nicolas Capenscb986762017-01-20 11:34:37 -05005614 Int4::Int4(RValue<UShort4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005615 {
Nicolas Capensd4227962016-11-09 14:24:25 -05005616 int swizzle[8] = {0, 8, 1, 9, 2, 10, 3, 11};
5617 Value *c = Nucleus::createShuffleVector(cast.value, Short8(0, 0, 0, 0, 0, 0, 0, 0).loadValue(), swizzle);
5618 Value *d = Nucleus::createBitCast(c, Int4::getType());
5619 storeValue(d);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005620 }
5621
Nicolas Capenscb986762017-01-20 11:34:37 -05005622 Int4::Int4(int xyzw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005623 {
5624 constant(xyzw, xyzw, xyzw, xyzw);
5625 }
5626
Nicolas Capenscb986762017-01-20 11:34:37 -05005627 Int4::Int4(int x, int yzw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005628 {
5629 constant(x, yzw, yzw, yzw);
5630 }
5631
Nicolas Capenscb986762017-01-20 11:34:37 -05005632 Int4::Int4(int x, int y, int zw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005633 {
5634 constant(x, y, zw, zw);
5635 }
5636
Nicolas Capenscb986762017-01-20 11:34:37 -05005637 Int4::Int4(int x, int y, int z, int w) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005638 {
5639 constant(x, y, z, w);
5640 }
5641
5642 void Int4::constant(int x, int y, int z, int w)
5643 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04005644 int64_t constantVector[4] = {x, y, z, w};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04005645 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005646 }
5647
Nicolas Capenscb986762017-01-20 11:34:37 -05005648 Int4::Int4(RValue<Int4> rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005649 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005650 storeValue(rhs.value);
5651 }
5652
Nicolas Capenscb986762017-01-20 11:34:37 -05005653 Int4::Int4(const Int4 &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005654 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005655 Value *value = rhs.loadValue();
5656 storeValue(value);
5657 }
5658
Nicolas Capenscb986762017-01-20 11:34:37 -05005659 Int4::Int4(const Reference<Int4> &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005660 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005661 Value *value = rhs.loadValue();
5662 storeValue(value);
5663 }
5664
Nicolas Capenscb986762017-01-20 11:34:37 -05005665 Int4::Int4(RValue<UInt4> rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005666 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005667 storeValue(rhs.value);
5668 }
5669
Nicolas Capenscb986762017-01-20 11:34:37 -05005670 Int4::Int4(const UInt4 &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005671 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005672 Value *value = rhs.loadValue();
5673 storeValue(value);
5674 }
5675
Nicolas Capenscb986762017-01-20 11:34:37 -05005676 Int4::Int4(const Reference<UInt4> &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005677 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005678 Value *value = rhs.loadValue();
5679 storeValue(value);
5680 }
5681
Nicolas Capenscb986762017-01-20 11:34:37 -05005682 Int4::Int4(RValue<Int2> lo, RValue<Int2> hi) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005683 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05005684 int shuffle[4] = {0, 1, 4, 5}; // Real type is v4i32
5685 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
5686
5687 storeValue(packed);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005688 }
5689
Nicolas Capenscb986762017-01-20 11:34:37 -05005690 Int4::Int4(RValue<Int> rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005691 {
Nicolas Capensf8beb4b2017-01-27 02:55:44 -08005692 Value *vector = Nucleus::createBitCast(rhs.value, Int4::getType());
Nicolas Capensd4227962016-11-09 14:24:25 -05005693
5694 int swizzle[4] = {0, 0, 0, 0};
Nicolas Capensf8beb4b2017-01-27 02:55:44 -08005695 Value *replicate = Nucleus::createShuffleVector(vector, vector, swizzle);
Nicolas Capensd4227962016-11-09 14:24:25 -05005696
5697 storeValue(replicate);
Nicolas Capens598f8d82016-09-26 15:09:10 -04005698 }
5699
Nicolas Capenscb986762017-01-20 11:34:37 -05005700 Int4::Int4(const Int &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005701 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005702 *this = RValue<Int>(rhs.loadValue());
5703 }
5704
Nicolas Capenscb986762017-01-20 11:34:37 -05005705 Int4::Int4(const Reference<Int> &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005706 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04005707 *this = RValue<Int>(rhs.loadValue());
5708 }
5709
Nicolas Capens96d4e092016-11-18 14:22:38 -05005710 RValue<Int4> Int4::operator=(RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005711 {
5712 storeValue(rhs.value);
5713
5714 return rhs;
5715 }
5716
Nicolas Capens96d4e092016-11-18 14:22:38 -05005717 RValue<Int4> Int4::operator=(const 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
Nicolas Capens96d4e092016-11-18 14:22:38 -05005725 RValue<Int4> Int4::operator=(const Reference<Int4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005726 {
5727 Value *value = rhs.loadValue();
5728 storeValue(value);
5729
5730 return RValue<Int4>(value);
5731 }
5732
5733 RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs)
5734 {
5735 return RValue<Int4>(Nucleus::createAdd(lhs.value, rhs.value));
5736 }
5737
5738 RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs)
5739 {
5740 return RValue<Int4>(Nucleus::createSub(lhs.value, rhs.value));
5741 }
5742
5743 RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs)
5744 {
5745 return RValue<Int4>(Nucleus::createMul(lhs.value, rhs.value));
5746 }
5747
5748 RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs)
5749 {
5750 return RValue<Int4>(Nucleus::createSDiv(lhs.value, rhs.value));
5751 }
5752
5753 RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs)
5754 {
5755 return RValue<Int4>(Nucleus::createSRem(lhs.value, rhs.value));
5756 }
5757
5758 RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs)
5759 {
5760 return RValue<Int4>(Nucleus::createAnd(lhs.value, rhs.value));
5761 }
5762
5763 RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs)
5764 {
5765 return RValue<Int4>(Nucleus::createOr(lhs.value, rhs.value));
5766 }
5767
5768 RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs)
5769 {
5770 return RValue<Int4>(Nucleus::createXor(lhs.value, rhs.value));
5771 }
5772
5773 RValue<Int4> operator<<(RValue<Int4> lhs, unsigned char rhs)
5774 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005775 if(emulateIntrinsics)
5776 {
5777 Int4 result;
5778 result = Insert(result, Extract(lhs, 0) << Int(rhs), 0);
5779 result = Insert(result, Extract(lhs, 1) << Int(rhs), 1);
5780 result = Insert(result, Extract(lhs, 2) << Int(rhs), 2);
5781 result = Insert(result, Extract(lhs, 3) << Int(rhs), 3);
5782
5783 return result;
5784 }
5785 else
5786 {
5787 return RValue<Int4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
5788 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005789 }
5790
5791 RValue<Int4> operator>>(RValue<Int4> lhs, unsigned char rhs)
5792 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04005793 if(emulateIntrinsics)
5794 {
5795 Int4 result;
5796 result = Insert(result, Extract(lhs, 0) >> Int(rhs), 0);
5797 result = Insert(result, Extract(lhs, 1) >> Int(rhs), 1);
5798 result = Insert(result, Extract(lhs, 2) >> Int(rhs), 2);
5799 result = Insert(result, Extract(lhs, 3) >> Int(rhs), 3);
5800
5801 return result;
5802 }
5803 else
5804 {
5805 return RValue<Int4>(Nucleus::createAShr(lhs.value, V(::context->getConstantInt32(rhs))));
5806 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005807 }
5808
5809 RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs)
5810 {
5811 return RValue<Int4>(Nucleus::createShl(lhs.value, rhs.value));
5812 }
5813
5814 RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs)
5815 {
5816 return RValue<Int4>(Nucleus::createAShr(lhs.value, rhs.value));
5817 }
5818
Nicolas Capens96d4e092016-11-18 14:22:38 -05005819 RValue<Int4> operator+=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005820 {
5821 return lhs = lhs + rhs;
5822 }
5823
Nicolas Capens96d4e092016-11-18 14:22:38 -05005824 RValue<Int4> operator-=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005825 {
5826 return lhs = lhs - rhs;
5827 }
5828
Nicolas Capens96d4e092016-11-18 14:22:38 -05005829 RValue<Int4> operator*=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005830 {
5831 return lhs = lhs * rhs;
5832 }
5833
Nicolas Capens96d4e092016-11-18 14:22:38 -05005834// RValue<Int4> operator/=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005835// {
5836// return lhs = lhs / rhs;
5837// }
5838
Nicolas Capens96d4e092016-11-18 14:22:38 -05005839// RValue<Int4> operator%=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005840// {
5841// return lhs = lhs % rhs;
5842// }
5843
Nicolas Capens96d4e092016-11-18 14:22:38 -05005844 RValue<Int4> operator&=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005845 {
5846 return lhs = lhs & rhs;
5847 }
5848
Nicolas Capens96d4e092016-11-18 14:22:38 -05005849 RValue<Int4> operator|=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005850 {
5851 return lhs = lhs | rhs;
5852 }
5853
Nicolas Capens96d4e092016-11-18 14:22:38 -05005854 RValue<Int4> operator^=(Int4 &lhs, RValue<Int4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005855 {
5856 return lhs = lhs ^ rhs;
5857 }
5858
Nicolas Capens96d4e092016-11-18 14:22:38 -05005859 RValue<Int4> operator<<=(Int4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005860 {
5861 return lhs = lhs << rhs;
5862 }
5863
Nicolas Capens96d4e092016-11-18 14:22:38 -05005864 RValue<Int4> operator>>=(Int4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005865 {
5866 return lhs = lhs >> rhs;
5867 }
5868
5869 RValue<Int4> operator+(RValue<Int4> val)
5870 {
5871 return val;
5872 }
5873
5874 RValue<Int4> operator-(RValue<Int4> val)
5875 {
5876 return RValue<Int4>(Nucleus::createNeg(val.value));
5877 }
5878
5879 RValue<Int4> operator~(RValue<Int4> val)
5880 {
5881 return RValue<Int4>(Nucleus::createNot(val.value));
5882 }
5883
5884 RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y)
5885 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005886 return RValue<Int4>(Nucleus::createICmpEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005887 }
5888
5889 RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y)
5890 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005891 return RValue<Int4>(Nucleus::createICmpSLT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005892 }
5893
5894 RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y)
5895 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005896 return RValue<Int4>(Nucleus::createICmpSLE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005897 }
5898
5899 RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y)
5900 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005901 return RValue<Int4>(Nucleus::createICmpNE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005902 }
5903
5904 RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y)
5905 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005906 return RValue<Int4>(Nucleus::createICmpSGE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005907 }
5908
5909 RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y)
5910 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05005911 return RValue<Int4>(Nucleus::createICmpSGT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005912 }
5913
5914 RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y)
5915 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04005916 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
5917 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sle, condition, x.value, y.value);
5918 ::basicBlock->appendInst(cmp);
5919
5920 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5921 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
5922 ::basicBlock->appendInst(select);
5923
5924 return RValue<Int4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005925 }
5926
5927 RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y)
5928 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04005929 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
5930 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sgt, condition, x.value, y.value);
5931 ::basicBlock->appendInst(cmp);
5932
5933 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5934 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
5935 ::basicBlock->appendInst(select);
5936
5937 return RValue<Int4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04005938 }
5939
5940 RValue<Int4> RoundInt(RValue<Float4> cast)
5941 {
Nicolas Capens091f3502017-10-03 14:56:49 -04005942 if(emulateIntrinsics || CPUID::ARM)
Nicolas Capensf7b75882017-04-26 09:30:47 -04005943 {
5944 // Push the fractional part off the mantissa. Accurate up to +/-2^22.
5945 return Int4((cast + Float4(0x00C00000)) - Float4(0x00C00000));
5946 }
5947 else
5948 {
5949 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
5950 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Nearbyint, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5951 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5952 auto nearbyint = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
5953 nearbyint->addArg(cast.value);
5954 ::basicBlock->appendInst(nearbyint);
Nicolas Capensa8086512016-11-07 17:32:17 -05005955
Nicolas Capensf7b75882017-04-26 09:30:47 -04005956 return RValue<Int4>(V(result));
5957 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005958 }
5959
Nicolas Capens33438a62017-09-27 11:47:35 -04005960 RValue<Short8> PackSigned(RValue<Int4> x, RValue<Int4> y)
Nicolas Capens598f8d82016-09-26 15:09:10 -04005961 {
Nicolas Capens8960fbf2017-07-25 15:32:12 -04005962 if(emulateIntrinsics)
5963 {
5964 Short8 result;
Nicolas Capens33438a62017-09-27 11:47:35 -04005965 result = Insert(result, SaturateSigned(Extract(x, 0)), 0);
5966 result = Insert(result, SaturateSigned(Extract(x, 1)), 1);
5967 result = Insert(result, SaturateSigned(Extract(x, 2)), 2);
5968 result = Insert(result, SaturateSigned(Extract(x, 3)), 3);
5969 result = Insert(result, SaturateSigned(Extract(y, 0)), 4);
5970 result = Insert(result, SaturateSigned(Extract(y, 1)), 5);
5971 result = Insert(result, SaturateSigned(Extract(y, 2)), 6);
5972 result = Insert(result, SaturateSigned(Extract(y, 3)), 7);
Nicolas Capensec54a172016-10-25 17:32:37 -04005973
Nicolas Capens8960fbf2017-07-25 15:32:12 -04005974 return result;
5975 }
5976 else
5977 {
5978 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
5979 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackSigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
5980 auto target = ::context->getConstantUndef(Ice::IceType_i32);
5981 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
5982 pack->addArg(x.value);
5983 pack->addArg(y.value);
5984 ::basicBlock->appendInst(pack);
5985
5986 return RValue<Short8>(V(result));
5987 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04005988 }
5989
Nicolas Capens33438a62017-09-27 11:47:35 -04005990 RValue<UShort8> PackUnsigned(RValue<Int4> x, RValue<Int4> y)
5991 {
Nicolas Capens091f3502017-10-03 14:56:49 -04005992 if(emulateIntrinsics || !(CPUID::SSE4_1 || CPUID::ARM))
5993 {
5994 RValue<Int4> sx = As<Int4>(x);
5995 RValue<Int4> bx = (sx & ~(sx >> 31)) - Int4(0x8000);
5996
5997 RValue<Int4> sy = As<Int4>(y);
5998 RValue<Int4> by = (sy & ~(sy >> 31)) - Int4(0x8000);
5999
6000 return As<UShort8>(PackSigned(bx, by) + Short8(0x8000u));
6001 }
6002 else
Nicolas Capens33438a62017-09-27 11:47:35 -04006003 {
6004 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
6005 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6006 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6007 auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
6008 pack->addArg(x.value);
6009 pack->addArg(y.value);
6010 ::basicBlock->appendInst(pack);
6011
6012 return RValue<UShort8>(V(result));
6013 }
Nicolas Capens33438a62017-09-27 11:47:35 -04006014 }
6015
Nicolas Capens598f8d82016-09-26 15:09:10 -04006016 RValue<Int> Extract(RValue<Int4> x, int i)
6017 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006018 return RValue<Int>(Nucleus::createExtractElement(x.value, Int::getType(), i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006019 }
6020
6021 RValue<Int4> Insert(RValue<Int4> x, RValue<Int> element, int i)
6022 {
6023 return RValue<Int4>(Nucleus::createInsertElement(x.value, element.value, i));
6024 }
6025
6026 RValue<Int> SignMask(RValue<Int4> x)
6027 {
Nicolas Capens091f3502017-10-03 14:56:49 -04006028 if(emulateIntrinsics || CPUID::ARM)
Nicolas Capensd6cacad2017-07-25 15:32:12 -04006029 {
6030 Int4 xx = (x >> 31) & Int4(0x00000001, 0x00000002, 0x00000004, 0x00000008);
6031 return Extract(xx, 0) | Extract(xx, 1) | Extract(xx, 2) | Extract(xx, 3);
6032 }
6033 else
6034 {
6035 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
6036 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6037 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6038 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
6039 movmsk->addArg(x.value);
6040 ::basicBlock->appendInst(movmsk);
Nicolas Capensf2cb9df2016-10-21 17:26:13 -04006041
Nicolas Capensd6cacad2017-07-25 15:32:12 -04006042 return RValue<Int>(V(result));
6043 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04006044 }
6045
6046 RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select)
6047 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006048 return RValue<Int4>(createSwizzle4(x.value, select));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006049 }
6050
6051 Type *Int4::getType()
6052 {
Nicolas Capens23d99a42016-09-30 14:57:16 -04006053 return T(Ice::IceType_v4i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006054 }
6055
Nicolas Capenscb986762017-01-20 11:34:37 -05006056 UInt4::UInt4() : XYZW(this)
6057 {
6058 }
6059
6060 UInt4::UInt4(RValue<Float4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006061 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05006062 // Smallest positive value representable in UInt, but not in Int
6063 const unsigned int ustart = 0x80000000u;
6064 const float ustartf = float(ustart);
6065
6066 // Check if the value can be represented as an Int
6067 Int4 uiValue = CmpNLT(cast, Float4(ustartf));
6068 // If the value is too large, subtract ustart and re-add it after conversion.
6069 uiValue = (uiValue & As<Int4>(As<UInt4>(Int4(cast - Float4(ustartf))) + UInt4(ustart))) |
6070 // Otherwise, just convert normally
6071 (~uiValue & Int4(cast));
6072 // If the value is negative, store 0, otherwise store the result of the conversion
6073 storeValue((~(As<Int4>(cast) >> 31) & uiValue).value);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006074 }
6075
Nicolas Capenscb986762017-01-20 11:34:37 -05006076 UInt4::UInt4(int xyzw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006077 {
6078 constant(xyzw, xyzw, xyzw, xyzw);
6079 }
6080
Nicolas Capenscb986762017-01-20 11:34:37 -05006081 UInt4::UInt4(int x, int yzw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006082 {
6083 constant(x, yzw, yzw, yzw);
6084 }
6085
Nicolas Capenscb986762017-01-20 11:34:37 -05006086 UInt4::UInt4(int x, int y, int zw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006087 {
6088 constant(x, y, zw, zw);
6089 }
6090
Nicolas Capenscb986762017-01-20 11:34:37 -05006091 UInt4::UInt4(int x, int y, int z, int w) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006092 {
6093 constant(x, y, z, w);
6094 }
6095
6096 void UInt4::constant(int x, int y, int z, int w)
6097 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04006098 int64_t constantVector[4] = {x, y, z, w};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04006099 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006100 }
6101
Nicolas Capenscb986762017-01-20 11:34:37 -05006102 UInt4::UInt4(RValue<UInt4> rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006103 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006104 storeValue(rhs.value);
6105 }
6106
Nicolas Capenscb986762017-01-20 11:34:37 -05006107 UInt4::UInt4(const UInt4 &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006108 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006109 Value *value = rhs.loadValue();
6110 storeValue(value);
6111 }
6112
Nicolas Capenscb986762017-01-20 11:34:37 -05006113 UInt4::UInt4(const Reference<UInt4> &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006114 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006115 Value *value = rhs.loadValue();
6116 storeValue(value);
6117 }
6118
Nicolas Capenscb986762017-01-20 11:34:37 -05006119 UInt4::UInt4(RValue<Int4> rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006120 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006121 storeValue(rhs.value);
6122 }
6123
Nicolas Capenscb986762017-01-20 11:34:37 -05006124 UInt4::UInt4(const Int4 &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006125 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006126 Value *value = rhs.loadValue();
6127 storeValue(value);
6128 }
6129
Nicolas Capenscb986762017-01-20 11:34:37 -05006130 UInt4::UInt4(const Reference<Int4> &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006131 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006132 Value *value = rhs.loadValue();
6133 storeValue(value);
6134 }
6135
Nicolas Capenscb986762017-01-20 11:34:37 -05006136 UInt4::UInt4(RValue<UInt2> lo, RValue<UInt2> hi) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006137 {
Nicolas Capensc70a1162016-12-03 00:16:14 -05006138 int shuffle[4] = {0, 1, 4, 5}; // Real type is v4i32
6139 Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
6140
6141 storeValue(packed);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006142 }
6143
Nicolas Capens96d4e092016-11-18 14:22:38 -05006144 RValue<UInt4> UInt4::operator=(RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006145 {
6146 storeValue(rhs.value);
6147
6148 return rhs;
6149 }
6150
Nicolas Capens96d4e092016-11-18 14:22:38 -05006151 RValue<UInt4> UInt4::operator=(const 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
Nicolas Capens96d4e092016-11-18 14:22:38 -05006159 RValue<UInt4> UInt4::operator=(const Reference<UInt4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006160 {
6161 Value *value = rhs.loadValue();
6162 storeValue(value);
6163
6164 return RValue<UInt4>(value);
6165 }
6166
6167 RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs)
6168 {
6169 return RValue<UInt4>(Nucleus::createAdd(lhs.value, rhs.value));
6170 }
6171
6172 RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs)
6173 {
6174 return RValue<UInt4>(Nucleus::createSub(lhs.value, rhs.value));
6175 }
6176
6177 RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs)
6178 {
6179 return RValue<UInt4>(Nucleus::createMul(lhs.value, rhs.value));
6180 }
6181
6182 RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs)
6183 {
6184 return RValue<UInt4>(Nucleus::createUDiv(lhs.value, rhs.value));
6185 }
6186
6187 RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs)
6188 {
6189 return RValue<UInt4>(Nucleus::createURem(lhs.value, rhs.value));
6190 }
6191
6192 RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs)
6193 {
6194 return RValue<UInt4>(Nucleus::createAnd(lhs.value, rhs.value));
6195 }
6196
6197 RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs)
6198 {
6199 return RValue<UInt4>(Nucleus::createOr(lhs.value, rhs.value));
6200 }
6201
6202 RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs)
6203 {
6204 return RValue<UInt4>(Nucleus::createXor(lhs.value, rhs.value));
6205 }
6206
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04006207 RValue<UInt> Extract(RValue<UInt4> x, int i)
6208 {
6209 return RValue<UInt>(Nucleus::createExtractElement(x.value, UInt::getType(), i));
6210 }
6211
6212 RValue<UInt4> Insert(RValue<UInt4> x, RValue<UInt> element, int i)
6213 {
6214 return RValue<UInt4>(Nucleus::createInsertElement(x.value, element.value, i));
6215 }
6216
Nicolas Capens598f8d82016-09-26 15:09:10 -04006217 RValue<UInt4> operator<<(RValue<UInt4> lhs, unsigned char rhs)
6218 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04006219 if(emulateIntrinsics)
6220 {
6221 UInt4 result;
6222 result = Insert(result, Extract(lhs, 0) << UInt(rhs), 0);
6223 result = Insert(result, Extract(lhs, 1) << UInt(rhs), 1);
6224 result = Insert(result, Extract(lhs, 2) << UInt(rhs), 2);
6225 result = Insert(result, Extract(lhs, 3) << UInt(rhs), 3);
6226
6227 return result;
6228 }
6229 else
6230 {
6231 return RValue<UInt4>(Nucleus::createShl(lhs.value, V(::context->getConstantInt32(rhs))));
6232 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04006233 }
6234
6235 RValue<UInt4> operator>>(RValue<UInt4> lhs, unsigned char rhs)
6236 {
Nicolas Capens8be6c7b2017-07-25 15:32:12 -04006237 if(emulateIntrinsics)
6238 {
6239 UInt4 result;
6240 result = Insert(result, Extract(lhs, 0) >> UInt(rhs), 0);
6241 result = Insert(result, Extract(lhs, 1) >> UInt(rhs), 1);
6242 result = Insert(result, Extract(lhs, 2) >> UInt(rhs), 2);
6243 result = Insert(result, Extract(lhs, 3) >> UInt(rhs), 3);
6244
6245 return result;
6246 }
6247 else
6248 {
6249 return RValue<UInt4>(Nucleus::createLShr(lhs.value, V(::context->getConstantInt32(rhs))));
6250 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04006251 }
6252
6253 RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs)
6254 {
6255 return RValue<UInt4>(Nucleus::createShl(lhs.value, rhs.value));
6256 }
6257
6258 RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs)
6259 {
6260 return RValue<UInt4>(Nucleus::createLShr(lhs.value, rhs.value));
6261 }
6262
Nicolas Capens96d4e092016-11-18 14:22:38 -05006263 RValue<UInt4> operator+=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006264 {
6265 return lhs = lhs + rhs;
6266 }
6267
Nicolas Capens96d4e092016-11-18 14:22:38 -05006268 RValue<UInt4> operator-=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006269 {
6270 return lhs = lhs - rhs;
6271 }
6272
Nicolas Capens96d4e092016-11-18 14:22:38 -05006273 RValue<UInt4> operator*=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006274 {
6275 return lhs = lhs * rhs;
6276 }
6277
Nicolas Capens96d4e092016-11-18 14:22:38 -05006278// RValue<UInt4> operator/=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006279// {
6280// return lhs = lhs / rhs;
6281// }
6282
Nicolas Capens96d4e092016-11-18 14:22:38 -05006283// RValue<UInt4> operator%=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006284// {
6285// return lhs = lhs % rhs;
6286// }
6287
Nicolas Capens96d4e092016-11-18 14:22:38 -05006288 RValue<UInt4> operator&=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006289 {
6290 return lhs = lhs & rhs;
6291 }
6292
Nicolas Capens96d4e092016-11-18 14:22:38 -05006293 RValue<UInt4> operator|=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006294 {
6295 return lhs = lhs | rhs;
6296 }
6297
Nicolas Capens96d4e092016-11-18 14:22:38 -05006298 RValue<UInt4> operator^=(UInt4 &lhs, RValue<UInt4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006299 {
6300 return lhs = lhs ^ rhs;
6301 }
6302
Nicolas Capens96d4e092016-11-18 14:22:38 -05006303 RValue<UInt4> operator<<=(UInt4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006304 {
6305 return lhs = lhs << rhs;
6306 }
6307
Nicolas Capens96d4e092016-11-18 14:22:38 -05006308 RValue<UInt4> operator>>=(UInt4 &lhs, unsigned char rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006309 {
6310 return lhs = lhs >> rhs;
6311 }
6312
6313 RValue<UInt4> operator+(RValue<UInt4> val)
6314 {
6315 return val;
6316 }
6317
6318 RValue<UInt4> operator-(RValue<UInt4> val)
6319 {
6320 return RValue<UInt4>(Nucleus::createNeg(val.value));
6321 }
6322
6323 RValue<UInt4> operator~(RValue<UInt4> val)
6324 {
6325 return RValue<UInt4>(Nucleus::createNot(val.value));
6326 }
6327
6328 RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y)
6329 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006330 return RValue<UInt4>(Nucleus::createICmpEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006331 }
6332
6333 RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y)
6334 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006335 return RValue<UInt4>(Nucleus::createICmpULT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006336 }
6337
6338 RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y)
6339 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006340 return RValue<UInt4>(Nucleus::createICmpULE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006341 }
6342
6343 RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y)
6344 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006345 return RValue<UInt4>(Nucleus::createICmpNE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006346 }
6347
6348 RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y)
6349 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006350 return RValue<UInt4>(Nucleus::createICmpUGE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006351 }
6352
6353 RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y)
6354 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006355 return RValue<UInt4>(Nucleus::createICmpUGT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006356 }
6357
6358 RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y)
6359 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006360 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
6361 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ule, condition, x.value, y.value);
6362 ::basicBlock->appendInst(cmp);
6363
6364 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
6365 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
6366 ::basicBlock->appendInst(select);
6367
6368 return RValue<UInt4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006369 }
6370
6371 RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y)
6372 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006373 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
6374 auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ugt, condition, x.value, y.value);
6375 ::basicBlock->appendInst(cmp);
6376
6377 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
6378 auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
6379 ::basicBlock->appendInst(select);
6380
6381 return RValue<UInt4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006382 }
6383
Nicolas Capens598f8d82016-09-26 15:09:10 -04006384 Type *UInt4::getType()
6385 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04006386 return T(Ice::IceType_v4i32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006387 }
6388
6389 Float::Float(RValue<Int> cast)
6390 {
6391 Value *integer = Nucleus::createSIToFP(cast.value, Float::getType());
6392
6393 storeValue(integer);
6394 }
6395
Alexis Hetucfd96322017-07-24 14:44:33 -04006396 Float::Float(RValue<UInt> cast)
6397 {
6398 RValue<Float> result = Float(Int(cast & UInt(0x7FFFFFFF))) +
6399 As<Float>((As<Int>(cast) >> 31) & As<Int>(Float(0x80000000u)));
6400
6401 storeValue(result.value);
6402 }
6403
Nicolas Capens598f8d82016-09-26 15:09:10 -04006404 Float::Float(float x)
6405 {
6406 storeValue(Nucleus::createConstantFloat(x));
6407 }
6408
6409 Float::Float(RValue<Float> rhs)
6410 {
6411 storeValue(rhs.value);
6412 }
6413
6414 Float::Float(const Float &rhs)
6415 {
6416 Value *value = rhs.loadValue();
6417 storeValue(value);
6418 }
6419
6420 Float::Float(const Reference<Float> &rhs)
6421 {
6422 Value *value = rhs.loadValue();
6423 storeValue(value);
6424 }
6425
Nicolas Capens96d4e092016-11-18 14:22:38 -05006426 RValue<Float> Float::operator=(RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006427 {
6428 storeValue(rhs.value);
6429
6430 return rhs;
6431 }
6432
Nicolas Capens96d4e092016-11-18 14:22:38 -05006433 RValue<Float> Float::operator=(const 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
Nicolas Capens96d4e092016-11-18 14:22:38 -05006441 RValue<Float> Float::operator=(const Reference<Float> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006442 {
6443 Value *value = rhs.loadValue();
6444 storeValue(value);
6445
6446 return RValue<Float>(value);
6447 }
6448
6449 RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs)
6450 {
6451 return RValue<Float>(Nucleus::createFAdd(lhs.value, rhs.value));
6452 }
6453
6454 RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs)
6455 {
6456 return RValue<Float>(Nucleus::createFSub(lhs.value, rhs.value));
6457 }
6458
6459 RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs)
6460 {
6461 return RValue<Float>(Nucleus::createFMul(lhs.value, rhs.value));
6462 }
6463
6464 RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs)
6465 {
6466 return RValue<Float>(Nucleus::createFDiv(lhs.value, rhs.value));
6467 }
6468
Nicolas Capens96d4e092016-11-18 14:22:38 -05006469 RValue<Float> operator+=(Float &lhs, RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006470 {
6471 return lhs = lhs + rhs;
6472 }
6473
Nicolas Capens96d4e092016-11-18 14:22:38 -05006474 RValue<Float> operator-=(Float &lhs, RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006475 {
6476 return lhs = lhs - rhs;
6477 }
6478
Nicolas Capens96d4e092016-11-18 14:22:38 -05006479 RValue<Float> operator*=(Float &lhs, RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006480 {
6481 return lhs = lhs * rhs;
6482 }
6483
Nicolas Capens96d4e092016-11-18 14:22:38 -05006484 RValue<Float> operator/=(Float &lhs, RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006485 {
6486 return lhs = lhs / rhs;
6487 }
6488
6489 RValue<Float> operator+(RValue<Float> val)
6490 {
6491 return val;
6492 }
6493
6494 RValue<Float> operator-(RValue<Float> val)
6495 {
6496 return RValue<Float>(Nucleus::createFNeg(val.value));
6497 }
6498
6499 RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs)
6500 {
6501 return RValue<Bool>(Nucleus::createFCmpOLT(lhs.value, rhs.value));
6502 }
6503
6504 RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs)
6505 {
6506 return RValue<Bool>(Nucleus::createFCmpOLE(lhs.value, rhs.value));
6507 }
6508
6509 RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs)
6510 {
6511 return RValue<Bool>(Nucleus::createFCmpOGT(lhs.value, rhs.value));
6512 }
6513
6514 RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs)
6515 {
6516 return RValue<Bool>(Nucleus::createFCmpOGE(lhs.value, rhs.value));
6517 }
6518
6519 RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs)
6520 {
6521 return RValue<Bool>(Nucleus::createFCmpONE(lhs.value, rhs.value));
6522 }
6523
6524 RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs)
6525 {
6526 return RValue<Bool>(Nucleus::createFCmpOEQ(lhs.value, rhs.value));
6527 }
6528
6529 RValue<Float> Abs(RValue<Float> x)
6530 {
6531 return IfThenElse(x > 0.0f, x, -x);
6532 }
6533
6534 RValue<Float> Max(RValue<Float> x, RValue<Float> y)
6535 {
6536 return IfThenElse(x > y, x, y);
6537 }
6538
6539 RValue<Float> Min(RValue<Float> x, RValue<Float> y)
6540 {
6541 return IfThenElse(x < y, x, y);
6542 }
6543
6544 RValue<Float> Rcp_pp(RValue<Float> x, bool exactAtPow2)
6545 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04006546 return 1.0f / x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04006547 }
6548
6549 RValue<Float> RcpSqrt_pp(RValue<Float> x)
6550 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04006551 return Rcp_pp(Sqrt(x));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006552 }
6553
6554 RValue<Float> Sqrt(RValue<Float> x)
6555 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04006556 Ice::Variable *result = ::function->makeVariable(Ice::IceType_f32);
6557 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Sqrt, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6558 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6559 auto sqrt = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
6560 sqrt->addArg(x.value);
6561 ::basicBlock->appendInst(sqrt);
6562
6563 return RValue<Float>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006564 }
6565
6566 RValue<Float> Round(RValue<Float> x)
6567 {
Nicolas Capensa8086512016-11-07 17:32:17 -05006568 return Float4(Round(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04006569 }
6570
6571 RValue<Float> Trunc(RValue<Float> x)
6572 {
Nicolas Capensa8086512016-11-07 17:32:17 -05006573 return Float4(Trunc(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04006574 }
6575
6576 RValue<Float> Frac(RValue<Float> x)
6577 {
Nicolas Capensa8086512016-11-07 17:32:17 -05006578 return Float4(Frac(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04006579 }
6580
6581 RValue<Float> Floor(RValue<Float> x)
6582 {
Nicolas Capensa8086512016-11-07 17:32:17 -05006583 return Float4(Floor(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04006584 }
6585
6586 RValue<Float> Ceil(RValue<Float> x)
6587 {
Nicolas Capensa8086512016-11-07 17:32:17 -05006588 return Float4(Ceil(Float4(x))).x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04006589 }
6590
6591 Type *Float::getType()
6592 {
Nicolas Capens9709d4f2016-09-30 11:44:14 -04006593 return T(Ice::IceType_f32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006594 }
6595
6596 Float2::Float2(RValue<Float4> cast)
6597 {
Nicolas Capens22008782016-10-20 01:11:47 -04006598 storeValue(Nucleus::createBitCast(cast.value, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006599 }
6600
6601 Type *Float2::getType()
6602 {
Nicolas Capens4cfd4572016-10-20 01:00:19 -04006603 return T(Type_v2f32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006604 }
6605
Nicolas Capenscb986762017-01-20 11:34:37 -05006606 Float4::Float4(RValue<Byte4> 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<SByte4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006615 {
Nicolas Capensd4227962016-11-09 14:24:25 -05006616 Value *a = Int4(cast).loadValue();
6617 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
6618
6619 storeValue(xyzw);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006620 }
6621
Nicolas Capenscb986762017-01-20 11:34:37 -05006622 Float4::Float4(RValue<Short4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006623 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006624 Int4 c(cast);
6625 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
6626 }
6627
Nicolas Capenscb986762017-01-20 11:34:37 -05006628 Float4::Float4(RValue<UShort4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006629 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006630 Int4 c(cast);
6631 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
6632 }
6633
Nicolas Capenscb986762017-01-20 11:34:37 -05006634 Float4::Float4(RValue<Int4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006635 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006636 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType());
6637
6638 storeValue(xyzw);
6639 }
6640
Nicolas Capenscb986762017-01-20 11:34:37 -05006641 Float4::Float4(RValue<UInt4> cast) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006642 {
Nicolas Capens96445fe2016-12-15 14:45:13 -05006643 RValue<Float4> result = Float4(Int4(cast & UInt4(0x7FFFFFFF))) +
6644 As<Float4>((As<Int4>(cast) >> 31) & As<Int4>(Float4(0x80000000u)));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006645
Nicolas Capens96445fe2016-12-15 14:45:13 -05006646 storeValue(result.value);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006647 }
6648
Nicolas Capenscb986762017-01-20 11:34:37 -05006649 Float4::Float4() : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006650 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006651 }
6652
Nicolas Capenscb986762017-01-20 11:34:37 -05006653 Float4::Float4(float xyzw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006654 {
6655 constant(xyzw, xyzw, xyzw, xyzw);
6656 }
6657
Nicolas Capenscb986762017-01-20 11:34:37 -05006658 Float4::Float4(float x, float yzw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006659 {
6660 constant(x, yzw, yzw, yzw);
6661 }
6662
Nicolas Capenscb986762017-01-20 11:34:37 -05006663 Float4::Float4(float x, float y, float zw) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006664 {
6665 constant(x, y, zw, zw);
6666 }
6667
Nicolas Capenscb986762017-01-20 11:34:37 -05006668 Float4::Float4(float x, float y, float z, float w) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006669 {
6670 constant(x, y, z, w);
6671 }
6672
6673 void Float4::constant(float x, float y, float z, float w)
6674 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04006675 double constantVector[4] = {x, y, z, w};
Nicolas Capens8dfd9a72016-10-13 17:44:51 -04006676 storeValue(Nucleus::createConstantVector(constantVector, getType()));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006677 }
6678
Nicolas Capenscb986762017-01-20 11:34:37 -05006679 Float4::Float4(RValue<Float4> rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006680 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006681 storeValue(rhs.value);
6682 }
6683
Nicolas Capenscb986762017-01-20 11:34:37 -05006684 Float4::Float4(const Float4 &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006685 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006686 Value *value = rhs.loadValue();
6687 storeValue(value);
6688 }
6689
Nicolas Capenscb986762017-01-20 11:34:37 -05006690 Float4::Float4(const Reference<Float4> &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006691 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006692 Value *value = rhs.loadValue();
6693 storeValue(value);
6694 }
6695
Nicolas Capenscb986762017-01-20 11:34:37 -05006696 Float4::Float4(RValue<Float> rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006697 {
Nicolas Capensf8beb4b2017-01-27 02:55:44 -08006698 Value *vector = Nucleus::createBitCast(rhs.value, Float4::getType());
Nicolas Capensd4227962016-11-09 14:24:25 -05006699
6700 int swizzle[4] = {0, 0, 0, 0};
Nicolas Capensf8beb4b2017-01-27 02:55:44 -08006701 Value *replicate = Nucleus::createShuffleVector(vector, vector, swizzle);
Nicolas Capensd4227962016-11-09 14:24:25 -05006702
6703 storeValue(replicate);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006704 }
6705
Nicolas Capenscb986762017-01-20 11:34:37 -05006706 Float4::Float4(const Float &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006707 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006708 *this = RValue<Float>(rhs.loadValue());
6709 }
6710
Nicolas Capenscb986762017-01-20 11:34:37 -05006711 Float4::Float4(const Reference<Float> &rhs) : XYZW(this)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006712 {
Nicolas Capens598f8d82016-09-26 15:09:10 -04006713 *this = RValue<Float>(rhs.loadValue());
6714 }
6715
Nicolas Capens96d4e092016-11-18 14:22:38 -05006716 RValue<Float4> Float4::operator=(float x)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006717 {
6718 return *this = Float4(x, x, x, x);
6719 }
6720
Nicolas Capens96d4e092016-11-18 14:22:38 -05006721 RValue<Float4> Float4::operator=(RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006722 {
6723 storeValue(rhs.value);
6724
6725 return rhs;
6726 }
6727
Nicolas Capens96d4e092016-11-18 14:22:38 -05006728 RValue<Float4> Float4::operator=(const 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=(const Reference<Float4> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006737 {
6738 Value *value = rhs.loadValue();
6739 storeValue(value);
6740
6741 return RValue<Float4>(value);
6742 }
6743
Nicolas Capens96d4e092016-11-18 14:22:38 -05006744 RValue<Float4> Float4::operator=(RValue<Float> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006745 {
6746 return *this = Float4(rhs);
6747 }
6748
Nicolas Capens96d4e092016-11-18 14:22:38 -05006749 RValue<Float4> Float4::operator=(const Float &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006750 {
6751 return *this = Float4(rhs);
6752 }
6753
Nicolas Capens96d4e092016-11-18 14:22:38 -05006754 RValue<Float4> Float4::operator=(const Reference<Float> &rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006755 {
6756 return *this = Float4(rhs);
6757 }
6758
6759 RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs)
6760 {
6761 return RValue<Float4>(Nucleus::createFAdd(lhs.value, rhs.value));
6762 }
6763
6764 RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs)
6765 {
6766 return RValue<Float4>(Nucleus::createFSub(lhs.value, rhs.value));
6767 }
6768
6769 RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs)
6770 {
6771 return RValue<Float4>(Nucleus::createFMul(lhs.value, rhs.value));
6772 }
6773
6774 RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs)
6775 {
6776 return RValue<Float4>(Nucleus::createFDiv(lhs.value, rhs.value));
6777 }
6778
6779 RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs)
6780 {
6781 return RValue<Float4>(Nucleus::createFRem(lhs.value, rhs.value));
6782 }
6783
Nicolas Capens96d4e092016-11-18 14:22:38 -05006784 RValue<Float4> operator+=(Float4 &lhs, RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006785 {
6786 return lhs = lhs + rhs;
6787 }
6788
Nicolas Capens96d4e092016-11-18 14:22:38 -05006789 RValue<Float4> operator-=(Float4 &lhs, RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006790 {
6791 return lhs = lhs - rhs;
6792 }
6793
Nicolas Capens96d4e092016-11-18 14:22:38 -05006794 RValue<Float4> operator*=(Float4 &lhs, RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006795 {
6796 return lhs = lhs * rhs;
6797 }
6798
Nicolas Capens96d4e092016-11-18 14:22:38 -05006799 RValue<Float4> operator/=(Float4 &lhs, RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006800 {
6801 return lhs = lhs / rhs;
6802 }
6803
Nicolas Capens96d4e092016-11-18 14:22:38 -05006804 RValue<Float4> operator%=(Float4 &lhs, RValue<Float4> rhs)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006805 {
6806 return lhs = lhs % rhs;
6807 }
6808
6809 RValue<Float4> operator+(RValue<Float4> val)
6810 {
6811 return val;
6812 }
6813
6814 RValue<Float4> operator-(RValue<Float4> val)
6815 {
6816 return RValue<Float4>(Nucleus::createFNeg(val.value));
6817 }
6818
6819 RValue<Float4> Abs(RValue<Float4> x)
6820 {
Nicolas Capens84272242016-11-09 13:31:06 -05006821 Value *vector = Nucleus::createBitCast(x.value, Int4::getType());
6822 int64_t constantVector[4] = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF};
6823 Value *result = Nucleus::createAnd(vector, V(Nucleus::createConstantVector(constantVector, Int4::getType())));
6824
6825 return As<Float4>(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006826 }
6827
6828 RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y)
6829 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006830 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
Nicolas Capens5cdb91a2017-02-13 12:39:18 -05006831 auto cmp = Ice::InstFcmp::create(::function, Ice::InstFcmp::Ogt, condition, x.value, y.value);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006832 ::basicBlock->appendInst(cmp);
6833
6834 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
Nicolas Capens5cdb91a2017-02-13 12:39:18 -05006835 auto select = Ice::InstSelect::create(::function, result, condition, x.value, y.value);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006836 ::basicBlock->appendInst(select);
6837
6838 return RValue<Float4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006839 }
6840
6841 RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y)
6842 {
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006843 Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
Nicolas Capens5cdb91a2017-02-13 12:39:18 -05006844 auto cmp = Ice::InstFcmp::create(::function, Ice::InstFcmp::Olt, condition, x.value, y.value);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006845 ::basicBlock->appendInst(cmp);
6846
6847 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
Nicolas Capens5cdb91a2017-02-13 12:39:18 -05006848 auto select = Ice::InstSelect::create(::function, result, condition, x.value, y.value);
Nicolas Capens53a8a3f2016-10-26 00:23:12 -04006849 ::basicBlock->appendInst(select);
6850
6851 return RValue<Float4>(V(result));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006852 }
6853
6854 RValue<Float4> Rcp_pp(RValue<Float4> x, bool exactAtPow2)
6855 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04006856 return Float4(1.0f) / x;
Nicolas Capens598f8d82016-09-26 15:09:10 -04006857 }
6858
6859 RValue<Float4> RcpSqrt_pp(RValue<Float4> x)
6860 {
Nicolas Capensd52e9362016-10-31 23:23:15 -04006861 return Rcp_pp(Sqrt(x));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006862 }
6863
6864 RValue<Float4> Sqrt(RValue<Float4> x)
6865 {
Nicolas Capens091f3502017-10-03 14:56:49 -04006866 if(emulateIntrinsics || CPUID::ARM)
Nicolas Capens9f737d32017-07-25 17:26:14 -04006867 {
6868 Float4 result;
6869 result.x = Sqrt(Float(Float4(x).x));
6870 result.y = Sqrt(Float(Float4(x).y));
6871 result.z = Sqrt(Float(Float4(x).z));
6872 result.w = Sqrt(Float(Float4(x).w));
Nicolas Capensd52e9362016-10-31 23:23:15 -04006873
Nicolas Capens9f737d32017-07-25 17:26:14 -04006874 return result;
6875 }
6876 else
6877 {
6878 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
6879 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Sqrt, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6880 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6881 auto sqrt = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
6882 sqrt->addArg(x.value);
6883 ::basicBlock->appendInst(sqrt);
6884
6885 return RValue<Float4>(V(result));
6886 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04006887 }
6888
Nicolas Capensc94ab742016-11-08 15:15:31 -05006889 RValue<Float4> Insert(RValue<Float4> x, RValue<Float> element, int i)
Nicolas Capens598f8d82016-09-26 15:09:10 -04006890 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05006891 return RValue<Float4>(Nucleus::createInsertElement(x.value, element.value, i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006892 }
6893
6894 RValue<Float> Extract(RValue<Float4> x, int i)
6895 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006896 return RValue<Float>(Nucleus::createExtractElement(x.value, Float::getType(), i));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006897 }
6898
6899 RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select)
6900 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006901 return RValue<Float4>(createSwizzle4(x.value, select));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006902 }
6903
6904 RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
6905 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04006906 int shuffle[4] =
6907 {
6908 ((imm >> 0) & 0x03) + 0,
6909 ((imm >> 2) & 0x03) + 0,
6910 ((imm >> 4) & 0x03) + 4,
6911 ((imm >> 6) & 0x03) + 4,
6912 };
6913
6914 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006915 }
6916
6917 RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y)
6918 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04006919 int shuffle[4] = {0, 4, 1, 5};
6920 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006921 }
6922
6923 RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y)
6924 {
Nicolas Capens37fbece2016-10-21 15:08:56 -04006925 int shuffle[4] = {2, 6, 3, 7};
6926 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006927 }
6928
6929 RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select)
6930 {
6931 Value *vector = lhs.loadValue();
Nicolas Capensa4c30b02016-11-08 15:43:17 -05006932 Value *result = createMask4(vector, rhs.value, select);
6933 lhs.storeValue(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006934
Nicolas Capensa4c30b02016-11-08 15:43:17 -05006935 return RValue<Float4>(result);
Nicolas Capens598f8d82016-09-26 15:09:10 -04006936 }
6937
6938 RValue<Int> SignMask(RValue<Float4> x)
6939 {
Nicolas Capens091f3502017-10-03 14:56:49 -04006940 if(emulateIntrinsics || CPUID::ARM)
Nicolas Capensd6cacad2017-07-25 15:32:12 -04006941 {
6942 Int4 xx = (As<Int4>(x) >> 31) & Int4(0x00000001, 0x00000002, 0x00000004, 0x00000008);
6943 return Extract(xx, 0) | Extract(xx, 1) | Extract(xx, 2) | Extract(xx, 3);
6944 }
6945 else
6946 {
6947 Ice::Variable *result = ::function->makeVariable(Ice::IceType_i32);
6948 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::SignMask, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
6949 auto target = ::context->getConstantUndef(Ice::IceType_i32);
6950 auto movmsk = Ice::InstIntrinsicCall::create(::function, 1, result, target, intrinsic);
6951 movmsk->addArg(x.value);
6952 ::basicBlock->appendInst(movmsk);
Nicolas Capensf2cb9df2016-10-21 17:26:13 -04006953
Nicolas Capensd6cacad2017-07-25 15:32:12 -04006954 return RValue<Int>(V(result));
6955 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04006956 }
6957
6958 RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y)
6959 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006960 return RValue<Int4>(Nucleus::createFCmpOEQ(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006961 }
6962
6963 RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y)
6964 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006965 return RValue<Int4>(Nucleus::createFCmpOLT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006966 }
6967
6968 RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y)
6969 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006970 return RValue<Int4>(Nucleus::createFCmpOLE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006971 }
6972
6973 RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y)
6974 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006975 return RValue<Int4>(Nucleus::createFCmpONE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006976 }
6977
6978 RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y)
6979 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006980 return RValue<Int4>(Nucleus::createFCmpOGE(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006981 }
6982
6983 RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y)
6984 {
Nicolas Capens5e6ca092017-01-13 15:09:21 -05006985 return RValue<Int4>(Nucleus::createFCmpOGT(x.value, y.value));
Nicolas Capens598f8d82016-09-26 15:09:10 -04006986 }
6987
Alexis Hetu8ef6d102017-11-09 15:49:09 -05006988 RValue<Int4> IsInf(RValue<Float4> x)
6989 {
6990 return CmpEQ(As<Int4>(x) & Int4(0x7FFFFFFF), Int4(0x7F800000));
6991 }
6992
6993 RValue<Int4> IsNan(RValue<Float4> x)
6994 {
6995 return ~CmpEQ(x, x);
6996 }
6997
Nicolas Capens598f8d82016-09-26 15:09:10 -04006998 RValue<Float4> Round(RValue<Float4> x)
6999 {
Nicolas Capens091f3502017-10-03 14:56:49 -04007000 if(emulateIntrinsics || CPUID::ARM)
Nicolas Capensf7b75882017-04-26 09:30:47 -04007001 {
7002 // Push the fractional part off the mantissa. Accurate up to +/-2^22.
7003 return (x + Float4(0x00C00000)) - Float4(0x00C00000);
7004 }
7005 else if(CPUID::SSE4_1)
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007006 {
7007 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
7008 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
7009 auto target = ::context->getConstantUndef(Ice::IceType_i32);
7010 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
7011 round->addArg(x.value);
7012 round->addArg(::context->getConstantInt32(0));
7013 ::basicBlock->appendInst(round);
Nicolas Capensa8086512016-11-07 17:32:17 -05007014
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007015 return RValue<Float4>(V(result));
7016 }
7017 else
7018 {
7019 return Float4(RoundInt(x));
7020 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04007021 }
7022
7023 RValue<Float4> Trunc(RValue<Float4> x)
7024 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007025 if(CPUID::SSE4_1)
7026 {
7027 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
7028 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
7029 auto target = ::context->getConstantUndef(Ice::IceType_i32);
7030 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
7031 round->addArg(x.value);
7032 round->addArg(::context->getConstantInt32(3));
7033 ::basicBlock->appendInst(round);
Nicolas Capensa8086512016-11-07 17:32:17 -05007034
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007035 return RValue<Float4>(V(result));
7036 }
7037 else
7038 {
7039 return Float4(Int4(x));
7040 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04007041 }
7042
7043 RValue<Float4> Frac(RValue<Float4> x)
7044 {
Nicolas Capensb9230422017-07-17 10:27:33 -04007045 Float4 frc;
7046
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007047 if(CPUID::SSE4_1)
7048 {
Nicolas Capensb9230422017-07-17 10:27:33 -04007049 frc = x - Floor(x);
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007050 }
7051 else
7052 {
Nicolas Capensb9230422017-07-17 10:27:33 -04007053 frc = x - Float4(Int4(x)); // Signed fractional part.
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007054
Nicolas Capensb9230422017-07-17 10:27:33 -04007055 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 -05007056 }
Nicolas Capensb9230422017-07-17 10:27:33 -04007057
7058 // x - floor(x) can be 1.0 for very small negative x.
7059 // Clamp against the value just below 1.0.
7060 return Min(frc, As<Float4>(Int4(0x3F7FFFFF)));
Nicolas Capens598f8d82016-09-26 15:09:10 -04007061 }
7062
7063 RValue<Float4> Floor(RValue<Float4> x)
7064 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007065 if(CPUID::SSE4_1)
7066 {
7067 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
7068 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
7069 auto target = ::context->getConstantUndef(Ice::IceType_i32);
7070 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
7071 round->addArg(x.value);
7072 round->addArg(::context->getConstantInt32(1));
7073 ::basicBlock->appendInst(round);
Nicolas Capensa8086512016-11-07 17:32:17 -05007074
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007075 return RValue<Float4>(V(result));
7076 }
7077 else
7078 {
7079 return x - Frac(x);
7080 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04007081 }
7082
7083 RValue<Float4> Ceil(RValue<Float4> x)
7084 {
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007085 if(CPUID::SSE4_1)
7086 {
7087 Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
7088 const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::Round, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
7089 auto target = ::context->getConstantUndef(Ice::IceType_i32);
7090 auto round = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
7091 round->addArg(x.value);
7092 round->addArg(::context->getConstantInt32(2));
7093 ::basicBlock->appendInst(round);
Nicolas Capensa8086512016-11-07 17:32:17 -05007094
Nicolas Capens9ca48d52017-01-14 12:52:55 -05007095 return RValue<Float4>(V(result));
7096 }
7097 else
7098 {
7099 return -Floor(-x);
7100 }
Nicolas Capens598f8d82016-09-26 15:09:10 -04007101 }
7102
7103 Type *Float4::getType()
7104 {
Nicolas Capens9709d4f2016-09-30 11:44:14 -04007105 return T(Ice::IceType_v4f32);
Nicolas Capens598f8d82016-09-26 15:09:10 -04007106 }
7107
7108 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset)
7109 {
Nicolas Capens8820f642016-09-30 04:42:43 -04007110 return lhs + RValue<Int>(Nucleus::createConstantInt(offset));
Nicolas Capens598f8d82016-09-26 15:09:10 -04007111 }
7112
7113 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
7114 {
Nicolas Capensd294def2017-01-26 17:44:37 -08007115 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value, false));
Nicolas Capens598f8d82016-09-26 15:09:10 -04007116 }
7117
7118 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
7119 {
Nicolas Capensd294def2017-01-26 17:44:37 -08007120 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value, true));
Nicolas Capens598f8d82016-09-26 15:09:10 -04007121 }
7122
Nicolas Capens96d4e092016-11-18 14:22:38 -05007123 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, int offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04007124 {
7125 return lhs = lhs + offset;
7126 }
7127
Nicolas Capens96d4e092016-11-18 14:22:38 -05007128 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<Int> offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04007129 {
7130 return lhs = lhs + offset;
7131 }
7132
Nicolas Capens96d4e092016-11-18 14:22:38 -05007133 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<UInt> offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04007134 {
7135 return lhs = lhs + offset;
7136 }
7137
7138 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset)
7139 {
7140 return lhs + -offset;
7141 }
7142
7143 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
7144 {
7145 return lhs + -offset;
7146 }
7147
7148 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
7149 {
7150 return lhs + -offset;
7151 }
7152
Nicolas Capens96d4e092016-11-18 14:22:38 -05007153 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, int offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04007154 {
7155 return lhs = lhs - offset;
7156 }
7157
Nicolas Capens96d4e092016-11-18 14:22:38 -05007158 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<Int> offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04007159 {
7160 return lhs = lhs - offset;
7161 }
7162
Nicolas Capens96d4e092016-11-18 14:22:38 -05007163 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<UInt> offset)
Nicolas Capens598f8d82016-09-26 15:09:10 -04007164 {
7165 return lhs = lhs - offset;
7166 }
7167
7168 void Return()
7169 {
7170 Nucleus::createRetVoid();
7171 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
7172 Nucleus::createUnreachable();
7173 }
7174
Nicolas Capenseb253d02016-11-18 14:40:40 -05007175 void Return(RValue<Int> ret)
Nicolas Capens598f8d82016-09-26 15:09:10 -04007176 {
Nicolas Capenseb253d02016-11-18 14:40:40 -05007177 Nucleus::createRet(ret.value);
Nicolas Capensfdcca2d2016-10-20 11:31:36 -04007178 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
7179 Nucleus::createUnreachable();
Nicolas Capens598f8d82016-09-26 15:09:10 -04007180 }
7181
Nicolas Capensf4eec2f2017-05-24 15:46:48 -04007182 void branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB)
Nicolas Capens598f8d82016-09-26 15:09:10 -04007183 {
7184 Nucleus::createCondBr(cmp.value, bodyBB, endBB);
7185 Nucleus::setInsertBlock(bodyBB);
Nicolas Capens598f8d82016-09-26 15:09:10 -04007186 }
7187
Nicolas Capens598f8d82016-09-26 15:09:10 -04007188 RValue<Long> Ticks()
7189 {
Nicolas Capensc37252c2016-09-28 16:11:54 -04007190 assert(false && "UNIMPLEMENTED"); return RValue<Long>(V(nullptr));
Nicolas Capens598f8d82016-09-26 15:09:10 -04007191 }
7192}