blob: bb691825108a977a6d8f52d402a3ccee65abe38e [file] [log] [blame]
Nicolas Capens0bac2852016-05-07 06:09:58 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
John Bauman89401822014-05-06 15:04:28 -04002//
Nicolas Capens0bac2852016-05-07 06:09:58 -04003// 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
John Bauman89401822014-05-06 15:04:28 -04006//
Nicolas Capens0bac2852016-05-07 06:09:58 -04007// http://www.apache.org/licenses/LICENSE-2.0
John Bauman89401822014-05-06 15:04:28 -04008//
Nicolas Capens0bac2852016-05-07 06:09:58 -04009// 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.
John Bauman89401822014-05-06 15:04:28 -040014
15#include "Nucleus.hpp"
16
17#include "llvm/Support/IRBuilder.h"
18#include "llvm/Function.h"
19#include "llvm/GlobalVariable.h"
20#include "llvm/Module.h"
21#include "llvm/LLVMContext.h"
22#include "llvm/Constants.h"
23#include "llvm/Intrinsics.h"
John Bauman66b8ab22014-05-06 15:57:45 -040024#include "llvm/PassManager.h"
John Bauman89401822014-05-06 15:04:28 -040025#include "llvm/Analysis/LoopPass.h"
26#include "llvm/Transforms/Scalar.h"
27#include "llvm/Target/TargetData.h"
John Bauman89401822014-05-06 15:04:28 -040028#include "llvm/Target/TargetOptions.h"
John Bauman19bac1e2014-05-06 15:23:49 -040029#include "llvm/Support/TargetSelect.h"
John Bauman89401822014-05-06 15:04:28 -040030#include "../lib/ExecutionEngine/JIT/JIT.h"
John Bauman89401822014-05-06 15:04:28 -040031
Nicolas Capensdaa5d912016-09-28 16:56:36 -040032#include "LLVMRoutine.hpp"
33#include "LLVMRoutineManager.hpp"
John Bauman89401822014-05-06 15:04:28 -040034#include "x86.hpp"
35#include "CPUID.hpp"
36#include "Thread.hpp"
37#include "Memory.hpp"
Nicolas Capens3bbc5e12016-09-27 10:49:52 -040038#include "MutexLock.hpp"
John Bauman89401822014-05-06 15:04:28 -040039
40#include <fstream>
41
Nicolas Capens47dc8672017-04-25 12:54:39 -040042#if defined(__i386__) || defined(__x86_64__)
43#include <xmmintrin.h>
44#endif
45
Nicolas Capenscb122582014-05-06 23:34:44 -040046#if defined(__x86_64__) && defined(_WIN32)
John Bauman66b8ab22014-05-06 15:57:45 -040047extern "C" void X86CompilationCallback()
48{
49 assert(false); // UNIMPLEMENTED
50}
51#endif
52
John Bauman89401822014-05-06 15:04:28 -040053extern "C"
54{
55 bool (*CodeAnalystInitialize)() = 0;
56 void (*CodeAnalystCompleteJITLog)() = 0;
57 bool (*CodeAnalystLogJITCode)(const void *jitCodeStartAddr, unsigned int jitCodeSize, const wchar_t *functionName) = 0;
58}
59
60namespace llvm
61{
62 extern bool JITEmitDebugInfo;
63}
64
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -040065namespace
66{
Nicolas Capensdaa5d912016-09-28 16:56:36 -040067 sw::LLVMRoutineManager *routineManager = nullptr;
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -040068 llvm::ExecutionEngine *executionEngine = nullptr;
69 llvm::IRBuilder<> *builder = nullptr;
70 llvm::LLVMContext *context = nullptr;
71 llvm::Module *module = nullptr;
72 llvm::Function *function = nullptr;
Nicolas Capens3bbc5e12016-09-27 10:49:52 -040073
Jorge E. Moreiraf8faed62016-12-02 17:03:54 -080074 sw::MutexLock codegenMutex;
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -040075}
76
John Bauman89401822014-05-06 15:04:28 -040077namespace sw
78{
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -040079 Optimization optimization[10] = {InstructionCombining, Disabled};
John Bauman89401822014-05-06 15:04:28 -040080
Nicolas Capensfbf2bc52017-07-26 17:26:17 -040081 enum EmulatedType
82 {
83 Type_v2i32,
84 Type_v4i16,
85 Type_v2i16,
86 Type_v8i8,
87 Type_v4i8,
88 Type_v2f32,
89 EmulatedTypeCount
90 };
91
Nicolas Capens19336542016-09-26 10:32:29 -040092 class Value : public llvm::Value {};
Nicolas Capensb98fe5c2016-11-09 12:24:06 -050093 class SwitchCases : public llvm::SwitchInst {};
Nicolas Capensc8b67a42016-09-25 15:02:52 -040094 class BasicBlock : public llvm::BasicBlock {};
Nicolas Capensac230122016-09-20 14:30:06 -040095
Nicolas Capensfbf2bc52017-07-26 17:26:17 -040096 llvm::Type *T(Type *t)
97 {
98 std::uintptr_t type = reinterpret_cast<std::uintptr_t>(t);
99 if(type < EmulatedTypeCount)
100 {
101 switch(type)
102 {
103 case Type_v2i32: return llvm::Type::getX86_MMXTy(*::context);
104 case Type_v4i16: return llvm::Type::getX86_MMXTy(*::context);
105 case Type_v2i16: return llvm::Type::getInt32Ty(*::context);
106 case Type_v8i8: return llvm::Type::getX86_MMXTy(*::context);
107 case Type_v4i8: return llvm::Type::getInt32Ty(*::context);
108 case Type_v2f32: return llvm::VectorType::get(T(Float::getType()), 2);
109 default: assert(false);
110 }
111 }
112
113 return reinterpret_cast<llvm::Type*>(t);
114 }
115
Nicolas Capensac230122016-09-20 14:30:06 -0400116 inline Type *T(llvm::Type *t)
117 {
118 return reinterpret_cast<Type*>(t);
119 }
120
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400121 Type *T(EmulatedType t)
122 {
123 return reinterpret_cast<Type*>(t);
124 }
125
Nicolas Capens19336542016-09-26 10:32:29 -0400126 inline Value *V(llvm::Value *t)
127 {
128 return reinterpret_cast<Value*>(t);
129 }
130
Nicolas Capensac230122016-09-20 14:30:06 -0400131 inline std::vector<llvm::Type*> &T(std::vector<Type*> &t)
132 {
133 return reinterpret_cast<std::vector<llvm::Type*>&>(t);
134 }
135
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400136 inline BasicBlock *B(llvm::BasicBlock *t)
137 {
138 return reinterpret_cast<BasicBlock*>(t);
139 }
140
John Bauman89401822014-05-06 15:04:28 -0400141 Nucleus::Nucleus()
142 {
Nicolas Capens3bbc5e12016-09-27 10:49:52 -0400143 ::codegenMutex.lock(); // Reactor and LLVM are currently not thread safe
Nicolas Capensb7ea9842015-04-01 10:54:59 -0400144
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400145 llvm::InitializeNativeTarget();
146 llvm::JITEmitDebugInfo = false;
John Bauman89401822014-05-06 15:04:28 -0400147
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400148 if(!::context)
John Bauman89401822014-05-06 15:04:28 -0400149 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400150 ::context = new llvm::LLVMContext();
John Bauman89401822014-05-06 15:04:28 -0400151 }
152
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400153 ::module = new llvm::Module("", *::context);
Nicolas Capensdaa5d912016-09-28 16:56:36 -0400154 ::routineManager = new LLVMRoutineManager();
John Bauman66b8ab22014-05-06 15:57:45 -0400155
John Bauman89401822014-05-06 15:04:28 -0400156 #if defined(__x86_64__)
157 const char *architecture = "x86-64";
158 #else
159 const char *architecture = "x86";
160 #endif
161
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400162 llvm::SmallVector<std::string, 1> MAttrs;
John Bauman89401822014-05-06 15:04:28 -0400163 MAttrs.push_back(CPUID::supportsMMX() ? "+mmx" : "-mmx");
164 MAttrs.push_back(CPUID::supportsCMOV() ? "+cmov" : "-cmov");
165 MAttrs.push_back(CPUID::supportsSSE() ? "+sse" : "-sse");
166 MAttrs.push_back(CPUID::supportsSSE2() ? "+sse2" : "-sse2");
167 MAttrs.push_back(CPUID::supportsSSE3() ? "+sse3" : "-sse3");
168 MAttrs.push_back(CPUID::supportsSSSE3() ? "+ssse3" : "-ssse3");
169 MAttrs.push_back(CPUID::supportsSSE4_1() ? "+sse41" : "-sse41");
170
John Bauman19bac1e2014-05-06 15:23:49 -0400171 std::string error;
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400172 llvm::TargetMachine *targetMachine = llvm::EngineBuilder::selectTarget(::module, architecture, "", MAttrs, llvm::Reloc::Default, llvm::CodeModel::JITDefault, &error);
173 ::executionEngine = llvm::JIT::createJIT(::module, 0, ::routineManager, llvm::CodeGenOpt::Aggressive, true, targetMachine);
John Bauman89401822014-05-06 15:04:28 -0400174
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400175 if(!::builder)
John Bauman89401822014-05-06 15:04:28 -0400176 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400177 ::builder = new llvm::IRBuilder<>(*::context);
John Bauman89401822014-05-06 15:04:28 -0400178
John Bauman66b8ab22014-05-06 15:57:45 -0400179 #if defined(_WIN32)
180 HMODULE CodeAnalyst = LoadLibrary("CAJitNtfyLib.dll");
181 if(CodeAnalyst)
182 {
183 CodeAnalystInitialize = (bool(*)())GetProcAddress(CodeAnalyst, "CAJIT_Initialize");
184 CodeAnalystCompleteJITLog = (void(*)())GetProcAddress(CodeAnalyst, "CAJIT_CompleteJITLog");
185 CodeAnalystLogJITCode = (bool(*)(const void*, unsigned int, const wchar_t*))GetProcAddress(CodeAnalyst, "CAJIT_LogJITCode");
186
187 CodeAnalystInitialize();
188 }
189 #endif
John Bauman89401822014-05-06 15:04:28 -0400190 }
191 }
192
193 Nucleus::~Nucleus()
194 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400195 delete ::executionEngine;
196 ::executionEngine = nullptr;
John Bauman89401822014-05-06 15:04:28 -0400197
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400198 ::routineManager = nullptr;
199 ::function = nullptr;
200 ::module = nullptr;
Nicolas Capensb7ea9842015-04-01 10:54:59 -0400201
Nicolas Capens3bbc5e12016-09-27 10:49:52 -0400202 ::codegenMutex.unlock();
John Bauman89401822014-05-06 15:04:28 -0400203 }
204
205 Routine *Nucleus::acquireRoutine(const wchar_t *name, bool runOptimizations)
206 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400207 if(::builder->GetInsertBlock()->empty() || !::builder->GetInsertBlock()->back().isTerminator())
John Bauman19bac1e2014-05-06 15:23:49 -0400208 {
Nicolas Capensac230122016-09-20 14:30:06 -0400209 llvm::Type *type = ::function->getReturnType();
John Bauman19bac1e2014-05-06 15:23:49 -0400210
211 if(type->isVoidTy())
212 {
213 createRetVoid();
214 }
215 else
216 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400217 createRet(V(llvm::UndefValue::get(type)));
John Bauman19bac1e2014-05-06 15:23:49 -0400218 }
219 }
John Bauman89401822014-05-06 15:04:28 -0400220
221 if(false)
222 {
John Bauman66b8ab22014-05-06 15:57:45 -0400223 std::string error;
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400224 llvm::raw_fd_ostream file("llvm-dump-unopt.txt", error);
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400225 ::module->print(file, 0);
John Bauman89401822014-05-06 15:04:28 -0400226 }
227
228 if(runOptimizations)
229 {
230 optimize();
231 }
232
233 if(false)
234 {
John Bauman66b8ab22014-05-06 15:57:45 -0400235 std::string error;
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400236 llvm::raw_fd_ostream file("llvm-dump-opt.txt", error);
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400237 ::module->print(file, 0);
John Bauman89401822014-05-06 15:04:28 -0400238 }
239
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400240 void *entry = ::executionEngine->getPointerToFunction(::function);
Nicolas Capensdaa5d912016-09-28 16:56:36 -0400241 LLVMRoutine *routine = ::routineManager->acquireRoutine(entry);
John Bauman89401822014-05-06 15:04:28 -0400242
243 if(CodeAnalystLogJITCode)
244 {
Nicolas Capensd946e0a2014-06-26 11:31:08 -0400245 CodeAnalystLogJITCode(routine->getEntry(), routine->getCodeSize(), name);
John Bauman89401822014-05-06 15:04:28 -0400246 }
247
248 return routine;
249 }
250
251 void Nucleus::optimize()
252 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400253 static llvm::PassManager *passManager = nullptr;
John Bauman66b8ab22014-05-06 15:57:45 -0400254
John Bauman89401822014-05-06 15:04:28 -0400255 if(!passManager)
256 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400257 passManager = new llvm::PassManager();
John Bauman89401822014-05-06 15:04:28 -0400258
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400259 llvm::UnsafeFPMath = true;
260 // llvm::NoInfsFPMath = true;
261 // llvm::NoNaNsFPMath = true;
John Bauman89401822014-05-06 15:04:28 -0400262
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400263 passManager->add(new llvm::TargetData(*::executionEngine->getTargetData()));
264 passManager->add(llvm::createScalarReplAggregatesPass());
John Bauman89401822014-05-06 15:04:28 -0400265
266 for(int pass = 0; pass < 10 && optimization[pass] != Disabled; pass++)
267 {
268 switch(optimization[pass])
269 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400270 case Disabled: break;
271 case CFGSimplification: passManager->add(llvm::createCFGSimplificationPass()); break;
272 case LICM: passManager->add(llvm::createLICMPass()); break;
273 case AggressiveDCE: passManager->add(llvm::createAggressiveDCEPass()); break;
274 case GVN: passManager->add(llvm::createGVNPass()); break;
275 case InstructionCombining: passManager->add(llvm::createInstructionCombiningPass()); break;
276 case Reassociate: passManager->add(llvm::createReassociatePass()); break;
277 case DeadStoreElimination: passManager->add(llvm::createDeadStoreEliminationPass()); break;
278 case SCCP: passManager->add(llvm::createSCCPPass()); break;
279 case ScalarReplAggregates: passManager->add(llvm::createScalarReplAggregatesPass()); break;
John Bauman89401822014-05-06 15:04:28 -0400280 default:
281 assert(false);
282 }
283 }
284 }
285
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400286 passManager->run(*::module);
John Bauman89401822014-05-06 15:04:28 -0400287 }
288
John Bauman19bac1e2014-05-06 15:23:49 -0400289 Value *Nucleus::allocateStackVariable(Type *type, int arraySize)
John Bauman89401822014-05-06 15:04:28 -0400290 {
291 // Need to allocate it in the entry block for mem2reg to work
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400292 llvm::BasicBlock &entryBlock = ::function->getEntryBlock();
John Bauman89401822014-05-06 15:04:28 -0400293
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400294 llvm::Instruction *declaration;
John Bauman89401822014-05-06 15:04:28 -0400295
296 if(arraySize)
297 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400298 declaration = new llvm::AllocaInst(T(type), Nucleus::createConstantInt(arraySize));
John Bauman89401822014-05-06 15:04:28 -0400299 }
300 else
301 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400302 declaration = new llvm::AllocaInst(T(type), (Value*)nullptr);
John Bauman89401822014-05-06 15:04:28 -0400303 }
304
305 entryBlock.getInstList().push_front(declaration);
306
Nicolas Capens19336542016-09-26 10:32:29 -0400307 return V(declaration);
John Bauman89401822014-05-06 15:04:28 -0400308 }
309
310 BasicBlock *Nucleus::createBasicBlock()
311 {
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400312 return B(BasicBlock::Create(*::context, "", ::function));
John Bauman89401822014-05-06 15:04:28 -0400313 }
314
315 BasicBlock *Nucleus::getInsertBlock()
316 {
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400317 return B(::builder->GetInsertBlock());
John Bauman89401822014-05-06 15:04:28 -0400318 }
319
320 void Nucleus::setInsertBlock(BasicBlock *basicBlock)
321 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400322 // assert(::builder->GetInsertBlock()->back().isTerminator());
323 return ::builder->SetInsertPoint(basicBlock);
John Bauman89401822014-05-06 15:04:28 -0400324 }
325
Nicolas Capensac230122016-09-20 14:30:06 -0400326 void Nucleus::createFunction(Type *ReturnType, std::vector<Type*> &Params)
John Bauman89401822014-05-06 15:04:28 -0400327 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400328 llvm::FunctionType *functionType = llvm::FunctionType::get(T(ReturnType), T(Params), false);
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400329 ::function = llvm::Function::Create(functionType, llvm::GlobalValue::InternalLinkage, "", ::module);
330 ::function->setCallingConv(llvm::CallingConv::C);
John Bauman89401822014-05-06 15:04:28 -0400331
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400332 ::builder->SetInsertPoint(BasicBlock::Create(*::context, "", ::function));
John Bauman89401822014-05-06 15:04:28 -0400333 }
334
Nicolas Capens19336542016-09-26 10:32:29 -0400335 Value *Nucleus::getArgument(unsigned int index)
John Bauman89401822014-05-06 15:04:28 -0400336 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400337 llvm::Function::arg_iterator args = ::function->arg_begin();
John Bauman89401822014-05-06 15:04:28 -0400338
339 while(index)
340 {
341 args++;
342 index--;
343 }
344
Nicolas Capens19336542016-09-26 10:32:29 -0400345 return V(&*args);
John Bauman89401822014-05-06 15:04:28 -0400346 }
347
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400348 void Nucleus::createRetVoid()
John Bauman89401822014-05-06 15:04:28 -0400349 {
John Bauman66b8ab22014-05-06 15:57:45 -0400350 x86::emms();
351
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400352 ::builder->CreateRetVoid();
John Bauman89401822014-05-06 15:04:28 -0400353 }
354
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400355 void Nucleus::createRet(Value *v)
John Bauman89401822014-05-06 15:04:28 -0400356 {
John Bauman66b8ab22014-05-06 15:57:45 -0400357 x86::emms();
358
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400359 ::builder->CreateRet(v);
John Bauman89401822014-05-06 15:04:28 -0400360 }
361
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400362 void Nucleus::createBr(BasicBlock *dest)
John Bauman89401822014-05-06 15:04:28 -0400363 {
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400364 ::builder->CreateBr(dest);
John Bauman89401822014-05-06 15:04:28 -0400365 }
366
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400367 void Nucleus::createCondBr(Value *cond, BasicBlock *ifTrue, BasicBlock *ifFalse)
John Bauman89401822014-05-06 15:04:28 -0400368 {
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400369 ::builder->CreateCondBr(cond, ifTrue, ifFalse);
John Bauman89401822014-05-06 15:04:28 -0400370 }
371
372 Value *Nucleus::createAdd(Value *lhs, Value *rhs)
373 {
Nicolas Capens19336542016-09-26 10:32:29 -0400374 return V(::builder->CreateAdd(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400375 }
376
377 Value *Nucleus::createSub(Value *lhs, Value *rhs)
378 {
Nicolas Capens19336542016-09-26 10:32:29 -0400379 return V(::builder->CreateSub(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400380 }
381
382 Value *Nucleus::createMul(Value *lhs, Value *rhs)
383 {
Nicolas Capens19336542016-09-26 10:32:29 -0400384 return V(::builder->CreateMul(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400385 }
386
387 Value *Nucleus::createUDiv(Value *lhs, Value *rhs)
388 {
Nicolas Capens19336542016-09-26 10:32:29 -0400389 return V(::builder->CreateUDiv(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400390 }
391
392 Value *Nucleus::createSDiv(Value *lhs, Value *rhs)
393 {
Nicolas Capens19336542016-09-26 10:32:29 -0400394 return V(::builder->CreateSDiv(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400395 }
396
397 Value *Nucleus::createFAdd(Value *lhs, Value *rhs)
398 {
Nicolas Capens19336542016-09-26 10:32:29 -0400399 return V(::builder->CreateFAdd(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400400 }
401
402 Value *Nucleus::createFSub(Value *lhs, Value *rhs)
403 {
Nicolas Capens19336542016-09-26 10:32:29 -0400404 return V(::builder->CreateFSub(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400405 }
406
407 Value *Nucleus::createFMul(Value *lhs, Value *rhs)
408 {
Nicolas Capens19336542016-09-26 10:32:29 -0400409 return V(::builder->CreateFMul(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400410 }
411
412 Value *Nucleus::createFDiv(Value *lhs, Value *rhs)
413 {
Nicolas Capens19336542016-09-26 10:32:29 -0400414 return V(::builder->CreateFDiv(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400415 }
416
417 Value *Nucleus::createURem(Value *lhs, Value *rhs)
418 {
Nicolas Capens19336542016-09-26 10:32:29 -0400419 return V(::builder->CreateURem(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400420 }
421
422 Value *Nucleus::createSRem(Value *lhs, Value *rhs)
423 {
Nicolas Capens19336542016-09-26 10:32:29 -0400424 return V(::builder->CreateSRem(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400425 }
426
427 Value *Nucleus::createFRem(Value *lhs, Value *rhs)
428 {
Nicolas Capens19336542016-09-26 10:32:29 -0400429 return V(::builder->CreateFRem(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400430 }
431
432 Value *Nucleus::createShl(Value *lhs, Value *rhs)
433 {
Nicolas Capens19336542016-09-26 10:32:29 -0400434 return V(::builder->CreateShl(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400435 }
436
437 Value *Nucleus::createLShr(Value *lhs, Value *rhs)
438 {
Nicolas Capens19336542016-09-26 10:32:29 -0400439 return V(::builder->CreateLShr(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400440 }
441
442 Value *Nucleus::createAShr(Value *lhs, Value *rhs)
443 {
Nicolas Capens19336542016-09-26 10:32:29 -0400444 return V(::builder->CreateAShr(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400445 }
446
447 Value *Nucleus::createAnd(Value *lhs, Value *rhs)
448 {
Nicolas Capens19336542016-09-26 10:32:29 -0400449 return V(::builder->CreateAnd(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400450 }
451
452 Value *Nucleus::createOr(Value *lhs, Value *rhs)
453 {
Nicolas Capens19336542016-09-26 10:32:29 -0400454 return V(::builder->CreateOr(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400455 }
456
457 Value *Nucleus::createXor(Value *lhs, Value *rhs)
458 {
Nicolas Capens19336542016-09-26 10:32:29 -0400459 return V(::builder->CreateXor(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400460 }
461
Nicolas Capens19336542016-09-26 10:32:29 -0400462 Value *Nucleus::createNeg(Value *v)
John Bauman89401822014-05-06 15:04:28 -0400463 {
Nicolas Capens19336542016-09-26 10:32:29 -0400464 return V(::builder->CreateNeg(v));
John Bauman89401822014-05-06 15:04:28 -0400465 }
466
Nicolas Capens19336542016-09-26 10:32:29 -0400467 Value *Nucleus::createFNeg(Value *v)
John Bauman89401822014-05-06 15:04:28 -0400468 {
Nicolas Capens19336542016-09-26 10:32:29 -0400469 return V(::builder->CreateFNeg(v));
John Bauman89401822014-05-06 15:04:28 -0400470 }
471
Nicolas Capens19336542016-09-26 10:32:29 -0400472 Value *Nucleus::createNot(Value *v)
John Bauman89401822014-05-06 15:04:28 -0400473 {
Nicolas Capens19336542016-09-26 10:32:29 -0400474 return V(::builder->CreateNot(v));
John Bauman89401822014-05-06 15:04:28 -0400475 }
476
Nicolas Capense12780d2016-09-27 14:18:07 -0400477 Value *Nucleus::createLoad(Value *ptr, Type *type, bool isVolatile, unsigned int align)
John Bauman89401822014-05-06 15:04:28 -0400478 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400479 assert(ptr->getType()->getContainedType(0) == T(type));
480 return V(::builder->Insert(new llvm::LoadInst(ptr, "", isVolatile, align)));
John Bauman89401822014-05-06 15:04:28 -0400481 }
482
Nicolas Capens6d738712016-09-30 04:15:22 -0400483 Value *Nucleus::createStore(Value *value, Value *ptr, Type *type, bool isVolatile, unsigned int align)
John Bauman89401822014-05-06 15:04:28 -0400484 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400485 assert(ptr->getType()->getContainedType(0) == T(type));
486 ::builder->Insert(new llvm::StoreInst(value, ptr, isVolatile, align));
Nicolas Capensb955d5b2016-09-28 22:36:28 -0400487 return value;
John Bauman89401822014-05-06 15:04:28 -0400488 }
489
Nicolas Capensd294def2017-01-26 17:44:37 -0800490 Value *Nucleus::createGEP(Value *ptr, Type *type, Value *index, bool unsignedIndex)
John Bauman89401822014-05-06 15:04:28 -0400491 {
Nicolas Capensd294def2017-01-26 17:44:37 -0800492 if(unsignedIndex && sizeof(void*) == 8)
493 {
494 index = createZExt(index, Long::getType());
495 }
496
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400497 assert(ptr->getType()->getContainedType(0) == T(type));
Nicolas Capens19336542016-09-26 10:32:29 -0400498 return V(::builder->CreateGEP(ptr, index));
John Bauman89401822014-05-06 15:04:28 -0400499 }
500
John Bauman19bac1e2014-05-06 15:23:49 -0400501 Value *Nucleus::createAtomicAdd(Value *ptr, Value *value)
502 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400503 return V(::builder->CreateAtomicRMW(llvm::AtomicRMWInst::Add, ptr, value, llvm::SequentiallyConsistent));
John Bauman19bac1e2014-05-06 15:23:49 -0400504 }
505
Nicolas Capens19336542016-09-26 10:32:29 -0400506 Value *Nucleus::createTrunc(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400507 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400508 return V(::builder->CreateTrunc(v, T(destType)));
John Bauman89401822014-05-06 15:04:28 -0400509 }
510
Nicolas Capens19336542016-09-26 10:32:29 -0400511 Value *Nucleus::createZExt(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400512 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400513 return V(::builder->CreateZExt(v, T(destType)));
John Bauman89401822014-05-06 15:04:28 -0400514 }
515
Nicolas Capens19336542016-09-26 10:32:29 -0400516 Value *Nucleus::createSExt(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400517 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400518 return V(::builder->CreateSExt(v, T(destType)));
John Bauman89401822014-05-06 15:04:28 -0400519 }
520
Nicolas Capens19336542016-09-26 10:32:29 -0400521 Value *Nucleus::createFPToSI(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400522 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400523 return V(::builder->CreateFPToSI(v, T(destType)));
John Bauman89401822014-05-06 15:04:28 -0400524 }
525
Nicolas Capens19336542016-09-26 10:32:29 -0400526 Value *Nucleus::createSIToFP(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400527 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400528 return V(::builder->CreateSIToFP(v, T(destType)));
John Bauman89401822014-05-06 15:04:28 -0400529 }
530
Nicolas Capens19336542016-09-26 10:32:29 -0400531 Value *Nucleus::createFPTrunc(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400532 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400533 return V(::builder->CreateFPTrunc(v, T(destType)));
John Bauman89401822014-05-06 15:04:28 -0400534 }
535
Nicolas Capens19336542016-09-26 10:32:29 -0400536 Value *Nucleus::createFPExt(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400537 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400538 return V(::builder->CreateFPExt(v, T(destType)));
John Bauman89401822014-05-06 15:04:28 -0400539 }
540
Nicolas Capens19336542016-09-26 10:32:29 -0400541 Value *Nucleus::createBitCast(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400542 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400543 return V(::builder->CreateBitCast(v, T(destType)));
John Bauman89401822014-05-06 15:04:28 -0400544 }
545
John Bauman89401822014-05-06 15:04:28 -0400546 Value *Nucleus::createICmpEQ(Value *lhs, Value *rhs)
547 {
Nicolas Capens19336542016-09-26 10:32:29 -0400548 return V(::builder->CreateICmpEQ(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400549 }
550
551 Value *Nucleus::createICmpNE(Value *lhs, Value *rhs)
552 {
Nicolas Capens19336542016-09-26 10:32:29 -0400553 return V(::builder->CreateICmpNE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400554 }
555
556 Value *Nucleus::createICmpUGT(Value *lhs, Value *rhs)
557 {
Nicolas Capens19336542016-09-26 10:32:29 -0400558 return V(::builder->CreateICmpUGT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400559 }
560
561 Value *Nucleus::createICmpUGE(Value *lhs, Value *rhs)
562 {
Nicolas Capens19336542016-09-26 10:32:29 -0400563 return V(::builder->CreateICmpUGE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400564 }
565
566 Value *Nucleus::createICmpULT(Value *lhs, Value *rhs)
567 {
Nicolas Capens19336542016-09-26 10:32:29 -0400568 return V(::builder->CreateICmpULT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400569 }
570
571 Value *Nucleus::createICmpULE(Value *lhs, Value *rhs)
572 {
Nicolas Capens19336542016-09-26 10:32:29 -0400573 return V(::builder->CreateICmpULE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400574 }
575
576 Value *Nucleus::createICmpSGT(Value *lhs, Value *rhs)
577 {
Nicolas Capens19336542016-09-26 10:32:29 -0400578 return V(::builder->CreateICmpSGT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400579 }
580
581 Value *Nucleus::createICmpSGE(Value *lhs, Value *rhs)
582 {
Nicolas Capens19336542016-09-26 10:32:29 -0400583 return V(::builder->CreateICmpSGE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400584 }
585
586 Value *Nucleus::createICmpSLT(Value *lhs, Value *rhs)
587 {
Nicolas Capens19336542016-09-26 10:32:29 -0400588 return V(::builder->CreateICmpSLT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400589 }
590
591 Value *Nucleus::createICmpSLE(Value *lhs, Value *rhs)
592 {
Nicolas Capens19336542016-09-26 10:32:29 -0400593 return V(::builder->CreateICmpSLE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400594 }
595
596 Value *Nucleus::createFCmpOEQ(Value *lhs, Value *rhs)
597 {
Nicolas Capens19336542016-09-26 10:32:29 -0400598 return V(::builder->CreateFCmpOEQ(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400599 }
600
601 Value *Nucleus::createFCmpOGT(Value *lhs, Value *rhs)
602 {
Nicolas Capens19336542016-09-26 10:32:29 -0400603 return V(::builder->CreateFCmpOGT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400604 }
605
606 Value *Nucleus::createFCmpOGE(Value *lhs, Value *rhs)
607 {
Nicolas Capens19336542016-09-26 10:32:29 -0400608 return V(::builder->CreateFCmpOGE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400609 }
610
611 Value *Nucleus::createFCmpOLT(Value *lhs, Value *rhs)
612 {
Nicolas Capens19336542016-09-26 10:32:29 -0400613 return V(::builder->CreateFCmpOLT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400614 }
615
616 Value *Nucleus::createFCmpOLE(Value *lhs, Value *rhs)
617 {
Nicolas Capens19336542016-09-26 10:32:29 -0400618 return V(::builder->CreateFCmpOLE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400619 }
620
621 Value *Nucleus::createFCmpONE(Value *lhs, Value *rhs)
622 {
Nicolas Capens19336542016-09-26 10:32:29 -0400623 return V(::builder->CreateFCmpONE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400624 }
625
626 Value *Nucleus::createFCmpORD(Value *lhs, Value *rhs)
627 {
Nicolas Capens19336542016-09-26 10:32:29 -0400628 return V(::builder->CreateFCmpORD(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400629 }
630
631 Value *Nucleus::createFCmpUNO(Value *lhs, Value *rhs)
632 {
Nicolas Capens19336542016-09-26 10:32:29 -0400633 return V(::builder->CreateFCmpUNO(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400634 }
635
636 Value *Nucleus::createFCmpUEQ(Value *lhs, Value *rhs)
637 {
Nicolas Capens19336542016-09-26 10:32:29 -0400638 return V(::builder->CreateFCmpUEQ(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400639 }
640
641 Value *Nucleus::createFCmpUGT(Value *lhs, Value *rhs)
642 {
Nicolas Capens19336542016-09-26 10:32:29 -0400643 return V(::builder->CreateFCmpUGT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400644 }
645
646 Value *Nucleus::createFCmpUGE(Value *lhs, Value *rhs)
647 {
Nicolas Capens19336542016-09-26 10:32:29 -0400648 return V(::builder->CreateFCmpUGE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400649 }
650
651 Value *Nucleus::createFCmpULT(Value *lhs, Value *rhs)
652 {
Nicolas Capens19336542016-09-26 10:32:29 -0400653 return V(::builder->CreateFCmpULT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400654 }
655
656 Value *Nucleus::createFCmpULE(Value *lhs, Value *rhs)
657 {
Nicolas Capens19336542016-09-26 10:32:29 -0400658 return V(::builder->CreateFCmpULE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400659 }
660
661 Value *Nucleus::createFCmpUNE(Value *lhs, Value *rhs)
662 {
Nicolas Capens19336542016-09-26 10:32:29 -0400663 return V(::builder->CreateFCmpULE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400664 }
665
Nicolas Capense95d5342016-09-30 11:37:28 -0400666 Value *Nucleus::createExtractElement(Value *vector, Type *type, int index)
John Bauman89401822014-05-06 15:04:28 -0400667 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400668 assert(vector->getType()->getContainedType(0) == T(type));
Nicolas Capens19336542016-09-26 10:32:29 -0400669 return V(::builder->CreateExtractElement(vector, createConstantInt(index)));
John Bauman89401822014-05-06 15:04:28 -0400670 }
671
672 Value *Nucleus::createInsertElement(Value *vector, Value *element, int index)
673 {
Nicolas Capens19336542016-09-26 10:32:29 -0400674 return V(::builder->CreateInsertElement(vector, element, createConstantInt(index)));
John Bauman89401822014-05-06 15:04:28 -0400675 }
676
Nicolas Capense89cd582016-09-30 14:23:47 -0400677 Value *Nucleus::createShuffleVector(Value *V1, Value *V2, const int *select)
John Bauman89401822014-05-06 15:04:28 -0400678 {
Nicolas Capense89cd582016-09-30 14:23:47 -0400679 int size = llvm::cast<llvm::VectorType>(V1->getType())->getNumElements();
680 const int maxSize = 16;
681 llvm::Constant *swizzle[maxSize];
682 assert(size <= maxSize);
683
684 for(int i = 0; i < size; i++)
685 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400686 swizzle[i] = llvm::ConstantInt::get(llvm::Type::getInt32Ty(*::context), select[i]);
Nicolas Capense89cd582016-09-30 14:23:47 -0400687 }
688
689 llvm::Value *shuffle = llvm::ConstantVector::get(llvm::ArrayRef<llvm::Constant*>(swizzle, size));
690
691 return V(::builder->CreateShuffleVector(V1, V2, shuffle));
John Bauman89401822014-05-06 15:04:28 -0400692 }
693
694 Value *Nucleus::createSelect(Value *C, Value *ifTrue, Value *ifFalse)
695 {
Nicolas Capens19336542016-09-26 10:32:29 -0400696 return V(::builder->CreateSelect(C, ifTrue, ifFalse));
John Bauman89401822014-05-06 15:04:28 -0400697 }
698
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500699 SwitchCases *Nucleus::createSwitch(Value *control, BasicBlock *defaultBranch, unsigned numCases)
John Bauman89401822014-05-06 15:04:28 -0400700 {
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500701 return reinterpret_cast<SwitchCases*>(::builder->CreateSwitch(control, defaultBranch, numCases));
John Bauman89401822014-05-06 15:04:28 -0400702 }
703
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500704 void Nucleus::addSwitchCase(SwitchCases *switchCases, int label, BasicBlock *branch)
John Bauman89401822014-05-06 15:04:28 -0400705 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400706 switchCases->addCase(llvm::ConstantInt::get(llvm::Type::getInt32Ty(*::context), label, true), branch);
John Bauman89401822014-05-06 15:04:28 -0400707 }
708
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400709 void Nucleus::createUnreachable()
John Bauman89401822014-05-06 15:04:28 -0400710 {
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400711 ::builder->CreateUnreachable();
John Bauman89401822014-05-06 15:04:28 -0400712 }
713
Nicolas Capense95d5342016-09-30 11:37:28 -0400714 static Value *createSwizzle4(Value *val, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -0400715 {
Nicolas Capense89cd582016-09-30 14:23:47 -0400716 int swizzle[4] =
717 {
718 (select >> 0) & 0x03,
719 (select >> 2) & 0x03,
720 (select >> 4) & 0x03,
721 (select >> 6) & 0x03,
722 };
John Bauman89401822014-05-06 15:04:28 -0400723
Nicolas Capense89cd582016-09-30 14:23:47 -0400724 return Nucleus::createShuffleVector(val, val, swizzle);
John Bauman89401822014-05-06 15:04:28 -0400725 }
726
Nicolas Capense95d5342016-09-30 11:37:28 -0400727 static Value *createMask4(Value *lhs, Value *rhs, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -0400728 {
729 bool mask[4] = {false, false, false, false};
730
731 mask[(select >> 0) & 0x03] = true;
732 mask[(select >> 2) & 0x03] = true;
733 mask[(select >> 4) & 0x03] = true;
734 mask[(select >> 6) & 0x03] = true;
735
Nicolas Capense89cd582016-09-30 14:23:47 -0400736 int swizzle[4] =
737 {
738 mask[0] ? 4 : 0,
739 mask[1] ? 5 : 1,
740 mask[2] ? 6 : 2,
741 mask[3] ? 7 : 3,
742 };
John Bauman89401822014-05-06 15:04:28 -0400743
Nicolas Capensa29d6532016-12-05 21:38:09 -0500744 return Nucleus::createShuffleVector(lhs, rhs, swizzle);
John Bauman89401822014-05-06 15:04:28 -0400745 }
746
Nicolas Capensac230122016-09-20 14:30:06 -0400747 Type *Nucleus::getPointerType(Type *ElementType)
John Bauman89401822014-05-06 15:04:28 -0400748 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400749 return T(llvm::PointerType::get(T(ElementType), 0));
John Bauman89401822014-05-06 15:04:28 -0400750 }
751
Nicolas Capens13ac2322016-10-13 14:52:12 -0400752 Value *Nucleus::createNullValue(Type *Ty)
John Bauman89401822014-05-06 15:04:28 -0400753 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400754 return V(llvm::Constant::getNullValue(T(Ty)));
John Bauman89401822014-05-06 15:04:28 -0400755 }
756
Nicolas Capens13ac2322016-10-13 14:52:12 -0400757 Value *Nucleus::createConstantLong(int64_t i)
John Bauman89401822014-05-06 15:04:28 -0400758 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400759 return V(llvm::ConstantInt::get(llvm::Type::getInt64Ty(*::context), i, true));
John Bauman89401822014-05-06 15:04:28 -0400760 }
761
Nicolas Capens13ac2322016-10-13 14:52:12 -0400762 Value *Nucleus::createConstantInt(int i)
John Bauman89401822014-05-06 15:04:28 -0400763 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400764 return V(llvm::ConstantInt::get(llvm::Type::getInt32Ty(*::context), i, true));
John Bauman89401822014-05-06 15:04:28 -0400765 }
766
Nicolas Capens13ac2322016-10-13 14:52:12 -0400767 Value *Nucleus::createConstantInt(unsigned int i)
John Bauman89401822014-05-06 15:04:28 -0400768 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400769 return V(llvm::ConstantInt::get(llvm::Type::getInt32Ty(*::context), i, false));
John Bauman89401822014-05-06 15:04:28 -0400770 }
771
Nicolas Capens13ac2322016-10-13 14:52:12 -0400772 Value *Nucleus::createConstantBool(bool b)
John Bauman89401822014-05-06 15:04:28 -0400773 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400774 return V(llvm::ConstantInt::get(llvm::Type::getInt1Ty(*::context), b));
John Bauman89401822014-05-06 15:04:28 -0400775 }
776
Nicolas Capens13ac2322016-10-13 14:52:12 -0400777 Value *Nucleus::createConstantByte(signed char i)
John Bauman89401822014-05-06 15:04:28 -0400778 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400779 return V(llvm::ConstantInt::get(llvm::Type::getInt8Ty(*::context), i, true));
John Bauman89401822014-05-06 15:04:28 -0400780 }
781
Nicolas Capens13ac2322016-10-13 14:52:12 -0400782 Value *Nucleus::createConstantByte(unsigned char i)
John Bauman89401822014-05-06 15:04:28 -0400783 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400784 return V(llvm::ConstantInt::get(llvm::Type::getInt8Ty(*::context), i, false));
John Bauman89401822014-05-06 15:04:28 -0400785 }
786
Nicolas Capens13ac2322016-10-13 14:52:12 -0400787 Value *Nucleus::createConstantShort(short i)
John Bauman89401822014-05-06 15:04:28 -0400788 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400789 return V(llvm::ConstantInt::get(llvm::Type::getInt16Ty(*::context), i, true));
John Bauman89401822014-05-06 15:04:28 -0400790 }
791
Nicolas Capens13ac2322016-10-13 14:52:12 -0400792 Value *Nucleus::createConstantShort(unsigned short i)
John Bauman89401822014-05-06 15:04:28 -0400793 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400794 return V(llvm::ConstantInt::get(llvm::Type::getInt16Ty(*::context), i, false));
John Bauman89401822014-05-06 15:04:28 -0400795 }
796
Nicolas Capens13ac2322016-10-13 14:52:12 -0400797 Value *Nucleus::createConstantFloat(float x)
John Bauman89401822014-05-06 15:04:28 -0400798 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400799 return V(llvm::ConstantFP::get(T(Float::getType()), x));
John Bauman89401822014-05-06 15:04:28 -0400800 }
801
Nicolas Capens13ac2322016-10-13 14:52:12 -0400802 Value *Nucleus::createNullPointer(Type *Ty)
John Bauman89401822014-05-06 15:04:28 -0400803 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400804 return V(llvm::ConstantPointerNull::get(llvm::PointerType::get(T(Ty), 0)));
John Bauman89401822014-05-06 15:04:28 -0400805 }
806
Nicolas Capens13ac2322016-10-13 14:52:12 -0400807 Value *Nucleus::createConstantVector(const int64_t *constants, Type *type)
John Bauman89401822014-05-06 15:04:28 -0400808 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400809 assert(llvm::isa<llvm::VectorType>(T(type)));
810 const int numConstants = llvm::cast<llvm::VectorType>(T(type))->getNumElements();
Nicolas Capens13ac2322016-10-13 14:52:12 -0400811 assert(numConstants <= 16);
812 llvm::Constant *constantVector[16];
813
814 for(int i = 0; i < numConstants; i++)
815 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400816 constantVector[i] = llvm::ConstantInt::get(T(type)->getContainedType(0), constants[i]);
Nicolas Capens13ac2322016-10-13 14:52:12 -0400817 }
818
819 return V(llvm::ConstantVector::get(llvm::ArrayRef<llvm::Constant*>(constantVector, numConstants)));
820 }
821
822 Value *Nucleus::createConstantVector(const double *constants, Type *type)
823 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400824 assert(llvm::isa<llvm::VectorType>(T(type)));
825 const int numConstants = llvm::cast<llvm::VectorType>(T(type))->getNumElements();
Nicolas Capens13ac2322016-10-13 14:52:12 -0400826 assert(numConstants <= 8);
827 llvm::Constant *constantVector[8];
828
829 for(int i = 0; i < numConstants; i++)
830 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -0400831 constantVector[i] = llvm::ConstantFP::get(T(type)->getContainedType(0), constants[i]);
Nicolas Capens13ac2322016-10-13 14:52:12 -0400832 }
833
834 return V(llvm::ConstantVector::get(llvm::ArrayRef<llvm::Constant*>(constantVector, numConstants)));
John Bauman89401822014-05-06 15:04:28 -0400835 }
836
John Bauman19bac1e2014-05-06 15:23:49 -0400837 Type *Void::getType()
John Bauman89401822014-05-06 15:04:28 -0400838 {
Nicolas Capensac230122016-09-20 14:30:06 -0400839 return T(llvm::Type::getVoidTy(*::context));
John Bauman89401822014-05-06 15:04:28 -0400840 }
841
Nicolas Capens297d26e2016-11-18 12:52:17 -0500842 class MMX : public LValue<MMX>
Nicolas Capens4f738a12016-09-20 15:46:16 -0400843 {
844 public:
845 static Type *getType();
846 };
847
John Bauman19bac1e2014-05-06 15:23:49 -0400848 Type *MMX::getType()
849 {
Nicolas Capensac230122016-09-20 14:30:06 -0400850 return T(llvm::Type::getX86_MMXTy(*::context));
John Bauman19bac1e2014-05-06 15:23:49 -0400851 }
852
Nicolas Capens81f18302016-01-14 09:32:35 -0500853 Bool::Bool(Argument<Bool> argument)
John Bauman89401822014-05-06 15:04:28 -0400854 {
Nicolas Capens81f18302016-01-14 09:32:35 -0500855 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -0400856 }
857
John Bauman89401822014-05-06 15:04:28 -0400858 Bool::Bool(bool x)
859 {
John Bauman66b8ab22014-05-06 15:57:45 -0400860 storeValue(Nucleus::createConstantBool(x));
John Bauman89401822014-05-06 15:04:28 -0400861 }
862
John Bauman19bac1e2014-05-06 15:23:49 -0400863 Bool::Bool(RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400864 {
John Bauman66b8ab22014-05-06 15:57:45 -0400865 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400866 }
867
868 Bool::Bool(const Bool &rhs)
869 {
John Bauman66b8ab22014-05-06 15:57:45 -0400870 Value *value = rhs.loadValue();
871 storeValue(value);
872 }
John Bauman89401822014-05-06 15:04:28 -0400873
John Bauman66b8ab22014-05-06 15:57:45 -0400874 Bool::Bool(const Reference<Bool> &rhs)
875 {
876 Value *value = rhs.loadValue();
877 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400878 }
879
Nicolas Capens96d4e092016-11-18 14:22:38 -0500880 RValue<Bool> Bool::operator=(RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400881 {
John Bauman66b8ab22014-05-06 15:57:45 -0400882 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400883
884 return rhs;
885 }
886
Nicolas Capens96d4e092016-11-18 14:22:38 -0500887 RValue<Bool> Bool::operator=(const Bool &rhs)
John Bauman89401822014-05-06 15:04:28 -0400888 {
John Bauman66b8ab22014-05-06 15:57:45 -0400889 Value *value = rhs.loadValue();
890 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400891
892 return RValue<Bool>(value);
893 }
894
Nicolas Capens96d4e092016-11-18 14:22:38 -0500895 RValue<Bool> Bool::operator=(const Reference<Bool> &rhs)
John Bauman89401822014-05-06 15:04:28 -0400896 {
John Bauman66b8ab22014-05-06 15:57:45 -0400897 Value *value = rhs.loadValue();
898 storeValue(value);
899
900 return RValue<Bool>(value);
John Bauman89401822014-05-06 15:04:28 -0400901 }
902
John Bauman19bac1e2014-05-06 15:23:49 -0400903 RValue<Bool> operator!(RValue<Bool> val)
John Bauman89401822014-05-06 15:04:28 -0400904 {
905 return RValue<Bool>(Nucleus::createNot(val.value));
906 }
907
John Bauman19bac1e2014-05-06 15:23:49 -0400908 RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400909 {
910 return RValue<Bool>(Nucleus::createAnd(lhs.value, rhs.value));
911 }
912
John Bauman19bac1e2014-05-06 15:23:49 -0400913 RValue<Bool> operator||(RValue<Bool> lhs, RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400914 {
915 return RValue<Bool>(Nucleus::createOr(lhs.value, rhs.value));
916 }
917
John Bauman19bac1e2014-05-06 15:23:49 -0400918 Type *Bool::getType()
John Bauman89401822014-05-06 15:04:28 -0400919 {
Nicolas Capensac230122016-09-20 14:30:06 -0400920 return T(llvm::Type::getInt1Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -0400921 }
922
Nicolas Capens81f18302016-01-14 09:32:35 -0500923 Byte::Byte(Argument<Byte> argument)
John Bauman89401822014-05-06 15:04:28 -0400924 {
Nicolas Capens81f18302016-01-14 09:32:35 -0500925 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -0400926 }
927
John Bauman19bac1e2014-05-06 15:23:49 -0400928 Byte::Byte(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -0400929 {
John Bauman89401822014-05-06 15:04:28 -0400930 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
931
John Bauman66b8ab22014-05-06 15:57:45 -0400932 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -0400933 }
934
Alexis Hetu77dfab42015-11-23 13:31:22 -0500935 Byte::Byte(RValue<UInt> cast)
936 {
937 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
938
939 storeValue(integer);
940 }
941
942 Byte::Byte(RValue<UShort> cast)
943 {
944 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
945
946 storeValue(integer);
947 }
948
John Bauman89401822014-05-06 15:04:28 -0400949 Byte::Byte(int x)
950 {
John Bauman66b8ab22014-05-06 15:57:45 -0400951 storeValue(Nucleus::createConstantByte((unsigned char)x));
John Bauman89401822014-05-06 15:04:28 -0400952 }
953
954 Byte::Byte(unsigned char x)
955 {
John Bauman66b8ab22014-05-06 15:57:45 -0400956 storeValue(Nucleus::createConstantByte(x));
John Bauman89401822014-05-06 15:04:28 -0400957 }
958
John Bauman19bac1e2014-05-06 15:23:49 -0400959 Byte::Byte(RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400960 {
John Bauman66b8ab22014-05-06 15:57:45 -0400961 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400962 }
963
964 Byte::Byte(const Byte &rhs)
965 {
John Bauman66b8ab22014-05-06 15:57:45 -0400966 Value *value = rhs.loadValue();
967 storeValue(value);
968 }
John Bauman89401822014-05-06 15:04:28 -0400969
John Bauman66b8ab22014-05-06 15:57:45 -0400970 Byte::Byte(const Reference<Byte> &rhs)
971 {
972 Value *value = rhs.loadValue();
973 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400974 }
975
Nicolas Capens96d4e092016-11-18 14:22:38 -0500976 RValue<Byte> Byte::operator=(RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400977 {
John Bauman66b8ab22014-05-06 15:57:45 -0400978 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400979
980 return rhs;
981 }
982
Nicolas Capens96445fe2016-12-15 14:45:13 -0500983 RValue<Byte> Byte::operator=(const Byte &rhs)
John Bauman89401822014-05-06 15:04:28 -0400984 {
John Bauman66b8ab22014-05-06 15:57:45 -0400985 Value *value = rhs.loadValue();
986 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400987
988 return RValue<Byte>(value);
989 }
990
Nicolas Capens96d4e092016-11-18 14:22:38 -0500991 RValue<Byte> Byte::operator=(const Reference<Byte> &rhs)
John Bauman89401822014-05-06 15:04:28 -0400992 {
John Bauman66b8ab22014-05-06 15:57:45 -0400993 Value *value = rhs.loadValue();
994 storeValue(value);
995
996 return RValue<Byte>(value);
John Bauman89401822014-05-06 15:04:28 -0400997 }
998
John Bauman19bac1e2014-05-06 15:23:49 -0400999 RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001000 {
1001 return RValue<Byte>(Nucleus::createAdd(lhs.value, rhs.value));
1002 }
1003
John Bauman19bac1e2014-05-06 15:23:49 -04001004 RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001005 {
1006 return RValue<Byte>(Nucleus::createSub(lhs.value, rhs.value));
1007 }
1008
John Bauman19bac1e2014-05-06 15:23:49 -04001009 RValue<Byte> operator*(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001010 {
1011 return RValue<Byte>(Nucleus::createMul(lhs.value, rhs.value));
1012 }
1013
John Bauman19bac1e2014-05-06 15:23:49 -04001014 RValue<Byte> operator/(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001015 {
1016 return RValue<Byte>(Nucleus::createUDiv(lhs.value, rhs.value));
1017 }
1018
John Bauman19bac1e2014-05-06 15:23:49 -04001019 RValue<Byte> operator%(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001020 {
1021 return RValue<Byte>(Nucleus::createURem(lhs.value, rhs.value));
1022 }
1023
John Bauman19bac1e2014-05-06 15:23:49 -04001024 RValue<Byte> operator&(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001025 {
1026 return RValue<Byte>(Nucleus::createAnd(lhs.value, rhs.value));
1027 }
1028
John Bauman19bac1e2014-05-06 15:23:49 -04001029 RValue<Byte> operator|(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001030 {
1031 return RValue<Byte>(Nucleus::createOr(lhs.value, rhs.value));
1032 }
1033
John Bauman19bac1e2014-05-06 15:23:49 -04001034 RValue<Byte> operator^(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001035 {
1036 return RValue<Byte>(Nucleus::createXor(lhs.value, rhs.value));
1037 }
1038
John Bauman19bac1e2014-05-06 15:23:49 -04001039 RValue<Byte> operator<<(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001040 {
1041 return RValue<Byte>(Nucleus::createShl(lhs.value, rhs.value));
1042 }
1043
John Bauman19bac1e2014-05-06 15:23:49 -04001044 RValue<Byte> operator>>(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001045 {
1046 return RValue<Byte>(Nucleus::createLShr(lhs.value, rhs.value));
1047 }
1048
Nicolas Capens96d4e092016-11-18 14:22:38 -05001049 RValue<Byte> operator+=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001050 {
1051 return lhs = lhs + rhs;
1052 }
1053
Nicolas Capens96d4e092016-11-18 14:22:38 -05001054 RValue<Byte> operator-=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001055 {
1056 return lhs = lhs - rhs;
1057 }
1058
Nicolas Capens96d4e092016-11-18 14:22:38 -05001059 RValue<Byte> operator*=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001060 {
1061 return lhs = lhs * rhs;
1062 }
1063
Nicolas Capens96d4e092016-11-18 14:22:38 -05001064 RValue<Byte> operator/=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001065 {
1066 return lhs = lhs / rhs;
1067 }
1068
Nicolas Capens96d4e092016-11-18 14:22:38 -05001069 RValue<Byte> operator%=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001070 {
1071 return lhs = lhs % rhs;
1072 }
1073
Nicolas Capens96d4e092016-11-18 14:22:38 -05001074 RValue<Byte> operator&=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001075 {
1076 return lhs = lhs & rhs;
1077 }
1078
Nicolas Capens96d4e092016-11-18 14:22:38 -05001079 RValue<Byte> operator|=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001080 {
1081 return lhs = lhs | rhs;
1082 }
1083
Nicolas Capens96d4e092016-11-18 14:22:38 -05001084 RValue<Byte> operator^=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001085 {
1086 return lhs = lhs ^ rhs;
1087 }
1088
Nicolas Capens96d4e092016-11-18 14:22:38 -05001089 RValue<Byte> operator<<=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001090 {
1091 return lhs = lhs << rhs;
1092 }
1093
Nicolas Capens96d4e092016-11-18 14:22:38 -05001094 RValue<Byte> operator>>=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001095 {
1096 return lhs = lhs >> rhs;
1097 }
1098
John Bauman19bac1e2014-05-06 15:23:49 -04001099 RValue<Byte> operator+(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001100 {
1101 return val;
1102 }
1103
John Bauman19bac1e2014-05-06 15:23:49 -04001104 RValue<Byte> operator-(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001105 {
1106 return RValue<Byte>(Nucleus::createNeg(val.value));
1107 }
1108
John Bauman19bac1e2014-05-06 15:23:49 -04001109 RValue<Byte> operator~(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001110 {
1111 return RValue<Byte>(Nucleus::createNot(val.value));
1112 }
1113
Nicolas Capens96d4e092016-11-18 14:22:38 -05001114 RValue<Byte> operator++(Byte &val, int) // Post-increment
John Bauman89401822014-05-06 15:04:28 -04001115 {
1116 RValue<Byte> res = val;
1117
Nicolas Capens19336542016-09-26 10:32:29 -04001118 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantByte((unsigned char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001119 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001120
1121 return res;
1122 }
1123
Nicolas Capens96d4e092016-11-18 14:22:38 -05001124 const Byte &operator++(Byte &val) // Pre-increment
John Bauman89401822014-05-06 15:04:28 -04001125 {
Nicolas Capens19336542016-09-26 10:32:29 -04001126 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantByte((unsigned char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001127 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001128
1129 return val;
1130 }
1131
Nicolas Capens96d4e092016-11-18 14:22:38 -05001132 RValue<Byte> operator--(Byte &val, int) // Post-decrement
John Bauman89401822014-05-06 15:04:28 -04001133 {
1134 RValue<Byte> res = val;
1135
Nicolas Capens19336542016-09-26 10:32:29 -04001136 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantByte((unsigned char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001137 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001138
1139 return res;
1140 }
1141
Nicolas Capens96d4e092016-11-18 14:22:38 -05001142 const Byte &operator--(Byte &val) // Pre-decrement
John Bauman89401822014-05-06 15:04:28 -04001143 {
Nicolas Capens19336542016-09-26 10:32:29 -04001144 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantByte((unsigned char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001145 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001146
1147 return val;
1148 }
1149
John Bauman19bac1e2014-05-06 15:23:49 -04001150 RValue<Bool> operator<(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001151 {
1152 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1153 }
1154
John Bauman19bac1e2014-05-06 15:23:49 -04001155 RValue<Bool> operator<=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001156 {
1157 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1158 }
1159
John Bauman19bac1e2014-05-06 15:23:49 -04001160 RValue<Bool> operator>(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001161 {
1162 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1163 }
1164
John Bauman19bac1e2014-05-06 15:23:49 -04001165 RValue<Bool> operator>=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001166 {
1167 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1168 }
1169
John Bauman19bac1e2014-05-06 15:23:49 -04001170 RValue<Bool> operator!=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001171 {
1172 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1173 }
1174
John Bauman19bac1e2014-05-06 15:23:49 -04001175 RValue<Bool> operator==(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001176 {
1177 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1178 }
1179
John Bauman19bac1e2014-05-06 15:23:49 -04001180 Type *Byte::getType()
John Bauman89401822014-05-06 15:04:28 -04001181 {
Nicolas Capensac230122016-09-20 14:30:06 -04001182 return T(llvm::Type::getInt8Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001183 }
1184
Nicolas Capens81f18302016-01-14 09:32:35 -05001185 SByte::SByte(Argument<SByte> argument)
John Bauman89401822014-05-06 15:04:28 -04001186 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001187 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001188 }
1189
Alexis Hetu77dfab42015-11-23 13:31:22 -05001190 SByte::SByte(RValue<Int> cast)
1191 {
1192 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1193
1194 storeValue(integer);
1195 }
1196
1197 SByte::SByte(RValue<Short> cast)
1198 {
1199 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1200
1201 storeValue(integer);
1202 }
1203
John Bauman89401822014-05-06 15:04:28 -04001204 SByte::SByte(signed char x)
1205 {
John Bauman66b8ab22014-05-06 15:57:45 -04001206 storeValue(Nucleus::createConstantByte(x));
John Bauman89401822014-05-06 15:04:28 -04001207 }
1208
John Bauman19bac1e2014-05-06 15:23:49 -04001209 SByte::SByte(RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001210 {
John Bauman66b8ab22014-05-06 15:57:45 -04001211 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001212 }
1213
1214 SByte::SByte(const SByte &rhs)
1215 {
John Bauman66b8ab22014-05-06 15:57:45 -04001216 Value *value = rhs.loadValue();
1217 storeValue(value);
1218 }
John Bauman89401822014-05-06 15:04:28 -04001219
John Bauman66b8ab22014-05-06 15:57:45 -04001220 SByte::SByte(const Reference<SByte> &rhs)
1221 {
1222 Value *value = rhs.loadValue();
1223 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001224 }
1225
Nicolas Capens96d4e092016-11-18 14:22:38 -05001226 RValue<SByte> SByte::operator=(RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001227 {
John Bauman66b8ab22014-05-06 15:57:45 -04001228 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001229
1230 return rhs;
1231 }
1232
Nicolas Capens96d4e092016-11-18 14:22:38 -05001233 RValue<SByte> SByte::operator=(const SByte &rhs)
John Bauman89401822014-05-06 15:04:28 -04001234 {
John Bauman66b8ab22014-05-06 15:57:45 -04001235 Value *value = rhs.loadValue();
1236 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001237
1238 return RValue<SByte>(value);
1239 }
1240
Nicolas Capens96d4e092016-11-18 14:22:38 -05001241 RValue<SByte> SByte::operator=(const Reference<SByte> &rhs)
John Bauman89401822014-05-06 15:04:28 -04001242 {
John Bauman66b8ab22014-05-06 15:57:45 -04001243 Value *value = rhs.loadValue();
1244 storeValue(value);
1245
1246 return RValue<SByte>(value);
John Bauman89401822014-05-06 15:04:28 -04001247 }
1248
John Bauman19bac1e2014-05-06 15:23:49 -04001249 RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001250 {
1251 return RValue<SByte>(Nucleus::createAdd(lhs.value, rhs.value));
1252 }
1253
John Bauman19bac1e2014-05-06 15:23:49 -04001254 RValue<SByte> operator-(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001255 {
1256 return RValue<SByte>(Nucleus::createSub(lhs.value, rhs.value));
1257 }
1258
John Bauman19bac1e2014-05-06 15:23:49 -04001259 RValue<SByte> operator*(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001260 {
1261 return RValue<SByte>(Nucleus::createMul(lhs.value, rhs.value));
1262 }
1263
John Bauman19bac1e2014-05-06 15:23:49 -04001264 RValue<SByte> operator/(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001265 {
1266 return RValue<SByte>(Nucleus::createSDiv(lhs.value, rhs.value));
1267 }
1268
John Bauman19bac1e2014-05-06 15:23:49 -04001269 RValue<SByte> operator%(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001270 {
1271 return RValue<SByte>(Nucleus::createSRem(lhs.value, rhs.value));
1272 }
1273
John Bauman19bac1e2014-05-06 15:23:49 -04001274 RValue<SByte> operator&(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001275 {
1276 return RValue<SByte>(Nucleus::createAnd(lhs.value, rhs.value));
1277 }
1278
John Bauman19bac1e2014-05-06 15:23:49 -04001279 RValue<SByte> operator|(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001280 {
1281 return RValue<SByte>(Nucleus::createOr(lhs.value, rhs.value));
1282 }
1283
John Bauman19bac1e2014-05-06 15:23:49 -04001284 RValue<SByte> operator^(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001285 {
1286 return RValue<SByte>(Nucleus::createXor(lhs.value, rhs.value));
1287 }
1288
John Bauman19bac1e2014-05-06 15:23:49 -04001289 RValue<SByte> operator<<(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001290 {
1291 return RValue<SByte>(Nucleus::createShl(lhs.value, rhs.value));
1292 }
1293
John Bauman19bac1e2014-05-06 15:23:49 -04001294 RValue<SByte> operator>>(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001295 {
1296 return RValue<SByte>(Nucleus::createAShr(lhs.value, rhs.value));
1297 }
1298
Nicolas Capens96d4e092016-11-18 14:22:38 -05001299 RValue<SByte> operator+=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001300 {
1301 return lhs = lhs + rhs;
1302 }
1303
Nicolas Capens96d4e092016-11-18 14:22:38 -05001304 RValue<SByte> operator-=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001305 {
1306 return lhs = lhs - rhs;
1307 }
1308
Nicolas Capens96d4e092016-11-18 14:22:38 -05001309 RValue<SByte> operator*=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001310 {
1311 return lhs = lhs * rhs;
1312 }
1313
Nicolas Capens96d4e092016-11-18 14:22:38 -05001314 RValue<SByte> operator/=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001315 {
1316 return lhs = lhs / rhs;
1317 }
1318
Nicolas Capens96d4e092016-11-18 14:22:38 -05001319 RValue<SByte> operator%=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001320 {
1321 return lhs = lhs % rhs;
1322 }
1323
Nicolas Capens96d4e092016-11-18 14:22:38 -05001324 RValue<SByte> operator&=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001325 {
1326 return lhs = lhs & rhs;
1327 }
1328
Nicolas Capens96d4e092016-11-18 14:22:38 -05001329 RValue<SByte> operator|=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001330 {
1331 return lhs = lhs | rhs;
1332 }
1333
Nicolas Capens96d4e092016-11-18 14:22:38 -05001334 RValue<SByte> operator^=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001335 {
1336 return lhs = lhs ^ rhs;
1337 }
1338
Nicolas Capens96d4e092016-11-18 14:22:38 -05001339 RValue<SByte> operator<<=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001340 {
1341 return lhs = lhs << rhs;
1342 }
1343
Nicolas Capens96d4e092016-11-18 14:22:38 -05001344 RValue<SByte> operator>>=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001345 {
1346 return lhs = lhs >> rhs;
1347 }
1348
John Bauman19bac1e2014-05-06 15:23:49 -04001349 RValue<SByte> operator+(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001350 {
1351 return val;
1352 }
1353
John Bauman19bac1e2014-05-06 15:23:49 -04001354 RValue<SByte> operator-(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001355 {
1356 return RValue<SByte>(Nucleus::createNeg(val.value));
1357 }
1358
John Bauman19bac1e2014-05-06 15:23:49 -04001359 RValue<SByte> operator~(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001360 {
1361 return RValue<SByte>(Nucleus::createNot(val.value));
1362 }
1363
Nicolas Capens96d4e092016-11-18 14:22:38 -05001364 RValue<SByte> operator++(SByte &val, int) // Post-increment
John Bauman89401822014-05-06 15:04:28 -04001365 {
1366 RValue<SByte> res = val;
1367
Nicolas Capens19336542016-09-26 10:32:29 -04001368 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantByte((signed char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001369 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001370
1371 return res;
1372 }
1373
Nicolas Capens96d4e092016-11-18 14:22:38 -05001374 const SByte &operator++(SByte &val) // Pre-increment
John Bauman89401822014-05-06 15:04:28 -04001375 {
Nicolas Capens19336542016-09-26 10:32:29 -04001376 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantByte((signed char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001377 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001378
1379 return val;
1380 }
1381
Nicolas Capens96d4e092016-11-18 14:22:38 -05001382 RValue<SByte> operator--(SByte &val, int) // Post-decrement
John Bauman89401822014-05-06 15:04:28 -04001383 {
1384 RValue<SByte> res = val;
1385
Nicolas Capens19336542016-09-26 10:32:29 -04001386 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantByte((signed char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001387 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001388
1389 return res;
1390 }
1391
Nicolas Capens96d4e092016-11-18 14:22:38 -05001392 const SByte &operator--(SByte &val) // Pre-decrement
John Bauman89401822014-05-06 15:04:28 -04001393 {
Nicolas Capens19336542016-09-26 10:32:29 -04001394 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantByte((signed char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001395 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001396
1397 return val;
1398 }
1399
John Bauman19bac1e2014-05-06 15:23:49 -04001400 RValue<Bool> operator<(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001401 {
1402 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
1403 }
1404
John Bauman19bac1e2014-05-06 15:23:49 -04001405 RValue<Bool> operator<=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001406 {
1407 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
1408 }
1409
John Bauman19bac1e2014-05-06 15:23:49 -04001410 RValue<Bool> operator>(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001411 {
1412 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
1413 }
1414
John Bauman19bac1e2014-05-06 15:23:49 -04001415 RValue<Bool> operator>=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001416 {
1417 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
1418 }
1419
John Bauman19bac1e2014-05-06 15:23:49 -04001420 RValue<Bool> operator!=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001421 {
1422 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1423 }
1424
John Bauman19bac1e2014-05-06 15:23:49 -04001425 RValue<Bool> operator==(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001426 {
1427 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1428 }
1429
John Bauman19bac1e2014-05-06 15:23:49 -04001430 Type *SByte::getType()
John Bauman89401822014-05-06 15:04:28 -04001431 {
Nicolas Capensac230122016-09-20 14:30:06 -04001432 return T(llvm::Type::getInt8Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001433 }
1434
Nicolas Capens81f18302016-01-14 09:32:35 -05001435 Short::Short(Argument<Short> argument)
John Bauman89401822014-05-06 15:04:28 -04001436 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001437 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001438 }
1439
John Bauman19bac1e2014-05-06 15:23:49 -04001440 Short::Short(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04001441 {
John Bauman89401822014-05-06 15:04:28 -04001442 Value *integer = Nucleus::createTrunc(cast.value, Short::getType());
1443
John Bauman66b8ab22014-05-06 15:57:45 -04001444 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04001445 }
1446
John Bauman89401822014-05-06 15:04:28 -04001447 Short::Short(short x)
1448 {
John Bauman66b8ab22014-05-06 15:57:45 -04001449 storeValue(Nucleus::createConstantShort(x));
John Bauman89401822014-05-06 15:04:28 -04001450 }
1451
John Bauman19bac1e2014-05-06 15:23:49 -04001452 Short::Short(RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001453 {
John Bauman66b8ab22014-05-06 15:57:45 -04001454 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001455 }
1456
1457 Short::Short(const Short &rhs)
1458 {
John Bauman66b8ab22014-05-06 15:57:45 -04001459 Value *value = rhs.loadValue();
1460 storeValue(value);
1461 }
John Bauman89401822014-05-06 15:04:28 -04001462
John Bauman66b8ab22014-05-06 15:57:45 -04001463 Short::Short(const Reference<Short> &rhs)
1464 {
1465 Value *value = rhs.loadValue();
1466 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001467 }
1468
Nicolas Capens96d4e092016-11-18 14:22:38 -05001469 RValue<Short> Short::operator=(RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001470 {
John Bauman66b8ab22014-05-06 15:57:45 -04001471 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001472
1473 return rhs;
1474 }
1475
Nicolas Capens96d4e092016-11-18 14:22:38 -05001476 RValue<Short> Short::operator=(const Short &rhs)
John Bauman89401822014-05-06 15:04:28 -04001477 {
John Bauman66b8ab22014-05-06 15:57:45 -04001478 Value *value = rhs.loadValue();
1479 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001480
1481 return RValue<Short>(value);
1482 }
1483
Nicolas Capens96d4e092016-11-18 14:22:38 -05001484 RValue<Short> Short::operator=(const Reference<Short> &rhs)
John Bauman89401822014-05-06 15:04:28 -04001485 {
John Bauman66b8ab22014-05-06 15:57:45 -04001486 Value *value = rhs.loadValue();
1487 storeValue(value);
1488
1489 return RValue<Short>(value);
John Bauman89401822014-05-06 15:04:28 -04001490 }
1491
John Bauman19bac1e2014-05-06 15:23:49 -04001492 RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001493 {
1494 return RValue<Short>(Nucleus::createAdd(lhs.value, rhs.value));
1495 }
1496
John Bauman19bac1e2014-05-06 15:23:49 -04001497 RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001498 {
1499 return RValue<Short>(Nucleus::createSub(lhs.value, rhs.value));
1500 }
1501
John Bauman19bac1e2014-05-06 15:23:49 -04001502 RValue<Short> operator*(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001503 {
1504 return RValue<Short>(Nucleus::createMul(lhs.value, rhs.value));
1505 }
1506
John Bauman19bac1e2014-05-06 15:23:49 -04001507 RValue<Short> operator/(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001508 {
1509 return RValue<Short>(Nucleus::createSDiv(lhs.value, rhs.value));
1510 }
1511
John Bauman19bac1e2014-05-06 15:23:49 -04001512 RValue<Short> operator%(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001513 {
1514 return RValue<Short>(Nucleus::createSRem(lhs.value, rhs.value));
1515 }
1516
John Bauman19bac1e2014-05-06 15:23:49 -04001517 RValue<Short> operator&(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001518 {
1519 return RValue<Short>(Nucleus::createAnd(lhs.value, rhs.value));
1520 }
1521
John Bauman19bac1e2014-05-06 15:23:49 -04001522 RValue<Short> operator|(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001523 {
1524 return RValue<Short>(Nucleus::createOr(lhs.value, rhs.value));
1525 }
1526
John Bauman19bac1e2014-05-06 15:23:49 -04001527 RValue<Short> operator^(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001528 {
1529 return RValue<Short>(Nucleus::createXor(lhs.value, rhs.value));
1530 }
1531
John Bauman19bac1e2014-05-06 15:23:49 -04001532 RValue<Short> operator<<(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001533 {
1534 return RValue<Short>(Nucleus::createShl(lhs.value, rhs.value));
1535 }
1536
John Bauman19bac1e2014-05-06 15:23:49 -04001537 RValue<Short> operator>>(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001538 {
1539 return RValue<Short>(Nucleus::createAShr(lhs.value, rhs.value));
1540 }
1541
Nicolas Capens96d4e092016-11-18 14:22:38 -05001542 RValue<Short> operator+=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001543 {
1544 return lhs = lhs + rhs;
1545 }
1546
Nicolas Capens96d4e092016-11-18 14:22:38 -05001547 RValue<Short> operator-=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001548 {
1549 return lhs = lhs - rhs;
1550 }
1551
Nicolas Capens96d4e092016-11-18 14:22:38 -05001552 RValue<Short> operator*=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001553 {
1554 return lhs = lhs * rhs;
1555 }
1556
Nicolas Capens96d4e092016-11-18 14:22:38 -05001557 RValue<Short> operator/=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001558 {
1559 return lhs = lhs / rhs;
1560 }
1561
Nicolas Capens96d4e092016-11-18 14:22:38 -05001562 RValue<Short> operator%=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001563 {
1564 return lhs = lhs % rhs;
1565 }
1566
Nicolas Capens96d4e092016-11-18 14:22:38 -05001567 RValue<Short> operator&=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001568 {
1569 return lhs = lhs & rhs;
1570 }
1571
Nicolas Capens96d4e092016-11-18 14:22:38 -05001572 RValue<Short> operator|=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001573 {
1574 return lhs = lhs | rhs;
1575 }
1576
Nicolas Capens96d4e092016-11-18 14:22:38 -05001577 RValue<Short> operator^=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001578 {
1579 return lhs = lhs ^ rhs;
1580 }
1581
Nicolas Capens96d4e092016-11-18 14:22:38 -05001582 RValue<Short> operator<<=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001583 {
1584 return lhs = lhs << rhs;
1585 }
1586
Nicolas Capens96d4e092016-11-18 14:22:38 -05001587 RValue<Short> operator>>=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001588 {
1589 return lhs = lhs >> rhs;
1590 }
1591
John Bauman19bac1e2014-05-06 15:23:49 -04001592 RValue<Short> operator+(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001593 {
1594 return val;
1595 }
1596
John Bauman19bac1e2014-05-06 15:23:49 -04001597 RValue<Short> operator-(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001598 {
1599 return RValue<Short>(Nucleus::createNeg(val.value));
1600 }
1601
John Bauman19bac1e2014-05-06 15:23:49 -04001602 RValue<Short> operator~(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001603 {
1604 return RValue<Short>(Nucleus::createNot(val.value));
1605 }
1606
Nicolas Capens96d4e092016-11-18 14:22:38 -05001607 RValue<Short> operator++(Short &val, int) // Post-increment
John Bauman89401822014-05-06 15:04:28 -04001608 {
1609 RValue<Short> res = val;
1610
Nicolas Capens19336542016-09-26 10:32:29 -04001611 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantShort((short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001612 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001613
1614 return res;
1615 }
1616
Nicolas Capens96d4e092016-11-18 14:22:38 -05001617 const Short &operator++(Short &val) // Pre-increment
John Bauman89401822014-05-06 15:04:28 -04001618 {
Nicolas Capens19336542016-09-26 10:32:29 -04001619 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantShort((short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001620 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001621
1622 return val;
1623 }
1624
Nicolas Capens96d4e092016-11-18 14:22:38 -05001625 RValue<Short> operator--(Short &val, int) // Post-decrement
John Bauman89401822014-05-06 15:04:28 -04001626 {
1627 RValue<Short> res = val;
1628
Nicolas Capens19336542016-09-26 10:32:29 -04001629 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantShort((short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001630 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001631
1632 return res;
1633 }
1634
Nicolas Capens96d4e092016-11-18 14:22:38 -05001635 const Short &operator--(Short &val) // Pre-decrement
John Bauman89401822014-05-06 15:04:28 -04001636 {
Nicolas Capens19336542016-09-26 10:32:29 -04001637 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantShort((short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001638 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001639
1640 return val;
1641 }
1642
John Bauman19bac1e2014-05-06 15:23:49 -04001643 RValue<Bool> operator<(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001644 {
1645 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
1646 }
1647
John Bauman19bac1e2014-05-06 15:23:49 -04001648 RValue<Bool> operator<=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001649 {
1650 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
1651 }
1652
John Bauman19bac1e2014-05-06 15:23:49 -04001653 RValue<Bool> operator>(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001654 {
1655 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
1656 }
1657
John Bauman19bac1e2014-05-06 15:23:49 -04001658 RValue<Bool> operator>=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001659 {
1660 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
1661 }
1662
John Bauman19bac1e2014-05-06 15:23:49 -04001663 RValue<Bool> operator!=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001664 {
1665 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1666 }
1667
John Bauman19bac1e2014-05-06 15:23:49 -04001668 RValue<Bool> operator==(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001669 {
1670 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1671 }
1672
John Bauman19bac1e2014-05-06 15:23:49 -04001673 Type *Short::getType()
John Bauman89401822014-05-06 15:04:28 -04001674 {
Nicolas Capensac230122016-09-20 14:30:06 -04001675 return T(llvm::Type::getInt16Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001676 }
1677
Nicolas Capens81f18302016-01-14 09:32:35 -05001678 UShort::UShort(Argument<UShort> argument)
John Bauman89401822014-05-06 15:04:28 -04001679 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001680 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001681 }
1682
Alexis Hetu77dfab42015-11-23 13:31:22 -05001683 UShort::UShort(RValue<UInt> cast)
1684 {
1685 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
1686
1687 storeValue(integer);
1688 }
1689
Alexis Hetu75b650f2015-11-19 17:40:15 -05001690 UShort::UShort(RValue<Int> cast)
1691 {
1692 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
1693
1694 storeValue(integer);
1695 }
1696
John Bauman89401822014-05-06 15:04:28 -04001697 UShort::UShort(unsigned short x)
1698 {
John Bauman66b8ab22014-05-06 15:57:45 -04001699 storeValue(Nucleus::createConstantShort(x));
John Bauman89401822014-05-06 15:04:28 -04001700 }
1701
John Bauman19bac1e2014-05-06 15:23:49 -04001702 UShort::UShort(RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001703 {
John Bauman66b8ab22014-05-06 15:57:45 -04001704 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001705 }
1706
1707 UShort::UShort(const UShort &rhs)
1708 {
John Bauman66b8ab22014-05-06 15:57:45 -04001709 Value *value = rhs.loadValue();
1710 storeValue(value);
1711 }
John Bauman89401822014-05-06 15:04:28 -04001712
John Bauman66b8ab22014-05-06 15:57:45 -04001713 UShort::UShort(const Reference<UShort> &rhs)
1714 {
1715 Value *value = rhs.loadValue();
1716 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001717 }
1718
Nicolas Capens96d4e092016-11-18 14:22:38 -05001719 RValue<UShort> UShort::operator=(RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001720 {
John Bauman66b8ab22014-05-06 15:57:45 -04001721 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001722
1723 return rhs;
1724 }
1725
Nicolas Capens96d4e092016-11-18 14:22:38 -05001726 RValue<UShort> UShort::operator=(const UShort &rhs)
John Bauman89401822014-05-06 15:04:28 -04001727 {
John Bauman66b8ab22014-05-06 15:57:45 -04001728 Value *value = rhs.loadValue();
1729 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001730
1731 return RValue<UShort>(value);
1732 }
1733
Nicolas Capens96d4e092016-11-18 14:22:38 -05001734 RValue<UShort> UShort::operator=(const Reference<UShort> &rhs)
John Bauman89401822014-05-06 15:04:28 -04001735 {
John Bauman66b8ab22014-05-06 15:57:45 -04001736 Value *value = rhs.loadValue();
1737 storeValue(value);
1738
1739 return RValue<UShort>(value);
John Bauman89401822014-05-06 15:04:28 -04001740 }
1741
John Bauman19bac1e2014-05-06 15:23:49 -04001742 RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001743 {
1744 return RValue<UShort>(Nucleus::createAdd(lhs.value, rhs.value));
1745 }
1746
John Bauman19bac1e2014-05-06 15:23:49 -04001747 RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001748 {
1749 return RValue<UShort>(Nucleus::createSub(lhs.value, rhs.value));
1750 }
1751
John Bauman19bac1e2014-05-06 15:23:49 -04001752 RValue<UShort> operator*(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001753 {
1754 return RValue<UShort>(Nucleus::createMul(lhs.value, rhs.value));
1755 }
1756
John Bauman19bac1e2014-05-06 15:23:49 -04001757 RValue<UShort> operator/(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001758 {
1759 return RValue<UShort>(Nucleus::createUDiv(lhs.value, rhs.value));
1760 }
1761
John Bauman19bac1e2014-05-06 15:23:49 -04001762 RValue<UShort> operator%(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001763 {
1764 return RValue<UShort>(Nucleus::createURem(lhs.value, rhs.value));
1765 }
1766
John Bauman19bac1e2014-05-06 15:23:49 -04001767 RValue<UShort> operator&(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001768 {
1769 return RValue<UShort>(Nucleus::createAnd(lhs.value, rhs.value));
1770 }
1771
John Bauman19bac1e2014-05-06 15:23:49 -04001772 RValue<UShort> operator|(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001773 {
1774 return RValue<UShort>(Nucleus::createOr(lhs.value, rhs.value));
1775 }
1776
John Bauman19bac1e2014-05-06 15:23:49 -04001777 RValue<UShort> operator^(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001778 {
1779 return RValue<UShort>(Nucleus::createXor(lhs.value, rhs.value));
1780 }
1781
John Bauman19bac1e2014-05-06 15:23:49 -04001782 RValue<UShort> operator<<(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001783 {
1784 return RValue<UShort>(Nucleus::createShl(lhs.value, rhs.value));
1785 }
1786
John Bauman19bac1e2014-05-06 15:23:49 -04001787 RValue<UShort> operator>>(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001788 {
1789 return RValue<UShort>(Nucleus::createLShr(lhs.value, rhs.value));
1790 }
1791
Nicolas Capens96d4e092016-11-18 14:22:38 -05001792 RValue<UShort> operator+=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001793 {
1794 return lhs = lhs + rhs;
1795 }
1796
Nicolas Capens96d4e092016-11-18 14:22:38 -05001797 RValue<UShort> operator-=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001798 {
1799 return lhs = lhs - rhs;
1800 }
1801
Nicolas Capens96d4e092016-11-18 14:22:38 -05001802 RValue<UShort> operator*=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001803 {
1804 return lhs = lhs * rhs;
1805 }
1806
Nicolas Capens96d4e092016-11-18 14:22:38 -05001807 RValue<UShort> operator/=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001808 {
1809 return lhs = lhs / rhs;
1810 }
1811
Nicolas Capens96d4e092016-11-18 14:22:38 -05001812 RValue<UShort> operator%=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001813 {
1814 return lhs = lhs % rhs;
1815 }
1816
Nicolas Capens96d4e092016-11-18 14:22:38 -05001817 RValue<UShort> operator&=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001818 {
1819 return lhs = lhs & rhs;
1820 }
1821
Nicolas Capens96d4e092016-11-18 14:22:38 -05001822 RValue<UShort> operator|=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001823 {
1824 return lhs = lhs | rhs;
1825 }
1826
Nicolas Capens96d4e092016-11-18 14:22:38 -05001827 RValue<UShort> operator^=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001828 {
1829 return lhs = lhs ^ rhs;
1830 }
1831
Nicolas Capens96d4e092016-11-18 14:22:38 -05001832 RValue<UShort> operator<<=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001833 {
1834 return lhs = lhs << rhs;
1835 }
1836
Nicolas Capens96d4e092016-11-18 14:22:38 -05001837 RValue<UShort> operator>>=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001838 {
1839 return lhs = lhs >> rhs;
1840 }
1841
John Bauman19bac1e2014-05-06 15:23:49 -04001842 RValue<UShort> operator+(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001843 {
1844 return val;
1845 }
1846
John Bauman19bac1e2014-05-06 15:23:49 -04001847 RValue<UShort> operator-(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001848 {
1849 return RValue<UShort>(Nucleus::createNeg(val.value));
1850 }
1851
John Bauman19bac1e2014-05-06 15:23:49 -04001852 RValue<UShort> operator~(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001853 {
1854 return RValue<UShort>(Nucleus::createNot(val.value));
1855 }
1856
Nicolas Capens96d4e092016-11-18 14:22:38 -05001857 RValue<UShort> operator++(UShort &val, int) // Post-increment
John Bauman89401822014-05-06 15:04:28 -04001858 {
1859 RValue<UShort> res = val;
1860
Nicolas Capens19336542016-09-26 10:32:29 -04001861 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantShort((unsigned short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001862 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001863
1864 return res;
1865 }
1866
Nicolas Capens96d4e092016-11-18 14:22:38 -05001867 const UShort &operator++(UShort &val) // Pre-increment
John Bauman89401822014-05-06 15:04:28 -04001868 {
Nicolas Capens19336542016-09-26 10:32:29 -04001869 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantShort((unsigned short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001870 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001871
1872 return val;
1873 }
1874
Nicolas Capens96d4e092016-11-18 14:22:38 -05001875 RValue<UShort> operator--(UShort &val, int) // Post-decrement
John Bauman89401822014-05-06 15:04:28 -04001876 {
1877 RValue<UShort> res = val;
1878
Nicolas Capens19336542016-09-26 10:32:29 -04001879 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantShort((unsigned short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001880 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001881
1882 return res;
1883 }
1884
Nicolas Capens96d4e092016-11-18 14:22:38 -05001885 const UShort &operator--(UShort &val) // Pre-decrement
John Bauman89401822014-05-06 15:04:28 -04001886 {
Nicolas Capens19336542016-09-26 10:32:29 -04001887 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantShort((unsigned short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001888 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001889
1890 return val;
1891 }
1892
John Bauman19bac1e2014-05-06 15:23:49 -04001893 RValue<Bool> operator<(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001894 {
1895 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1896 }
1897
John Bauman19bac1e2014-05-06 15:23:49 -04001898 RValue<Bool> operator<=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001899 {
1900 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1901 }
1902
John Bauman19bac1e2014-05-06 15:23:49 -04001903 RValue<Bool> operator>(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001904 {
1905 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1906 }
1907
John Bauman19bac1e2014-05-06 15:23:49 -04001908 RValue<Bool> operator>=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001909 {
1910 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1911 }
1912
John Bauman19bac1e2014-05-06 15:23:49 -04001913 RValue<Bool> operator!=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001914 {
1915 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1916 }
1917
John Bauman19bac1e2014-05-06 15:23:49 -04001918 RValue<Bool> operator==(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001919 {
1920 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1921 }
1922
John Bauman19bac1e2014-05-06 15:23:49 -04001923 Type *UShort::getType()
John Bauman89401822014-05-06 15:04:28 -04001924 {
Nicolas Capensac230122016-09-20 14:30:06 -04001925 return T(llvm::Type::getInt16Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001926 }
1927
Nicolas Capens16b5f152016-10-13 13:39:01 -04001928 Byte4::Byte4(RValue<Byte8> cast)
1929 {
Nicolas Capens16b5f152016-10-13 13:39:01 -04001930 storeValue(Nucleus::createTrunc(Nucleus::createBitCast(cast.value, Long::getType()), Int::getType()));
1931 }
1932
1933 Byte4::Byte4(const Reference<Byte4> &rhs)
1934 {
Nicolas Capens16b5f152016-10-13 13:39:01 -04001935 Value *value = rhs.loadValue();
1936 storeValue(value);
1937 }
1938
John Bauman19bac1e2014-05-06 15:23:49 -04001939 Type *Byte4::getType()
John Bauman89401822014-05-06 15:04:28 -04001940 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04001941 return T(Type_v4i8);
John Bauman89401822014-05-06 15:04:28 -04001942 }
1943
John Bauman19bac1e2014-05-06 15:23:49 -04001944 Type *SByte4::getType()
John Bauman89401822014-05-06 15:04:28 -04001945 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04001946 return T(Type_v4i8);
John Bauman89401822014-05-06 15:04:28 -04001947 }
1948
Nicolas Capens3bbc5e12016-09-27 10:49:52 -04001949 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)
John Bauman89401822014-05-06 15:04:28 -04001950 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04001951 int64_t constantVector[8] = {x0, x1, x2, x3, x4, x5, x6, x7};
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04001952 Value *vector = V(Nucleus::createConstantVector(constantVector, T(llvm::VectorType::get(T(Byte::getType()), 8))));
John Bauman89401822014-05-06 15:04:28 -04001953
John Bauman66b8ab22014-05-06 15:57:45 -04001954 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04001955 }
1956
John Bauman19bac1e2014-05-06 15:23:49 -04001957 Byte8::Byte8(RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04001958 {
John Bauman66b8ab22014-05-06 15:57:45 -04001959 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001960 }
1961
1962 Byte8::Byte8(const Byte8 &rhs)
1963 {
John Bauman66b8ab22014-05-06 15:57:45 -04001964 Value *value = rhs.loadValue();
1965 storeValue(value);
1966 }
1967
1968 Byte8::Byte8(const Reference<Byte8> &rhs)
1969 {
John Bauman66b8ab22014-05-06 15:57:45 -04001970 Value *value = rhs.loadValue();
1971 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001972 }
1973
Nicolas Capens96d4e092016-11-18 14:22:38 -05001974 RValue<Byte8> Byte8::operator=(RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04001975 {
John Bauman66b8ab22014-05-06 15:57:45 -04001976 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001977
1978 return rhs;
1979 }
1980
Nicolas Capens96d4e092016-11-18 14:22:38 -05001981 RValue<Byte8> Byte8::operator=(const Byte8 &rhs)
John Bauman89401822014-05-06 15:04:28 -04001982 {
John Bauman66b8ab22014-05-06 15:57:45 -04001983 Value *value = rhs.loadValue();
1984 storeValue(value);
1985
1986 return RValue<Byte8>(value);
1987 }
1988
Nicolas Capens96d4e092016-11-18 14:22:38 -05001989 RValue<Byte8> Byte8::operator=(const Reference<Byte8> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04001990 {
1991 Value *value = rhs.loadValue();
1992 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001993
1994 return RValue<Byte8>(value);
1995 }
1996
John Bauman19bac1e2014-05-06 15:23:49 -04001997 RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04001998 {
John Bauman19bac1e2014-05-06 15:23:49 -04001999 if(CPUID::supportsMMX2())
2000 {
2001 return x86::paddb(lhs, rhs);
2002 }
2003 else
2004 {
2005 return RValue<Byte8>(Nucleus::createAdd(lhs.value, rhs.value));
2006 }
John Bauman89401822014-05-06 15:04:28 -04002007 }
2008
John Bauman19bac1e2014-05-06 15:23:49 -04002009 RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002010 {
John Bauman19bac1e2014-05-06 15:23:49 -04002011 if(CPUID::supportsMMX2())
2012 {
2013 return x86::psubb(lhs, rhs);
2014 }
2015 else
2016 {
2017 return RValue<Byte8>(Nucleus::createSub(lhs.value, rhs.value));
2018 }
John Bauman89401822014-05-06 15:04:28 -04002019 }
2020
John Bauman19bac1e2014-05-06 15:23:49 -04002021// RValue<Byte8> operator*(RValue<Byte8> lhs, RValue<Byte8> rhs)
2022// {
2023// return RValue<Byte8>(Nucleus::createMul(lhs.value, rhs.value));
2024// }
2025
2026// RValue<Byte8> operator/(RValue<Byte8> lhs, RValue<Byte8> rhs)
2027// {
2028// return RValue<Byte8>(Nucleus::createUDiv(lhs.value, rhs.value));
2029// }
2030
2031// RValue<Byte8> operator%(RValue<Byte8> lhs, RValue<Byte8> rhs)
2032// {
2033// return RValue<Byte8>(Nucleus::createURem(lhs.value, rhs.value));
2034// }
2035
2036 RValue<Byte8> operator&(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002037 {
John Bauman19bac1e2014-05-06 15:23:49 -04002038 if(CPUID::supportsMMX2())
2039 {
2040 return As<Byte8>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
2041 }
2042 else
2043 {
2044 return RValue<Byte8>(Nucleus::createAnd(lhs.value, rhs.value));
2045 }
John Bauman89401822014-05-06 15:04:28 -04002046 }
2047
John Bauman19bac1e2014-05-06 15:23:49 -04002048 RValue<Byte8> operator|(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002049 {
John Bauman19bac1e2014-05-06 15:23:49 -04002050 if(CPUID::supportsMMX2())
2051 {
2052 return As<Byte8>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
2053 }
2054 else
2055 {
2056 return RValue<Byte8>(Nucleus::createOr(lhs.value, rhs.value));
2057 }
John Bauman89401822014-05-06 15:04:28 -04002058 }
2059
John Bauman19bac1e2014-05-06 15:23:49 -04002060 RValue<Byte8> operator^(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002061 {
John Bauman19bac1e2014-05-06 15:23:49 -04002062 if(CPUID::supportsMMX2())
2063 {
2064 return As<Byte8>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
2065 }
2066 else
John Bauman66b8ab22014-05-06 15:57:45 -04002067 {
John Bauman19bac1e2014-05-06 15:23:49 -04002068 return RValue<Byte8>(Nucleus::createXor(lhs.value, rhs.value));
2069 }
John Bauman89401822014-05-06 15:04:28 -04002070 }
2071
John Bauman19bac1e2014-05-06 15:23:49 -04002072// RValue<Byte8> operator<<(RValue<Byte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002073// {
2074// return RValue<Byte8>(Nucleus::createShl(lhs.value, rhs.value));
2075// }
2076
John Bauman19bac1e2014-05-06 15:23:49 -04002077// RValue<Byte8> operator>>(RValue<Byte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002078// {
2079// return RValue<Byte8>(Nucleus::createLShr(lhs.value, rhs.value));
2080// }
2081
Nicolas Capens96d4e092016-11-18 14:22:38 -05002082 RValue<Byte8> operator+=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002083 {
2084 return lhs = lhs + rhs;
2085 }
2086
Nicolas Capens96d4e092016-11-18 14:22:38 -05002087 RValue<Byte8> operator-=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002088 {
2089 return lhs = lhs - rhs;
2090 }
2091
Nicolas Capens96d4e092016-11-18 14:22:38 -05002092// RValue<Byte8> operator*=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002093// {
2094// return lhs = lhs * rhs;
2095// }
John Bauman89401822014-05-06 15:04:28 -04002096
Nicolas Capens96d4e092016-11-18 14:22:38 -05002097// RValue<Byte8> operator/=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002098// {
2099// return lhs = lhs / rhs;
2100// }
John Bauman89401822014-05-06 15:04:28 -04002101
Nicolas Capens96d4e092016-11-18 14:22:38 -05002102// RValue<Byte8> operator%=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002103// {
2104// return lhs = lhs % rhs;
2105// }
John Bauman89401822014-05-06 15:04:28 -04002106
Nicolas Capens96d4e092016-11-18 14:22:38 -05002107 RValue<Byte8> operator&=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002108 {
2109 return lhs = lhs & rhs;
2110 }
2111
Nicolas Capens96d4e092016-11-18 14:22:38 -05002112 RValue<Byte8> operator|=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002113 {
2114 return lhs = lhs | rhs;
2115 }
2116
Nicolas Capens96d4e092016-11-18 14:22:38 -05002117 RValue<Byte8> operator^=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002118 {
2119 return lhs = lhs ^ rhs;
2120 }
2121
Nicolas Capens96d4e092016-11-18 14:22:38 -05002122// RValue<Byte8> operator<<=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002123// {
2124// return lhs = lhs << rhs;
2125// }
2126
Nicolas Capens96d4e092016-11-18 14:22:38 -05002127// RValue<Byte8> operator>>=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002128// {
2129// return lhs = lhs >> rhs;
2130// }
2131
John Bauman19bac1e2014-05-06 15:23:49 -04002132// RValue<Byte8> operator+(RValue<Byte8> val)
2133// {
2134// return val;
2135// }
2136
2137// RValue<Byte8> operator-(RValue<Byte8> val)
2138// {
2139// return RValue<Byte8>(Nucleus::createNeg(val.value));
2140// }
2141
2142 RValue<Byte8> operator~(RValue<Byte8> val)
John Bauman89401822014-05-06 15:04:28 -04002143 {
John Bauman19bac1e2014-05-06 15:23:49 -04002144 if(CPUID::supportsMMX2())
2145 {
Nicolas Capens16b5f152016-10-13 13:39:01 -04002146 return val ^ Byte8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
John Bauman19bac1e2014-05-06 15:23:49 -04002147 }
2148 else
2149 {
2150 return RValue<Byte8>(Nucleus::createNot(val.value));
2151 }
John Bauman89401822014-05-06 15:04:28 -04002152 }
2153
John Bauman19bac1e2014-05-06 15:23:49 -04002154 RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002155 {
2156 return x86::paddusb(x, y);
2157 }
John Bauman66b8ab22014-05-06 15:57:45 -04002158
John Bauman19bac1e2014-05-06 15:23:49 -04002159 RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002160 {
2161 return x86::psubusb(x, y);
2162 }
2163
John Bauman19bac1e2014-05-06 15:23:49 -04002164 RValue<Short4> Unpack(RValue<Byte4> x)
John Bauman89401822014-05-06 15:04:28 -04002165 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04002166 Value *int2 = Nucleus::createInsertElement(V(llvm::UndefValue::get(llvm::VectorType::get(T(Int::getType()), 2))), x.value, 0);
John Bauman19bac1e2014-05-06 15:23:49 -04002167 Value *byte8 = Nucleus::createBitCast(int2, Byte8::getType());
John Bauman89401822014-05-06 15:04:28 -04002168
John Bauman19bac1e2014-05-06 15:23:49 -04002169 return UnpackLow(RValue<Byte8>(byte8), RValue<Byte8>(byte8));
2170 }
John Bauman89401822014-05-06 15:04:28 -04002171
Nicolas Capens411273e2017-01-26 15:13:36 -08002172 RValue<Short4> Unpack(RValue<Byte4> x, RValue<Byte4> y)
2173 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04002174 Value *xx = Nucleus::createInsertElement(V(llvm::UndefValue::get(llvm::VectorType::get(T(Int::getType()), 2))), x.value, 0);
2175 Value *yy = Nucleus::createInsertElement(V(llvm::UndefValue::get(llvm::VectorType::get(T(Int::getType()), 2))), y.value, 0);
Nicolas Capens411273e2017-01-26 15:13:36 -08002176
2177 return UnpackLow(As<Byte8>(xx), As<Byte8>(yy));
2178 }
2179
John Bauman19bac1e2014-05-06 15:23:49 -04002180 RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y)
2181 {
2182 if(CPUID::supportsMMX2())
2183 {
2184 return x86::punpcklbw(x, y);
2185 }
2186 else
2187 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002188 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11};
2189 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman19bac1e2014-05-06 15:23:49 -04002190
2191 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2192 }
John Bauman89401822014-05-06 15:04:28 -04002193 }
John Bauman66b8ab22014-05-06 15:57:45 -04002194
John Bauman19bac1e2014-05-06 15:23:49 -04002195 RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002196 {
John Bauman19bac1e2014-05-06 15:23:49 -04002197 if(CPUID::supportsMMX2())
2198 {
2199 return x86::punpckhbw(x, y);
2200 }
2201 else
2202 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002203 int shuffle[8] = {4, 12, 5, 13, 6, 14, 7, 15};
2204 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002205
John Bauman19bac1e2014-05-06 15:23:49 -04002206 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2207 }
John Bauman89401822014-05-06 15:04:28 -04002208 }
2209
John Bauman19bac1e2014-05-06 15:23:49 -04002210 RValue<Int> SignMask(RValue<Byte8> x)
John Bauman89401822014-05-06 15:04:28 -04002211 {
2212 return x86::pmovmskb(x);
2213 }
2214
John Bauman19bac1e2014-05-06 15:23:49 -04002215// RValue<Byte8> CmpGT(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002216// {
2217// return x86::pcmpgtb(x, y); // FIXME: Signedness
2218// }
John Bauman66b8ab22014-05-06 15:57:45 -04002219
John Bauman19bac1e2014-05-06 15:23:49 -04002220 RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002221 {
2222 return x86::pcmpeqb(x, y);
2223 }
2224
John Bauman19bac1e2014-05-06 15:23:49 -04002225 Type *Byte8::getType()
John Bauman89401822014-05-06 15:04:28 -04002226 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04002227 return T(Type_v8i8);
John Bauman89401822014-05-06 15:04:28 -04002228 }
2229
Nicolas Capens3bbc5e12016-09-27 10:49:52 -04002230 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)
John Bauman89401822014-05-06 15:04:28 -04002231 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04002232 int64_t constantVector[8] = {x0, x1, x2, x3, x4, x5, x6, x7};
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04002233 Value *vector = V(Nucleus::createConstantVector(constantVector, T(llvm::VectorType::get(T(SByte::getType()), 8))));
John Bauman89401822014-05-06 15:04:28 -04002234
John Bauman66b8ab22014-05-06 15:57:45 -04002235 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04002236 }
2237
John Bauman19bac1e2014-05-06 15:23:49 -04002238 SByte8::SByte8(RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002239 {
John Bauman66b8ab22014-05-06 15:57:45 -04002240 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002241 }
2242
2243 SByte8::SByte8(const SByte8 &rhs)
2244 {
John Bauman66b8ab22014-05-06 15:57:45 -04002245 Value *value = rhs.loadValue();
2246 storeValue(value);
2247 }
2248
2249 SByte8::SByte8(const Reference<SByte8> &rhs)
2250 {
John Bauman66b8ab22014-05-06 15:57:45 -04002251 Value *value = rhs.loadValue();
2252 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002253 }
2254
Nicolas Capens96d4e092016-11-18 14:22:38 -05002255 RValue<SByte8> SByte8::operator=(RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002256 {
John Bauman66b8ab22014-05-06 15:57:45 -04002257 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002258
2259 return rhs;
2260 }
2261
Nicolas Capens96d4e092016-11-18 14:22:38 -05002262 RValue<SByte8> SByte8::operator=(const SByte8 &rhs)
John Bauman89401822014-05-06 15:04:28 -04002263 {
John Bauman66b8ab22014-05-06 15:57:45 -04002264 Value *value = rhs.loadValue();
2265 storeValue(value);
2266
2267 return RValue<SByte8>(value);
2268 }
2269
Nicolas Capens96d4e092016-11-18 14:22:38 -05002270 RValue<SByte8> SByte8::operator=(const Reference<SByte8> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04002271 {
2272 Value *value = rhs.loadValue();
2273 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002274
2275 return RValue<SByte8>(value);
2276 }
2277
John Bauman19bac1e2014-05-06 15:23:49 -04002278 RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002279 {
John Bauman19bac1e2014-05-06 15:23:49 -04002280 if(CPUID::supportsMMX2())
2281 {
2282 return As<SByte8>(x86::paddb(As<Byte8>(lhs), As<Byte8>(rhs)));
2283 }
2284 else
2285 {
2286 return RValue<SByte8>(Nucleus::createAdd(lhs.value, rhs.value));
2287 }
John Bauman89401822014-05-06 15:04:28 -04002288 }
2289
John Bauman19bac1e2014-05-06 15:23:49 -04002290 RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002291 {
John Bauman19bac1e2014-05-06 15:23:49 -04002292 if(CPUID::supportsMMX2())
2293 {
2294 return As<SByte8>(x86::psubb(As<Byte8>(lhs), As<Byte8>(rhs)));
2295 }
2296 else
2297 {
2298 return RValue<SByte8>(Nucleus::createSub(lhs.value, rhs.value));
2299 }
John Bauman89401822014-05-06 15:04:28 -04002300 }
2301
John Bauman19bac1e2014-05-06 15:23:49 -04002302// RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs)
2303// {
2304// return RValue<SByte8>(Nucleus::createMul(lhs.value, rhs.value));
2305// }
John Bauman89401822014-05-06 15:04:28 -04002306
John Bauman19bac1e2014-05-06 15:23:49 -04002307// RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs)
2308// {
2309// return RValue<SByte8>(Nucleus::createSDiv(lhs.value, rhs.value));
2310// }
John Bauman89401822014-05-06 15:04:28 -04002311
John Bauman19bac1e2014-05-06 15:23:49 -04002312// RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs)
2313// {
2314// return RValue<SByte8>(Nucleus::createSRem(lhs.value, rhs.value));
2315// }
John Bauman89401822014-05-06 15:04:28 -04002316
John Bauman19bac1e2014-05-06 15:23:49 -04002317 RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002318 {
2319 return RValue<SByte8>(Nucleus::createAnd(lhs.value, rhs.value));
2320 }
2321
John Bauman19bac1e2014-05-06 15:23:49 -04002322 RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002323 {
2324 return RValue<SByte8>(Nucleus::createOr(lhs.value, rhs.value));
2325 }
2326
John Bauman19bac1e2014-05-06 15:23:49 -04002327 RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002328 {
2329 return RValue<SByte8>(Nucleus::createXor(lhs.value, rhs.value));
2330 }
2331
John Bauman19bac1e2014-05-06 15:23:49 -04002332// RValue<SByte8> operator<<(RValue<SByte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002333// {
2334// return RValue<SByte8>(Nucleus::createShl(lhs.value, rhs.value));
2335// }
2336
John Bauman19bac1e2014-05-06 15:23:49 -04002337// RValue<SByte8> operator>>(RValue<SByte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002338// {
2339// return RValue<SByte8>(Nucleus::createAShr(lhs.value, rhs.value));
2340// }
2341
Nicolas Capens96d4e092016-11-18 14:22:38 -05002342 RValue<SByte8> operator+=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002343 {
2344 return lhs = lhs + rhs;
2345 }
2346
Nicolas Capens96d4e092016-11-18 14:22:38 -05002347 RValue<SByte8> operator-=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002348 {
2349 return lhs = lhs - rhs;
2350 }
2351
Nicolas Capens96d4e092016-11-18 14:22:38 -05002352// RValue<SByte8> operator*=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002353// {
2354// return lhs = lhs * rhs;
2355// }
John Bauman89401822014-05-06 15:04:28 -04002356
Nicolas Capens96d4e092016-11-18 14:22:38 -05002357// RValue<SByte8> operator/=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002358// {
2359// return lhs = lhs / rhs;
2360// }
John Bauman89401822014-05-06 15:04:28 -04002361
Nicolas Capens96d4e092016-11-18 14:22:38 -05002362// RValue<SByte8> operator%=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002363// {
2364// return lhs = lhs % rhs;
2365// }
John Bauman89401822014-05-06 15:04:28 -04002366
Nicolas Capens96d4e092016-11-18 14:22:38 -05002367 RValue<SByte8> operator&=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002368 {
2369 return lhs = lhs & rhs;
2370 }
2371
Nicolas Capens96d4e092016-11-18 14:22:38 -05002372 RValue<SByte8> operator|=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002373 {
2374 return lhs = lhs | rhs;
2375 }
2376
Nicolas Capens96d4e092016-11-18 14:22:38 -05002377 RValue<SByte8> operator^=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002378 {
2379 return lhs = lhs ^ rhs;
2380 }
2381
Nicolas Capens96d4e092016-11-18 14:22:38 -05002382// RValue<SByte8> operator<<=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002383// {
2384// return lhs = lhs << rhs;
2385// }
2386
Nicolas Capens96d4e092016-11-18 14:22:38 -05002387// RValue<SByte8> operator>>=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002388// {
2389// return lhs = lhs >> rhs;
2390// }
2391
John Bauman19bac1e2014-05-06 15:23:49 -04002392// RValue<SByte8> operator+(RValue<SByte8> val)
2393// {
2394// return val;
2395// }
2396
2397// RValue<SByte8> operator-(RValue<SByte8> val)
2398// {
2399// return RValue<SByte8>(Nucleus::createNeg(val.value));
2400// }
2401
2402 RValue<SByte8> operator~(RValue<SByte8> val)
John Bauman89401822014-05-06 15:04:28 -04002403 {
John Bauman19bac1e2014-05-06 15:23:49 -04002404 if(CPUID::supportsMMX2())
2405 {
Nicolas Capens16b5f152016-10-13 13:39:01 -04002406 return val ^ SByte8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
John Bauman19bac1e2014-05-06 15:23:49 -04002407 }
2408 else
2409 {
2410 return RValue<SByte8>(Nucleus::createNot(val.value));
2411 }
John Bauman89401822014-05-06 15:04:28 -04002412 }
2413
John Bauman19bac1e2014-05-06 15:23:49 -04002414 RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002415 {
2416 return x86::paddsb(x, y);
2417 }
John Bauman66b8ab22014-05-06 15:57:45 -04002418
John Bauman19bac1e2014-05-06 15:23:49 -04002419 RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002420 {
2421 return x86::psubsb(x, y);
2422 }
2423
John Bauman19bac1e2014-05-06 15:23:49 -04002424 RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002425 {
John Bauman19bac1e2014-05-06 15:23:49 -04002426 if(CPUID::supportsMMX2())
2427 {
2428 return As<Short4>(x86::punpcklbw(As<Byte8>(x), As<Byte8>(y)));
2429 }
2430 else
2431 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002432 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11};
2433 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002434
John Bauman19bac1e2014-05-06 15:23:49 -04002435 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2436 }
John Bauman89401822014-05-06 15:04:28 -04002437 }
John Bauman66b8ab22014-05-06 15:57:45 -04002438
John Bauman19bac1e2014-05-06 15:23:49 -04002439 RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002440 {
John Bauman19bac1e2014-05-06 15:23:49 -04002441 if(CPUID::supportsMMX2())
2442 {
2443 return As<Short4>(x86::punpckhbw(As<Byte8>(x), As<Byte8>(y)));
2444 }
2445 else
2446 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002447 int shuffle[8] = {4, 12, 5, 13, 6, 14, 7, 15};
2448 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002449
John Bauman19bac1e2014-05-06 15:23:49 -04002450 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2451 }
John Bauman89401822014-05-06 15:04:28 -04002452 }
2453
John Bauman19bac1e2014-05-06 15:23:49 -04002454 RValue<Int> SignMask(RValue<SByte8> x)
John Bauman89401822014-05-06 15:04:28 -04002455 {
2456 return x86::pmovmskb(As<Byte8>(x));
2457 }
2458
John Bauman19bac1e2014-05-06 15:23:49 -04002459 RValue<Byte8> CmpGT(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002460 {
2461 return x86::pcmpgtb(x, y);
2462 }
John Bauman66b8ab22014-05-06 15:57:45 -04002463
John Bauman19bac1e2014-05-06 15:23:49 -04002464 RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002465 {
2466 return x86::pcmpeqb(As<Byte8>(x), As<Byte8>(y));
2467 }
2468
John Bauman19bac1e2014-05-06 15:23:49 -04002469 Type *SByte8::getType()
John Bauman89401822014-05-06 15:04:28 -04002470 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04002471 return T(Type_v8i8);
John Bauman89401822014-05-06 15:04:28 -04002472 }
2473
John Bauman19bac1e2014-05-06 15:23:49 -04002474 Byte16::Byte16(RValue<Byte16> rhs)
John Bauman89401822014-05-06 15:04:28 -04002475 {
John Bauman66b8ab22014-05-06 15:57:45 -04002476 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002477 }
2478
2479 Byte16::Byte16(const Byte16 &rhs)
2480 {
John Bauman66b8ab22014-05-06 15:57:45 -04002481 Value *value = rhs.loadValue();
2482 storeValue(value);
2483 }
2484
2485 Byte16::Byte16(const Reference<Byte16> &rhs)
2486 {
John Bauman66b8ab22014-05-06 15:57:45 -04002487 Value *value = rhs.loadValue();
2488 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002489 }
2490
Nicolas Capens96d4e092016-11-18 14:22:38 -05002491 RValue<Byte16> Byte16::operator=(RValue<Byte16> rhs)
John Bauman89401822014-05-06 15:04:28 -04002492 {
John Bauman66b8ab22014-05-06 15:57:45 -04002493 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002494
2495 return rhs;
2496 }
2497
Nicolas Capens96d4e092016-11-18 14:22:38 -05002498 RValue<Byte16> Byte16::operator=(const Byte16 &rhs)
John Bauman89401822014-05-06 15:04:28 -04002499 {
John Bauman66b8ab22014-05-06 15:57:45 -04002500 Value *value = rhs.loadValue();
2501 storeValue(value);
2502
2503 return RValue<Byte16>(value);
2504 }
2505
Nicolas Capens96d4e092016-11-18 14:22:38 -05002506 RValue<Byte16> Byte16::operator=(const Reference<Byte16> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04002507 {
2508 Value *value = rhs.loadValue();
2509 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002510
2511 return RValue<Byte16>(value);
2512 }
2513
John Bauman19bac1e2014-05-06 15:23:49 -04002514 Type *Byte16::getType()
John Bauman89401822014-05-06 15:04:28 -04002515 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04002516 return T(llvm::VectorType::get(T(Byte::getType()), 16));
John Bauman89401822014-05-06 15:04:28 -04002517 }
2518
John Bauman19bac1e2014-05-06 15:23:49 -04002519 Type *SByte16::getType()
John Bauman89401822014-05-06 15:04:28 -04002520 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04002521 return T(llvm::VectorType::get(T(SByte::getType()), 16));
John Bauman89401822014-05-06 15:04:28 -04002522 }
2523
Nicolas Capens16b5f152016-10-13 13:39:01 -04002524 Short2::Short2(RValue<Short4> cast)
2525 {
2526 storeValue(Nucleus::createTrunc(Nucleus::createBitCast(cast.value, Long::getType()), UInt::getType()));
2527 }
2528
2529 Type *Short2::getType()
2530 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04002531 return T(Type_v2i16);
Nicolas Capens16b5f152016-10-13 13:39:01 -04002532 }
2533
2534 UShort2::UShort2(RValue<UShort4> cast)
2535 {
2536 storeValue(Nucleus::createTrunc(Nucleus::createBitCast(cast.value, Long::getType()), UInt::getType()));
2537 }
2538
2539 Type *UShort2::getType()
2540 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04002541 return T(Type_v2i16);
Nicolas Capens16b5f152016-10-13 13:39:01 -04002542 }
2543
John Bauman19bac1e2014-05-06 15:23:49 -04002544 Short4::Short4(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04002545 {
John Bauman89401822014-05-06 15:04:28 -04002546 Value *extend = Nucleus::createZExt(cast.value, Long::getType());
Nicolas Capensbea4dce2017-07-24 16:54:44 -04002547 Value *swizzle = Swizzle(As<Short4>(extend), 0x00).value;
John Bauman66b8ab22014-05-06 15:57:45 -04002548
2549 storeValue(swizzle);
John Bauman89401822014-05-06 15:04:28 -04002550 }
2551
John Bauman19bac1e2014-05-06 15:23:49 -04002552 Short4::Short4(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04002553 {
John Bauman89401822014-05-06 15:04:28 -04002554 Value *short8 = Nucleus::createBitCast(cast.value, Short8::getType());
2555
2556 #if 0 // FIXME: Check codegen (pshuflw phshufhw pshufd)
2557 Constant *pack[8];
2558 pack[0] = Nucleus::createConstantInt(0);
2559 pack[1] = Nucleus::createConstantInt(2);
2560 pack[2] = Nucleus::createConstantInt(4);
2561 pack[3] = Nucleus::createConstantInt(6);
2562
2563 Value *short4 = Nucleus::createShuffleVector(short8, short8, Nucleus::createConstantVector(pack, 4));
2564 #else
2565 Value *packed;
2566
2567 // FIXME: Use Swizzle<Short8>
2568 if(!CPUID::supportsSSSE3())
2569 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002570 int pshuflw[8] = {0, 2, 0, 2, 4, 5, 6, 7};
2571 int pshufhw[8] = {0, 1, 2, 3, 4, 6, 4, 6};
John Bauman89401822014-05-06 15:04:28 -04002572
Nicolas Capense89cd582016-09-30 14:23:47 -04002573 Value *shuffle1 = Nucleus::createShuffleVector(short8, short8, pshuflw);
2574 Value *shuffle2 = Nucleus::createShuffleVector(shuffle1, shuffle1, pshufhw);
John Bauman89401822014-05-06 15:04:28 -04002575 Value *int4 = Nucleus::createBitCast(shuffle2, Int4::getType());
Nicolas Capense95d5342016-09-30 11:37:28 -04002576 packed = createSwizzle4(int4, 0x88);
John Bauman89401822014-05-06 15:04:28 -04002577 }
2578 else
2579 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002580 int pshufb[16] = {0, 1, 4, 5, 8, 9, 12, 13, 0, 1, 4, 5, 8, 9, 12, 13};
John Bauman89401822014-05-06 15:04:28 -04002581 Value *byte16 = Nucleus::createBitCast(cast.value, Byte16::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04002582 packed = Nucleus::createShuffleVector(byte16, byte16, pshufb);
John Bauman89401822014-05-06 15:04:28 -04002583 }
2584
2585 #if 0 // FIXME: No optimal instruction selection
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04002586 Value *qword2 = Nucleus::createBitCast(packed, T(llvm::VectorType::get(T(Long::getType()), 2)));
John Bauman89401822014-05-06 15:04:28 -04002587 Value *element = Nucleus::createExtractElement(qword2, 0);
2588 Value *short4 = Nucleus::createBitCast(element, Short4::getType());
2589 #else // FIXME: Requires SSE
Nicolas Capensbea4dce2017-07-24 16:54:44 -04002590 Value *int2 = RValue<Int2>(Int2(As<Int4>(packed))).value;
John Bauman89401822014-05-06 15:04:28 -04002591 Value *short4 = Nucleus::createBitCast(int2, Short4::getType());
2592 #endif
2593 #endif
2594
John Bauman66b8ab22014-05-06 15:57:45 -04002595 storeValue(short4);
John Bauman89401822014-05-06 15:04:28 -04002596 }
2597
John Bauman19bac1e2014-05-06 15:23:49 -04002598// Short4::Short4(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04002599// {
2600// }
2601
John Bauman19bac1e2014-05-06 15:23:49 -04002602 Short4::Short4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04002603 {
John Bauman89401822014-05-06 15:04:28 -04002604 Int4 v4i32 = Int4(cast);
2605 v4i32 = As<Int4>(x86::packssdw(v4i32, v4i32));
John Bauman66b8ab22014-05-06 15:57:45 -04002606
2607 storeValue(As<Short4>(Int2(v4i32)).value);
John Bauman89401822014-05-06 15:04:28 -04002608 }
2609
John Bauman19bac1e2014-05-06 15:23:49 -04002610 Short4::Short4(short xyzw)
2611 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04002612 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04002613 Value *vector = V(Nucleus::createConstantVector(constantVector, T(llvm::VectorType::get(T(Short::getType()), 4))));
John Bauman19bac1e2014-05-06 15:23:49 -04002614
John Bauman66b8ab22014-05-06 15:57:45 -04002615 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman19bac1e2014-05-06 15:23:49 -04002616 }
2617
John Bauman89401822014-05-06 15:04:28 -04002618 Short4::Short4(short x, short y, short z, short w)
2619 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04002620 int64_t constantVector[4] = {x, y, z, w};
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04002621 Value *vector = V(Nucleus::createConstantVector(constantVector, T(llvm::VectorType::get(T(Short::getType()), 4))));
John Bauman19bac1e2014-05-06 15:23:49 -04002622
John Bauman66b8ab22014-05-06 15:57:45 -04002623 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04002624 }
2625
John Bauman19bac1e2014-05-06 15:23:49 -04002626 Short4::Short4(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002627 {
John Bauman66b8ab22014-05-06 15:57:45 -04002628 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002629 }
2630
2631 Short4::Short4(const Short4 &rhs)
2632 {
John Bauman66b8ab22014-05-06 15:57:45 -04002633 Value *value = rhs.loadValue();
2634 storeValue(value);
2635 }
2636
2637 Short4::Short4(const Reference<Short4> &rhs)
2638 {
John Bauman66b8ab22014-05-06 15:57:45 -04002639 Value *value = rhs.loadValue();
2640 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002641 }
2642
John Bauman19bac1e2014-05-06 15:23:49 -04002643 Short4::Short4(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002644 {
John Bauman66b8ab22014-05-06 15:57:45 -04002645 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002646 }
2647
2648 Short4::Short4(const UShort4 &rhs)
2649 {
John Bauman66b8ab22014-05-06 15:57:45 -04002650 storeValue(rhs.loadValue());
2651 }
2652
2653 Short4::Short4(const Reference<UShort4> &rhs)
2654 {
John Bauman66b8ab22014-05-06 15:57:45 -04002655 storeValue(rhs.loadValue());
John Bauman89401822014-05-06 15:04:28 -04002656 }
2657
Nicolas Capens96d4e092016-11-18 14:22:38 -05002658 RValue<Short4> Short4::operator=(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002659 {
John Bauman66b8ab22014-05-06 15:57:45 -04002660 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002661
2662 return rhs;
2663 }
2664
Nicolas Capens96d4e092016-11-18 14:22:38 -05002665 RValue<Short4> Short4::operator=(const Short4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04002666 {
John Bauman66b8ab22014-05-06 15:57:45 -04002667 Value *value = rhs.loadValue();
2668 storeValue(value);
2669
2670 return RValue<Short4>(value);
2671 }
2672
Nicolas Capens96d4e092016-11-18 14:22:38 -05002673 RValue<Short4> Short4::operator=(const Reference<Short4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04002674 {
2675 Value *value = rhs.loadValue();
2676 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002677
2678 return RValue<Short4>(value);
2679 }
2680
Nicolas Capens96d4e092016-11-18 14:22:38 -05002681 RValue<Short4> Short4::operator=(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002682 {
John Bauman66b8ab22014-05-06 15:57:45 -04002683 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002684
John Bauman66b8ab22014-05-06 15:57:45 -04002685 return RValue<Short4>(rhs);
John Bauman89401822014-05-06 15:04:28 -04002686 }
2687
Nicolas Capens96d4e092016-11-18 14:22:38 -05002688 RValue<Short4> Short4::operator=(const UShort4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04002689 {
John Bauman66b8ab22014-05-06 15:57:45 -04002690 Value *value = rhs.loadValue();
2691 storeValue(value);
2692
2693 return RValue<Short4>(value);
2694 }
2695
Nicolas Capens96d4e092016-11-18 14:22:38 -05002696 RValue<Short4> Short4::operator=(const Reference<UShort4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04002697 {
2698 Value *value = rhs.loadValue();
2699 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002700
2701 return RValue<Short4>(value);
2702 }
2703
John Bauman19bac1e2014-05-06 15:23:49 -04002704 RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002705 {
John Bauman19bac1e2014-05-06 15:23:49 -04002706 if(CPUID::supportsMMX2())
2707 {
2708 return x86::paddw(lhs, rhs);
2709 }
2710 else
2711 {
2712 return RValue<Short4>(Nucleus::createAdd(lhs.value, rhs.value));
2713 }
John Bauman89401822014-05-06 15:04:28 -04002714 }
2715
John Bauman19bac1e2014-05-06 15:23:49 -04002716 RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002717 {
John Bauman19bac1e2014-05-06 15:23:49 -04002718 if(CPUID::supportsMMX2())
2719 {
2720 return x86::psubw(lhs, rhs);
2721 }
2722 else
2723 {
2724 return RValue<Short4>(Nucleus::createSub(lhs.value, rhs.value));
2725 }
John Bauman89401822014-05-06 15:04:28 -04002726 }
2727
John Bauman19bac1e2014-05-06 15:23:49 -04002728 RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002729 {
John Bauman19bac1e2014-05-06 15:23:49 -04002730 if(CPUID::supportsMMX2())
2731 {
2732 return x86::pmullw(lhs, rhs);
2733 }
2734 else
2735 {
2736 return RValue<Short4>(Nucleus::createMul(lhs.value, rhs.value));
2737 }
John Bauman89401822014-05-06 15:04:28 -04002738 }
2739
John Bauman19bac1e2014-05-06 15:23:49 -04002740// RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs)
2741// {
2742// return RValue<Short4>(Nucleus::createSDiv(lhs.value, rhs.value));
2743// }
2744
2745// RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs)
2746// {
2747// return RValue<Short4>(Nucleus::createSRem(lhs.value, rhs.value));
2748// }
2749
2750 RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002751 {
John Bauman19bac1e2014-05-06 15:23:49 -04002752 if(CPUID::supportsMMX2())
2753 {
2754 return x86::pand(lhs, rhs);
2755 }
2756 else
2757 {
2758 return RValue<Short4>(Nucleus::createAnd(lhs.value, rhs.value));
2759 }
John Bauman89401822014-05-06 15:04:28 -04002760 }
2761
John Bauman19bac1e2014-05-06 15:23:49 -04002762 RValue<Short4> operator|(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002763 {
John Bauman19bac1e2014-05-06 15:23:49 -04002764 if(CPUID::supportsMMX2())
2765 {
2766 return x86::por(lhs, rhs);
2767 }
2768 else
2769 {
2770 return RValue<Short4>(Nucleus::createOr(lhs.value, rhs.value));
2771 }
John Bauman89401822014-05-06 15:04:28 -04002772 }
2773
John Bauman19bac1e2014-05-06 15:23:49 -04002774 RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002775 {
John Bauman19bac1e2014-05-06 15:23:49 -04002776 if(CPUID::supportsMMX2())
2777 {
2778 return x86::pxor(lhs, rhs);
2779 }
2780 else
2781 {
2782 return RValue<Short4>(Nucleus::createXor(lhs.value, rhs.value));
2783 }
John Bauman89401822014-05-06 15:04:28 -04002784 }
2785
John Bauman19bac1e2014-05-06 15:23:49 -04002786 RValue<Short4> operator<<(RValue<Short4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002787 {
2788 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
2789
2790 return x86::psllw(lhs, rhs);
2791 }
2792
John Bauman19bac1e2014-05-06 15:23:49 -04002793 RValue<Short4> operator>>(RValue<Short4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002794 {
2795 // return RValue<Short4>(Nucleus::createAShr(lhs.value, rhs.value));
2796
2797 return x86::psraw(lhs, rhs);
2798 }
2799
Nicolas Capens96d4e092016-11-18 14:22:38 -05002800 RValue<Short4> operator+=(Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002801 {
2802 return lhs = lhs + rhs;
2803 }
2804
Nicolas Capens96d4e092016-11-18 14:22:38 -05002805 RValue<Short4> operator-=(Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002806 {
2807 return lhs = lhs - rhs;
2808 }
2809
Nicolas Capens96d4e092016-11-18 14:22:38 -05002810 RValue<Short4> operator*=(Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002811 {
2812 return lhs = lhs * rhs;
2813 }
2814
Nicolas Capens96d4e092016-11-18 14:22:38 -05002815// RValue<Short4> operator/=(Short4 &lhs, RValue<Short4> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002816// {
2817// return lhs = lhs / rhs;
2818// }
John Bauman89401822014-05-06 15:04:28 -04002819
Nicolas Capens96d4e092016-11-18 14:22:38 -05002820// RValue<Short4> operator%=(Short4 &lhs, RValue<Short4> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002821// {
2822// return lhs = lhs % rhs;
2823// }
John Bauman89401822014-05-06 15:04:28 -04002824
Nicolas Capens96d4e092016-11-18 14:22:38 -05002825 RValue<Short4> operator&=(Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002826 {
2827 return lhs = lhs & rhs;
2828 }
2829
Nicolas Capens96d4e092016-11-18 14:22:38 -05002830 RValue<Short4> operator|=(Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002831 {
2832 return lhs = lhs | rhs;
2833 }
2834
Nicolas Capens96d4e092016-11-18 14:22:38 -05002835 RValue<Short4> operator^=(Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002836 {
2837 return lhs = lhs ^ rhs;
2838 }
2839
Nicolas Capens96d4e092016-11-18 14:22:38 -05002840 RValue<Short4> operator<<=(Short4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002841 {
2842 return lhs = lhs << rhs;
2843 }
2844
Nicolas Capens96d4e092016-11-18 14:22:38 -05002845 RValue<Short4> operator>>=(Short4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002846 {
2847 return lhs = lhs >> rhs;
2848 }
2849
John Bauman19bac1e2014-05-06 15:23:49 -04002850// RValue<Short4> operator+(RValue<Short4> val)
2851// {
2852// return val;
2853// }
2854
2855 RValue<Short4> operator-(RValue<Short4> val)
John Bauman89401822014-05-06 15:04:28 -04002856 {
John Bauman19bac1e2014-05-06 15:23:49 -04002857 if(CPUID::supportsMMX2())
2858 {
2859 return Short4(0, 0, 0, 0) - val;
2860 }
2861 else
2862 {
2863 return RValue<Short4>(Nucleus::createNeg(val.value));
2864 }
John Bauman89401822014-05-06 15:04:28 -04002865 }
2866
John Bauman19bac1e2014-05-06 15:23:49 -04002867 RValue<Short4> operator~(RValue<Short4> val)
John Bauman89401822014-05-06 15:04:28 -04002868 {
John Bauman19bac1e2014-05-06 15:23:49 -04002869 if(CPUID::supportsMMX2())
2870 {
2871 return val ^ Short4(0xFFFFu, 0xFFFFu, 0xFFFFu, 0xFFFFu);
2872 }
2873 else
2874 {
2875 return RValue<Short4>(Nucleus::createNot(val.value));
2876 }
John Bauman89401822014-05-06 15:04:28 -04002877 }
2878
John Bauman19bac1e2014-05-06 15:23:49 -04002879 RValue<Short4> RoundShort4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04002880 {
2881 RValue<Int4> v4i32 = x86::cvtps2dq(cast);
Nicolas Capens698633a2015-02-04 00:16:13 -05002882 RValue<Short8> v8i16 = x86::packssdw(v4i32, v4i32);
John Bauman66b8ab22014-05-06 15:57:45 -04002883
Nicolas Capens698633a2015-02-04 00:16:13 -05002884 return As<Short4>(Int2(As<Int4>(v8i16)));
John Bauman89401822014-05-06 15:04:28 -04002885 }
2886
John Bauman19bac1e2014-05-06 15:23:49 -04002887 RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002888 {
2889 return x86::pmaxsw(x, y);
2890 }
2891
John Bauman19bac1e2014-05-06 15:23:49 -04002892 RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002893 {
2894 return x86::pminsw(x, y);
2895 }
2896
John Bauman19bac1e2014-05-06 15:23:49 -04002897 RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002898 {
2899 return x86::paddsw(x, y);
2900 }
2901
John Bauman19bac1e2014-05-06 15:23:49 -04002902 RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002903 {
2904 return x86::psubsw(x, y);
2905 }
2906
John Bauman19bac1e2014-05-06 15:23:49 -04002907 RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002908 {
2909 return x86::pmulhw(x, y);
2910 }
2911
John Bauman19bac1e2014-05-06 15:23:49 -04002912 RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002913 {
2914 return x86::pmaddwd(x, y);
2915 }
2916
John Bauman19bac1e2014-05-06 15:23:49 -04002917 RValue<SByte8> Pack(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002918 {
2919 return x86::packsswb(x, y);
2920 }
2921
John Bauman19bac1e2014-05-06 15:23:49 -04002922 RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002923 {
John Bauman19bac1e2014-05-06 15:23:49 -04002924 if(CPUID::supportsMMX2())
2925 {
2926 return x86::punpcklwd(x, y);
2927 }
2928 else
2929 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002930 int shuffle[4] = {0, 4, 1, 5};
2931 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002932
John Bauman19bac1e2014-05-06 15:23:49 -04002933 return RValue<Int2>(Nucleus::createBitCast(packed, Int2::getType()));
2934 }
John Bauman89401822014-05-06 15:04:28 -04002935 }
2936
John Bauman19bac1e2014-05-06 15:23:49 -04002937 RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002938 {
John Bauman19bac1e2014-05-06 15:23:49 -04002939 if(CPUID::supportsMMX2())
2940 {
2941 return x86::punpckhwd(x, y);
2942 }
2943 else
2944 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002945 int shuffle[4] = {2, 6, 3, 7};
2946 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002947
John Bauman19bac1e2014-05-06 15:23:49 -04002948 return RValue<Int2>(Nucleus::createBitCast(packed, Int2::getType()));
2949 }
John Bauman89401822014-05-06 15:04:28 -04002950 }
2951
John Bauman19bac1e2014-05-06 15:23:49 -04002952 RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04002953 {
John Bauman19bac1e2014-05-06 15:23:49 -04002954 if(CPUID::supportsMMX2())
2955 {
2956 return x86::pshufw(x, select);
2957 }
2958 else
2959 {
Nicolas Capense95d5342016-09-30 11:37:28 -04002960 return RValue<Short4>(createSwizzle4(x.value, select));
John Bauman19bac1e2014-05-06 15:23:49 -04002961 }
John Bauman89401822014-05-06 15:04:28 -04002962 }
2963
John Bauman19bac1e2014-05-06 15:23:49 -04002964 RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i)
John Bauman89401822014-05-06 15:04:28 -04002965 {
John Bauman19bac1e2014-05-06 15:23:49 -04002966 if(CPUID::supportsMMX2())
2967 {
2968 return x86::pinsrw(val, Int(element), i);
2969 }
2970 else
2971 {
2972 return RValue<Short4>(Nucleus::createInsertElement(val.value, element.value, i));
2973 }
John Bauman89401822014-05-06 15:04:28 -04002974 }
2975
John Bauman19bac1e2014-05-06 15:23:49 -04002976 RValue<Short> Extract(RValue<Short4> val, int i)
John Bauman89401822014-05-06 15:04:28 -04002977 {
John Bauman19bac1e2014-05-06 15:23:49 -04002978 if(CPUID::supportsMMX2())
2979 {
2980 return Short(x86::pextrw(val, i));
2981 }
2982 else
2983 {
Nicolas Capense95d5342016-09-30 11:37:28 -04002984 return RValue<Short>(Nucleus::createExtractElement(val.value, Short::getType(), i));
John Bauman19bac1e2014-05-06 15:23:49 -04002985 }
John Bauman89401822014-05-06 15:04:28 -04002986 }
2987
John Bauman19bac1e2014-05-06 15:23:49 -04002988 RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002989 {
2990 return x86::pcmpgtw(x, y);
2991 }
2992
John Bauman19bac1e2014-05-06 15:23:49 -04002993 RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002994 {
2995 return x86::pcmpeqw(x, y);
2996 }
2997
John Bauman19bac1e2014-05-06 15:23:49 -04002998 Type *Short4::getType()
John Bauman89401822014-05-06 15:04:28 -04002999 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04003000 return T(Type_v4i16);
John Bauman89401822014-05-06 15:04:28 -04003001 }
3002
John Bauman19bac1e2014-05-06 15:23:49 -04003003 UShort4::UShort4(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04003004 {
John Bauman89401822014-05-06 15:04:28 -04003005 *this = Short4(cast);
3006 }
3007
John Bauman19bac1e2014-05-06 15:23:49 -04003008 UShort4::UShort4(RValue<Float4> cast, bool saturate)
John Bauman89401822014-05-06 15:04:28 -04003009 {
John Bauman89401822014-05-06 15:04:28 -04003010 Float4 sat;
3011
3012 if(saturate)
3013 {
3014 if(CPUID::supportsSSE4_1())
3015 {
3016 sat = Min(cast, Float4(0xFFFF)); // packusdw takes care of 0x0000 saturation
3017 }
3018 else
3019 {
3020 sat = Max(Min(cast, Float4(0xFFFF)), Float4(0x0000));
3021 }
3022 }
3023 else
3024 {
3025 sat = cast;
3026 }
3027
3028 Int4 int4(sat);
3029
3030 if(!saturate || !CPUID::supportsSSE4_1())
3031 {
Nicolas Capens3e7062b2017-01-17 14:01:33 -05003032 *this = Short4(int4);
John Bauman89401822014-05-06 15:04:28 -04003033 }
3034 else
3035 {
Nicolas Capens3e7062b2017-01-17 14:01:33 -05003036 *this = As<Short4>(Int2(As<Int4>(x86::packusdw(int4, int4))));
John Bauman89401822014-05-06 15:04:28 -04003037 }
3038 }
3039
Alexis Hetu90c7ad62016-06-27 11:50:40 -04003040 UShort4::UShort4(unsigned short xyzw)
3041 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04003042 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04003043 Value *vector = V(Nucleus::createConstantVector(constantVector, T(llvm::VectorType::get(T(UShort::getType()), 4))));
Alexis Hetu90c7ad62016-06-27 11:50:40 -04003044
3045 storeValue(Nucleus::createBitCast(vector, getType()));
3046 }
3047
John Bauman89401822014-05-06 15:04:28 -04003048 UShort4::UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w)
3049 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04003050 int64_t constantVector[4] = {x, y, z, w};
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04003051 Value *vector = V(Nucleus::createConstantVector(constantVector, T(llvm::VectorType::get(T(UShort::getType()), 4))));
John Bauman89401822014-05-06 15:04:28 -04003052
John Bauman66b8ab22014-05-06 15:57:45 -04003053 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04003054 }
3055
John Bauman19bac1e2014-05-06 15:23:49 -04003056 UShort4::UShort4(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003057 {
John Bauman66b8ab22014-05-06 15:57:45 -04003058 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003059 }
3060
3061 UShort4::UShort4(const UShort4 &rhs)
3062 {
John Bauman66b8ab22014-05-06 15:57:45 -04003063 Value *value = rhs.loadValue();
3064 storeValue(value);
3065 }
3066
3067 UShort4::UShort4(const Reference<UShort4> &rhs)
3068 {
John Bauman66b8ab22014-05-06 15:57:45 -04003069 Value *value = rhs.loadValue();
3070 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003071 }
3072
John Bauman19bac1e2014-05-06 15:23:49 -04003073 UShort4::UShort4(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003074 {
John Bauman66b8ab22014-05-06 15:57:45 -04003075 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003076 }
3077
3078 UShort4::UShort4(const Short4 &rhs)
3079 {
John Bauman66b8ab22014-05-06 15:57:45 -04003080 Value *value = rhs.loadValue();
3081 storeValue(value);
3082 }
3083
3084 UShort4::UShort4(const Reference<Short4> &rhs)
3085 {
John Bauman66b8ab22014-05-06 15:57:45 -04003086 Value *value = rhs.loadValue();
3087 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003088 }
3089
Nicolas Capens96d4e092016-11-18 14:22:38 -05003090 RValue<UShort4> UShort4::operator=(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003091 {
John Bauman66b8ab22014-05-06 15:57:45 -04003092 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003093
3094 return rhs;
3095 }
3096
Nicolas Capens96d4e092016-11-18 14:22:38 -05003097 RValue<UShort4> UShort4::operator=(const UShort4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04003098 {
John Bauman66b8ab22014-05-06 15:57:45 -04003099 Value *value = rhs.loadValue();
3100 storeValue(value);
3101
3102 return RValue<UShort4>(value);
3103 }
3104
Nicolas Capens96d4e092016-11-18 14:22:38 -05003105 RValue<UShort4> UShort4::operator=(const Reference<UShort4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04003106 {
3107 Value *value = rhs.loadValue();
3108 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003109
3110 return RValue<UShort4>(value);
3111 }
3112
Nicolas Capens96d4e092016-11-18 14:22:38 -05003113 RValue<UShort4> UShort4::operator=(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003114 {
John Bauman66b8ab22014-05-06 15:57:45 -04003115 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003116
John Bauman66b8ab22014-05-06 15:57:45 -04003117 return RValue<UShort4>(rhs);
John Bauman89401822014-05-06 15:04:28 -04003118 }
3119
Nicolas Capens96d4e092016-11-18 14:22:38 -05003120 RValue<UShort4> UShort4::operator=(const Short4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04003121 {
John Bauman66b8ab22014-05-06 15:57:45 -04003122 Value *value = rhs.loadValue();
3123 storeValue(value);
3124
3125 return RValue<UShort4>(value);
3126 }
3127
Nicolas Capens96d4e092016-11-18 14:22:38 -05003128 RValue<UShort4> UShort4::operator=(const Reference<Short4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04003129 {
3130 Value *value = rhs.loadValue();
3131 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003132
3133 return RValue<UShort4>(value);
3134 }
3135
John Bauman19bac1e2014-05-06 15:23:49 -04003136 RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003137 {
John Bauman19bac1e2014-05-06 15:23:49 -04003138 if(CPUID::supportsMMX2())
3139 {
3140 return As<UShort4>(x86::paddw(As<Short4>(lhs), As<Short4>(rhs)));
3141 }
3142 else
3143 {
3144 return RValue<UShort4>(Nucleus::createAdd(lhs.value, rhs.value));
3145 }
John Bauman89401822014-05-06 15:04:28 -04003146 }
3147
John Bauman19bac1e2014-05-06 15:23:49 -04003148 RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003149 {
John Bauman19bac1e2014-05-06 15:23:49 -04003150 if(CPUID::supportsMMX2())
3151 {
3152 return As<UShort4>(x86::psubw(As<Short4>(lhs), As<Short4>(rhs)));
3153 }
3154 else
3155 {
3156 return RValue<UShort4>(Nucleus::createSub(lhs.value, rhs.value));
3157 }
John Bauman89401822014-05-06 15:04:28 -04003158 }
3159
John Bauman19bac1e2014-05-06 15:23:49 -04003160 RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003161 {
John Bauman19bac1e2014-05-06 15:23:49 -04003162 if(CPUID::supportsMMX2())
3163 {
3164 return As<UShort4>(x86::pmullw(As<Short4>(lhs), As<Short4>(rhs)));
3165 }
3166 else
3167 {
3168 return RValue<UShort4>(Nucleus::createMul(lhs.value, rhs.value));
3169 }
John Bauman89401822014-05-06 15:04:28 -04003170 }
3171
Nicolas Capens16b5f152016-10-13 13:39:01 -04003172 RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs)
3173 {
3174 if(CPUID::supportsMMX2())
3175 {
3176 return As<UShort4>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
3177 }
3178 else
3179 {
3180 return RValue<UShort4>(Nucleus::createAnd(lhs.value, rhs.value));
3181 }
3182 }
3183
3184 RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs)
3185 {
3186 if(CPUID::supportsMMX2())
3187 {
3188 return As<UShort4>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
3189 }
3190 else
3191 {
3192 return RValue<UShort4>(Nucleus::createOr(lhs.value, rhs.value));
3193 }
3194 }
3195
3196 RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs)
3197 {
3198 if(CPUID::supportsMMX2())
3199 {
3200 return As<UShort4>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
3201 }
3202 else
3203 {
3204 return RValue<UShort4>(Nucleus::createXor(lhs.value, rhs.value));
3205 }
3206 }
3207
John Bauman19bac1e2014-05-06 15:23:49 -04003208 RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003209 {
3210 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
3211
3212 return As<UShort4>(x86::psllw(As<Short4>(lhs), rhs));
3213 }
3214
John Bauman19bac1e2014-05-06 15:23:49 -04003215 RValue<UShort4> operator>>(RValue<UShort4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003216 {
3217 // return RValue<Short4>(Nucleus::createLShr(lhs.value, rhs.value));
3218
3219 return x86::psrlw(lhs, rhs);
3220 }
3221
Nicolas Capens96d4e092016-11-18 14:22:38 -05003222 RValue<UShort4> operator<<=(UShort4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003223 {
3224 return lhs = lhs << rhs;
3225 }
3226
Nicolas Capens96d4e092016-11-18 14:22:38 -05003227 RValue<UShort4> operator>>=(UShort4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003228 {
3229 return lhs = lhs >> rhs;
3230 }
3231
John Bauman19bac1e2014-05-06 15:23:49 -04003232 RValue<UShort4> operator~(RValue<UShort4> val)
John Bauman89401822014-05-06 15:04:28 -04003233 {
John Bauman19bac1e2014-05-06 15:23:49 -04003234 if(CPUID::supportsMMX2())
3235 {
3236 return As<UShort4>(As<Short4>(val) ^ Short4(0xFFFFu, 0xFFFFu, 0xFFFFu, 0xFFFFu));
3237 }
3238 else
3239 {
3240 return RValue<UShort4>(Nucleus::createNot(val.value));
3241 }
John Bauman89401822014-05-06 15:04:28 -04003242 }
3243
John Bauman19bac1e2014-05-06 15:23:49 -04003244 RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003245 {
John Bauman66b8ab22014-05-06 15:57:45 -04003246 return RValue<UShort4>(Max(As<Short4>(x) - Short4(0x8000u, 0x8000u, 0x8000u, 0x8000u), As<Short4>(y) - Short4(0x8000u, 0x8000u, 0x8000u, 0x8000u)) + Short4(0x8000u, 0x8000u, 0x8000u, 0x8000u));
John Bauman89401822014-05-06 15:04:28 -04003247 }
3248
John Bauman19bac1e2014-05-06 15:23:49 -04003249 RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003250 {
John Bauman66b8ab22014-05-06 15:57:45 -04003251 return RValue<UShort4>(Min(As<Short4>(x) - Short4(0x8000u, 0x8000u, 0x8000u, 0x8000u), As<Short4>(y) - Short4(0x8000u, 0x8000u, 0x8000u, 0x8000u)) + Short4(0x8000u, 0x8000u, 0x8000u, 0x8000u));
John Bauman89401822014-05-06 15:04:28 -04003252 }
3253
John Bauman19bac1e2014-05-06 15:23:49 -04003254 RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003255 {
3256 return x86::paddusw(x, y);
3257 }
3258
John Bauman19bac1e2014-05-06 15:23:49 -04003259 RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003260 {
3261 return x86::psubusw(x, y);
3262 }
3263
John Bauman19bac1e2014-05-06 15:23:49 -04003264 RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003265 {
3266 return x86::pmulhuw(x, y);
3267 }
3268
John Bauman19bac1e2014-05-06 15:23:49 -04003269 RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003270 {
3271 return x86::pavgw(x, y);
3272 }
3273
John Bauman19bac1e2014-05-06 15:23:49 -04003274 RValue<Byte8> Pack(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003275 {
3276 return x86::packuswb(x, y);
3277 }
3278
John Bauman19bac1e2014-05-06 15:23:49 -04003279 Type *UShort4::getType()
John Bauman89401822014-05-06 15:04:28 -04003280 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04003281 return T(Type_v4i16);
John Bauman89401822014-05-06 15:04:28 -04003282 }
3283
Nicolas Capens3e7062b2017-01-17 14:01:33 -05003284 Short8::Short8(short c)
3285 {
3286 int64_t constantVector[8] = {c, c, c, c, c, c, c, c};
3287 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3288 }
3289
John Bauman89401822014-05-06 15:04:28 -04003290 Short8::Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7)
3291 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04003292 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
3293 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04003294 }
3295
John Bauman19bac1e2014-05-06 15:23:49 -04003296 Short8::Short8(RValue<Short8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003297 {
John Bauman66b8ab22014-05-06 15:57:45 -04003298 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003299 }
3300
Nicolas Capensef8cd662016-06-30 15:34:40 -04003301 Short8::Short8(const Reference<Short8> &rhs)
3302 {
Nicolas Capensef8cd662016-06-30 15:34:40 -04003303 Value *value = rhs.loadValue();
3304 storeValue(value);
3305 }
3306
Nicolas Capens62abb552016-01-05 12:03:47 -05003307 Short8::Short8(RValue<Short4> lo, RValue<Short4> hi)
3308 {
3309 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
3310 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
3311
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04003312 Value *long2 = V(llvm::UndefValue::get(llvm::VectorType::get(T(Long::getType()), 2)));
Nicolas Capens62abb552016-01-05 12:03:47 -05003313 long2 = Nucleus::createInsertElement(long2, loLong, 0);
3314 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
3315 Value *short8 = Nucleus::createBitCast(long2, Short8::getType());
3316
3317 storeValue(short8);
3318 }
3319
John Bauman19bac1e2014-05-06 15:23:49 -04003320 RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003321 {
3322 return RValue<Short8>(Nucleus::createAdd(lhs.value, rhs.value));
3323 }
3324
John Bauman19bac1e2014-05-06 15:23:49 -04003325 RValue<Short8> operator&(RValue<Short8> lhs, RValue<Short8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003326 {
3327 return RValue<Short8>(Nucleus::createAnd(lhs.value, rhs.value));
3328 }
3329
John Bauman19bac1e2014-05-06 15:23:49 -04003330 RValue<Short8> operator<<(RValue<Short8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003331 {
3332 return x86::psllw(lhs, rhs); // FIXME: Fallback required
3333 }
3334
John Bauman19bac1e2014-05-06 15:23:49 -04003335 RValue<Short8> operator>>(RValue<Short8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003336 {
3337 return x86::psraw(lhs, rhs); // FIXME: Fallback required
3338 }
3339
John Bauman19bac1e2014-05-06 15:23:49 -04003340 RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04003341 {
3342 return x86::pmaddwd(x, y); // FIXME: Fallback required
3343 }
3344
Alexis Hetu0f448072016-03-18 10:56:08 -04003345 RValue<Int4> Abs(RValue<Int4> x)
3346 {
3347 if(CPUID::supportsSSSE3())
3348 {
3349 return x86::pabsd(x);
3350 }
3351 else
3352 {
3353 Int4 mask = (x >> 31);
3354 return (mask ^ x) - mask;
3355 }
3356 }
3357
John Bauman19bac1e2014-05-06 15:23:49 -04003358 RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04003359 {
3360 return x86::pmulhw(x, y); // FIXME: Fallback required
3361 }
3362
John Bauman19bac1e2014-05-06 15:23:49 -04003363 Type *Short8::getType()
John Bauman89401822014-05-06 15:04:28 -04003364 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04003365 return T(llvm::VectorType::get(T(Short::getType()), 8));
John Bauman89401822014-05-06 15:04:28 -04003366 }
3367
Nicolas Capens3e7062b2017-01-17 14:01:33 -05003368 UShort8::UShort8(unsigned short c)
3369 {
3370 int64_t constantVector[8] = {c, c, c, c, c, c, c, c};
3371 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3372 }
3373
John Bauman89401822014-05-06 15:04:28 -04003374 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)
3375 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04003376 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
3377 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04003378 }
3379
John Bauman19bac1e2014-05-06 15:23:49 -04003380 UShort8::UShort8(RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003381 {
John Bauman66b8ab22014-05-06 15:57:45 -04003382 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003383 }
3384
Nicolas Capensef8cd662016-06-30 15:34:40 -04003385 UShort8::UShort8(const Reference<UShort8> &rhs)
3386 {
Nicolas Capensef8cd662016-06-30 15:34:40 -04003387 Value *value = rhs.loadValue();
3388 storeValue(value);
3389 }
3390
Nicolas Capens62abb552016-01-05 12:03:47 -05003391 UShort8::UShort8(RValue<UShort4> lo, RValue<UShort4> hi)
3392 {
3393 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
3394 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
3395
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04003396 Value *long2 = V(llvm::UndefValue::get(llvm::VectorType::get(T(Long::getType()), 2)));
Nicolas Capens62abb552016-01-05 12:03:47 -05003397 long2 = Nucleus::createInsertElement(long2, loLong, 0);
3398 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
3399 Value *short8 = Nucleus::createBitCast(long2, Short8::getType());
3400
3401 storeValue(short8);
3402 }
3403
Nicolas Capens96d4e092016-11-18 14:22:38 -05003404 RValue<UShort8> UShort8::operator=(RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003405 {
John Bauman66b8ab22014-05-06 15:57:45 -04003406 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003407
3408 return rhs;
3409 }
3410
Nicolas Capens96d4e092016-11-18 14:22:38 -05003411 RValue<UShort8> UShort8::operator=(const UShort8 &rhs)
John Bauman89401822014-05-06 15:04:28 -04003412 {
John Bauman66b8ab22014-05-06 15:57:45 -04003413 Value *value = rhs.loadValue();
3414 storeValue(value);
3415
3416 return RValue<UShort8>(value);
3417 }
3418
Nicolas Capens96d4e092016-11-18 14:22:38 -05003419 RValue<UShort8> UShort8::operator=(const Reference<UShort8> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04003420 {
3421 Value *value = rhs.loadValue();
3422 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003423
3424 return RValue<UShort8>(value);
3425 }
3426
John Bauman19bac1e2014-05-06 15:23:49 -04003427 RValue<UShort8> operator&(RValue<UShort8> lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003428 {
3429 return RValue<UShort8>(Nucleus::createAnd(lhs.value, rhs.value));
3430 }
3431
John Bauman19bac1e2014-05-06 15:23:49 -04003432 RValue<UShort8> operator<<(RValue<UShort8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003433 {
3434 return As<UShort8>(x86::psllw(As<Short8>(lhs), rhs)); // FIXME: Fallback required
3435 }
3436
John Bauman19bac1e2014-05-06 15:23:49 -04003437 RValue<UShort8> operator>>(RValue<UShort8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003438 {
3439 return x86::psrlw(lhs, rhs); // FIXME: Fallback required
3440 }
3441
John Bauman19bac1e2014-05-06 15:23:49 -04003442 RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003443 {
3444 return RValue<UShort8>(Nucleus::createAdd(lhs.value, rhs.value));
3445 }
3446
John Bauman19bac1e2014-05-06 15:23:49 -04003447 RValue<UShort8> operator*(RValue<UShort8> lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003448 {
3449 return RValue<UShort8>(Nucleus::createMul(lhs.value, rhs.value));
3450 }
3451
Nicolas Capens96d4e092016-11-18 14:22:38 -05003452 RValue<UShort8> operator+=(UShort8 &lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003453 {
3454 return lhs = lhs + rhs;
3455 }
3456
John Bauman19bac1e2014-05-06 15:23:49 -04003457 RValue<UShort8> operator~(RValue<UShort8> val)
John Bauman89401822014-05-06 15:04:28 -04003458 {
3459 return RValue<UShort8>(Nucleus::createNot(val.value));
3460 }
3461
John Bauman19bac1e2014-05-06 15:23:49 -04003462 RValue<UShort8> Swizzle(RValue<UShort8> x, char select0, char select1, char select2, char select3, char select4, char select5, char select6, char select7)
John Bauman89401822014-05-06 15:04:28 -04003463 {
Nicolas Capense89cd582016-09-30 14:23:47 -04003464 int pshufb[16] =
3465 {
3466 select0 + 0,
3467 select0 + 1,
3468 select1 + 0,
3469 select1 + 1,
3470 select2 + 0,
3471 select2 + 1,
3472 select3 + 0,
3473 select3 + 1,
3474 select4 + 0,
3475 select4 + 1,
3476 select5 + 0,
3477 select5 + 1,
3478 select6 + 0,
3479 select6 + 1,
3480 select7 + 0,
3481 select7 + 1,
3482 };
John Bauman89401822014-05-06 15:04:28 -04003483
3484 Value *byte16 = Nucleus::createBitCast(x.value, Byte16::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04003485 Value *shuffle = Nucleus::createShuffleVector(byte16, byte16, pshufb);
John Bauman89401822014-05-06 15:04:28 -04003486 Value *short8 = Nucleus::createBitCast(shuffle, UShort8::getType());
3487
3488 return RValue<UShort8>(short8);
3489 }
3490
John Bauman19bac1e2014-05-06 15:23:49 -04003491 RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y)
John Bauman89401822014-05-06 15:04:28 -04003492 {
3493 return x86::pmulhuw(x, y); // FIXME: Fallback required
3494 }
3495
John Bauman19bac1e2014-05-06 15:23:49 -04003496 Type *UShort8::getType()
John Bauman89401822014-05-06 15:04:28 -04003497 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04003498 return T(llvm::VectorType::get(T(UShort::getType()), 8));
John Bauman89401822014-05-06 15:04:28 -04003499 }
3500
Nicolas Capens81f18302016-01-14 09:32:35 -05003501 Int::Int(Argument<Int> argument)
John Bauman89401822014-05-06 15:04:28 -04003502 {
Nicolas Capens81f18302016-01-14 09:32:35 -05003503 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04003504 }
3505
John Bauman19bac1e2014-05-06 15:23:49 -04003506 Int::Int(RValue<Byte> cast)
John Bauman89401822014-05-06 15:04:28 -04003507 {
John Bauman89401822014-05-06 15:04:28 -04003508 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3509
John Bauman66b8ab22014-05-06 15:57:45 -04003510 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003511 }
3512
John Bauman19bac1e2014-05-06 15:23:49 -04003513 Int::Int(RValue<SByte> cast)
John Bauman89401822014-05-06 15:04:28 -04003514 {
John Bauman89401822014-05-06 15:04:28 -04003515 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3516
John Bauman66b8ab22014-05-06 15:57:45 -04003517 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003518 }
3519
John Bauman19bac1e2014-05-06 15:23:49 -04003520 Int::Int(RValue<Short> cast)
John Bauman89401822014-05-06 15:04:28 -04003521 {
John Bauman89401822014-05-06 15:04:28 -04003522 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3523
John Bauman66b8ab22014-05-06 15:57:45 -04003524 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003525 }
3526
John Bauman19bac1e2014-05-06 15:23:49 -04003527 Int::Int(RValue<UShort> cast)
John Bauman89401822014-05-06 15:04:28 -04003528 {
John Bauman89401822014-05-06 15:04:28 -04003529 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3530
John Bauman66b8ab22014-05-06 15:57:45 -04003531 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003532 }
3533
John Bauman19bac1e2014-05-06 15:23:49 -04003534 Int::Int(RValue<Int2> cast)
John Bauman89401822014-05-06 15:04:28 -04003535 {
John Bauman89401822014-05-06 15:04:28 -04003536 *this = Extract(cast, 0);
3537 }
3538
John Bauman19bac1e2014-05-06 15:23:49 -04003539 Int::Int(RValue<Long> cast)
John Bauman89401822014-05-06 15:04:28 -04003540 {
John Bauman89401822014-05-06 15:04:28 -04003541 Value *integer = Nucleus::createTrunc(cast.value, Int::getType());
3542
John Bauman66b8ab22014-05-06 15:57:45 -04003543 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003544 }
3545
John Bauman19bac1e2014-05-06 15:23:49 -04003546 Int::Int(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04003547 {
John Bauman89401822014-05-06 15:04:28 -04003548 Value *integer = Nucleus::createFPToSI(cast.value, Int::getType());
3549
John Bauman66b8ab22014-05-06 15:57:45 -04003550 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003551 }
3552
John Bauman89401822014-05-06 15:04:28 -04003553 Int::Int(int x)
3554 {
John Bauman66b8ab22014-05-06 15:57:45 -04003555 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04003556 }
3557
John Bauman19bac1e2014-05-06 15:23:49 -04003558 Int::Int(RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003559 {
John Bauman66b8ab22014-05-06 15:57:45 -04003560 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003561 }
3562
John Bauman19bac1e2014-05-06 15:23:49 -04003563 Int::Int(RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04003564 {
John Bauman66b8ab22014-05-06 15:57:45 -04003565 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003566 }
3567
3568 Int::Int(const Int &rhs)
3569 {
John Bauman66b8ab22014-05-06 15:57:45 -04003570 Value *value = rhs.loadValue();
3571 storeValue(value);
3572 }
John Bauman89401822014-05-06 15:04:28 -04003573
John Bauman66b8ab22014-05-06 15:57:45 -04003574 Int::Int(const Reference<Int> &rhs)
3575 {
3576 Value *value = rhs.loadValue();
3577 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003578 }
3579
3580 Int::Int(const UInt &rhs)
3581 {
John Bauman66b8ab22014-05-06 15:57:45 -04003582 Value *value = rhs.loadValue();
3583 storeValue(value);
3584 }
John Bauman89401822014-05-06 15:04:28 -04003585
John Bauman66b8ab22014-05-06 15:57:45 -04003586 Int::Int(const Reference<UInt> &rhs)
3587 {
3588 Value *value = rhs.loadValue();
3589 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003590 }
3591
Nicolas Capens96d4e092016-11-18 14:22:38 -05003592 RValue<Int> Int::operator=(int rhs)
John Bauman89401822014-05-06 15:04:28 -04003593 {
John Bauman66b8ab22014-05-06 15:57:45 -04003594 return RValue<Int>(storeValue(Nucleus::createConstantInt(rhs)));
John Bauman89401822014-05-06 15:04:28 -04003595 }
3596
Nicolas Capens96d4e092016-11-18 14:22:38 -05003597 RValue<Int> Int::operator=(RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003598 {
John Bauman66b8ab22014-05-06 15:57:45 -04003599 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003600
3601 return rhs;
3602 }
3603
Nicolas Capens96d4e092016-11-18 14:22:38 -05003604 RValue<Int> Int::operator=(RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04003605 {
John Bauman66b8ab22014-05-06 15:57:45 -04003606 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003607
John Bauman66b8ab22014-05-06 15:57:45 -04003608 return RValue<Int>(rhs);
John Bauman89401822014-05-06 15:04:28 -04003609 }
3610
Nicolas Capens96d4e092016-11-18 14:22:38 -05003611 RValue<Int> Int::operator=(const Int &rhs)
John Bauman89401822014-05-06 15:04:28 -04003612 {
John Bauman66b8ab22014-05-06 15:57:45 -04003613 Value *value = rhs.loadValue();
3614 storeValue(value);
3615
3616 return RValue<Int>(value);
3617 }
3618
Nicolas Capens96d4e092016-11-18 14:22:38 -05003619 RValue<Int> Int::operator=(const Reference<Int> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04003620 {
3621 Value *value = rhs.loadValue();
3622 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003623
3624 return RValue<Int>(value);
3625 }
3626
Nicolas Capens96d4e092016-11-18 14:22:38 -05003627 RValue<Int> Int::operator=(const UInt &rhs)
John Bauman89401822014-05-06 15:04:28 -04003628 {
John Bauman66b8ab22014-05-06 15:57:45 -04003629 Value *value = rhs.loadValue();
3630 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003631
3632 return RValue<Int>(value);
3633 }
3634
Nicolas Capens96d4e092016-11-18 14:22:38 -05003635 RValue<Int> Int::operator=(const Reference<UInt> &rhs)
John Bauman89401822014-05-06 15:04:28 -04003636 {
John Bauman66b8ab22014-05-06 15:57:45 -04003637 Value *value = rhs.loadValue();
3638 storeValue(value);
3639
3640 return RValue<Int>(value);
John Bauman89401822014-05-06 15:04:28 -04003641 }
3642
John Bauman19bac1e2014-05-06 15:23:49 -04003643 RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003644 {
3645 return RValue<Int>(Nucleus::createAdd(lhs.value, rhs.value));
3646 }
3647
John Bauman19bac1e2014-05-06 15:23:49 -04003648 RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003649 {
3650 return RValue<Int>(Nucleus::createSub(lhs.value, rhs.value));
3651 }
3652
John Bauman19bac1e2014-05-06 15:23:49 -04003653 RValue<Int> operator*(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003654 {
3655 return RValue<Int>(Nucleus::createMul(lhs.value, rhs.value));
3656 }
3657
John Bauman19bac1e2014-05-06 15:23:49 -04003658 RValue<Int> operator/(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003659 {
3660 return RValue<Int>(Nucleus::createSDiv(lhs.value, rhs.value));
3661 }
3662
John Bauman19bac1e2014-05-06 15:23:49 -04003663 RValue<Int> operator%(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003664 {
3665 return RValue<Int>(Nucleus::createSRem(lhs.value, rhs.value));
3666 }
3667
John Bauman19bac1e2014-05-06 15:23:49 -04003668 RValue<Int> operator&(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003669 {
3670 return RValue<Int>(Nucleus::createAnd(lhs.value, rhs.value));
3671 }
3672
John Bauman19bac1e2014-05-06 15:23:49 -04003673 RValue<Int> operator|(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003674 {
3675 return RValue<Int>(Nucleus::createOr(lhs.value, rhs.value));
3676 }
3677
John Bauman19bac1e2014-05-06 15:23:49 -04003678 RValue<Int> operator^(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003679 {
3680 return RValue<Int>(Nucleus::createXor(lhs.value, rhs.value));
3681 }
3682
John Bauman19bac1e2014-05-06 15:23:49 -04003683 RValue<Int> operator<<(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003684 {
3685 return RValue<Int>(Nucleus::createShl(lhs.value, rhs.value));
3686 }
3687
John Bauman19bac1e2014-05-06 15:23:49 -04003688 RValue<Int> operator>>(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003689 {
3690 return RValue<Int>(Nucleus::createAShr(lhs.value, rhs.value));
3691 }
3692
Nicolas Capens96d4e092016-11-18 14:22:38 -05003693 RValue<Int> operator+=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003694 {
3695 return lhs = lhs + rhs;
3696 }
3697
Nicolas Capens96d4e092016-11-18 14:22:38 -05003698 RValue<Int> operator-=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003699 {
3700 return lhs = lhs - rhs;
3701 }
3702
Nicolas Capens96d4e092016-11-18 14:22:38 -05003703 RValue<Int> operator*=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003704 {
3705 return lhs = lhs * rhs;
3706 }
3707
Nicolas Capens96d4e092016-11-18 14:22:38 -05003708 RValue<Int> operator/=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003709 {
3710 return lhs = lhs / rhs;
3711 }
3712
Nicolas Capens96d4e092016-11-18 14:22:38 -05003713 RValue<Int> operator%=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003714 {
3715 return lhs = lhs % rhs;
3716 }
3717
Nicolas Capens96d4e092016-11-18 14:22:38 -05003718 RValue<Int> operator&=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003719 {
3720 return lhs = lhs & rhs;
3721 }
3722
Nicolas Capens96d4e092016-11-18 14:22:38 -05003723 RValue<Int> operator|=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003724 {
3725 return lhs = lhs | rhs;
3726 }
3727
Nicolas Capens96d4e092016-11-18 14:22:38 -05003728 RValue<Int> operator^=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003729 {
3730 return lhs = lhs ^ rhs;
3731 }
3732
Nicolas Capens96d4e092016-11-18 14:22:38 -05003733 RValue<Int> operator<<=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003734 {
3735 return lhs = lhs << rhs;
3736 }
3737
Nicolas Capens96d4e092016-11-18 14:22:38 -05003738 RValue<Int> operator>>=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003739 {
3740 return lhs = lhs >> rhs;
3741 }
3742
John Bauman19bac1e2014-05-06 15:23:49 -04003743 RValue<Int> operator+(RValue<Int> val)
John Bauman89401822014-05-06 15:04:28 -04003744 {
3745 return val;
3746 }
3747
John Bauman19bac1e2014-05-06 15:23:49 -04003748 RValue<Int> operator-(RValue<Int> val)
John Bauman89401822014-05-06 15:04:28 -04003749 {
3750 return RValue<Int>(Nucleus::createNeg(val.value));
3751 }
3752
John Bauman19bac1e2014-05-06 15:23:49 -04003753 RValue<Int> operator~(RValue<Int> val)
John Bauman89401822014-05-06 15:04:28 -04003754 {
3755 return RValue<Int>(Nucleus::createNot(val.value));
3756 }
3757
Nicolas Capens96d4e092016-11-18 14:22:38 -05003758 RValue<Int> operator++(Int &val, int) // Post-increment
John Bauman89401822014-05-06 15:04:28 -04003759 {
3760 RValue<Int> res = val;
3761
Nicolas Capens19336542016-09-26 10:32:29 -04003762 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04003763 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04003764
3765 return res;
3766 }
3767
Nicolas Capens96d4e092016-11-18 14:22:38 -05003768 const Int &operator++(Int &val) // Pre-increment
John Bauman89401822014-05-06 15:04:28 -04003769 {
Nicolas Capens19336542016-09-26 10:32:29 -04003770 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04003771 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04003772
3773 return val;
3774 }
3775
Nicolas Capens96d4e092016-11-18 14:22:38 -05003776 RValue<Int> operator--(Int &val, int) // Post-decrement
John Bauman89401822014-05-06 15:04:28 -04003777 {
3778 RValue<Int> res = val;
3779
Nicolas Capens19336542016-09-26 10:32:29 -04003780 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04003781 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04003782
3783 return res;
3784 }
3785
Nicolas Capens96d4e092016-11-18 14:22:38 -05003786 const Int &operator--(Int &val) // Pre-decrement
John Bauman89401822014-05-06 15:04:28 -04003787 {
Nicolas Capens19336542016-09-26 10:32:29 -04003788 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04003789 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04003790
3791 return val;
3792 }
3793
John Bauman19bac1e2014-05-06 15:23:49 -04003794 RValue<Bool> operator<(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003795 {
3796 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
3797 }
3798
John Bauman19bac1e2014-05-06 15:23:49 -04003799 RValue<Bool> operator<=(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003800 {
3801 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
3802 }
3803
John Bauman19bac1e2014-05-06 15:23:49 -04003804 RValue<Bool> operator>(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003805 {
3806 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
3807 }
3808
John Bauman19bac1e2014-05-06 15:23:49 -04003809 RValue<Bool> operator>=(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003810 {
3811 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
3812 }
3813
John Bauman19bac1e2014-05-06 15:23:49 -04003814 RValue<Bool> operator!=(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003815 {
3816 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
3817 }
3818
John Bauman19bac1e2014-05-06 15:23:49 -04003819 RValue<Bool> operator==(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003820 {
3821 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
3822 }
3823
John Bauman19bac1e2014-05-06 15:23:49 -04003824 RValue<Int> Max(RValue<Int> x, RValue<Int> y)
3825 {
3826 return IfThenElse(x > y, x, y);
3827 }
3828
3829 RValue<Int> Min(RValue<Int> x, RValue<Int> y)
3830 {
3831 return IfThenElse(x < y, x, y);
3832 }
3833
3834 RValue<Int> Clamp(RValue<Int> x, RValue<Int> min, RValue<Int> max)
3835 {
3836 return Min(Max(x, min), max);
3837 }
3838
3839 RValue<Int> RoundInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04003840 {
3841 return x86::cvtss2si(cast);
3842
John Bauman66b8ab22014-05-06 15:57:45 -04003843 // return IfThenElse(val > 0.0f, Int(val + 0.5f), Int(val - 0.5f));
John Bauman89401822014-05-06 15:04:28 -04003844 }
3845
John Bauman19bac1e2014-05-06 15:23:49 -04003846 Type *Int::getType()
John Bauman89401822014-05-06 15:04:28 -04003847 {
Nicolas Capensac230122016-09-20 14:30:06 -04003848 return T(llvm::Type::getInt32Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04003849 }
3850
John Bauman19bac1e2014-05-06 15:23:49 -04003851 Long::Long(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04003852 {
John Bauman89401822014-05-06 15:04:28 -04003853 Value *integer = Nucleus::createSExt(cast.value, Long::getType());
3854
John Bauman66b8ab22014-05-06 15:57:45 -04003855 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003856 }
3857
John Bauman19bac1e2014-05-06 15:23:49 -04003858 Long::Long(RValue<UInt> cast)
John Bauman89401822014-05-06 15:04:28 -04003859 {
John Bauman89401822014-05-06 15:04:28 -04003860 Value *integer = Nucleus::createZExt(cast.value, Long::getType());
3861
John Bauman66b8ab22014-05-06 15:57:45 -04003862 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003863 }
3864
John Bauman19bac1e2014-05-06 15:23:49 -04003865 Long::Long(RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04003866 {
John Bauman66b8ab22014-05-06 15:57:45 -04003867 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003868 }
3869
Nicolas Capens96d4e092016-11-18 14:22:38 -05003870 RValue<Long> Long::operator=(int64_t rhs)
John Bauman89401822014-05-06 15:04:28 -04003871 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04003872 return RValue<Long>(storeValue(Nucleus::createConstantLong(rhs)));
John Bauman89401822014-05-06 15:04:28 -04003873 }
3874
Nicolas Capens96d4e092016-11-18 14:22:38 -05003875 RValue<Long> Long::operator=(RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04003876 {
John Bauman66b8ab22014-05-06 15:57:45 -04003877 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003878
3879 return rhs;
3880 }
3881
Nicolas Capens96d4e092016-11-18 14:22:38 -05003882 RValue<Long> Long::operator=(const Long &rhs)
John Bauman89401822014-05-06 15:04:28 -04003883 {
John Bauman66b8ab22014-05-06 15:57:45 -04003884 Value *value = rhs.loadValue();
3885 storeValue(value);
3886
3887 return RValue<Long>(value);
3888 }
3889
Nicolas Capens96d4e092016-11-18 14:22:38 -05003890 RValue<Long> Long::operator=(const Reference<Long> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04003891 {
3892 Value *value = rhs.loadValue();
3893 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003894
3895 return RValue<Long>(value);
3896 }
3897
John Bauman19bac1e2014-05-06 15:23:49 -04003898 RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04003899 {
3900 return RValue<Long>(Nucleus::createAdd(lhs.value, rhs.value));
3901 }
3902
John Bauman19bac1e2014-05-06 15:23:49 -04003903 RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04003904 {
3905 return RValue<Long>(Nucleus::createSub(lhs.value, rhs.value));
3906 }
3907
Nicolas Capens96d4e092016-11-18 14:22:38 -05003908 RValue<Long> operator+=(Long &lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04003909 {
3910 return lhs = lhs + rhs;
3911 }
3912
Nicolas Capens96d4e092016-11-18 14:22:38 -05003913 RValue<Long> operator-=(Long &lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04003914 {
3915 return lhs = lhs - rhs;
3916 }
3917
John Bauman66b8ab22014-05-06 15:57:45 -04003918 RValue<Long> AddAtomic(RValue<Pointer<Long> > x, RValue<Long> y)
John Bauman89401822014-05-06 15:04:28 -04003919 {
John Bauman19bac1e2014-05-06 15:23:49 -04003920 return RValue<Long>(Nucleus::createAtomicAdd(x.value, y.value));
John Bauman89401822014-05-06 15:04:28 -04003921 }
3922
John Bauman19bac1e2014-05-06 15:23:49 -04003923 Type *Long::getType()
John Bauman89401822014-05-06 15:04:28 -04003924 {
Nicolas Capensac230122016-09-20 14:30:06 -04003925 return T(llvm::Type::getInt64Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04003926 }
3927
Nicolas Capens81f18302016-01-14 09:32:35 -05003928 UInt::UInt(Argument<UInt> argument)
John Bauman89401822014-05-06 15:04:28 -04003929 {
Nicolas Capens81f18302016-01-14 09:32:35 -05003930 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04003931 }
3932
John Bauman19bac1e2014-05-06 15:23:49 -04003933 UInt::UInt(RValue<UShort> cast)
John Bauman89401822014-05-06 15:04:28 -04003934 {
John Bauman89401822014-05-06 15:04:28 -04003935 Value *integer = Nucleus::createZExt(cast.value, UInt::getType());
3936
John Bauman66b8ab22014-05-06 15:57:45 -04003937 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003938 }
3939
John Bauman19bac1e2014-05-06 15:23:49 -04003940 UInt::UInt(RValue<Long> cast)
John Bauman89401822014-05-06 15:04:28 -04003941 {
John Bauman89401822014-05-06 15:04:28 -04003942 Value *integer = Nucleus::createTrunc(cast.value, UInt::getType());
3943
John Bauman66b8ab22014-05-06 15:57:45 -04003944 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003945 }
3946
John Bauman19bac1e2014-05-06 15:23:49 -04003947 UInt::UInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04003948 {
Alexis Hetu764d1422016-09-28 08:44:22 -04003949 // Note: createFPToUI is broken, must perform conversion using createFPtoSI
3950 // Value *integer = Nucleus::createFPToUI(cast.value, UInt::getType());
John Bauman89401822014-05-06 15:04:28 -04003951
Alexis Hetu764d1422016-09-28 08:44:22 -04003952 // Smallest positive value representable in UInt, but not in Int
3953 const unsigned int ustart = 0x80000000u;
3954 const float ustartf = float(ustart);
3955
3956 // If the value is negative, store 0, otherwise store the result of the conversion
3957 storeValue((~(As<Int>(cast) >> 31) &
3958 // Check if the value can be represented as an Int
3959 IfThenElse(cast >= ustartf,
3960 // If the value is too large, subtract ustart and re-add it after conversion.
3961 As<Int>(As<UInt>(Int(cast - Float(ustartf))) + UInt(ustart)),
3962 // Otherwise, just convert normally
3963 Int(cast))).value);
John Bauman89401822014-05-06 15:04:28 -04003964 }
3965
John Bauman89401822014-05-06 15:04:28 -04003966 UInt::UInt(int x)
3967 {
John Bauman66b8ab22014-05-06 15:57:45 -04003968 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04003969 }
3970
3971 UInt::UInt(unsigned int x)
3972 {
John Bauman66b8ab22014-05-06 15:57:45 -04003973 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04003974 }
3975
John Bauman19bac1e2014-05-06 15:23:49 -04003976 UInt::UInt(RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04003977 {
John Bauman66b8ab22014-05-06 15:57:45 -04003978 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003979 }
3980
John Bauman19bac1e2014-05-06 15:23:49 -04003981 UInt::UInt(RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003982 {
John Bauman66b8ab22014-05-06 15:57:45 -04003983 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003984 }
3985
3986 UInt::UInt(const UInt &rhs)
3987 {
John Bauman66b8ab22014-05-06 15:57:45 -04003988 Value *value = rhs.loadValue();
3989 storeValue(value);
3990 }
John Bauman89401822014-05-06 15:04:28 -04003991
John Bauman66b8ab22014-05-06 15:57:45 -04003992 UInt::UInt(const Reference<UInt> &rhs)
3993 {
3994 Value *value = rhs.loadValue();
3995 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003996 }
3997
3998 UInt::UInt(const Int &rhs)
3999 {
John Bauman66b8ab22014-05-06 15:57:45 -04004000 Value *value = rhs.loadValue();
4001 storeValue(value);
4002 }
John Bauman89401822014-05-06 15:04:28 -04004003
John Bauman66b8ab22014-05-06 15:57:45 -04004004 UInt::UInt(const Reference<Int> &rhs)
4005 {
4006 Value *value = rhs.loadValue();
4007 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004008 }
4009
Nicolas Capens96d4e092016-11-18 14:22:38 -05004010 RValue<UInt> UInt::operator=(unsigned int rhs)
John Bauman89401822014-05-06 15:04:28 -04004011 {
John Bauman66b8ab22014-05-06 15:57:45 -04004012 return RValue<UInt>(storeValue(Nucleus::createConstantInt(rhs)));
John Bauman89401822014-05-06 15:04:28 -04004013 }
4014
Nicolas Capens96d4e092016-11-18 14:22:38 -05004015 RValue<UInt> UInt::operator=(RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004016 {
John Bauman66b8ab22014-05-06 15:57:45 -04004017 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004018
4019 return rhs;
4020 }
4021
Nicolas Capens96d4e092016-11-18 14:22:38 -05004022 RValue<UInt> UInt::operator=(RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004023 {
John Bauman66b8ab22014-05-06 15:57:45 -04004024 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004025
John Bauman66b8ab22014-05-06 15:57:45 -04004026 return RValue<UInt>(rhs);
John Bauman89401822014-05-06 15:04:28 -04004027 }
4028
Nicolas Capens96d4e092016-11-18 14:22:38 -05004029 RValue<UInt> UInt::operator=(const UInt &rhs)
John Bauman89401822014-05-06 15:04:28 -04004030 {
John Bauman66b8ab22014-05-06 15:57:45 -04004031 Value *value = rhs.loadValue();
4032 storeValue(value);
4033
4034 return RValue<UInt>(value);
4035 }
4036
Nicolas Capens96d4e092016-11-18 14:22:38 -05004037 RValue<UInt> UInt::operator=(const Reference<UInt> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04004038 {
4039 Value *value = rhs.loadValue();
4040 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004041
4042 return RValue<UInt>(value);
4043 }
4044
Nicolas Capens96d4e092016-11-18 14:22:38 -05004045 RValue<UInt> UInt::operator=(const Int &rhs)
John Bauman89401822014-05-06 15:04:28 -04004046 {
John Bauman66b8ab22014-05-06 15:57:45 -04004047 Value *value = rhs.loadValue();
4048 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004049
4050 return RValue<UInt>(value);
4051 }
4052
Nicolas Capens96d4e092016-11-18 14:22:38 -05004053 RValue<UInt> UInt::operator=(const Reference<Int> &rhs)
John Bauman89401822014-05-06 15:04:28 -04004054 {
John Bauman66b8ab22014-05-06 15:57:45 -04004055 Value *value = rhs.loadValue();
4056 storeValue(value);
4057
4058 return RValue<UInt>(value);
John Bauman89401822014-05-06 15:04:28 -04004059 }
4060
John Bauman19bac1e2014-05-06 15:23:49 -04004061 RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004062 {
4063 return RValue<UInt>(Nucleus::createAdd(lhs.value, rhs.value));
4064 }
4065
John Bauman19bac1e2014-05-06 15:23:49 -04004066 RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004067 {
4068 return RValue<UInt>(Nucleus::createSub(lhs.value, rhs.value));
4069 }
4070
John Bauman19bac1e2014-05-06 15:23:49 -04004071 RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004072 {
4073 return RValue<UInt>(Nucleus::createMul(lhs.value, rhs.value));
4074 }
4075
John Bauman19bac1e2014-05-06 15:23:49 -04004076 RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004077 {
4078 return RValue<UInt>(Nucleus::createUDiv(lhs.value, rhs.value));
4079 }
4080
John Bauman19bac1e2014-05-06 15:23:49 -04004081 RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004082 {
4083 return RValue<UInt>(Nucleus::createURem(lhs.value, rhs.value));
4084 }
4085
John Bauman19bac1e2014-05-06 15:23:49 -04004086 RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004087 {
4088 return RValue<UInt>(Nucleus::createAnd(lhs.value, rhs.value));
4089 }
4090
John Bauman19bac1e2014-05-06 15:23:49 -04004091 RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004092 {
4093 return RValue<UInt>(Nucleus::createOr(lhs.value, rhs.value));
4094 }
4095
John Bauman19bac1e2014-05-06 15:23:49 -04004096 RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004097 {
4098 return RValue<UInt>(Nucleus::createXor(lhs.value, rhs.value));
4099 }
4100
John Bauman19bac1e2014-05-06 15:23:49 -04004101 RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004102 {
4103 return RValue<UInt>(Nucleus::createShl(lhs.value, rhs.value));
4104 }
4105
John Bauman19bac1e2014-05-06 15:23:49 -04004106 RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004107 {
4108 return RValue<UInt>(Nucleus::createLShr(lhs.value, rhs.value));
4109 }
4110
Nicolas Capens96d4e092016-11-18 14:22:38 -05004111 RValue<UInt> operator+=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004112 {
4113 return lhs = lhs + rhs;
4114 }
4115
Nicolas Capens96d4e092016-11-18 14:22:38 -05004116 RValue<UInt> operator-=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004117 {
4118 return lhs = lhs - rhs;
4119 }
4120
Nicolas Capens96d4e092016-11-18 14:22:38 -05004121 RValue<UInt> operator*=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004122 {
4123 return lhs = lhs * rhs;
4124 }
4125
Nicolas Capens96d4e092016-11-18 14:22:38 -05004126 RValue<UInt> operator/=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004127 {
4128 return lhs = lhs / rhs;
4129 }
4130
Nicolas Capens96d4e092016-11-18 14:22:38 -05004131 RValue<UInt> operator%=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004132 {
4133 return lhs = lhs % rhs;
4134 }
4135
Nicolas Capens96d4e092016-11-18 14:22:38 -05004136 RValue<UInt> operator&=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004137 {
4138 return lhs = lhs & rhs;
4139 }
4140
Nicolas Capens96d4e092016-11-18 14:22:38 -05004141 RValue<UInt> operator|=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004142 {
4143 return lhs = lhs | rhs;
4144 }
4145
Nicolas Capens96d4e092016-11-18 14:22:38 -05004146 RValue<UInt> operator^=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004147 {
4148 return lhs = lhs ^ rhs;
4149 }
4150
Nicolas Capens96d4e092016-11-18 14:22:38 -05004151 RValue<UInt> operator<<=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004152 {
4153 return lhs = lhs << rhs;
4154 }
4155
Nicolas Capens96d4e092016-11-18 14:22:38 -05004156 RValue<UInt> operator>>=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004157 {
4158 return lhs = lhs >> rhs;
4159 }
4160
John Bauman19bac1e2014-05-06 15:23:49 -04004161 RValue<UInt> operator+(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004162 {
4163 return val;
4164 }
4165
John Bauman19bac1e2014-05-06 15:23:49 -04004166 RValue<UInt> operator-(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004167 {
4168 return RValue<UInt>(Nucleus::createNeg(val.value));
4169 }
4170
John Bauman19bac1e2014-05-06 15:23:49 -04004171 RValue<UInt> operator~(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004172 {
4173 return RValue<UInt>(Nucleus::createNot(val.value));
4174 }
4175
Nicolas Capens96d4e092016-11-18 14:22:38 -05004176 RValue<UInt> operator++(UInt &val, int) // Post-increment
John Bauman89401822014-05-06 15:04:28 -04004177 {
4178 RValue<UInt> res = val;
4179
Nicolas Capens19336542016-09-26 10:32:29 -04004180 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04004181 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004182
4183 return res;
4184 }
4185
Nicolas Capens96d4e092016-11-18 14:22:38 -05004186 const UInt &operator++(UInt &val) // Pre-increment
John Bauman89401822014-05-06 15:04:28 -04004187 {
Nicolas Capens19336542016-09-26 10:32:29 -04004188 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04004189 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004190
4191 return val;
4192 }
4193
Nicolas Capens96d4e092016-11-18 14:22:38 -05004194 RValue<UInt> operator--(UInt &val, int) // Post-decrement
John Bauman89401822014-05-06 15:04:28 -04004195 {
4196 RValue<UInt> res = val;
4197
Nicolas Capens19336542016-09-26 10:32:29 -04004198 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04004199 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004200
4201 return res;
4202 }
4203
Nicolas Capens96d4e092016-11-18 14:22:38 -05004204 const UInt &operator--(UInt &val) // Pre-decrement
John Bauman89401822014-05-06 15:04:28 -04004205 {
Nicolas Capens19336542016-09-26 10:32:29 -04004206 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04004207 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004208
4209 return val;
4210 }
4211
John Bauman19bac1e2014-05-06 15:23:49 -04004212 RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y)
4213 {
4214 return IfThenElse(x > y, x, y);
4215 }
4216
4217 RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y)
4218 {
4219 return IfThenElse(x < y, x, y);
4220 }
4221
4222 RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max)
4223 {
4224 return Min(Max(x, min), max);
4225 }
4226
4227 RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004228 {
4229 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
4230 }
4231
John Bauman19bac1e2014-05-06 15:23:49 -04004232 RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004233 {
4234 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
4235 }
4236
John Bauman19bac1e2014-05-06 15:23:49 -04004237 RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004238 {
4239 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
4240 }
4241
John Bauman19bac1e2014-05-06 15:23:49 -04004242 RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004243 {
4244 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
4245 }
4246
John Bauman19bac1e2014-05-06 15:23:49 -04004247 RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004248 {
4249 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
4250 }
4251
John Bauman19bac1e2014-05-06 15:23:49 -04004252 RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004253 {
4254 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
4255 }
4256
John Bauman19bac1e2014-05-06 15:23:49 -04004257// RValue<UInt> RoundUInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04004258// {
4259// return x86::cvtss2si(val); // FIXME: Unsigned
4260//
John Bauman66b8ab22014-05-06 15:57:45 -04004261// // return IfThenElse(val > 0.0f, Int(val + 0.5f), Int(val - 0.5f));
John Bauman89401822014-05-06 15:04:28 -04004262// }
4263
John Bauman19bac1e2014-05-06 15:23:49 -04004264 Type *UInt::getType()
John Bauman89401822014-05-06 15:04:28 -04004265 {
Nicolas Capensac230122016-09-20 14:30:06 -04004266 return T(llvm::Type::getInt32Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04004267 }
4268
John Bauman19bac1e2014-05-06 15:23:49 -04004269// Int2::Int2(RValue<Int> cast)
4270// {
John Bauman19bac1e2014-05-06 15:23:49 -04004271// Value *extend = Nucleus::createZExt(cast.value, Long::getType());
4272// Value *vector = Nucleus::createBitCast(extend, Int2::getType());
John Bauman66b8ab22014-05-06 15:57:45 -04004273//
Nicolas Capense89cd582016-09-30 14:23:47 -04004274// int shuffle[2] = {0, 0};
4275// Value *replicate = Nucleus::createShuffleVector(vector, vector, shuffle);
John Bauman19bac1e2014-05-06 15:23:49 -04004276//
John Bauman66b8ab22014-05-06 15:57:45 -04004277// storeValue(replicate);
John Bauman19bac1e2014-05-06 15:23:49 -04004278// }
John Bauman89401822014-05-06 15:04:28 -04004279
John Bauman19bac1e2014-05-06 15:23:49 -04004280 Int2::Int2(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04004281 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04004282 Value *long2 = Nucleus::createBitCast(cast.value, T(llvm::VectorType::get(T(Long::getType()), 2)));
Nicolas Capense95d5342016-09-30 11:37:28 -04004283 Value *element = Nucleus::createExtractElement(long2, Long::getType(), 0);
John Bauman89401822014-05-06 15:04:28 -04004284 Value *int2 = Nucleus::createBitCast(element, Int2::getType());
4285
John Bauman66b8ab22014-05-06 15:57:45 -04004286 storeValue(int2);
John Bauman89401822014-05-06 15:04:28 -04004287 }
4288
John Bauman89401822014-05-06 15:04:28 -04004289 Int2::Int2(int x, int y)
4290 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04004291 int64_t constantVector[2] = {x, y};
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04004292 Value *vector = V(Nucleus::createConstantVector(constantVector, T(llvm::VectorType::get(T(Int::getType()), 2))));
John Bauman89401822014-05-06 15:04:28 -04004293
John Bauman66b8ab22014-05-06 15:57:45 -04004294 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04004295 }
4296
John Bauman19bac1e2014-05-06 15:23:49 -04004297 Int2::Int2(RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004298 {
John Bauman66b8ab22014-05-06 15:57:45 -04004299 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004300 }
4301
4302 Int2::Int2(const Int2 &rhs)
4303 {
John Bauman66b8ab22014-05-06 15:57:45 -04004304 Value *value = rhs.loadValue();
4305 storeValue(value);
4306 }
4307
4308 Int2::Int2(const Reference<Int2> &rhs)
4309 {
John Bauman66b8ab22014-05-06 15:57:45 -04004310 Value *value = rhs.loadValue();
4311 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004312 }
4313
Nicolas Capens62abb552016-01-05 12:03:47 -05004314 Int2::Int2(RValue<Int> lo, RValue<Int> hi)
4315 {
Nicolas Capensb40a2562016-01-05 00:08:45 -05004316 if(CPUID::supportsMMX2())
4317 {
4318 // movd mm0, lo
4319 // movd mm1, hi
4320 // punpckldq mm0, mm1
Nicolas Capens45f187a2016-12-02 15:30:56 -05004321
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04004322 Value *loLong = Nucleus::createInsertElement(V(llvm::UndefValue::get(llvm::VectorType::get(T(Int::getType()), 2))), lo.value, 0);
4323 loLong = Nucleus::createInsertElement(loLong, V(llvm::ConstantInt::get(T(Int::getType()), 0)), 1);
4324 Value *hiLong = Nucleus::createInsertElement(V(llvm::UndefValue::get(llvm::VectorType::get(T(Int::getType()), 2))), hi.value, 0);
4325 hiLong = Nucleus::createInsertElement(hiLong, V(llvm::ConstantInt::get(T(Int::getType()), 0)), 1);
Nicolas Capens45f187a2016-12-02 15:30:56 -05004326
4327 storeValue(As<Int2>(UnpackLow(As<Int2>(loLong), As<Int2>(hiLong))).value);
Nicolas Capensb40a2562016-01-05 00:08:45 -05004328 }
4329 else
4330 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004331 int shuffle[2] = {0, 1};
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04004332 Value *packed = Nucleus::createShuffleVector(Nucleus::createBitCast(lo.value, T(llvm::VectorType::get(T(Int::getType()), 1))), Nucleus::createBitCast(hi.value, T(llvm::VectorType::get(T(Int::getType()), 1))), shuffle);
Nicolas Capens05b3d662016-02-25 23:58:33 -05004333
Nicolas Capensb40a2562016-01-05 00:08:45 -05004334 storeValue(Nucleus::createBitCast(packed, Int2::getType()));
4335 }
Nicolas Capens62abb552016-01-05 12:03:47 -05004336 }
4337
Nicolas Capens96d4e092016-11-18 14:22:38 -05004338 RValue<Int2> Int2::operator=(RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004339 {
John Bauman66b8ab22014-05-06 15:57:45 -04004340 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004341
4342 return rhs;
4343 }
4344
Nicolas Capens96d4e092016-11-18 14:22:38 -05004345 RValue<Int2> Int2::operator=(const Int2 &rhs)
John Bauman89401822014-05-06 15:04:28 -04004346 {
John Bauman66b8ab22014-05-06 15:57:45 -04004347 Value *value = rhs.loadValue();
4348 storeValue(value);
4349
4350 return RValue<Int2>(value);
4351 }
4352
Nicolas Capens96d4e092016-11-18 14:22:38 -05004353 RValue<Int2> Int2::operator=(const Reference<Int2> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04004354 {
4355 Value *value = rhs.loadValue();
4356 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004357
4358 return RValue<Int2>(value);
4359 }
4360
John Bauman19bac1e2014-05-06 15:23:49 -04004361 RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004362 {
John Bauman19bac1e2014-05-06 15:23:49 -04004363 if(CPUID::supportsMMX2())
4364 {
4365 return x86::paddd(lhs, rhs);
4366 }
4367 else
4368 {
4369 return RValue<Int2>(Nucleus::createAdd(lhs.value, rhs.value));
4370 }
John Bauman89401822014-05-06 15:04:28 -04004371 }
4372
John Bauman19bac1e2014-05-06 15:23:49 -04004373 RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004374 {
John Bauman19bac1e2014-05-06 15:23:49 -04004375 if(CPUID::supportsMMX2())
4376 {
4377 return x86::psubd(lhs, rhs);
4378 }
4379 else
4380 {
4381 return RValue<Int2>(Nucleus::createSub(lhs.value, rhs.value));
4382 }
John Bauman89401822014-05-06 15:04:28 -04004383 }
4384
John Bauman19bac1e2014-05-06 15:23:49 -04004385// RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs)
4386// {
4387// return RValue<Int2>(Nucleus::createMul(lhs.value, rhs.value));
4388// }
4389
4390// RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs)
4391// {
4392// return RValue<Int2>(Nucleus::createSDiv(lhs.value, rhs.value));
4393// }
4394
4395// RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs)
4396// {
4397// return RValue<Int2>(Nucleus::createSRem(lhs.value, rhs.value));
4398// }
4399
4400 RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004401 {
John Bauman19bac1e2014-05-06 15:23:49 -04004402 if(CPUID::supportsMMX2())
4403 {
4404 return As<Int2>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
4405 }
4406 else
4407 {
4408 return RValue<Int2>(Nucleus::createAnd(lhs.value, rhs.value));
4409 }
John Bauman89401822014-05-06 15:04:28 -04004410 }
4411
John Bauman19bac1e2014-05-06 15:23:49 -04004412 RValue<Int2> operator|(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004413 {
John Bauman19bac1e2014-05-06 15:23:49 -04004414 if(CPUID::supportsMMX2())
4415 {
4416 return As<Int2>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
4417 }
4418 else
4419 {
4420 return RValue<Int2>(Nucleus::createOr(lhs.value, rhs.value));
4421 }
John Bauman89401822014-05-06 15:04:28 -04004422 }
4423
John Bauman19bac1e2014-05-06 15:23:49 -04004424 RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004425 {
John Bauman19bac1e2014-05-06 15:23:49 -04004426 if(CPUID::supportsMMX2())
4427 {
4428 return As<Int2>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
4429 }
4430 else
4431 {
4432 return RValue<Int2>(Nucleus::createXor(lhs.value, rhs.value));
4433 }
John Bauman89401822014-05-06 15:04:28 -04004434 }
4435
John Bauman19bac1e2014-05-06 15:23:49 -04004436 RValue<Int2> operator<<(RValue<Int2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004437 {
4438 // return RValue<Int2>(Nucleus::createShl(lhs.value, rhs.value));
4439
4440 return x86::pslld(lhs, rhs);
4441 }
4442
John Bauman19bac1e2014-05-06 15:23:49 -04004443 RValue<Int2> operator>>(RValue<Int2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004444 {
4445 // return RValue<Int2>(Nucleus::createAShr(lhs.value, rhs.value));
4446
4447 return x86::psrad(lhs, rhs);
4448 }
4449
Nicolas Capens96d4e092016-11-18 14:22:38 -05004450 RValue<Int2> operator+=(Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004451 {
4452 return lhs = lhs + rhs;
4453 }
4454
Nicolas Capens96d4e092016-11-18 14:22:38 -05004455 RValue<Int2> operator-=(Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004456 {
4457 return lhs = lhs - rhs;
4458 }
4459
Nicolas Capens96d4e092016-11-18 14:22:38 -05004460// RValue<Int2> operator*=(Int2 &lhs, RValue<Int2> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04004461// {
4462// return lhs = lhs * rhs;
4463// }
John Bauman89401822014-05-06 15:04:28 -04004464
Nicolas Capens96d4e092016-11-18 14:22:38 -05004465// RValue<Int2> operator/=(Int2 &lhs, RValue<Int2> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04004466// {
4467// return lhs = lhs / rhs;
4468// }
John Bauman89401822014-05-06 15:04:28 -04004469
Nicolas Capens96d4e092016-11-18 14:22:38 -05004470// RValue<Int2> operator%=(Int2 &lhs, RValue<Int2> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04004471// {
4472// return lhs = lhs % rhs;
4473// }
John Bauman89401822014-05-06 15:04:28 -04004474
Nicolas Capens96d4e092016-11-18 14:22:38 -05004475 RValue<Int2> operator&=(Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004476 {
4477 return lhs = lhs & rhs;
4478 }
4479
Nicolas Capens96d4e092016-11-18 14:22:38 -05004480 RValue<Int2> operator|=(Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004481 {
4482 return lhs = lhs | rhs;
4483 }
4484
Nicolas Capens96d4e092016-11-18 14:22:38 -05004485 RValue<Int2> operator^=(Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004486 {
4487 return lhs = lhs ^ rhs;
4488 }
4489
Nicolas Capens96d4e092016-11-18 14:22:38 -05004490 RValue<Int2> operator<<=(Int2 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004491 {
4492 return lhs = lhs << rhs;
4493 }
4494
Nicolas Capens96d4e092016-11-18 14:22:38 -05004495 RValue<Int2> operator>>=(Int2 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004496 {
4497 return lhs = lhs >> rhs;
4498 }
4499
John Bauman19bac1e2014-05-06 15:23:49 -04004500// RValue<Int2> operator+(RValue<Int2> val)
4501// {
4502// return val;
4503// }
4504
4505// RValue<Int2> operator-(RValue<Int2> val)
4506// {
4507// return RValue<Int2>(Nucleus::createNeg(val.value));
4508// }
4509
4510 RValue<Int2> operator~(RValue<Int2> val)
John Bauman89401822014-05-06 15:04:28 -04004511 {
John Bauman19bac1e2014-05-06 15:23:49 -04004512 if(CPUID::supportsMMX2())
4513 {
4514 return val ^ Int2(0xFFFFFFFF, 0xFFFFFFFF);
4515 }
4516 else
4517 {
4518 return RValue<Int2>(Nucleus::createNot(val.value));
4519 }
John Bauman89401822014-05-06 15:04:28 -04004520 }
4521
Nicolas Capens45f187a2016-12-02 15:30:56 -05004522 RValue<Short4> UnpackLow(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04004523 {
John Bauman19bac1e2014-05-06 15:23:49 -04004524 if(CPUID::supportsMMX2())
4525 {
4526 return x86::punpckldq(x, y);
4527 }
4528 else
4529 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004530 int shuffle[2] = {0, 2};
4531 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04004532
Nicolas Capens45f187a2016-12-02 15:30:56 -05004533 return As<Short4>(packed);
John Bauman19bac1e2014-05-06 15:23:49 -04004534 }
John Bauman89401822014-05-06 15:04:28 -04004535 }
John Bauman66b8ab22014-05-06 15:57:45 -04004536
Nicolas Capens45f187a2016-12-02 15:30:56 -05004537 RValue<Short4> UnpackHigh(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04004538 {
John Bauman19bac1e2014-05-06 15:23:49 -04004539 if(CPUID::supportsMMX2())
4540 {
4541 return x86::punpckhdq(x, y);
4542 }
4543 else
4544 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004545 int shuffle[2] = {1, 3};
4546 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04004547
Nicolas Capens45f187a2016-12-02 15:30:56 -05004548 return As<Short4>(packed);
John Bauman19bac1e2014-05-06 15:23:49 -04004549 }
John Bauman89401822014-05-06 15:04:28 -04004550 }
4551
John Bauman19bac1e2014-05-06 15:23:49 -04004552 RValue<Int> Extract(RValue<Int2> val, int i)
John Bauman89401822014-05-06 15:04:28 -04004553 {
4554 if(false) // FIXME: LLVM does not generate optimal code
4555 {
Nicolas Capense95d5342016-09-30 11:37:28 -04004556 return RValue<Int>(Nucleus::createExtractElement(val.value, Int::getType(), i));
John Bauman89401822014-05-06 15:04:28 -04004557 }
4558 else
4559 {
4560 if(i == 0)
4561 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04004562 return RValue<Int>(Nucleus::createExtractElement(Nucleus::createBitCast(val.value, T(llvm::VectorType::get(T(Int::getType()), 2))), Int::getType(), 0));
John Bauman89401822014-05-06 15:04:28 -04004563 }
4564 else
4565 {
4566 Int2 val2 = As<Int2>(UnpackHigh(val, val));
4567
4568 return Extract(val2, 0);
4569 }
4570 }
4571 }
4572
Nicolas Capensfff3c9b2015-05-13 23:40:44 -04004573 RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i)
4574 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04004575 return RValue<Int2>(Nucleus::createBitCast(Nucleus::createInsertElement(Nucleus::createBitCast(val.value, T(llvm::VectorType::get(T(Int::getType()), 2))), element.value, i), Int2::getType()));
Nicolas Capensfff3c9b2015-05-13 23:40:44 -04004576 }
John Bauman89401822014-05-06 15:04:28 -04004577
John Bauman19bac1e2014-05-06 15:23:49 -04004578 Type *Int2::getType()
John Bauman89401822014-05-06 15:04:28 -04004579 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04004580 return T(Type_v2i32);
John Bauman89401822014-05-06 15:04:28 -04004581 }
4582
John Bauman89401822014-05-06 15:04:28 -04004583 UInt2::UInt2(unsigned int x, unsigned int y)
4584 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04004585 int64_t constantVector[2] = {x, y};
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04004586 Value *vector = V(Nucleus::createConstantVector(constantVector, T(llvm::VectorType::get(T(UInt::getType()), 2))));
John Bauman89401822014-05-06 15:04:28 -04004587
John Bauman66b8ab22014-05-06 15:57:45 -04004588 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04004589 }
4590
John Bauman19bac1e2014-05-06 15:23:49 -04004591 UInt2::UInt2(RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004592 {
John Bauman66b8ab22014-05-06 15:57:45 -04004593 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004594 }
4595
4596 UInt2::UInt2(const UInt2 &rhs)
4597 {
John Bauman66b8ab22014-05-06 15:57:45 -04004598 Value *value = rhs.loadValue();
4599 storeValue(value);
4600 }
4601
4602 UInt2::UInt2(const Reference<UInt2> &rhs)
4603 {
John Bauman66b8ab22014-05-06 15:57:45 -04004604 Value *value = rhs.loadValue();
4605 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004606 }
4607
Nicolas Capens96d4e092016-11-18 14:22:38 -05004608 RValue<UInt2> UInt2::operator=(RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004609 {
John Bauman66b8ab22014-05-06 15:57:45 -04004610 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004611
4612 return rhs;
4613 }
4614
Nicolas Capens96d4e092016-11-18 14:22:38 -05004615 RValue<UInt2> UInt2::operator=(const UInt2 &rhs)
John Bauman89401822014-05-06 15:04:28 -04004616 {
John Bauman66b8ab22014-05-06 15:57:45 -04004617 Value *value = rhs.loadValue();
4618 storeValue(value);
4619
4620 return RValue<UInt2>(value);
4621 }
4622
Nicolas Capens96d4e092016-11-18 14:22:38 -05004623 RValue<UInt2> UInt2::operator=(const Reference<UInt2> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04004624 {
4625 Value *value = rhs.loadValue();
4626 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004627
4628 return RValue<UInt2>(value);
4629 }
4630
John Bauman19bac1e2014-05-06 15:23:49 -04004631 RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004632 {
John Bauman19bac1e2014-05-06 15:23:49 -04004633 if(CPUID::supportsMMX2())
4634 {
4635 return As<UInt2>(x86::paddd(As<Int2>(lhs), As<Int2>(rhs)));
4636 }
4637 else
4638 {
4639 return RValue<UInt2>(Nucleus::createAdd(lhs.value, rhs.value));
4640 }
John Bauman89401822014-05-06 15:04:28 -04004641 }
4642
John Bauman19bac1e2014-05-06 15:23:49 -04004643 RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004644 {
John Bauman19bac1e2014-05-06 15:23:49 -04004645 if(CPUID::supportsMMX2())
4646 {
4647 return As<UInt2>(x86::psubd(As<Int2>(lhs), As<Int2>(rhs)));
4648 }
4649 else
4650 {
4651 return RValue<UInt2>(Nucleus::createSub(lhs.value, rhs.value));
4652 }
John Bauman89401822014-05-06 15:04:28 -04004653 }
4654
John Bauman19bac1e2014-05-06 15:23:49 -04004655// RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs)
4656// {
4657// return RValue<UInt2>(Nucleus::createMul(lhs.value, rhs.value));
4658// }
4659
4660// RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs)
4661// {
4662// return RValue<UInt2>(Nucleus::createUDiv(lhs.value, rhs.value));
4663// }
4664
4665// RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs)
4666// {
4667// return RValue<UInt2>(Nucleus::createURem(lhs.value, rhs.value));
4668// }
4669
4670 RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004671 {
John Bauman19bac1e2014-05-06 15:23:49 -04004672 if(CPUID::supportsMMX2())
4673 {
4674 return As<UInt2>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
4675 }
4676 else
4677 {
4678 return RValue<UInt2>(Nucleus::createAnd(lhs.value, rhs.value));
4679 }
John Bauman89401822014-05-06 15:04:28 -04004680 }
4681
John Bauman19bac1e2014-05-06 15:23:49 -04004682 RValue<UInt2> operator|(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004683 {
John Bauman19bac1e2014-05-06 15:23:49 -04004684 if(CPUID::supportsMMX2())
4685 {
4686 return As<UInt2>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
4687 }
4688 else
4689 {
4690 return RValue<UInt2>(Nucleus::createOr(lhs.value, rhs.value));
4691 }
John Bauman89401822014-05-06 15:04:28 -04004692 }
4693
John Bauman19bac1e2014-05-06 15:23:49 -04004694 RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004695 {
John Bauman19bac1e2014-05-06 15:23:49 -04004696 if(CPUID::supportsMMX2())
4697 {
4698 return As<UInt2>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
4699 }
4700 else
4701 {
4702 return RValue<UInt2>(Nucleus::createXor(lhs.value, rhs.value));
4703 }
John Bauman89401822014-05-06 15:04:28 -04004704 }
4705
John Bauman19bac1e2014-05-06 15:23:49 -04004706 RValue<UInt2> operator<<(RValue<UInt2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004707 {
4708 // return RValue<UInt2>(Nucleus::createShl(lhs.value, rhs.value));
4709
4710 return As<UInt2>(x86::pslld(As<Int2>(lhs), rhs));
4711 }
4712
John Bauman19bac1e2014-05-06 15:23:49 -04004713 RValue<UInt2> operator>>(RValue<UInt2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004714 {
4715 // return RValue<UInt2>(Nucleus::createLShr(lhs.value, rhs.value));
4716
4717 return x86::psrld(lhs, rhs);
4718 }
4719
Nicolas Capens96d4e092016-11-18 14:22:38 -05004720 RValue<UInt2> operator+=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004721 {
4722 return lhs = lhs + rhs;
4723 }
4724
Nicolas Capens96d4e092016-11-18 14:22:38 -05004725 RValue<UInt2> operator-=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004726 {
4727 return lhs = lhs - rhs;
4728 }
4729
Nicolas Capens96d4e092016-11-18 14:22:38 -05004730// RValue<UInt2> operator*=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04004731// {
4732// return lhs = lhs * rhs;
4733// }
John Bauman89401822014-05-06 15:04:28 -04004734
Nicolas Capens96d4e092016-11-18 14:22:38 -05004735// RValue<UInt2> operator/=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04004736// {
4737// return lhs = lhs / rhs;
4738// }
John Bauman89401822014-05-06 15:04:28 -04004739
Nicolas Capens96d4e092016-11-18 14:22:38 -05004740// RValue<UInt2> operator%=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04004741// {
4742// return lhs = lhs % rhs;
4743// }
John Bauman89401822014-05-06 15:04:28 -04004744
Nicolas Capens96d4e092016-11-18 14:22:38 -05004745 RValue<UInt2> operator&=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004746 {
4747 return lhs = lhs & rhs;
4748 }
4749
Nicolas Capens96d4e092016-11-18 14:22:38 -05004750 RValue<UInt2> operator|=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004751 {
4752 return lhs = lhs | rhs;
4753 }
4754
Nicolas Capens96d4e092016-11-18 14:22:38 -05004755 RValue<UInt2> operator^=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004756 {
4757 return lhs = lhs ^ rhs;
4758 }
4759
Nicolas Capens96d4e092016-11-18 14:22:38 -05004760 RValue<UInt2> operator<<=(UInt2 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004761 {
4762 return lhs = lhs << rhs;
4763 }
4764
Nicolas Capens96d4e092016-11-18 14:22:38 -05004765 RValue<UInt2> operator>>=(UInt2 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004766 {
4767 return lhs = lhs >> rhs;
4768 }
4769
John Bauman19bac1e2014-05-06 15:23:49 -04004770// RValue<UInt2> operator+(RValue<UInt2> val)
4771// {
4772// return val;
4773// }
4774
4775// RValue<UInt2> operator-(RValue<UInt2> val)
4776// {
4777// return RValue<UInt2>(Nucleus::createNeg(val.value));
4778// }
4779
4780 RValue<UInt2> operator~(RValue<UInt2> val)
John Bauman89401822014-05-06 15:04:28 -04004781 {
John Bauman19bac1e2014-05-06 15:23:49 -04004782 if(CPUID::supportsMMX2())
4783 {
4784 return val ^ UInt2(0xFFFFFFFF, 0xFFFFFFFF);
4785 }
4786 else
4787 {
4788 return RValue<UInt2>(Nucleus::createNot(val.value));
4789 }
John Bauman89401822014-05-06 15:04:28 -04004790 }
4791
John Bauman19bac1e2014-05-06 15:23:49 -04004792 Type *UInt2::getType()
John Bauman89401822014-05-06 15:04:28 -04004793 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04004794 return T(Type_v2i32);
John Bauman89401822014-05-06 15:04:28 -04004795 }
4796
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004797 Int4::Int4(RValue<Byte4> cast)
4798 {
4799 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04004800 Value *a = Nucleus::createInsertElement(V(llvm::UndefValue::get(T(Int4::getType()))), x, 0);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004801
4802 Value *e;
4803
4804 if (CPUID::supportsSSE4_1())
4805 {
4806 e = x86::pmovzxbd(RValue<Int4>(a)).value;
4807 }
4808 else
4809 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004810 int swizzle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23};
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004811 Value *b = Nucleus::createBitCast(a, Byte16::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04004812 Value *c = Nucleus::createShuffleVector(b, V(Nucleus::createNullValue(Byte16::getType())), swizzle);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004813
Nicolas Capense89cd582016-09-30 14:23:47 -04004814 int swizzle2[8] = {0, 8, 1, 9, 2, 10, 3, 11};
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004815 Value *d = Nucleus::createBitCast(c, Short8::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04004816 e = Nucleus::createShuffleVector(d, V(Nucleus::createNullValue(Short8::getType())), swizzle2);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004817 }
4818
4819 Value *f = Nucleus::createBitCast(e, Int4::getType());
4820 storeValue(f);
4821 }
4822
4823 Int4::Int4(RValue<SByte4> cast)
4824 {
4825 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04004826 Value *a = Nucleus::createInsertElement(V(llvm::UndefValue::get(T(Int4::getType()))), x, 0);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004827
4828 Value *g;
4829
4830 if (CPUID::supportsSSE4_1())
4831 {
4832 g = x86::pmovsxbd(RValue<Int4>(a)).value;
4833 }
4834 else
4835 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004836 int swizzle[16] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7};
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004837 Value *b = Nucleus::createBitCast(a, Byte16::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04004838 Value *c = Nucleus::createShuffleVector(b, b, swizzle);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004839
Nicolas Capense89cd582016-09-30 14:23:47 -04004840 int swizzle2[8] = {0, 0, 1, 1, 2, 2, 3, 3};
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004841 Value *d = Nucleus::createBitCast(c, Short8::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04004842 Value *e = Nucleus::createShuffleVector(d, d, swizzle2);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004843
4844 Value *f = Nucleus::createBitCast(e, Int4::getType());
4845 // g = Nucleus::createAShr(f, Nucleus::createConstantInt(24));
4846 g = x86::psrad(RValue<Int4>(f), 24).value;
4847 }
4848
4849 storeValue(g);
4850 }
4851
John Bauman19bac1e2014-05-06 15:23:49 -04004852 Int4::Int4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04004853 {
John Bauman89401822014-05-06 15:04:28 -04004854 Value *xyzw = Nucleus::createFPToSI(cast.value, Int4::getType());
John Bauman89401822014-05-06 15:04:28 -04004855
John Bauman66b8ab22014-05-06 15:57:45 -04004856 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04004857 }
4858
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004859 Int4::Int4(RValue<Short4> cast)
4860 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04004861 Value *long2 = V(llvm::UndefValue::get(llvm::VectorType::get(T(Long::getType()), 2)));
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004862 Value *element = Nucleus::createBitCast(cast.value, Long::getType());
4863 long2 = Nucleus::createInsertElement(long2, element, 0);
4864 RValue<Int4> vector = RValue<Int4>(Nucleus::createBitCast(long2, Int4::getType()));
Nicolas Capens05b3d662016-02-25 23:58:33 -05004865
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004866 if(CPUID::supportsSSE4_1())
4867 {
4868 storeValue(x86::pmovsxwd(vector).value);
4869 }
4870 else
4871 {
4872 Value *b = Nucleus::createBitCast(vector.value, Short8::getType());
4873
Nicolas Capense89cd582016-09-30 14:23:47 -04004874 int swizzle[8] = {0, 0, 1, 1, 2, 2, 3, 3};
4875 Value *c = Nucleus::createShuffleVector(b, b, swizzle);
Nicolas Capens6ce5c332015-10-28 01:58:18 -04004876 Value *d = Nucleus::createBitCast(c, Int4::getType());
4877 storeValue(d);
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004878
4879 // Each Short is packed into each Int in the (Short | Short) format.
4880 // Shifting by 16 will retrieve the original Short value.
Nicolas Capensf549e3b2017-01-24 08:53:47 -08004881 // Shifting an Int will propagate the sign bit, which will work
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004882 // for both positive and negative values of a Short.
4883 *this >>= 16;
4884 }
4885 }
4886
4887 Int4::Int4(RValue<UShort4> cast)
4888 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04004889 Value *long2 = V(llvm::UndefValue::get(llvm::VectorType::get(T(Long::getType()), 2)));
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004890 Value *element = Nucleus::createBitCast(cast.value, Long::getType());
4891 long2 = Nucleus::createInsertElement(long2, element, 0);
4892 RValue<Int4> vector = RValue<Int4>(Nucleus::createBitCast(long2, Int4::getType()));
4893
4894 if(CPUID::supportsSSE4_1())
4895 {
4896 storeValue(x86::pmovzxwd(RValue<Int4>(vector)).value);
4897 }
4898 else
4899 {
4900 Value *b = Nucleus::createBitCast(vector.value, Short8::getType());
4901
Nicolas Capense89cd582016-09-30 14:23:47 -04004902 int swizzle[8] = {0, 8, 1, 9, 2, 10, 3, 11};
4903 Value *c = Nucleus::createShuffleVector(b, V(Nucleus::createNullValue(Short8::getType())), swizzle);
Nicolas Capens6ce5c332015-10-28 01:58:18 -04004904 Value *d = Nucleus::createBitCast(c, Int4::getType());
4905 storeValue(d);
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004906 }
4907 }
4908
John Bauman89401822014-05-06 15:04:28 -04004909 Int4::Int4(int xyzw)
4910 {
4911 constant(xyzw, xyzw, xyzw, xyzw);
4912 }
4913
4914 Int4::Int4(int x, int yzw)
4915 {
4916 constant(x, yzw, yzw, yzw);
4917 }
4918
4919 Int4::Int4(int x, int y, int zw)
4920 {
4921 constant(x, y, zw, zw);
4922 }
4923
4924 Int4::Int4(int x, int y, int z, int w)
4925 {
4926 constant(x, y, z, w);
4927 }
4928
4929 void Int4::constant(int x, int y, int z, int w)
4930 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04004931 int64_t constantVector[4] = {x, y, z, w};
4932 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04004933 }
4934
John Bauman19bac1e2014-05-06 15:23:49 -04004935 Int4::Int4(RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04004936 {
John Bauman66b8ab22014-05-06 15:57:45 -04004937 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004938 }
4939
4940 Int4::Int4(const Int4 &rhs)
4941 {
John Bauman66b8ab22014-05-06 15:57:45 -04004942 Value *value = rhs.loadValue();
4943 storeValue(value);
4944 }
4945
4946 Int4::Int4(const Reference<Int4> &rhs)
4947 {
John Bauman66b8ab22014-05-06 15:57:45 -04004948 Value *value = rhs.loadValue();
4949 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004950 }
4951
John Bauman19bac1e2014-05-06 15:23:49 -04004952 Int4::Int4(RValue<UInt4> rhs)
4953 {
John Bauman66b8ab22014-05-06 15:57:45 -04004954 storeValue(rhs.value);
John Bauman19bac1e2014-05-06 15:23:49 -04004955 }
4956
4957 Int4::Int4(const UInt4 &rhs)
4958 {
John Bauman66b8ab22014-05-06 15:57:45 -04004959 Value *value = rhs.loadValue();
4960 storeValue(value);
4961 }
4962
4963 Int4::Int4(const Reference<UInt4> &rhs)
4964 {
John Bauman66b8ab22014-05-06 15:57:45 -04004965 Value *value = rhs.loadValue();
4966 storeValue(value);
John Bauman19bac1e2014-05-06 15:23:49 -04004967 }
4968
Nicolas Capens62abb552016-01-05 12:03:47 -05004969 Int4::Int4(RValue<Int2> lo, RValue<Int2> hi)
4970 {
4971 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
4972 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
4973
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04004974 Value *long2 = V(llvm::UndefValue::get(llvm::VectorType::get(T(Long::getType()), 2)));
Nicolas Capens62abb552016-01-05 12:03:47 -05004975 long2 = Nucleus::createInsertElement(long2, loLong, 0);
4976 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
4977 Value *int4 = Nucleus::createBitCast(long2, Int4::getType());
4978
4979 storeValue(int4);
4980 }
4981
Nicolas Capens24c8cf02016-08-15 15:33:14 -04004982 Int4::Int4(RValue<Int> rhs)
4983 {
Nicolas Capens24c8cf02016-08-15 15:33:14 -04004984 Value *vector = loadValue();
4985 Value *insert = Nucleus::createInsertElement(vector, rhs.value, 0);
4986
Nicolas Capense89cd582016-09-30 14:23:47 -04004987 int swizzle[4] = {0, 0, 0, 0};
4988 Value *replicate = Nucleus::createShuffleVector(insert, insert, swizzle);
Nicolas Capens24c8cf02016-08-15 15:33:14 -04004989
4990 storeValue(replicate);
4991 }
4992
4993 Int4::Int4(const Int &rhs)
4994 {
Nicolas Capens24c8cf02016-08-15 15:33:14 -04004995 *this = RValue<Int>(rhs.loadValue());
4996 }
4997
4998 Int4::Int4(const Reference<Int> &rhs)
4999 {
Nicolas Capens24c8cf02016-08-15 15:33:14 -04005000 *this = RValue<Int>(rhs.loadValue());
5001 }
5002
Nicolas Capens96d4e092016-11-18 14:22:38 -05005003 RValue<Int4> Int4::operator=(RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005004 {
John Bauman66b8ab22014-05-06 15:57:45 -04005005 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005006
5007 return rhs;
5008 }
5009
Nicolas Capens96d4e092016-11-18 14:22:38 -05005010 RValue<Int4> Int4::operator=(const Int4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04005011 {
John Bauman66b8ab22014-05-06 15:57:45 -04005012 Value *value = rhs.loadValue();
5013 storeValue(value);
5014
5015 return RValue<Int4>(value);
5016 }
5017
Nicolas Capens96d4e092016-11-18 14:22:38 -05005018 RValue<Int4> Int4::operator=(const Reference<Int4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04005019 {
5020 Value *value = rhs.loadValue();
5021 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005022
5023 return RValue<Int4>(value);
5024 }
5025
John Bauman19bac1e2014-05-06 15:23:49 -04005026 RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005027 {
5028 return RValue<Int4>(Nucleus::createAdd(lhs.value, rhs.value));
5029 }
5030
John Bauman19bac1e2014-05-06 15:23:49 -04005031 RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005032 {
5033 return RValue<Int4>(Nucleus::createSub(lhs.value, rhs.value));
5034 }
5035
John Bauman19bac1e2014-05-06 15:23:49 -04005036 RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005037 {
5038 return RValue<Int4>(Nucleus::createMul(lhs.value, rhs.value));
5039 }
5040
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005041 RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs)
5042 {
5043 return RValue<Int4>(Nucleus::createSDiv(lhs.value, rhs.value));
5044 }
John Bauman89401822014-05-06 15:04:28 -04005045
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005046 RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs)
5047 {
5048 return RValue<Int4>(Nucleus::createSRem(lhs.value, rhs.value));
5049 }
John Bauman89401822014-05-06 15:04:28 -04005050
John Bauman19bac1e2014-05-06 15:23:49 -04005051 RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005052 {
5053 return RValue<Int4>(Nucleus::createAnd(lhs.value, rhs.value));
5054 }
5055
John Bauman19bac1e2014-05-06 15:23:49 -04005056 RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005057 {
5058 return RValue<Int4>(Nucleus::createOr(lhs.value, rhs.value));
5059 }
5060
John Bauman19bac1e2014-05-06 15:23:49 -04005061 RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005062 {
5063 return RValue<Int4>(Nucleus::createXor(lhs.value, rhs.value));
5064 }
5065
John Bauman19bac1e2014-05-06 15:23:49 -04005066 RValue<Int4> operator<<(RValue<Int4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005067 {
John Bauman89401822014-05-06 15:04:28 -04005068 return x86::pslld(lhs, rhs);
5069 }
5070
John Bauman19bac1e2014-05-06 15:23:49 -04005071 RValue<Int4> operator>>(RValue<Int4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005072 {
John Bauman89401822014-05-06 15:04:28 -04005073 return x86::psrad(lhs, rhs);
5074 }
5075
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005076 RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs)
5077 {
5078 return RValue<Int4>(Nucleus::createShl(lhs.value, rhs.value));
5079 }
5080
5081 RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs)
5082 {
5083 return RValue<Int4>(Nucleus::createAShr(lhs.value, rhs.value));
5084 }
5085
Nicolas Capens96d4e092016-11-18 14:22:38 -05005086 RValue<Int4> operator+=(Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005087 {
5088 return lhs = lhs + rhs;
5089 }
5090
Nicolas Capens96d4e092016-11-18 14:22:38 -05005091 RValue<Int4> operator-=(Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005092 {
5093 return lhs = lhs - rhs;
5094 }
5095
Nicolas Capens96d4e092016-11-18 14:22:38 -05005096 RValue<Int4> operator*=(Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005097 {
5098 return lhs = lhs * rhs;
5099 }
5100
Nicolas Capens96d4e092016-11-18 14:22:38 -05005101// RValue<Int4> operator/=(Int4 &lhs, RValue<Int4> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04005102// {
5103// return lhs = lhs / rhs;
5104// }
John Bauman89401822014-05-06 15:04:28 -04005105
Nicolas Capens96d4e092016-11-18 14:22:38 -05005106// RValue<Int4> operator%=(Int4 &lhs, RValue<Int4> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04005107// {
5108// return lhs = lhs % rhs;
5109// }
John Bauman89401822014-05-06 15:04:28 -04005110
Nicolas Capens96d4e092016-11-18 14:22:38 -05005111 RValue<Int4> operator&=(Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005112 {
5113 return lhs = lhs & rhs;
5114 }
5115
Nicolas Capens96d4e092016-11-18 14:22:38 -05005116 RValue<Int4> operator|=(Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005117 {
5118 return lhs = lhs | rhs;
5119 }
5120
Nicolas Capens96d4e092016-11-18 14:22:38 -05005121 RValue<Int4> operator^=(Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005122 {
5123 return lhs = lhs ^ rhs;
5124 }
5125
Nicolas Capens96d4e092016-11-18 14:22:38 -05005126 RValue<Int4> operator<<=(Int4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005127 {
5128 return lhs = lhs << rhs;
5129 }
5130
Nicolas Capens96d4e092016-11-18 14:22:38 -05005131 RValue<Int4> operator>>=(Int4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005132 {
5133 return lhs = lhs >> rhs;
5134 }
5135
John Bauman19bac1e2014-05-06 15:23:49 -04005136 RValue<Int4> operator+(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005137 {
5138 return val;
5139 }
5140
John Bauman19bac1e2014-05-06 15:23:49 -04005141 RValue<Int4> operator-(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005142 {
5143 return RValue<Int4>(Nucleus::createNeg(val.value));
5144 }
5145
John Bauman19bac1e2014-05-06 15:23:49 -04005146 RValue<Int4> operator~(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005147 {
5148 return RValue<Int4>(Nucleus::createNot(val.value));
5149 }
5150
John Bauman19bac1e2014-05-06 15:23:49 -04005151 RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y)
5152 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005153 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
Alexis Hetufb603992016-04-26 11:50:40 -04005154 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5155 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
5156 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005157 }
5158
5159 RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y)
5160 {
5161 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLT(x.value, y.value), Int4::getType()));
5162 }
5163
5164 RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y)
5165 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005166 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5167 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5168 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLE(x.value, y.value), Int4::getType()));
5169 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGT(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005170 }
5171
5172 RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y)
5173 {
5174 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
5175 }
5176
5177 RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y)
5178 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005179 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5180 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5181 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGE(x.value, y.value), Int4::getType()));
5182 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLT(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005183 }
5184
5185 RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y)
5186 {
5187 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGT(x.value, y.value), Int4::getType()));
5188 }
5189
5190 RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y)
5191 {
5192 if(CPUID::supportsSSE4_1())
5193 {
5194 return x86::pmaxsd(x, y);
5195 }
5196 else
5197 {
5198 RValue<Int4> greater = CmpNLE(x, y);
Tom Anderson69bc6e82017-03-20 11:54:29 -07005199 return (x & greater) | (y & ~greater);
John Bauman19bac1e2014-05-06 15:23:49 -04005200 }
5201 }
5202
5203 RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y)
5204 {
5205 if(CPUID::supportsSSE4_1())
5206 {
5207 return x86::pminsd(x, y);
5208 }
5209 else
5210 {
5211 RValue<Int4> less = CmpLT(x, y);
Tom Anderson69bc6e82017-03-20 11:54:29 -07005212 return (x & less) | (y & ~less);
John Bauman19bac1e2014-05-06 15:23:49 -04005213 }
5214 }
5215
5216 RValue<Int4> RoundInt(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005217 {
5218 return x86::cvtps2dq(cast);
5219 }
5220
John Bauman19bac1e2014-05-06 15:23:49 -04005221 RValue<Short8> Pack(RValue<Int4> x, RValue<Int4> y)
John Bauman89401822014-05-06 15:04:28 -04005222 {
5223 return x86::packssdw(x, y);
5224 }
5225
John Bauman19bac1e2014-05-06 15:23:49 -04005226 RValue<Int> Extract(RValue<Int4> x, int i)
John Bauman89401822014-05-06 15:04:28 -04005227 {
Nicolas Capense95d5342016-09-30 11:37:28 -04005228 return RValue<Int>(Nucleus::createExtractElement(x.value, Int::getType(), i));
John Bauman89401822014-05-06 15:04:28 -04005229 }
5230
John Bauman19bac1e2014-05-06 15:23:49 -04005231 RValue<Int4> Insert(RValue<Int4> x, RValue<Int> element, int i)
John Bauman89401822014-05-06 15:04:28 -04005232 {
5233 return RValue<Int4>(Nucleus::createInsertElement(x.value, element.value, i));
5234 }
5235
John Bauman19bac1e2014-05-06 15:23:49 -04005236 RValue<Int> SignMask(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04005237 {
5238 return x86::movmskps(As<Float4>(x));
5239 }
5240
John Bauman19bac1e2014-05-06 15:23:49 -04005241 RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04005242 {
Nicolas Capense95d5342016-09-30 11:37:28 -04005243 return RValue<Int4>(createSwizzle4(x.value, select));
John Bauman89401822014-05-06 15:04:28 -04005244 }
5245
John Bauman19bac1e2014-05-06 15:23:49 -04005246 Type *Int4::getType()
John Bauman89401822014-05-06 15:04:28 -04005247 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04005248 return T(llvm::VectorType::get(T(Int::getType()), 4));
John Bauman89401822014-05-06 15:04:28 -04005249 }
5250
John Bauman19bac1e2014-05-06 15:23:49 -04005251 UInt4::UInt4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005252 {
Alexis Hetu764d1422016-09-28 08:44:22 -04005253 // Note: createFPToUI is broken, must perform conversion using createFPtoSI
5254 // Value *xyzw = Nucleus::createFPToUI(cast.value, UInt4::getType());
John Bauman89401822014-05-06 15:04:28 -04005255
Alexis Hetu764d1422016-09-28 08:44:22 -04005256 // Smallest positive value representable in UInt, but not in Int
5257 const unsigned int ustart = 0x80000000u;
5258 const float ustartf = float(ustart);
5259
5260 // Check if the value can be represented as an Int
5261 Int4 uiValue = CmpNLT(cast, Float4(ustartf));
5262 // If the value is too large, subtract ustart and re-add it after conversion.
5263 uiValue = (uiValue & As<Int4>(As<UInt4>(Int4(cast - Float4(ustartf))) + UInt4(ustart))) |
5264 // Otherwise, just convert normally
5265 (~uiValue & Int4(cast));
5266 // If the value is negative, store 0, otherwise store the result of the conversion
5267 storeValue((~(As<Int4>(cast) >> 31) & uiValue).value);
John Bauman89401822014-05-06 15:04:28 -04005268 }
5269
John Bauman19bac1e2014-05-06 15:23:49 -04005270 UInt4::UInt4(int xyzw)
5271 {
5272 constant(xyzw, xyzw, xyzw, xyzw);
5273 }
5274
5275 UInt4::UInt4(int x, int yzw)
5276 {
5277 constant(x, yzw, yzw, yzw);
5278 }
5279
5280 UInt4::UInt4(int x, int y, int zw)
5281 {
5282 constant(x, y, zw, zw);
5283 }
5284
5285 UInt4::UInt4(int x, int y, int z, int w)
5286 {
5287 constant(x, y, z, w);
5288 }
5289
5290 void UInt4::constant(int x, int y, int z, int w)
John Bauman89401822014-05-06 15:04:28 -04005291 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04005292 int64_t constantVector[4] = {x, y, z, w};
5293 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04005294 }
5295
John Bauman19bac1e2014-05-06 15:23:49 -04005296 UInt4::UInt4(RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005297 {
John Bauman66b8ab22014-05-06 15:57:45 -04005298 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005299 }
5300
5301 UInt4::UInt4(const UInt4 &rhs)
5302 {
John Bauman66b8ab22014-05-06 15:57:45 -04005303 Value *value = rhs.loadValue();
5304 storeValue(value);
5305 }
5306
5307 UInt4::UInt4(const Reference<UInt4> &rhs)
5308 {
John Bauman66b8ab22014-05-06 15:57:45 -04005309 Value *value = rhs.loadValue();
5310 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005311 }
5312
John Bauman19bac1e2014-05-06 15:23:49 -04005313 UInt4::UInt4(RValue<Int4> rhs)
5314 {
John Bauman66b8ab22014-05-06 15:57:45 -04005315 storeValue(rhs.value);
John Bauman19bac1e2014-05-06 15:23:49 -04005316 }
5317
5318 UInt4::UInt4(const Int4 &rhs)
5319 {
John Bauman66b8ab22014-05-06 15:57:45 -04005320 Value *value = rhs.loadValue();
5321 storeValue(value);
5322 }
5323
5324 UInt4::UInt4(const Reference<Int4> &rhs)
5325 {
John Bauman66b8ab22014-05-06 15:57:45 -04005326 Value *value = rhs.loadValue();
5327 storeValue(value);
John Bauman19bac1e2014-05-06 15:23:49 -04005328 }
5329
Nicolas Capens62abb552016-01-05 12:03:47 -05005330 UInt4::UInt4(RValue<UInt2> lo, RValue<UInt2> hi)
5331 {
5332 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
5333 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
5334
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04005335 Value *long2 = V(llvm::UndefValue::get(llvm::VectorType::get(T(Long::getType()), 2)));
Nicolas Capens62abb552016-01-05 12:03:47 -05005336 long2 = Nucleus::createInsertElement(long2, loLong, 0);
5337 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
5338 Value *uint4 = Nucleus::createBitCast(long2, Int4::getType());
5339
5340 storeValue(uint4);
5341 }
5342
Nicolas Capens96d4e092016-11-18 14:22:38 -05005343 RValue<UInt4> UInt4::operator=(RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005344 {
John Bauman66b8ab22014-05-06 15:57:45 -04005345 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005346
5347 return rhs;
5348 }
5349
Nicolas Capens96d4e092016-11-18 14:22:38 -05005350 RValue<UInt4> UInt4::operator=(const UInt4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04005351 {
John Bauman66b8ab22014-05-06 15:57:45 -04005352 Value *value = rhs.loadValue();
5353 storeValue(value);
5354
5355 return RValue<UInt4>(value);
5356 }
5357
Nicolas Capens96d4e092016-11-18 14:22:38 -05005358 RValue<UInt4> UInt4::operator=(const Reference<UInt4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04005359 {
5360 Value *value = rhs.loadValue();
5361 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005362
5363 return RValue<UInt4>(value);
5364 }
5365
John Bauman19bac1e2014-05-06 15:23:49 -04005366 RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005367 {
5368 return RValue<UInt4>(Nucleus::createAdd(lhs.value, rhs.value));
5369 }
5370
John Bauman19bac1e2014-05-06 15:23:49 -04005371 RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005372 {
5373 return RValue<UInt4>(Nucleus::createSub(lhs.value, rhs.value));
5374 }
5375
John Bauman19bac1e2014-05-06 15:23:49 -04005376 RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005377 {
5378 return RValue<UInt4>(Nucleus::createMul(lhs.value, rhs.value));
5379 }
5380
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005381 RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs)
5382 {
5383 return RValue<UInt4>(Nucleus::createUDiv(lhs.value, rhs.value));
5384 }
John Bauman89401822014-05-06 15:04:28 -04005385
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005386 RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs)
5387 {
5388 return RValue<UInt4>(Nucleus::createURem(lhs.value, rhs.value));
5389 }
John Bauman89401822014-05-06 15:04:28 -04005390
John Bauman19bac1e2014-05-06 15:23:49 -04005391 RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005392 {
5393 return RValue<UInt4>(Nucleus::createAnd(lhs.value, rhs.value));
5394 }
5395
John Bauman19bac1e2014-05-06 15:23:49 -04005396 RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005397 {
5398 return RValue<UInt4>(Nucleus::createOr(lhs.value, rhs.value));
5399 }
5400
John Bauman19bac1e2014-05-06 15:23:49 -04005401 RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005402 {
5403 return RValue<UInt4>(Nucleus::createXor(lhs.value, rhs.value));
5404 }
5405
John Bauman19bac1e2014-05-06 15:23:49 -04005406 RValue<UInt4> operator<<(RValue<UInt4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005407 {
John Bauman89401822014-05-06 15:04:28 -04005408 return As<UInt4>(x86::pslld(As<Int4>(lhs), rhs));
5409 }
5410
John Bauman19bac1e2014-05-06 15:23:49 -04005411 RValue<UInt4> operator>>(RValue<UInt4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005412 {
John Bauman89401822014-05-06 15:04:28 -04005413 return x86::psrld(lhs, rhs);
5414 }
5415
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005416 RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs)
5417 {
5418 return RValue<UInt4>(Nucleus::createShl(lhs.value, rhs.value));
5419 }
5420
5421 RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs)
5422 {
5423 return RValue<UInt4>(Nucleus::createLShr(lhs.value, rhs.value));
5424 }
5425
Nicolas Capens96d4e092016-11-18 14:22:38 -05005426 RValue<UInt4> operator+=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005427 {
5428 return lhs = lhs + rhs;
5429 }
5430
Nicolas Capens96d4e092016-11-18 14:22:38 -05005431 RValue<UInt4> operator-=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005432 {
5433 return lhs = lhs - rhs;
5434 }
5435
Nicolas Capens96d4e092016-11-18 14:22:38 -05005436 RValue<UInt4> operator*=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005437 {
5438 return lhs = lhs * rhs;
5439 }
5440
Nicolas Capens96d4e092016-11-18 14:22:38 -05005441// RValue<UInt4> operator/=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04005442// {
5443// return lhs = lhs / rhs;
5444// }
John Bauman89401822014-05-06 15:04:28 -04005445
Nicolas Capens96d4e092016-11-18 14:22:38 -05005446// RValue<UInt4> operator%=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04005447// {
5448// return lhs = lhs % rhs;
5449// }
John Bauman89401822014-05-06 15:04:28 -04005450
Nicolas Capens96d4e092016-11-18 14:22:38 -05005451 RValue<UInt4> operator&=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005452 {
5453 return lhs = lhs & rhs;
5454 }
5455
Nicolas Capens96d4e092016-11-18 14:22:38 -05005456 RValue<UInt4> operator|=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005457 {
5458 return lhs = lhs | rhs;
5459 }
5460
Nicolas Capens96d4e092016-11-18 14:22:38 -05005461 RValue<UInt4> operator^=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005462 {
5463 return lhs = lhs ^ rhs;
5464 }
5465
Nicolas Capens96d4e092016-11-18 14:22:38 -05005466 RValue<UInt4> operator<<=(UInt4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005467 {
5468 return lhs = lhs << rhs;
5469 }
5470
Nicolas Capens96d4e092016-11-18 14:22:38 -05005471 RValue<UInt4> operator>>=(UInt4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005472 {
5473 return lhs = lhs >> rhs;
5474 }
5475
John Bauman19bac1e2014-05-06 15:23:49 -04005476 RValue<UInt4> operator+(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04005477 {
5478 return val;
5479 }
5480
John Bauman19bac1e2014-05-06 15:23:49 -04005481 RValue<UInt4> operator-(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04005482 {
5483 return RValue<UInt4>(Nucleus::createNeg(val.value));
5484 }
5485
John Bauman19bac1e2014-05-06 15:23:49 -04005486 RValue<UInt4> operator~(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04005487 {
5488 return RValue<UInt4>(Nucleus::createNot(val.value));
5489 }
5490
John Bauman19bac1e2014-05-06 15:23:49 -04005491 RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y)
5492 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005493 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
Alexis Hetufb603992016-04-26 11:50:40 -04005494 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5495 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
5496 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005497 }
5498
5499 RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y)
5500 {
5501 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULT(x.value, y.value), Int4::getType()));
5502 }
5503
5504 RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y)
5505 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005506 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5507 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5508 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULE(x.value, y.value), Int4::getType()));
5509 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGT(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005510 }
5511
5512 RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y)
5513 {
5514 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
5515 }
5516
5517 RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y)
5518 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005519 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5520 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5521 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGE(x.value, y.value), Int4::getType()));
5522 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULT(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005523 }
5524
5525 RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y)
5526 {
5527 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGT(x.value, y.value), Int4::getType()));
5528 }
5529
5530 RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y)
5531 {
5532 if(CPUID::supportsSSE4_1())
5533 {
5534 return x86::pmaxud(x, y);
5535 }
5536 else
5537 {
5538 RValue<UInt4> greater = CmpNLE(x, y);
Tom Anderson69bc6e82017-03-20 11:54:29 -07005539 return (x & greater) | (y & ~greater);
John Bauman19bac1e2014-05-06 15:23:49 -04005540 }
5541 }
5542
5543 RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y)
5544 {
5545 if(CPUID::supportsSSE4_1())
5546 {
5547 return x86::pminud(x, y);
5548 }
5549 else
5550 {
5551 RValue<UInt4> less = CmpLT(x, y);
Tom Anderson69bc6e82017-03-20 11:54:29 -07005552 return (x & less) | (y & ~less);
John Bauman19bac1e2014-05-06 15:23:49 -04005553 }
5554 }
5555
5556 RValue<UShort8> Pack(RValue<UInt4> x, RValue<UInt4> y)
John Bauman89401822014-05-06 15:04:28 -04005557 {
Nicolas Capens3e7062b2017-01-17 14:01:33 -05005558 return x86::packusdw(As<Int4>(x), As<Int4>(y));
John Bauman89401822014-05-06 15:04:28 -04005559 }
5560
John Bauman19bac1e2014-05-06 15:23:49 -04005561 Type *UInt4::getType()
John Bauman89401822014-05-06 15:04:28 -04005562 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04005563 return T(llvm::VectorType::get(T(UInt::getType()), 4));
John Bauman89401822014-05-06 15:04:28 -04005564 }
5565
John Bauman19bac1e2014-05-06 15:23:49 -04005566 Float::Float(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04005567 {
John Bauman89401822014-05-06 15:04:28 -04005568 Value *integer = Nucleus::createSIToFP(cast.value, Float::getType());
5569
John Bauman66b8ab22014-05-06 15:57:45 -04005570 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04005571 }
5572
Alexis Hetucfd96322017-07-24 14:44:33 -04005573 Float::Float(RValue<UInt> cast)
5574 {
5575 RValue<Float> result = Float(Int(cast & UInt(0x7FFFFFFF))) +
5576 As<Float>((As<Int>(cast) >> 31) & As<Int>(Float(0x80000000u)));
5577
5578 storeValue(result.value);
5579 }
5580
John Bauman89401822014-05-06 15:04:28 -04005581 Float::Float(float x)
5582 {
John Bauman66b8ab22014-05-06 15:57:45 -04005583 storeValue(Nucleus::createConstantFloat(x));
John Bauman89401822014-05-06 15:04:28 -04005584 }
5585
John Bauman19bac1e2014-05-06 15:23:49 -04005586 Float::Float(RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005587 {
John Bauman66b8ab22014-05-06 15:57:45 -04005588 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005589 }
5590
5591 Float::Float(const Float &rhs)
5592 {
John Bauman66b8ab22014-05-06 15:57:45 -04005593 Value *value = rhs.loadValue();
5594 storeValue(value);
5595 }
John Bauman89401822014-05-06 15:04:28 -04005596
John Bauman66b8ab22014-05-06 15:57:45 -04005597 Float::Float(const Reference<Float> &rhs)
5598 {
5599 Value *value = rhs.loadValue();
5600 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005601 }
5602
Nicolas Capens96d4e092016-11-18 14:22:38 -05005603 RValue<Float> Float::operator=(RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005604 {
John Bauman66b8ab22014-05-06 15:57:45 -04005605 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005606
5607 return rhs;
5608 }
5609
Nicolas Capens96d4e092016-11-18 14:22:38 -05005610 RValue<Float> Float::operator=(const Float &rhs)
John Bauman89401822014-05-06 15:04:28 -04005611 {
John Bauman66b8ab22014-05-06 15:57:45 -04005612 Value *value = rhs.loadValue();
5613 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005614
5615 return RValue<Float>(value);
5616 }
5617
Nicolas Capens96d4e092016-11-18 14:22:38 -05005618 RValue<Float> Float::operator=(const Reference<Float> &rhs)
John Bauman89401822014-05-06 15:04:28 -04005619 {
John Bauman66b8ab22014-05-06 15:57:45 -04005620 Value *value = rhs.loadValue();
5621 storeValue(value);
5622
5623 return RValue<Float>(value);
John Bauman89401822014-05-06 15:04:28 -04005624 }
5625
John Bauman19bac1e2014-05-06 15:23:49 -04005626 RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005627 {
5628 return RValue<Float>(Nucleus::createFAdd(lhs.value, rhs.value));
5629 }
5630
John Bauman19bac1e2014-05-06 15:23:49 -04005631 RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005632 {
5633 return RValue<Float>(Nucleus::createFSub(lhs.value, rhs.value));
5634 }
5635
John Bauman19bac1e2014-05-06 15:23:49 -04005636 RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005637 {
5638 return RValue<Float>(Nucleus::createFMul(lhs.value, rhs.value));
5639 }
5640
John Bauman19bac1e2014-05-06 15:23:49 -04005641 RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005642 {
5643 return RValue<Float>(Nucleus::createFDiv(lhs.value, rhs.value));
5644 }
5645
Nicolas Capens96d4e092016-11-18 14:22:38 -05005646 RValue<Float> operator+=(Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005647 {
5648 return lhs = lhs + rhs;
5649 }
5650
Nicolas Capens96d4e092016-11-18 14:22:38 -05005651 RValue<Float> operator-=(Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005652 {
5653 return lhs = lhs - rhs;
5654 }
5655
Nicolas Capens96d4e092016-11-18 14:22:38 -05005656 RValue<Float> operator*=(Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005657 {
5658 return lhs = lhs * rhs;
5659 }
5660
Nicolas Capens96d4e092016-11-18 14:22:38 -05005661 RValue<Float> operator/=(Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005662 {
5663 return lhs = lhs / rhs;
5664 }
5665
John Bauman19bac1e2014-05-06 15:23:49 -04005666 RValue<Float> operator+(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04005667 {
5668 return val;
5669 }
5670
John Bauman19bac1e2014-05-06 15:23:49 -04005671 RValue<Float> operator-(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04005672 {
5673 return RValue<Float>(Nucleus::createFNeg(val.value));
5674 }
5675
John Bauman19bac1e2014-05-06 15:23:49 -04005676 RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005677 {
5678 return RValue<Bool>(Nucleus::createFCmpOLT(lhs.value, rhs.value));
5679 }
5680
John Bauman19bac1e2014-05-06 15:23:49 -04005681 RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005682 {
5683 return RValue<Bool>(Nucleus::createFCmpOLE(lhs.value, rhs.value));
5684 }
5685
John Bauman19bac1e2014-05-06 15:23:49 -04005686 RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005687 {
5688 return RValue<Bool>(Nucleus::createFCmpOGT(lhs.value, rhs.value));
5689 }
5690
John Bauman19bac1e2014-05-06 15:23:49 -04005691 RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005692 {
5693 return RValue<Bool>(Nucleus::createFCmpOGE(lhs.value, rhs.value));
5694 }
5695
John Bauman19bac1e2014-05-06 15:23:49 -04005696 RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005697 {
5698 return RValue<Bool>(Nucleus::createFCmpONE(lhs.value, rhs.value));
5699 }
5700
John Bauman19bac1e2014-05-06 15:23:49 -04005701 RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005702 {
5703 return RValue<Bool>(Nucleus::createFCmpOEQ(lhs.value, rhs.value));
5704 }
5705
John Bauman19bac1e2014-05-06 15:23:49 -04005706 RValue<Float> Abs(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04005707 {
John Bauman66b8ab22014-05-06 15:57:45 -04005708 return IfThenElse(x > 0.0f, x, -x);
John Bauman89401822014-05-06 15:04:28 -04005709 }
5710
John Bauman19bac1e2014-05-06 15:23:49 -04005711 RValue<Float> Max(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04005712 {
5713 return IfThenElse(x > y, x, y);
5714 }
5715
John Bauman19bac1e2014-05-06 15:23:49 -04005716 RValue<Float> Min(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04005717 {
5718 return IfThenElse(x < y, x, y);
5719 }
5720
Nicolas Capens05b3d662016-02-25 23:58:33 -05005721 RValue<Float> Rcp_pp(RValue<Float> x, bool exactAtPow2)
John Bauman89401822014-05-06 15:04:28 -04005722 {
Nicolas Capens47dc8672017-04-25 12:54:39 -04005723 #if defined(__i386__) || defined(__x86_64__)
5724 if(exactAtPow2)
5725 {
5726 // rcpss uses a piecewise-linear approximation which minimizes the relative error
5727 // but is not exact at power-of-two values. Rectify by multiplying by the inverse.
5728 return x86::rcpss(x) * Float(1.0f / _mm_cvtss_f32(_mm_rcp_ss(_mm_set_ps1(1.0f))));
5729 }
5730 #endif
5731
5732 return x86::rcpss(x);
John Bauman89401822014-05-06 15:04:28 -04005733 }
John Bauman66b8ab22014-05-06 15:57:45 -04005734
John Bauman19bac1e2014-05-06 15:23:49 -04005735 RValue<Float> RcpSqrt_pp(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04005736 {
5737 return x86::rsqrtss(x);
5738 }
5739
John Bauman19bac1e2014-05-06 15:23:49 -04005740 RValue<Float> Sqrt(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04005741 {
5742 return x86::sqrtss(x);
5743 }
5744
John Bauman19bac1e2014-05-06 15:23:49 -04005745 RValue<Float> Round(RValue<Float> x)
5746 {
5747 if(CPUID::supportsSSE4_1())
5748 {
5749 return x86::roundss(x, 0);
5750 }
5751 else
5752 {
5753 return Float4(Round(Float4(x))).x;
5754 }
5755 }
5756
5757 RValue<Float> Trunc(RValue<Float> x)
5758 {
5759 if(CPUID::supportsSSE4_1())
5760 {
5761 return x86::roundss(x, 3);
5762 }
5763 else
5764 {
5765 return Float(Int(x)); // Rounded toward zero
5766 }
5767 }
5768
5769 RValue<Float> Frac(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04005770 {
5771 if(CPUID::supportsSSE4_1())
5772 {
5773 return x - x86::floorss(x);
5774 }
5775 else
5776 {
John Bauman19bac1e2014-05-06 15:23:49 -04005777 return Float4(Frac(Float4(x))).x;
John Bauman89401822014-05-06 15:04:28 -04005778 }
5779 }
5780
John Bauman19bac1e2014-05-06 15:23:49 -04005781 RValue<Float> Floor(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04005782 {
5783 if(CPUID::supportsSSE4_1())
5784 {
5785 return x86::floorss(x);
5786 }
5787 else
5788 {
5789 return Float4(Floor(Float4(x))).x;
5790 }
5791 }
5792
John Bauman19bac1e2014-05-06 15:23:49 -04005793 RValue<Float> Ceil(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04005794 {
John Bauman19bac1e2014-05-06 15:23:49 -04005795 if(CPUID::supportsSSE4_1())
5796 {
5797 return x86::ceilss(x);
5798 }
5799 else
5800 {
5801 return Float4(Ceil(Float4(x))).x;
5802 }
John Bauman89401822014-05-06 15:04:28 -04005803 }
5804
John Bauman19bac1e2014-05-06 15:23:49 -04005805 Type *Float::getType()
John Bauman89401822014-05-06 15:04:28 -04005806 {
Nicolas Capensac230122016-09-20 14:30:06 -04005807 return T(llvm::Type::getFloatTy(*::context));
John Bauman89401822014-05-06 15:04:28 -04005808 }
5809
John Bauman19bac1e2014-05-06 15:23:49 -04005810 Float2::Float2(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005811 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04005812 Value *int64x2 = Nucleus::createBitCast(cast.value, T(llvm::VectorType::get(T(Long::getType()), 2)));
Nicolas Capense95d5342016-09-30 11:37:28 -04005813 Value *int64 = Nucleus::createExtractElement(int64x2, Long::getType(), 0);
John Bauman89401822014-05-06 15:04:28 -04005814 Value *float2 = Nucleus::createBitCast(int64, Float2::getType());
5815
John Bauman66b8ab22014-05-06 15:57:45 -04005816 storeValue(float2);
John Bauman89401822014-05-06 15:04:28 -04005817 }
5818
John Bauman19bac1e2014-05-06 15:23:49 -04005819 Type *Float2::getType()
John Bauman89401822014-05-06 15:04:28 -04005820 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04005821 return T(Type_v2f32);
John Bauman89401822014-05-06 15:04:28 -04005822 }
5823
Nicolas Capensa25311a2017-01-16 17:19:00 -05005824 Float4::Float4(RValue<Byte4> cast) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005825 {
John Bauman89401822014-05-06 15:04:28 -04005826 #if 0
5827 Value *xyzw = Nucleus::createUIToFP(cast.value, Float4::getType()); // FIXME: Crashes
5828 #elif 0
John Bauman66b8ab22014-05-06 15:57:45 -04005829 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04005830
5831 Value *i8x = Nucleus::createExtractElement(cast.value, 0);
5832 Value *f32x = Nucleus::createUIToFP(i8x, Float::getType());
5833 Value *x = Nucleus::createInsertElement(vector, f32x, 0);
5834
Nicolas Capens19336542016-09-26 10:32:29 -04005835 Value *i8y = Nucleus::createExtractElement(cast.value, V(Nucleus::createConstantInt(1)));
John Bauman89401822014-05-06 15:04:28 -04005836 Value *f32y = Nucleus::createUIToFP(i8y, Float::getType());
Nicolas Capens19336542016-09-26 10:32:29 -04005837 Value *xy = Nucleus::createInsertElement(x, f32y, V(Nucleus::createConstantInt(1)));
John Bauman89401822014-05-06 15:04:28 -04005838
5839 Value *i8z = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(2));
5840 Value *f32z = Nucleus::createUIToFP(i8z, Float::getType());
5841 Value *xyz = Nucleus::createInsertElement(xy, f32z, Nucleus::createConstantInt(2));
5842
5843 Value *i8w = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(3));
5844 Value *f32w = Nucleus::createUIToFP(i8w, Float::getType());
5845 Value *xyzw = Nucleus::createInsertElement(xyz, f32w, Nucleus::createConstantInt(3));
5846 #else
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005847 Value *a = Int4(cast).loadValue();
5848 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04005849 #endif
John Bauman66b8ab22014-05-06 15:57:45 -04005850
5851 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04005852 }
5853
Nicolas Capensa25311a2017-01-16 17:19:00 -05005854 Float4::Float4(RValue<SByte4> cast) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005855 {
John Bauman89401822014-05-06 15:04:28 -04005856 #if 0
5857 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType()); // FIXME: Crashes
5858 #elif 0
John Bauman66b8ab22014-05-06 15:57:45 -04005859 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04005860
5861 Value *i8x = Nucleus::createExtractElement(cast.value, 0);
5862 Value *f32x = Nucleus::createSIToFP(i8x, Float::getType());
5863 Value *x = Nucleus::createInsertElement(vector, f32x, 0);
5864
Nicolas Capens19336542016-09-26 10:32:29 -04005865 Value *i8y = Nucleus::createExtractElement(cast.value, V(Nucleus::createConstantInt(1)));
John Bauman89401822014-05-06 15:04:28 -04005866 Value *f32y = Nucleus::createSIToFP(i8y, Float::getType());
Nicolas Capens19336542016-09-26 10:32:29 -04005867 Value *xy = Nucleus::createInsertElement(x, f32y, V(Nucleus::createConstantInt(1)));
John Bauman89401822014-05-06 15:04:28 -04005868
5869 Value *i8z = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(2));
5870 Value *f32z = Nucleus::createSIToFP(i8z, Float::getType());
5871 Value *xyz = Nucleus::createInsertElement(xy, f32z, Nucleus::createConstantInt(2));
5872
5873 Value *i8w = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(3));
5874 Value *f32w = Nucleus::createSIToFP(i8w, Float::getType());
5875 Value *xyzw = Nucleus::createInsertElement(xyz, f32w, Nucleus::createConstantInt(3));
5876 #else
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005877 Value *a = Int4(cast).loadValue();
5878 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04005879 #endif
John Bauman66b8ab22014-05-06 15:57:45 -04005880
5881 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04005882 }
5883
Nicolas Capensa25311a2017-01-16 17:19:00 -05005884 Float4::Float4(RValue<Short4> cast) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005885 {
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005886 Int4 c(cast);
5887 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
John Bauman89401822014-05-06 15:04:28 -04005888 }
5889
Nicolas Capensa25311a2017-01-16 17:19:00 -05005890 Float4::Float4(RValue<UShort4> cast) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005891 {
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005892 Int4 c(cast);
5893 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
John Bauman89401822014-05-06 15:04:28 -04005894 }
5895
Nicolas Capensa25311a2017-01-16 17:19:00 -05005896 Float4::Float4(RValue<Int4> cast) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005897 {
John Bauman89401822014-05-06 15:04:28 -04005898 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04005899
John Bauman66b8ab22014-05-06 15:57:45 -04005900 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04005901 }
5902
Nicolas Capensa25311a2017-01-16 17:19:00 -05005903 Float4::Float4(RValue<UInt4> cast) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005904 {
Nicolas Capens96445fe2016-12-15 14:45:13 -05005905 RValue<Float4> result = Float4(Int4(cast & UInt4(0x7FFFFFFF))) +
5906 As<Float4>((As<Int4>(cast) >> 31) & As<Int4>(Float4(0x80000000u)));
John Bauman89401822014-05-06 15:04:28 -04005907
Nicolas Capens96445fe2016-12-15 14:45:13 -05005908 storeValue(result.value);
John Bauman89401822014-05-06 15:04:28 -04005909 }
5910
Nicolas Capensa25311a2017-01-16 17:19:00 -05005911 Float4::Float4() : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005912 {
John Bauman89401822014-05-06 15:04:28 -04005913 }
John Bauman66b8ab22014-05-06 15:57:45 -04005914
Nicolas Capensa25311a2017-01-16 17:19:00 -05005915 Float4::Float4(float xyzw) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005916 {
5917 constant(xyzw, xyzw, xyzw, xyzw);
5918 }
5919
Nicolas Capensa25311a2017-01-16 17:19:00 -05005920 Float4::Float4(float x, float yzw) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005921 {
5922 constant(x, yzw, yzw, yzw);
5923 }
5924
Nicolas Capensa25311a2017-01-16 17:19:00 -05005925 Float4::Float4(float x, float y, float zw) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005926 {
5927 constant(x, y, zw, zw);
5928 }
5929
Nicolas Capensa25311a2017-01-16 17:19:00 -05005930 Float4::Float4(float x, float y, float z, float w) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005931 {
5932 constant(x, y, z, w);
5933 }
5934
5935 void Float4::constant(float x, float y, float z, float w)
5936 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04005937 double constantVector[4] = {x, y, z, w};
5938 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04005939 }
5940
Nicolas Capensa25311a2017-01-16 17:19:00 -05005941 Float4::Float4(RValue<Float4> rhs) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005942 {
John Bauman66b8ab22014-05-06 15:57:45 -04005943 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005944 }
5945
Nicolas Capensa25311a2017-01-16 17:19:00 -05005946 Float4::Float4(const Float4 &rhs) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005947 {
John Bauman66b8ab22014-05-06 15:57:45 -04005948 Value *value = rhs.loadValue();
5949 storeValue(value);
5950 }
5951
Nicolas Capensa25311a2017-01-16 17:19:00 -05005952 Float4::Float4(const Reference<Float4> &rhs) : FloatXYZW(this)
John Bauman66b8ab22014-05-06 15:57:45 -04005953 {
John Bauman66b8ab22014-05-06 15:57:45 -04005954 Value *value = rhs.loadValue();
5955 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005956 }
5957
Nicolas Capensa25311a2017-01-16 17:19:00 -05005958 Float4::Float4(RValue<Float> rhs) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005959 {
John Bauman66b8ab22014-05-06 15:57:45 -04005960 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04005961 Value *insert = Nucleus::createInsertElement(vector, rhs.value, 0);
5962
Nicolas Capense89cd582016-09-30 14:23:47 -04005963 int swizzle[4] = {0, 0, 0, 0};
5964 Value *replicate = Nucleus::createShuffleVector(insert, insert, swizzle);
John Bauman89401822014-05-06 15:04:28 -04005965
John Bauman66b8ab22014-05-06 15:57:45 -04005966 storeValue(replicate);
John Bauman89401822014-05-06 15:04:28 -04005967 }
5968
Nicolas Capensa25311a2017-01-16 17:19:00 -05005969 Float4::Float4(const Float &rhs) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005970 {
John Bauman66b8ab22014-05-06 15:57:45 -04005971 *this = RValue<Float>(rhs.loadValue());
5972 }
John Bauman89401822014-05-06 15:04:28 -04005973
Nicolas Capensa25311a2017-01-16 17:19:00 -05005974 Float4::Float4(const Reference<Float> &rhs) : FloatXYZW(this)
John Bauman66b8ab22014-05-06 15:57:45 -04005975 {
John Bauman66b8ab22014-05-06 15:57:45 -04005976 *this = RValue<Float>(rhs.loadValue());
John Bauman89401822014-05-06 15:04:28 -04005977 }
5978
Nicolas Capens96d4e092016-11-18 14:22:38 -05005979 RValue<Float4> Float4::operator=(float x)
John Bauman89401822014-05-06 15:04:28 -04005980 {
5981 return *this = Float4(x, x, x, x);
5982 }
5983
Nicolas Capens96d4e092016-11-18 14:22:38 -05005984 RValue<Float4> Float4::operator=(RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005985 {
John Bauman66b8ab22014-05-06 15:57:45 -04005986 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005987
5988 return rhs;
5989 }
5990
Nicolas Capens96d4e092016-11-18 14:22:38 -05005991 RValue<Float4> Float4::operator=(const Float4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04005992 {
John Bauman66b8ab22014-05-06 15:57:45 -04005993 Value *value = rhs.loadValue();
5994 storeValue(value);
5995
5996 return RValue<Float4>(value);
5997 }
5998
Nicolas Capens96d4e092016-11-18 14:22:38 -05005999 RValue<Float4> Float4::operator=(const Reference<Float4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04006000 {
6001 Value *value = rhs.loadValue();
6002 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04006003
6004 return RValue<Float4>(value);
6005 }
6006
Nicolas Capens96d4e092016-11-18 14:22:38 -05006007 RValue<Float4> Float4::operator=(RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006008 {
6009 return *this = Float4(rhs);
6010 }
6011
Nicolas Capens96d4e092016-11-18 14:22:38 -05006012 RValue<Float4> Float4::operator=(const Float &rhs)
John Bauman89401822014-05-06 15:04:28 -04006013 {
6014 return *this = Float4(rhs);
6015 }
6016
Nicolas Capens96d4e092016-11-18 14:22:38 -05006017 RValue<Float4> Float4::operator=(const Reference<Float> &rhs)
John Bauman89401822014-05-06 15:04:28 -04006018 {
John Bauman66b8ab22014-05-06 15:57:45 -04006019 return *this = Float4(rhs);
John Bauman89401822014-05-06 15:04:28 -04006020 }
6021
John Bauman19bac1e2014-05-06 15:23:49 -04006022 RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006023 {
6024 return RValue<Float4>(Nucleus::createFAdd(lhs.value, rhs.value));
6025 }
6026
John Bauman19bac1e2014-05-06 15:23:49 -04006027 RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006028 {
6029 return RValue<Float4>(Nucleus::createFSub(lhs.value, rhs.value));
6030 }
6031
John Bauman19bac1e2014-05-06 15:23:49 -04006032 RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006033 {
6034 return RValue<Float4>(Nucleus::createFMul(lhs.value, rhs.value));
6035 }
6036
John Bauman19bac1e2014-05-06 15:23:49 -04006037 RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006038 {
6039 return RValue<Float4>(Nucleus::createFDiv(lhs.value, rhs.value));
6040 }
6041
John Bauman19bac1e2014-05-06 15:23:49 -04006042 RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006043 {
6044 return RValue<Float4>(Nucleus::createFRem(lhs.value, rhs.value));
6045 }
6046
Nicolas Capens96d4e092016-11-18 14:22:38 -05006047 RValue<Float4> operator+=(Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006048 {
6049 return lhs = lhs + rhs;
6050 }
6051
Nicolas Capens96d4e092016-11-18 14:22:38 -05006052 RValue<Float4> operator-=(Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006053 {
6054 return lhs = lhs - rhs;
6055 }
6056
Nicolas Capens96d4e092016-11-18 14:22:38 -05006057 RValue<Float4> operator*=(Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006058 {
6059 return lhs = lhs * rhs;
6060 }
6061
Nicolas Capens96d4e092016-11-18 14:22:38 -05006062 RValue<Float4> operator/=(Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006063 {
6064 return lhs = lhs / rhs;
6065 }
6066
Nicolas Capens96d4e092016-11-18 14:22:38 -05006067 RValue<Float4> operator%=(Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006068 {
6069 return lhs = lhs % rhs;
6070 }
6071
John Bauman19bac1e2014-05-06 15:23:49 -04006072 RValue<Float4> operator+(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006073 {
6074 return val;
6075 }
6076
John Bauman19bac1e2014-05-06 15:23:49 -04006077 RValue<Float4> operator-(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006078 {
6079 return RValue<Float4>(Nucleus::createFNeg(val.value));
6080 }
6081
John Bauman19bac1e2014-05-06 15:23:49 -04006082 RValue<Float4> Abs(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006083 {
6084 Value *vector = Nucleus::createBitCast(x.value, Int4::getType());
Nicolas Capens13ac2322016-10-13 14:52:12 -04006085 int64_t constantVector[4] = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF};
6086 Value *result = Nucleus::createAnd(vector, V(Nucleus::createConstantVector(constantVector, Int4::getType())));
John Bauman89401822014-05-06 15:04:28 -04006087
6088 return RValue<Float4>(Nucleus::createBitCast(result, Float4::getType()));
6089 }
6090
John Bauman19bac1e2014-05-06 15:23:49 -04006091 RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006092 {
6093 return x86::maxps(x, y);
6094 }
6095
John Bauman19bac1e2014-05-06 15:23:49 -04006096 RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006097 {
6098 return x86::minps(x, y);
6099 }
6100
Nicolas Capens05b3d662016-02-25 23:58:33 -05006101 RValue<Float4> Rcp_pp(RValue<Float4> x, bool exactAtPow2)
John Bauman89401822014-05-06 15:04:28 -04006102 {
Nicolas Capens47dc8672017-04-25 12:54:39 -04006103 #if defined(__i386__) || defined(__x86_64__)
6104 if(exactAtPow2)
6105 {
6106 // rcpps uses a piecewise-linear approximation which minimizes the relative error
6107 // but is not exact at power-of-two values. Rectify by multiplying by the inverse.
6108 return x86::rcpps(x) * Float4(1.0f / _mm_cvtss_f32(_mm_rcp_ss(_mm_set_ps1(1.0f))));
6109 }
6110 #endif
6111
6112 return x86::rcpps(x);
John Bauman89401822014-05-06 15:04:28 -04006113 }
John Bauman66b8ab22014-05-06 15:57:45 -04006114
John Bauman19bac1e2014-05-06 15:23:49 -04006115 RValue<Float4> RcpSqrt_pp(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006116 {
6117 return x86::rsqrtps(x);
6118 }
6119
John Bauman19bac1e2014-05-06 15:23:49 -04006120 RValue<Float4> Sqrt(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006121 {
6122 return x86::sqrtps(x);
6123 }
6124
Nicolas Capensc94ab742016-11-08 15:15:31 -05006125 RValue<Float4> Insert(RValue<Float4> val, RValue<Float> element, int i)
John Bauman89401822014-05-06 15:04:28 -04006126 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05006127 return RValue<Float4>(Nucleus::createInsertElement(val.value, element.value, i));
John Bauman89401822014-05-06 15:04:28 -04006128 }
6129
John Bauman19bac1e2014-05-06 15:23:49 -04006130 RValue<Float> Extract(RValue<Float4> x, int i)
John Bauman89401822014-05-06 15:04:28 -04006131 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006132 return RValue<Float>(Nucleus::createExtractElement(x.value, Float::getType(), i));
John Bauman89401822014-05-06 15:04:28 -04006133 }
6134
John Bauman19bac1e2014-05-06 15:23:49 -04006135 RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04006136 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006137 return RValue<Float4>(createSwizzle4(x.value, select));
John Bauman89401822014-05-06 15:04:28 -04006138 }
6139
John Bauman19bac1e2014-05-06 15:23:49 -04006140 RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006141 {
Nicolas Capense89cd582016-09-30 14:23:47 -04006142 int shuffle[4] =
6143 {
6144 ((imm >> 0) & 0x03) + 0,
6145 ((imm >> 2) & 0x03) + 0,
6146 ((imm >> 4) & 0x03) + 4,
6147 ((imm >> 6) & 0x03) + 4,
6148 };
John Bauman89401822014-05-06 15:04:28 -04006149
Nicolas Capense89cd582016-09-30 14:23:47 -04006150 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
John Bauman89401822014-05-06 15:04:28 -04006151 }
6152
John Bauman19bac1e2014-05-06 15:23:49 -04006153 RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006154 {
Nicolas Capense89cd582016-09-30 14:23:47 -04006155 int shuffle[4] = {0, 4, 1, 5};
6156 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
John Bauman89401822014-05-06 15:04:28 -04006157 }
6158
John Bauman19bac1e2014-05-06 15:23:49 -04006159 RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006160 {
Nicolas Capense89cd582016-09-30 14:23:47 -04006161 int shuffle[4] = {2, 6, 3, 7};
6162 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
John Bauman89401822014-05-06 15:04:28 -04006163 }
John Bauman66b8ab22014-05-06 15:57:45 -04006164
John Bauman19bac1e2014-05-06 15:23:49 -04006165 RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04006166 {
John Bauman66b8ab22014-05-06 15:57:45 -04006167 Value *vector = lhs.loadValue();
Nicolas Capense95d5342016-09-30 11:37:28 -04006168 Value *shuffle = createMask4(vector, rhs.value, select);
John Bauman66b8ab22014-05-06 15:57:45 -04006169 lhs.storeValue(shuffle);
John Bauman89401822014-05-06 15:04:28 -04006170
6171 return RValue<Float4>(shuffle);
6172 }
6173
John Bauman19bac1e2014-05-06 15:23:49 -04006174 RValue<Int> SignMask(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006175 {
6176 return x86::movmskps(x);
6177 }
6178
John Bauman19bac1e2014-05-06 15:23:49 -04006179 RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006180 {
6181 // return As<Int4>(x86::cmpeqps(x, y));
6182 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOEQ(x.value, y.value), Int4::getType()));
6183 }
6184
John Bauman19bac1e2014-05-06 15:23:49 -04006185 RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006186 {
6187 // return As<Int4>(x86::cmpltps(x, y));
6188 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOLT(x.value, y.value), Int4::getType()));
6189 }
6190
John Bauman19bac1e2014-05-06 15:23:49 -04006191 RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006192 {
6193 // return As<Int4>(x86::cmpleps(x, y));
6194 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOLE(x.value, y.value), Int4::getType()));
6195 }
6196
John Bauman19bac1e2014-05-06 15:23:49 -04006197 RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006198 {
6199 // return As<Int4>(x86::cmpneqps(x, y));
6200 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpONE(x.value, y.value), Int4::getType()));
6201 }
6202
John Bauman19bac1e2014-05-06 15:23:49 -04006203 RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006204 {
6205 // return As<Int4>(x86::cmpnltps(x, y));
6206 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOGE(x.value, y.value), Int4::getType()));
6207 }
6208
John Bauman19bac1e2014-05-06 15:23:49 -04006209 RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006210 {
6211 // return As<Int4>(x86::cmpnleps(x, y));
6212 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOGT(x.value, y.value), Int4::getType()));
6213 }
6214
John Bauman19bac1e2014-05-06 15:23:49 -04006215 RValue<Float4> Round(RValue<Float4> x)
6216 {
6217 if(CPUID::supportsSSE4_1())
6218 {
6219 return x86::roundps(x, 0);
6220 }
6221 else
6222 {
6223 return Float4(RoundInt(x));
6224 }
6225 }
6226
6227 RValue<Float4> Trunc(RValue<Float4> x)
6228 {
6229 if(CPUID::supportsSSE4_1())
6230 {
6231 return x86::roundps(x, 3);
6232 }
6233 else
6234 {
6235 return Float4(Int4(x)); // Rounded toward zero
6236 }
6237 }
6238
6239 RValue<Float4> Frac(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006240 {
Nicolas Capensb9230422017-07-17 10:27:33 -04006241 Float4 frc;
6242
John Bauman89401822014-05-06 15:04:28 -04006243 if(CPUID::supportsSSE4_1())
6244 {
Nicolas Capensb9230422017-07-17 10:27:33 -04006245 frc = x - x86::floorps(x);
John Bauman89401822014-05-06 15:04:28 -04006246 }
6247 else
6248 {
Nicolas Capensb9230422017-07-17 10:27:33 -04006249 frc = x - Float4(Int4(x)); // Signed fractional part.
John Bauman89401822014-05-06 15:04:28 -04006250
Nicolas Capensb9230422017-07-17 10:27:33 -04006251 frc += As<Float4>(As<Int4>(CmpNLE(Float4(0.0f), frc)) & As<Int4>(Float4(1.0f))); // Add 1.0 if negative.
John Bauman89401822014-05-06 15:04:28 -04006252 }
Nicolas Capensb9230422017-07-17 10:27:33 -04006253
6254 // x - floor(x) can be 1.0 for very small negative x.
6255 // Clamp against the value just below 1.0.
6256 return Min(frc, As<Float4>(Int4(0x3F7FFFFF)));
John Bauman89401822014-05-06 15:04:28 -04006257 }
6258
John Bauman19bac1e2014-05-06 15:23:49 -04006259 RValue<Float4> Floor(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006260 {
6261 if(CPUID::supportsSSE4_1())
6262 {
6263 return x86::floorps(x);
6264 }
6265 else
6266 {
John Bauman19bac1e2014-05-06 15:23:49 -04006267 return x - Frac(x);
John Bauman89401822014-05-06 15:04:28 -04006268 }
6269 }
6270
John Bauman19bac1e2014-05-06 15:23:49 -04006271 RValue<Float4> Ceil(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006272 {
John Bauman19bac1e2014-05-06 15:23:49 -04006273 if(CPUID::supportsSSE4_1())
6274 {
6275 return x86::ceilps(x);
6276 }
6277 else
6278 {
6279 return -Floor(-x);
6280 }
John Bauman89401822014-05-06 15:04:28 -04006281 }
6282
John Bauman19bac1e2014-05-06 15:23:49 -04006283 Type *Float4::getType()
John Bauman89401822014-05-06 15:04:28 -04006284 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006285 return T(llvm::VectorType::get(T(Float::getType()), 4));
John Bauman89401822014-05-06 15:04:28 -04006286 }
6287
Nicolas Capens81f18302016-01-14 09:32:35 -05006288 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006289 {
Nicolas Capensd294def2017-01-26 17:44:37 -08006290 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), V(Nucleus::createConstantInt(offset)), false));
John Bauman89401822014-05-06 15:04:28 -04006291 }
6292
Nicolas Capens81f18302016-01-14 09:32:35 -05006293 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006294 {
Nicolas Capensd294def2017-01-26 17:44:37 -08006295 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value, false));
John Bauman89401822014-05-06 15:04:28 -04006296 }
6297
Nicolas Capens81f18302016-01-14 09:32:35 -05006298 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006299 {
Nicolas Capensd294def2017-01-26 17:44:37 -08006300 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value, true));
John Bauman89401822014-05-06 15:04:28 -04006301 }
6302
Nicolas Capens96d4e092016-11-18 14:22:38 -05006303 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006304 {
6305 return lhs = lhs + offset;
6306 }
6307
Nicolas Capens96d4e092016-11-18 14:22:38 -05006308 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006309 {
6310 return lhs = lhs + offset;
6311 }
6312
Nicolas Capens96d4e092016-11-18 14:22:38 -05006313 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006314 {
6315 return lhs = lhs + offset;
6316 }
6317
Nicolas Capens81f18302016-01-14 09:32:35 -05006318 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006319 {
6320 return lhs + -offset;
6321 }
6322
Nicolas Capens81f18302016-01-14 09:32:35 -05006323 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006324 {
6325 return lhs + -offset;
6326 }
6327
Nicolas Capens81f18302016-01-14 09:32:35 -05006328 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006329 {
6330 return lhs + -offset;
6331 }
6332
Nicolas Capens96d4e092016-11-18 14:22:38 -05006333 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006334 {
6335 return lhs = lhs - offset;
6336 }
6337
Nicolas Capens96d4e092016-11-18 14:22:38 -05006338 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006339 {
6340 return lhs = lhs - offset;
6341 }
6342
Nicolas Capens96d4e092016-11-18 14:22:38 -05006343 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006344 {
6345 return lhs = lhs - offset;
6346 }
6347
6348 void Return()
6349 {
John Bauman89401822014-05-06 15:04:28 -04006350 Nucleus::createRetVoid();
6351 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
John Bauman19bac1e2014-05-06 15:23:49 -04006352 Nucleus::createUnreachable();
6353 }
6354
Nicolas Capenseb253d02016-11-18 14:40:40 -05006355 void Return(RValue<Int> ret)
John Bauman19bac1e2014-05-06 15:23:49 -04006356 {
Nicolas Capenseb253d02016-11-18 14:40:40 -05006357 Nucleus::createRet(ret.value);
John Bauman89401822014-05-06 15:04:28 -04006358 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
John Bauman19bac1e2014-05-06 15:23:49 -04006359 Nucleus::createUnreachable();
John Bauman89401822014-05-06 15:04:28 -04006360 }
6361
Nicolas Capensf4eec2f2017-05-24 15:46:48 -04006362 void branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB)
John Bauman89401822014-05-06 15:04:28 -04006363 {
6364 Nucleus::createCondBr(cmp.value, bodyBB, endBB);
John Bauman66b8ab22014-05-06 15:57:45 -04006365 Nucleus::setInsertBlock(bodyBB);
John Bauman89401822014-05-06 15:04:28 -04006366 }
6367
John Bauman89401822014-05-06 15:04:28 -04006368 RValue<Long> Ticks()
6369 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006370 llvm::Function *rdtsc = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::readcyclecounter);
John Bauman89401822014-05-06 15:04:28 -04006371
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006372 return RValue<Long>(V(::builder->CreateCall(rdtsc)));
John Bauman89401822014-05-06 15:04:28 -04006373 }
John Bauman89401822014-05-06 15:04:28 -04006374}
6375
6376namespace sw
6377{
6378 namespace x86
6379 {
John Bauman19bac1e2014-05-06 15:23:49 -04006380 RValue<Int> cvtss2si(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006381 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006382 llvm::Function *cvtss2si = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse_cvtss2si);
John Bauman66b8ab22014-05-06 15:57:45 -04006383
John Bauman89401822014-05-06 15:04:28 -04006384 Float4 vector;
6385 vector.x = val;
6386
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006387 return RValue<Int>(V(::builder->CreateCall(cvtss2si, RValue<Float4>(vector).value)));
John Bauman89401822014-05-06 15:04:28 -04006388 }
6389
John Bauman19bac1e2014-05-06 15:23:49 -04006390 RValue<Int2> cvtps2pi(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006391 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006392 llvm::Function *cvtps2pi = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse_cvtps2pi);
John Bauman89401822014-05-06 15:04:28 -04006393
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006394 return RValue<Int2>(V(::builder->CreateCall(cvtps2pi, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006395 }
6396
John Bauman19bac1e2014-05-06 15:23:49 -04006397 RValue<Int2> cvttps2pi(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006398 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006399 llvm::Function *cvttps2pi = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse_cvttps2pi);
John Bauman89401822014-05-06 15:04:28 -04006400
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006401 return RValue<Int2>(V(::builder->CreateCall(cvttps2pi, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006402 }
6403
John Bauman19bac1e2014-05-06 15:23:49 -04006404 RValue<Int4> cvtps2dq(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006405 {
6406 if(CPUID::supportsSSE2())
6407 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006408 llvm::Function *cvtps2dq = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse2_cvtps2dq);
John Bauman89401822014-05-06 15:04:28 -04006409
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006410 return RValue<Int4>(V(::builder->CreateCall(cvtps2dq, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006411 }
6412 else
6413 {
6414 Int2 lo = x86::cvtps2pi(val);
6415 Int2 hi = x86::cvtps2pi(Swizzle(val, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04006416
Nicolas Capens62abb552016-01-05 12:03:47 -05006417 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04006418 }
6419 }
6420
John Bauman19bac1e2014-05-06 15:23:49 -04006421 RValue<Float> rcpss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006422 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006423 llvm::Function *rcpss = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse_rcp_ss);
John Bauman89401822014-05-06 15:04:28 -04006424
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006425 Value *vector = Nucleus::createInsertElement(V(llvm::UndefValue::get(T(Float4::getType()))), val.value, 0);
John Bauman66b8ab22014-05-06 15:57:45 -04006426
Nicolas Capense95d5342016-09-30 11:37:28 -04006427 return RValue<Float>(Nucleus::createExtractElement(V(::builder->CreateCall(rcpss, vector)), Float::getType(), 0));
John Bauman89401822014-05-06 15:04:28 -04006428 }
6429
John Bauman19bac1e2014-05-06 15:23:49 -04006430 RValue<Float> sqrtss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006431 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006432 llvm::Function *sqrtss = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse_sqrt_ss);
John Bauman89401822014-05-06 15:04:28 -04006433
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006434 Value *vector = Nucleus::createInsertElement(V(llvm::UndefValue::get(T(Float4::getType()))), val.value, 0);
John Bauman66b8ab22014-05-06 15:57:45 -04006435
Nicolas Capense95d5342016-09-30 11:37:28 -04006436 return RValue<Float>(Nucleus::createExtractElement(V(::builder->CreateCall(sqrtss, vector)), Float::getType(), 0));
John Bauman89401822014-05-06 15:04:28 -04006437 }
6438
John Bauman19bac1e2014-05-06 15:23:49 -04006439 RValue<Float> rsqrtss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006440 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006441 llvm::Function *rsqrtss = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse_rsqrt_ss);
John Bauman66b8ab22014-05-06 15:57:45 -04006442
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006443 Value *vector = Nucleus::createInsertElement(V(llvm::UndefValue::get(T(Float4::getType()))), val.value, 0);
John Bauman89401822014-05-06 15:04:28 -04006444
Nicolas Capense95d5342016-09-30 11:37:28 -04006445 return RValue<Float>(Nucleus::createExtractElement(V(::builder->CreateCall(rsqrtss, vector)), Float::getType(), 0));
John Bauman89401822014-05-06 15:04:28 -04006446 }
6447
John Bauman19bac1e2014-05-06 15:23:49 -04006448 RValue<Float4> rcpps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006449 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006450 llvm::Function *rcpps = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse_rcp_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04006451
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006452 return RValue<Float4>(V(::builder->CreateCall(rcpps, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006453 }
6454
John Bauman19bac1e2014-05-06 15:23:49 -04006455 RValue<Float4> sqrtps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006456 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006457 llvm::Function *sqrtps = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse_sqrt_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04006458
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006459 return RValue<Float4>(V(::builder->CreateCall(sqrtps, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006460 }
6461
John Bauman19bac1e2014-05-06 15:23:49 -04006462 RValue<Float4> rsqrtps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006463 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006464 llvm::Function *rsqrtps = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse_rsqrt_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04006465
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006466 return RValue<Float4>(V(::builder->CreateCall(rsqrtps, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006467 }
6468
John Bauman19bac1e2014-05-06 15:23:49 -04006469 RValue<Float4> maxps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006470 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006471 llvm::Function *maxps = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse_max_ps);
John Bauman89401822014-05-06 15:04:28 -04006472
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006473 return RValue<Float4>(V(::builder->CreateCall2(maxps, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04006474 }
6475
John Bauman19bac1e2014-05-06 15:23:49 -04006476 RValue<Float4> minps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006477 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006478 llvm::Function *minps = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse_min_ps);
John Bauman89401822014-05-06 15:04:28 -04006479
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006480 return RValue<Float4>(V(::builder->CreateCall2(minps, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04006481 }
6482
John Bauman19bac1e2014-05-06 15:23:49 -04006483 RValue<Float> roundss(RValue<Float> val, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006484 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006485 llvm::Function *roundss = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse41_round_ss);
John Bauman89401822014-05-06 15:04:28 -04006486
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006487 Value *undef = V(llvm::UndefValue::get(T(Float4::getType())));
John Bauman89401822014-05-06 15:04:28 -04006488 Value *vector = Nucleus::createInsertElement(undef, val.value, 0);
6489
Nicolas Capense95d5342016-09-30 11:37:28 -04006490 return RValue<Float>(Nucleus::createExtractElement(V(::builder->CreateCall3(roundss, undef, vector, V(Nucleus::createConstantInt(imm)))), Float::getType(), 0));
John Bauman89401822014-05-06 15:04:28 -04006491 }
6492
John Bauman19bac1e2014-05-06 15:23:49 -04006493 RValue<Float> floorss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006494 {
6495 return roundss(val, 1);
6496 }
6497
John Bauman19bac1e2014-05-06 15:23:49 -04006498 RValue<Float> ceilss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006499 {
6500 return roundss(val, 2);
6501 }
6502
John Bauman19bac1e2014-05-06 15:23:49 -04006503 RValue<Float4> roundps(RValue<Float4> val, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006504 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006505 llvm::Function *roundps = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse41_round_ps);
John Bauman89401822014-05-06 15:04:28 -04006506
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006507 return RValue<Float4>(V(::builder->CreateCall2(roundps, val.value, V(Nucleus::createConstantInt(imm)))));
John Bauman89401822014-05-06 15:04:28 -04006508 }
6509
John Bauman19bac1e2014-05-06 15:23:49 -04006510 RValue<Float4> floorps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006511 {
6512 return roundps(val, 1);
6513 }
6514
John Bauman19bac1e2014-05-06 15:23:49 -04006515 RValue<Float4> ceilps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006516 {
6517 return roundps(val, 2);
6518 }
6519
John Bauman19bac1e2014-05-06 15:23:49 -04006520 RValue<Float4> cmpps(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006521 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006522 llvm::Function *cmpps = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse_cmp_ps);
John Bauman89401822014-05-06 15:04:28 -04006523
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006524 return RValue<Float4>(V(::builder->CreateCall3(cmpps, x.value, y.value, V(Nucleus::createConstantByte(imm)))));
John Bauman89401822014-05-06 15:04:28 -04006525 }
6526
John Bauman19bac1e2014-05-06 15:23:49 -04006527 RValue<Float4> cmpeqps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006528 {
6529 return cmpps(x, y, 0);
6530 }
6531
John Bauman19bac1e2014-05-06 15:23:49 -04006532 RValue<Float4> cmpltps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006533 {
6534 return cmpps(x, y, 1);
6535 }
6536
John Bauman19bac1e2014-05-06 15:23:49 -04006537 RValue<Float4> cmpleps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006538 {
6539 return cmpps(x, y, 2);
6540 }
6541
John Bauman19bac1e2014-05-06 15:23:49 -04006542 RValue<Float4> cmpunordps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006543 {
6544 return cmpps(x, y, 3);
6545 }
6546
John Bauman19bac1e2014-05-06 15:23:49 -04006547 RValue<Float4> cmpneqps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006548 {
6549 return cmpps(x, y, 4);
6550 }
6551
John Bauman19bac1e2014-05-06 15:23:49 -04006552 RValue<Float4> cmpnltps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006553 {
6554 return cmpps(x, y, 5);
6555 }
6556
John Bauman19bac1e2014-05-06 15:23:49 -04006557 RValue<Float4> cmpnleps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006558 {
6559 return cmpps(x, y, 6);
6560 }
6561
John Bauman19bac1e2014-05-06 15:23:49 -04006562 RValue<Float4> cmpordps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006563 {
6564 return cmpps(x, y, 7);
6565 }
6566
John Bauman19bac1e2014-05-06 15:23:49 -04006567 RValue<Float> cmpss(RValue<Float> x, RValue<Float> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006568 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006569 llvm::Function *cmpss = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse_cmp_ss);
John Bauman89401822014-05-06 15:04:28 -04006570
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006571 Value *vector1 = Nucleus::createInsertElement(V(llvm::UndefValue::get(T(Float4::getType()))), x.value, 0);
6572 Value *vector2 = Nucleus::createInsertElement(V(llvm::UndefValue::get(T(Float4::getType()))), y.value, 0);
John Bauman89401822014-05-06 15:04:28 -04006573
Nicolas Capense95d5342016-09-30 11:37:28 -04006574 return RValue<Float>(Nucleus::createExtractElement(V(::builder->CreateCall3(cmpss, vector1, vector2, V(Nucleus::createConstantByte(imm)))), Float::getType(), 0));
John Bauman89401822014-05-06 15:04:28 -04006575 }
6576
John Bauman19bac1e2014-05-06 15:23:49 -04006577 RValue<Float> cmpeqss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006578 {
6579 return cmpss(x, y, 0);
6580 }
6581
John Bauman19bac1e2014-05-06 15:23:49 -04006582 RValue<Float> cmpltss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006583 {
6584 return cmpss(x, y, 1);
6585 }
6586
John Bauman19bac1e2014-05-06 15:23:49 -04006587 RValue<Float> cmpless(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006588 {
6589 return cmpss(x, y, 2);
6590 }
6591
John Bauman19bac1e2014-05-06 15:23:49 -04006592 RValue<Float> cmpunordss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006593 {
6594 return cmpss(x, y, 3);
6595 }
6596
John Bauman19bac1e2014-05-06 15:23:49 -04006597 RValue<Float> cmpneqss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006598 {
6599 return cmpss(x, y, 4);
6600 }
6601
John Bauman19bac1e2014-05-06 15:23:49 -04006602 RValue<Float> cmpnltss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006603 {
6604 return cmpss(x, y, 5);
6605 }
6606
John Bauman19bac1e2014-05-06 15:23:49 -04006607 RValue<Float> cmpnless(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006608 {
6609 return cmpss(x, y, 6);
6610 }
6611
John Bauman19bac1e2014-05-06 15:23:49 -04006612 RValue<Float> cmpordss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006613 {
6614 return cmpss(x, y, 7);
6615 }
6616
Alexis Hetu0f448072016-03-18 10:56:08 -04006617 RValue<Int4> pabsd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04006618 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006619 llvm::Function *pabsd = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_ssse3_pabs_d_128);
John Bauman89401822014-05-06 15:04:28 -04006620
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006621 return RValue<Int4>(V(::builder->CreateCall(pabsd, x.value)));
John Bauman89401822014-05-06 15:04:28 -04006622 }
6623
John Bauman19bac1e2014-05-06 15:23:49 -04006624 RValue<Short4> paddsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006625 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006626 llvm::Function *paddsw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_padds_w);
John Bauman89401822014-05-06 15:04:28 -04006627
Nicolas Capens70dfff42016-10-27 10:20:28 -04006628 return As<Short4>(V(::builder->CreateCall2(paddsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006629 }
John Bauman66b8ab22014-05-06 15:57:45 -04006630
John Bauman19bac1e2014-05-06 15:23:49 -04006631 RValue<Short4> psubsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006632 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006633 llvm::Function *psubsw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_psubs_w);
John Bauman89401822014-05-06 15:04:28 -04006634
Nicolas Capens70dfff42016-10-27 10:20:28 -04006635 return As<Short4>(V(::builder->CreateCall2(psubsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006636 }
6637
John Bauman19bac1e2014-05-06 15:23:49 -04006638 RValue<UShort4> paddusw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04006639 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006640 llvm::Function *paddusw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_paddus_w);
John Bauman89401822014-05-06 15:04:28 -04006641
Nicolas Capens70dfff42016-10-27 10:20:28 -04006642 return As<UShort4>(V(::builder->CreateCall2(paddusw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006643 }
John Bauman66b8ab22014-05-06 15:57:45 -04006644
John Bauman19bac1e2014-05-06 15:23:49 -04006645 RValue<UShort4> psubusw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04006646 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006647 llvm::Function *psubusw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_psubus_w);
John Bauman89401822014-05-06 15:04:28 -04006648
Nicolas Capens70dfff42016-10-27 10:20:28 -04006649 return As<UShort4>(V(::builder->CreateCall2(psubusw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006650 }
6651
John Bauman19bac1e2014-05-06 15:23:49 -04006652 RValue<SByte8> paddsb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04006653 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006654 llvm::Function *paddsb = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_padds_b);
John Bauman89401822014-05-06 15:04:28 -04006655
Nicolas Capens70dfff42016-10-27 10:20:28 -04006656 return As<SByte8>(V(::builder->CreateCall2(paddsb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006657 }
John Bauman66b8ab22014-05-06 15:57:45 -04006658
John Bauman19bac1e2014-05-06 15:23:49 -04006659 RValue<SByte8> psubsb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04006660 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006661 llvm::Function *psubsb = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_psubs_b);
John Bauman89401822014-05-06 15:04:28 -04006662
Nicolas Capens70dfff42016-10-27 10:20:28 -04006663 return As<SByte8>(V(::builder->CreateCall2(psubsb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006664 }
John Bauman66b8ab22014-05-06 15:57:45 -04006665
John Bauman19bac1e2014-05-06 15:23:49 -04006666 RValue<Byte8> paddusb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04006667 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006668 llvm::Function *paddusb = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_paddus_b);
John Bauman89401822014-05-06 15:04:28 -04006669
Nicolas Capens70dfff42016-10-27 10:20:28 -04006670 return As<Byte8>(V(::builder->CreateCall2(paddusb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006671 }
John Bauman66b8ab22014-05-06 15:57:45 -04006672
John Bauman19bac1e2014-05-06 15:23:49 -04006673 RValue<Byte8> psubusb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04006674 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006675 llvm::Function *psubusb = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_psubus_b);
John Bauman89401822014-05-06 15:04:28 -04006676
Nicolas Capens70dfff42016-10-27 10:20:28 -04006677 return As<Byte8>(V(::builder->CreateCall2(psubusb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006678 }
6679
John Bauman19bac1e2014-05-06 15:23:49 -04006680 RValue<Short4> paddw(RValue<Short4> x, RValue<Short4> y)
6681 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006682 llvm::Function *paddw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_padd_w);
John Bauman19bac1e2014-05-06 15:23:49 -04006683
Nicolas Capens70dfff42016-10-27 10:20:28 -04006684 return As<Short4>(V(::builder->CreateCall2(paddw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006685 }
6686
6687 RValue<Short4> psubw(RValue<Short4> x, RValue<Short4> y)
6688 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006689 llvm::Function *psubw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_psub_w);
John Bauman19bac1e2014-05-06 15:23:49 -04006690
Nicolas Capens70dfff42016-10-27 10:20:28 -04006691 return As<Short4>(V(::builder->CreateCall2(psubw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006692 }
6693
6694 RValue<Short4> pmullw(RValue<Short4> x, RValue<Short4> y)
6695 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006696 llvm::Function *pmullw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_pmull_w);
John Bauman19bac1e2014-05-06 15:23:49 -04006697
Nicolas Capens70dfff42016-10-27 10:20:28 -04006698 return As<Short4>(V(::builder->CreateCall2(pmullw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006699 }
6700
6701 RValue<Short4> pand(RValue<Short4> x, RValue<Short4> y)
6702 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006703 llvm::Function *pand = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_pand);
John Bauman19bac1e2014-05-06 15:23:49 -04006704
Nicolas Capens70dfff42016-10-27 10:20:28 -04006705 return As<Short4>(V(::builder->CreateCall2(pand, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006706 }
6707
6708 RValue<Short4> por(RValue<Short4> x, RValue<Short4> y)
6709 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006710 llvm::Function *por = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_por);
John Bauman19bac1e2014-05-06 15:23:49 -04006711
Nicolas Capens70dfff42016-10-27 10:20:28 -04006712 return As<Short4>(V(::builder->CreateCall2(por, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006713 }
6714
6715 RValue<Short4> pxor(RValue<Short4> x, RValue<Short4> y)
6716 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006717 llvm::Function *pxor = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_pxor);
John Bauman19bac1e2014-05-06 15:23:49 -04006718
Nicolas Capens70dfff42016-10-27 10:20:28 -04006719 return As<Short4>(V(::builder->CreateCall2(pxor, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006720 }
6721
6722 RValue<Short4> pshufw(RValue<Short4> x, unsigned char y)
6723 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006724 llvm::Function *pshufw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse_pshuf_w);
John Bauman19bac1e2014-05-06 15:23:49 -04006725
Nicolas Capens70dfff42016-10-27 10:20:28 -04006726 return As<Short4>(V(::builder->CreateCall2(pshufw, As<MMX>(x).value, V(Nucleus::createConstantByte(y)))));
John Bauman19bac1e2014-05-06 15:23:49 -04006727 }
6728
6729 RValue<Int2> punpcklwd(RValue<Short4> x, RValue<Short4> y)
6730 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006731 llvm::Function *punpcklwd = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_punpcklwd);
John Bauman19bac1e2014-05-06 15:23:49 -04006732
Nicolas Capens70dfff42016-10-27 10:20:28 -04006733 return As<Int2>(V(::builder->CreateCall2(punpcklwd, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006734 }
6735
6736 RValue<Int2> punpckhwd(RValue<Short4> x, RValue<Short4> y)
6737 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006738 llvm::Function *punpckhwd = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_punpckhwd);
John Bauman19bac1e2014-05-06 15:23:49 -04006739
Nicolas Capens70dfff42016-10-27 10:20:28 -04006740 return As<Int2>(V(::builder->CreateCall2(punpckhwd, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006741 }
6742
6743 RValue<Short4> pinsrw(RValue<Short4> x, RValue<Int> y, unsigned int i)
6744 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006745 llvm::Function *pinsrw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_pinsr_w);
John Bauman19bac1e2014-05-06 15:23:49 -04006746
Nicolas Capens70dfff42016-10-27 10:20:28 -04006747 return As<Short4>(V(::builder->CreateCall3(pinsrw, As<MMX>(x).value, y.value, V(Nucleus::createConstantInt(i)))));
John Bauman19bac1e2014-05-06 15:23:49 -04006748 }
6749
6750 RValue<Int> pextrw(RValue<Short4> x, unsigned int i)
6751 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006752 llvm::Function *pextrw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_pextr_w);
John Bauman19bac1e2014-05-06 15:23:49 -04006753
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006754 return RValue<Int>(V(::builder->CreateCall2(pextrw, As<MMX>(x).value, V(Nucleus::createConstantInt(i)))));
John Bauman19bac1e2014-05-06 15:23:49 -04006755 }
6756
Nicolas Capens45f187a2016-12-02 15:30:56 -05006757 RValue<Short4> punpckldq(RValue<Int2> x, RValue<Int2> y)
John Bauman19bac1e2014-05-06 15:23:49 -04006758 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006759 llvm::Function *punpckldq = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_punpckldq);
John Bauman19bac1e2014-05-06 15:23:49 -04006760
Nicolas Capens45f187a2016-12-02 15:30:56 -05006761 return As<Short4>(V(::builder->CreateCall2(punpckldq, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006762 }
6763
Nicolas Capens45f187a2016-12-02 15:30:56 -05006764 RValue<Short4> punpckhdq(RValue<Int2> x, RValue<Int2> y)
John Bauman19bac1e2014-05-06 15:23:49 -04006765 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006766 llvm::Function *punpckhdq = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_punpckhdq);
John Bauman19bac1e2014-05-06 15:23:49 -04006767
Nicolas Capens45f187a2016-12-02 15:30:56 -05006768 return As<Short4>(V(::builder->CreateCall2(punpckhdq, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006769 }
6770
6771 RValue<Short4> punpcklbw(RValue<Byte8> x, RValue<Byte8> y)
6772 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006773 llvm::Function *punpcklbw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_punpcklbw);
John Bauman19bac1e2014-05-06 15:23:49 -04006774
Nicolas Capens70dfff42016-10-27 10:20:28 -04006775 return As<Short4>(V(::builder->CreateCall2(punpcklbw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006776 }
6777
6778 RValue<Short4> punpckhbw(RValue<Byte8> x, RValue<Byte8> y)
6779 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006780 llvm::Function *punpckhbw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_punpckhbw);
John Bauman19bac1e2014-05-06 15:23:49 -04006781
Nicolas Capens70dfff42016-10-27 10:20:28 -04006782 return As<Short4>(V(::builder->CreateCall2(punpckhbw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006783 }
6784
6785 RValue<Byte8> paddb(RValue<Byte8> x, RValue<Byte8> y)
6786 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006787 llvm::Function *paddb = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_padd_b);
John Bauman19bac1e2014-05-06 15:23:49 -04006788
Nicolas Capens70dfff42016-10-27 10:20:28 -04006789 return As<Byte8>(V(::builder->CreateCall2(paddb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006790 }
6791
6792 RValue<Byte8> psubb(RValue<Byte8> x, RValue<Byte8> y)
6793 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006794 llvm::Function *psubb = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_psub_b);
John Bauman19bac1e2014-05-06 15:23:49 -04006795
Nicolas Capens70dfff42016-10-27 10:20:28 -04006796 return As<Byte8>(V(::builder->CreateCall2(psubb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006797 }
6798
6799 RValue<Int2> paddd(RValue<Int2> x, RValue<Int2> y)
6800 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006801 llvm::Function *paddd = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_padd_d);
John Bauman19bac1e2014-05-06 15:23:49 -04006802
Nicolas Capens70dfff42016-10-27 10:20:28 -04006803 return As<Int2>(V(::builder->CreateCall2(paddd, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006804 }
6805
6806 RValue<Int2> psubd(RValue<Int2> x, RValue<Int2> y)
6807 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006808 llvm::Function *psubd = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_psub_d);
John Bauman19bac1e2014-05-06 15:23:49 -04006809
Nicolas Capens70dfff42016-10-27 10:20:28 -04006810 return As<Int2>(V(::builder->CreateCall2(psubd, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006811 }
6812
6813 RValue<UShort4> pavgw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04006814 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006815 llvm::Function *pavgw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_pavg_w);
John Bauman89401822014-05-06 15:04:28 -04006816
Nicolas Capens70dfff42016-10-27 10:20:28 -04006817 return As<UShort4>(V(::builder->CreateCall2(pavgw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006818 }
6819
John Bauman19bac1e2014-05-06 15:23:49 -04006820 RValue<Short4> pmaxsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006821 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006822 llvm::Function *pmaxsw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_pmaxs_w);
John Bauman89401822014-05-06 15:04:28 -04006823
Nicolas Capens70dfff42016-10-27 10:20:28 -04006824 return As<Short4>(V(::builder->CreateCall2(pmaxsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006825 }
6826
John Bauman19bac1e2014-05-06 15:23:49 -04006827 RValue<Short4> pminsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006828 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006829 llvm::Function *pminsw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_pmins_w);
John Bauman89401822014-05-06 15:04:28 -04006830
Nicolas Capens70dfff42016-10-27 10:20:28 -04006831 return As<Short4>(V(::builder->CreateCall2(pminsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006832 }
6833
John Bauman19bac1e2014-05-06 15:23:49 -04006834 RValue<Short4> pcmpgtw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006835 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006836 llvm::Function *pcmpgtw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_pcmpgt_w);
John Bauman89401822014-05-06 15:04:28 -04006837
Nicolas Capens70dfff42016-10-27 10:20:28 -04006838 return As<Short4>(V(::builder->CreateCall2(pcmpgtw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006839 }
6840
John Bauman19bac1e2014-05-06 15:23:49 -04006841 RValue<Short4> pcmpeqw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006842 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006843 llvm::Function *pcmpeqw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_pcmpeq_w);
John Bauman89401822014-05-06 15:04:28 -04006844
Nicolas Capens70dfff42016-10-27 10:20:28 -04006845 return As<Short4>(V(::builder->CreateCall2(pcmpeqw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006846 }
6847
John Bauman19bac1e2014-05-06 15:23:49 -04006848 RValue<Byte8> pcmpgtb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04006849 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006850 llvm::Function *pcmpgtb = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_pcmpgt_b);
John Bauman89401822014-05-06 15:04:28 -04006851
Nicolas Capens70dfff42016-10-27 10:20:28 -04006852 return As<Byte8>(V(::builder->CreateCall2(pcmpgtb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006853 }
6854
John Bauman19bac1e2014-05-06 15:23:49 -04006855 RValue<Byte8> pcmpeqb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04006856 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006857 llvm::Function *pcmpeqb = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_pcmpeq_b);
John Bauman89401822014-05-06 15:04:28 -04006858
Nicolas Capens70dfff42016-10-27 10:20:28 -04006859 return As<Byte8>(V(::builder->CreateCall2(pcmpeqb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006860 }
6861
John Bauman19bac1e2014-05-06 15:23:49 -04006862 RValue<Short4> packssdw(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04006863 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006864 llvm::Function *packssdw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_packssdw);
John Bauman89401822014-05-06 15:04:28 -04006865
Nicolas Capens70dfff42016-10-27 10:20:28 -04006866 return As<Short4>(V(::builder->CreateCall2(packssdw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006867 }
6868
John Bauman19bac1e2014-05-06 15:23:49 -04006869 RValue<Short8> packssdw(RValue<Int4> x, RValue<Int4> y)
John Bauman89401822014-05-06 15:04:28 -04006870 {
6871 if(CPUID::supportsSSE2())
6872 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006873 llvm::Function *packssdw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse2_packssdw_128);
John Bauman89401822014-05-06 15:04:28 -04006874
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006875 return RValue<Short8>(V(::builder->CreateCall2(packssdw, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04006876 }
6877 else
6878 {
6879 Int2 loX = Int2(x);
6880 Int2 hiX = Int2(Swizzle(x, 0xEE));
6881
6882 Int2 loY = Int2(y);
6883 Int2 hiY = Int2(Swizzle(y, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04006884
John Bauman89401822014-05-06 15:04:28 -04006885 Short4 lo = x86::packssdw(loX, hiX);
6886 Short4 hi = x86::packssdw(loY, hiY);
John Bauman66b8ab22014-05-06 15:57:45 -04006887
Nicolas Capens62abb552016-01-05 12:03:47 -05006888 return Short8(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04006889 }
6890 }
6891
John Bauman19bac1e2014-05-06 15:23:49 -04006892 RValue<SByte8> packsswb(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006893 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006894 llvm::Function *packsswb = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_packsswb);
John Bauman89401822014-05-06 15:04:28 -04006895
Nicolas Capens70dfff42016-10-27 10:20:28 -04006896 return As<SByte8>(V(::builder->CreateCall2(packsswb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006897 }
6898
John Bauman19bac1e2014-05-06 15:23:49 -04006899 RValue<Byte8> packuswb(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04006900 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006901 llvm::Function *packuswb = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_packuswb);
John Bauman89401822014-05-06 15:04:28 -04006902
Nicolas Capens70dfff42016-10-27 10:20:28 -04006903 return As<Byte8>(V(::builder->CreateCall2(packuswb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006904 }
6905
Nicolas Capens3e7062b2017-01-17 14:01:33 -05006906 RValue<UShort8> packusdw(RValue<Int4> x, RValue<Int4> y)
John Bauman89401822014-05-06 15:04:28 -04006907 {
6908 if(CPUID::supportsSSE4_1())
6909 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006910 llvm::Function *packusdw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse41_packusdw);
John Bauman66b8ab22014-05-06 15:57:45 -04006911
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006912 return RValue<UShort8>(V(::builder->CreateCall2(packusdw, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04006913 }
6914 else
6915 {
Nicolas Capens3e7062b2017-01-17 14:01:33 -05006916 RValue<Int4> bx = (x & ~(x >> 31)) - Int4(0x8000);
6917 RValue<Int4> by = (y & ~(y >> 31)) - Int4(0x8000);
6918
6919 return As<UShort8>(packssdw(bx, by) + Short8(0x8000u));
John Bauman89401822014-05-06 15:04:28 -04006920 }
6921 }
6922
John Bauman19bac1e2014-05-06 15:23:49 -04006923 RValue<UShort4> psrlw(RValue<UShort4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006924 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006925 llvm::Function *psrlw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_psrli_w);
John Bauman89401822014-05-06 15:04:28 -04006926
Nicolas Capens70dfff42016-10-27 10:20:28 -04006927 return As<UShort4>(V(::builder->CreateCall2(psrlw, As<MMX>(x).value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006928 }
6929
John Bauman19bac1e2014-05-06 15:23:49 -04006930 RValue<UShort8> psrlw(RValue<UShort8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006931 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006932 llvm::Function *psrlw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse2_psrli_w);
John Bauman89401822014-05-06 15:04:28 -04006933
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006934 return RValue<UShort8>(V(::builder->CreateCall2(psrlw, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006935 }
6936
John Bauman19bac1e2014-05-06 15:23:49 -04006937 RValue<Short4> psraw(RValue<Short4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006938 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006939 llvm::Function *psraw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_psrai_w);
John Bauman89401822014-05-06 15:04:28 -04006940
Nicolas Capens70dfff42016-10-27 10:20:28 -04006941 return As<Short4>(V(::builder->CreateCall2(psraw, As<MMX>(x).value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006942 }
6943
John Bauman19bac1e2014-05-06 15:23:49 -04006944 RValue<Short8> psraw(RValue<Short8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006945 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006946 llvm::Function *psraw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse2_psrai_w);
John Bauman89401822014-05-06 15:04:28 -04006947
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006948 return RValue<Short8>(V(::builder->CreateCall2(psraw, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006949 }
6950
John Bauman19bac1e2014-05-06 15:23:49 -04006951 RValue<Short4> psllw(RValue<Short4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006952 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006953 llvm::Function *psllw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_pslli_w);
John Bauman89401822014-05-06 15:04:28 -04006954
Nicolas Capens70dfff42016-10-27 10:20:28 -04006955 return As<Short4>(V(::builder->CreateCall2(psllw, As<MMX>(x).value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006956 }
6957
John Bauman19bac1e2014-05-06 15:23:49 -04006958 RValue<Short8> psllw(RValue<Short8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006959 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006960 llvm::Function *psllw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse2_pslli_w);
John Bauman89401822014-05-06 15:04:28 -04006961
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006962 return RValue<Short8>(V(::builder->CreateCall2(psllw, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006963 }
6964
John Bauman19bac1e2014-05-06 15:23:49 -04006965 RValue<Int2> pslld(RValue<Int2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006966 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006967 llvm::Function *pslld = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_pslli_d);
John Bauman89401822014-05-06 15:04:28 -04006968
Nicolas Capens70dfff42016-10-27 10:20:28 -04006969 return As<Int2>(V(::builder->CreateCall2(pslld, As<MMX>(x).value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006970 }
6971
John Bauman19bac1e2014-05-06 15:23:49 -04006972 RValue<Int4> pslld(RValue<Int4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006973 {
6974 if(CPUID::supportsSSE2())
6975 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006976 llvm::Function *pslld = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse2_pslli_d);
John Bauman89401822014-05-06 15:04:28 -04006977
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006978 return RValue<Int4>(V(::builder->CreateCall2(pslld, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006979 }
6980 else
6981 {
6982 Int2 lo = Int2(x);
6983 Int2 hi = Int2(Swizzle(x, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04006984
John Bauman89401822014-05-06 15:04:28 -04006985 lo = x86::pslld(lo, y);
6986 hi = x86::pslld(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04006987
Nicolas Capens62abb552016-01-05 12:03:47 -05006988 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04006989 }
6990 }
6991
John Bauman19bac1e2014-05-06 15:23:49 -04006992 RValue<Int2> psrad(RValue<Int2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006993 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04006994 llvm::Function *psrad = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_psrai_d);
John Bauman89401822014-05-06 15:04:28 -04006995
Nicolas Capens70dfff42016-10-27 10:20:28 -04006996 return As<Int2>(V(::builder->CreateCall2(psrad, As<MMX>(x).value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006997 }
6998
John Bauman19bac1e2014-05-06 15:23:49 -04006999 RValue<Int4> psrad(RValue<Int4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007000 {
7001 if(CPUID::supportsSSE2())
7002 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04007003 llvm::Function *psrad = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse2_psrai_d);
John Bauman89401822014-05-06 15:04:28 -04007004
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007005 return RValue<Int4>(V(::builder->CreateCall2(psrad, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007006 }
7007 else
7008 {
7009 Int2 lo = Int2(x);
7010 Int2 hi = Int2(Swizzle(x, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04007011
John Bauman89401822014-05-06 15:04:28 -04007012 lo = x86::psrad(lo, y);
7013 hi = x86::psrad(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04007014
Nicolas Capens62abb552016-01-05 12:03:47 -05007015 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007016 }
7017 }
7018
John Bauman19bac1e2014-05-06 15:23:49 -04007019 RValue<UInt2> psrld(RValue<UInt2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007020 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04007021 llvm::Function *psrld = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_psrli_d);
John Bauman89401822014-05-06 15:04:28 -04007022
Nicolas Capens70dfff42016-10-27 10:20:28 -04007023 return As<UInt2>(V(::builder->CreateCall2(psrld, As<MMX>(x).value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007024 }
7025
John Bauman19bac1e2014-05-06 15:23:49 -04007026 RValue<UInt4> psrld(RValue<UInt4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007027 {
7028 if(CPUID::supportsSSE2())
7029 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04007030 llvm::Function *psrld = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse2_psrli_d);
John Bauman89401822014-05-06 15:04:28 -04007031
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007032 return RValue<UInt4>(V(::builder->CreateCall2(psrld, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007033 }
7034 else
7035 {
7036 UInt2 lo = As<UInt2>(Int2(As<Int4>(x)));
7037 UInt2 hi = As<UInt2>(Int2(Swizzle(As<Int4>(x), 0xEE)));
John Bauman66b8ab22014-05-06 15:57:45 -04007038
John Bauman89401822014-05-06 15:04:28 -04007039 lo = x86::psrld(lo, y);
7040 hi = x86::psrld(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04007041
Nicolas Capens62abb552016-01-05 12:03:47 -05007042 return UInt4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007043 }
7044 }
7045
John Bauman19bac1e2014-05-06 15:23:49 -04007046 RValue<Int4> pmaxsd(RValue<Int4> x, RValue<Int4> y)
7047 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04007048 llvm::Function *pmaxsd = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse41_pmaxsd);
John Bauman19bac1e2014-05-06 15:23:49 -04007049
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007050 return RValue<Int4>(V(::builder->CreateCall2(pmaxsd, x.value, y.value)));
John Bauman19bac1e2014-05-06 15:23:49 -04007051 }
7052
7053 RValue<Int4> pminsd(RValue<Int4> x, RValue<Int4> y)
7054 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04007055 llvm::Function *pminsd = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse41_pminsd);
John Bauman19bac1e2014-05-06 15:23:49 -04007056
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007057 return RValue<Int4>(V(::builder->CreateCall2(pminsd, x.value, y.value)));
John Bauman19bac1e2014-05-06 15:23:49 -04007058 }
7059
7060 RValue<UInt4> pmaxud(RValue<UInt4> x, RValue<UInt4> y)
7061 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04007062 llvm::Function *pmaxud = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse41_pmaxud);
John Bauman19bac1e2014-05-06 15:23:49 -04007063
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007064 return RValue<UInt4>(V(::builder->CreateCall2(pmaxud, x.value, y.value)));
John Bauman19bac1e2014-05-06 15:23:49 -04007065 }
7066
7067 RValue<UInt4> pminud(RValue<UInt4> x, RValue<UInt4> y)
7068 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04007069 llvm::Function *pminud = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse41_pminud);
John Bauman19bac1e2014-05-06 15:23:49 -04007070
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007071 return RValue<UInt4>(V(::builder->CreateCall2(pminud, x.value, y.value)));
John Bauman19bac1e2014-05-06 15:23:49 -04007072 }
7073
7074 RValue<Short4> pmulhw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007075 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04007076 llvm::Function *pmulhw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_pmulh_w);
John Bauman89401822014-05-06 15:04:28 -04007077
Nicolas Capens70dfff42016-10-27 10:20:28 -04007078 return As<Short4>(V(::builder->CreateCall2(pmulhw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007079 }
7080
John Bauman19bac1e2014-05-06 15:23:49 -04007081 RValue<UShort4> pmulhuw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007082 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04007083 llvm::Function *pmulhuw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_pmulhu_w);
John Bauman89401822014-05-06 15:04:28 -04007084
Nicolas Capens70dfff42016-10-27 10:20:28 -04007085 return As<UShort4>(V(::builder->CreateCall2(pmulhuw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007086 }
7087
John Bauman19bac1e2014-05-06 15:23:49 -04007088 RValue<Int2> pmaddwd(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007089 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04007090 llvm::Function *pmaddwd = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_pmadd_wd);
John Bauman89401822014-05-06 15:04:28 -04007091
Nicolas Capens70dfff42016-10-27 10:20:28 -04007092 return As<Int2>(V(::builder->CreateCall2(pmaddwd, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007093 }
7094
John Bauman19bac1e2014-05-06 15:23:49 -04007095 RValue<Short8> pmulhw(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04007096 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04007097 llvm::Function *pmulhw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse2_pmulh_w);
John Bauman89401822014-05-06 15:04:28 -04007098
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007099 return RValue<Short8>(V(::builder->CreateCall2(pmulhw, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04007100 }
7101
John Bauman19bac1e2014-05-06 15:23:49 -04007102 RValue<UShort8> pmulhuw(RValue<UShort8> x, RValue<UShort8> y)
John Bauman89401822014-05-06 15:04:28 -04007103 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04007104 llvm::Function *pmulhuw = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse2_pmulhu_w);
John Bauman89401822014-05-06 15:04:28 -04007105
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007106 return RValue<UShort8>(V(::builder->CreateCall2(pmulhuw, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04007107 }
7108
John Bauman19bac1e2014-05-06 15:23:49 -04007109 RValue<Int4> pmaddwd(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04007110 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04007111 llvm::Function *pmaddwd = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse2_pmadd_wd);
John Bauman89401822014-05-06 15:04:28 -04007112
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007113 return RValue<Int4>(V(::builder->CreateCall2(pmaddwd, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04007114 }
7115
John Bauman19bac1e2014-05-06 15:23:49 -04007116 RValue<Int> movmskps(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04007117 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04007118 llvm::Function *movmskps = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse_movmsk_ps);
John Bauman89401822014-05-06 15:04:28 -04007119
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007120 return RValue<Int>(V(::builder->CreateCall(movmskps, x.value)));
John Bauman89401822014-05-06 15:04:28 -04007121 }
7122
John Bauman19bac1e2014-05-06 15:23:49 -04007123 RValue<Int> pmovmskb(RValue<Byte8> x)
John Bauman89401822014-05-06 15:04:28 -04007124 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04007125 llvm::Function *pmovmskb = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_pmovmskb);
John Bauman89401822014-05-06 15:04:28 -04007126
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007127 return RValue<Int>(V(::builder->CreateCall(pmovmskb, As<MMX>(x).value)));
John Bauman89401822014-05-06 15:04:28 -04007128 }
7129
Nicolas Capens81f18302016-01-14 09:32:35 -05007130 //RValue<Int2> movd(RValue<Pointer<Int>> x)
John Bauman89401822014-05-06 15:04:28 -04007131 //{
7132 // Value *element = Nucleus::createLoad(x.value);
7133
7134 //// Value *int2 = UndefValue::get(Int2::getType());
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04007135 //// int2 = Nucleus::createInsertElement(int2, element, ConstantInt::get(T(Int::getType()), 0));
John Bauman89401822014-05-06 15:04:28 -04007136
7137 // Value *int2 = Nucleus::createBitCast(Nucleus::createZExt(element, Long::getType()), Int2::getType());
7138
7139 // return RValue<Int2>(int2);
7140 //}
7141
John Bauman19bac1e2014-05-06 15:23:49 -04007142 //RValue<Int2> movdq2q(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007143 //{
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04007144 // Value *long2 = Nucleus::createBitCast(x.value, T(llvm::VectorType::get(T(Long::getType()), 2)));
7145 // Value *element = Nucleus::createExtractElement(long2, ConstantInt::get(T(Int::getType()), 0));
John Bauman89401822014-05-06 15:04:28 -04007146
7147 // return RValue<Int2>(Nucleus::createBitCast(element, Int2::getType()));
7148 //}
7149
John Bauman19bac1e2014-05-06 15:23:49 -04007150 RValue<Int4> pmovzxbd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007151 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04007152 llvm::Function *pmovzxbd = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse41_pmovzxbd);
John Bauman66b8ab22014-05-06 15:57:45 -04007153
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007154 return RValue<Int4>(V(::builder->CreateCall(pmovzxbd, Nucleus::createBitCast(x.value, Byte16::getType()))));
John Bauman89401822014-05-06 15:04:28 -04007155 }
7156
John Bauman19bac1e2014-05-06 15:23:49 -04007157 RValue<Int4> pmovsxbd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007158 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04007159 llvm::Function *pmovsxbd = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse41_pmovsxbd);
John Bauman66b8ab22014-05-06 15:57:45 -04007160
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007161 return RValue<Int4>(V(::builder->CreateCall(pmovsxbd, Nucleus::createBitCast(x.value, SByte16::getType()))));
John Bauman89401822014-05-06 15:04:28 -04007162 }
7163
John Bauman19bac1e2014-05-06 15:23:49 -04007164 RValue<Int4> pmovzxwd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007165 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04007166 llvm::Function *pmovzxwd = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse41_pmovzxwd);
John Bauman66b8ab22014-05-06 15:57:45 -04007167
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007168 return RValue<Int4>(V(::builder->CreateCall(pmovzxwd, Nucleus::createBitCast(x.value, UShort8::getType()))));
John Bauman89401822014-05-06 15:04:28 -04007169 }
7170
John Bauman19bac1e2014-05-06 15:23:49 -04007171 RValue<Int4> pmovsxwd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007172 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04007173 llvm::Function *pmovsxwd = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse41_pmovsxwd);
John Bauman66b8ab22014-05-06 15:57:45 -04007174
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007175 return RValue<Int4>(V(::builder->CreateCall(pmovsxwd, Nucleus::createBitCast(x.value, Short8::getType()))));
John Bauman89401822014-05-06 15:04:28 -04007176 }
7177
7178 void emms()
7179 {
Nicolas Capensfbf2bc52017-07-26 17:26:17 -04007180 llvm::Function *emms = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_mmx_emms);
John Bauman89401822014-05-06 15:04:28 -04007181
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007182 V(::builder->CreateCall(emms));
John Bauman89401822014-05-06 15:04:28 -04007183 }
7184 }
7185}