blob: 0d5685865d9e73479514d817f5bf8b0b29a3fb09 [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
Nicolas Capens05b3d662016-02-25 23:58:33 -050040#include <xmmintrin.h>
John Bauman89401822014-05-06 15:04:28 -040041#include <fstream>
42
Nicolas Capenscb122582014-05-06 23:34:44 -040043#if defined(__x86_64__) && defined(_WIN32)
John Bauman66b8ab22014-05-06 15:57:45 -040044extern "C" void X86CompilationCallback()
45{
46 assert(false); // UNIMPLEMENTED
47}
48#endif
49
John Bauman89401822014-05-06 15:04:28 -040050extern "C"
51{
52 bool (*CodeAnalystInitialize)() = 0;
53 void (*CodeAnalystCompleteJITLog)() = 0;
54 bool (*CodeAnalystLogJITCode)(const void *jitCodeStartAddr, unsigned int jitCodeSize, const wchar_t *functionName) = 0;
55}
56
57namespace llvm
58{
59 extern bool JITEmitDebugInfo;
60}
61
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -040062namespace
63{
Nicolas Capensdaa5d912016-09-28 16:56:36 -040064 sw::LLVMRoutineManager *routineManager = nullptr;
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -040065 llvm::ExecutionEngine *executionEngine = nullptr;
66 llvm::IRBuilder<> *builder = nullptr;
67 llvm::LLVMContext *context = nullptr;
68 llvm::Module *module = nullptr;
69 llvm::Function *function = nullptr;
Nicolas Capens3bbc5e12016-09-27 10:49:52 -040070
Jorge E. Moreiraf8faed62016-12-02 17:03:54 -080071 sw::MutexLock codegenMutex;
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -040072}
73
John Bauman89401822014-05-06 15:04:28 -040074namespace sw
75{
John Bauman89401822014-05-06 15:04:28 -040076 using namespace llvm;
John Bauman89401822014-05-06 15:04:28 -040077
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -040078 Optimization optimization[10] = {InstructionCombining, Disabled};
John Bauman89401822014-05-06 15:04:28 -040079
Nicolas Capensc8b67a42016-09-25 15:02:52 -040080 class Type : public llvm::Type {};
Nicolas Capens19336542016-09-26 10:32:29 -040081 class Value : public llvm::Value {};
Nicolas Capensb98fe5c2016-11-09 12:24:06 -050082 class SwitchCases : public llvm::SwitchInst {};
Nicolas Capensc8b67a42016-09-25 15:02:52 -040083 class BasicBlock : public llvm::BasicBlock {};
Nicolas Capensac230122016-09-20 14:30:06 -040084
85 inline Type *T(llvm::Type *t)
86 {
87 return reinterpret_cast<Type*>(t);
88 }
89
Nicolas Capens19336542016-09-26 10:32:29 -040090 inline Value *V(llvm::Value *t)
91 {
92 return reinterpret_cast<Value*>(t);
93 }
94
Nicolas Capensac230122016-09-20 14:30:06 -040095 inline std::vector<llvm::Type*> &T(std::vector<Type*> &t)
96 {
97 return reinterpret_cast<std::vector<llvm::Type*>&>(t);
98 }
99
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400100 inline BasicBlock *B(llvm::BasicBlock *t)
101 {
102 return reinterpret_cast<BasicBlock*>(t);
103 }
104
John Bauman89401822014-05-06 15:04:28 -0400105 Nucleus::Nucleus()
106 {
Nicolas Capens3bbc5e12016-09-27 10:49:52 -0400107 ::codegenMutex.lock(); // Reactor and LLVM are currently not thread safe
Nicolas Capensb7ea9842015-04-01 10:54:59 -0400108
John Bauman19bac1e2014-05-06 15:23:49 -0400109 InitializeNativeTarget();
John Bauman89401822014-05-06 15:04:28 -0400110 JITEmitDebugInfo = false;
111
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400112 if(!::context)
John Bauman89401822014-05-06 15:04:28 -0400113 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400114 ::context = new LLVMContext();
John Bauman89401822014-05-06 15:04:28 -0400115 }
116
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400117 ::module = new Module("", *::context);
Nicolas Capensdaa5d912016-09-28 16:56:36 -0400118 ::routineManager = new LLVMRoutineManager();
John Bauman66b8ab22014-05-06 15:57:45 -0400119
John Bauman89401822014-05-06 15:04:28 -0400120 #if defined(__x86_64__)
121 const char *architecture = "x86-64";
122 #else
123 const char *architecture = "x86";
124 #endif
125
126 SmallVector<std::string, 1> MAttrs;
127 MAttrs.push_back(CPUID::supportsMMX() ? "+mmx" : "-mmx");
128 MAttrs.push_back(CPUID::supportsCMOV() ? "+cmov" : "-cmov");
129 MAttrs.push_back(CPUID::supportsSSE() ? "+sse" : "-sse");
130 MAttrs.push_back(CPUID::supportsSSE2() ? "+sse2" : "-sse2");
131 MAttrs.push_back(CPUID::supportsSSE3() ? "+sse3" : "-sse3");
132 MAttrs.push_back(CPUID::supportsSSSE3() ? "+ssse3" : "-ssse3");
133 MAttrs.push_back(CPUID::supportsSSE4_1() ? "+sse41" : "-sse41");
134
John Bauman19bac1e2014-05-06 15:23:49 -0400135 std::string error;
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400136 TargetMachine *targetMachine = EngineBuilder::selectTarget(::module, architecture, "", MAttrs, Reloc::Default, CodeModel::JITDefault, &error);
137 ::executionEngine = JIT::createJIT(::module, 0, ::routineManager, CodeGenOpt::Aggressive, true, targetMachine);
John Bauman89401822014-05-06 15:04:28 -0400138
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400139 if(!::builder)
John Bauman89401822014-05-06 15:04:28 -0400140 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400141 ::builder = new IRBuilder<>(*::context);
John Bauman89401822014-05-06 15:04:28 -0400142
John Bauman66b8ab22014-05-06 15:57:45 -0400143 #if defined(_WIN32)
144 HMODULE CodeAnalyst = LoadLibrary("CAJitNtfyLib.dll");
145 if(CodeAnalyst)
146 {
147 CodeAnalystInitialize = (bool(*)())GetProcAddress(CodeAnalyst, "CAJIT_Initialize");
148 CodeAnalystCompleteJITLog = (void(*)())GetProcAddress(CodeAnalyst, "CAJIT_CompleteJITLog");
149 CodeAnalystLogJITCode = (bool(*)(const void*, unsigned int, const wchar_t*))GetProcAddress(CodeAnalyst, "CAJIT_LogJITCode");
150
151 CodeAnalystInitialize();
152 }
153 #endif
John Bauman89401822014-05-06 15:04:28 -0400154 }
155 }
156
157 Nucleus::~Nucleus()
158 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400159 delete ::executionEngine;
160 ::executionEngine = nullptr;
John Bauman89401822014-05-06 15:04:28 -0400161
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400162 ::routineManager = nullptr;
163 ::function = nullptr;
164 ::module = nullptr;
Nicolas Capensb7ea9842015-04-01 10:54:59 -0400165
Nicolas Capens3bbc5e12016-09-27 10:49:52 -0400166 ::codegenMutex.unlock();
John Bauman89401822014-05-06 15:04:28 -0400167 }
168
169 Routine *Nucleus::acquireRoutine(const wchar_t *name, bool runOptimizations)
170 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400171 if(::builder->GetInsertBlock()->empty() || !::builder->GetInsertBlock()->back().isTerminator())
John Bauman19bac1e2014-05-06 15:23:49 -0400172 {
Nicolas Capensac230122016-09-20 14:30:06 -0400173 llvm::Type *type = ::function->getReturnType();
John Bauman19bac1e2014-05-06 15:23:49 -0400174
175 if(type->isVoidTy())
176 {
177 createRetVoid();
178 }
179 else
180 {
Nicolas Capens19336542016-09-26 10:32:29 -0400181 createRet(V(UndefValue::get(type)));
John Bauman19bac1e2014-05-06 15:23:49 -0400182 }
183 }
John Bauman89401822014-05-06 15:04:28 -0400184
185 if(false)
186 {
John Bauman66b8ab22014-05-06 15:57:45 -0400187 std::string error;
188 raw_fd_ostream file("llvm-dump-unopt.txt", error);
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400189 ::module->print(file, 0);
John Bauman89401822014-05-06 15:04:28 -0400190 }
191
192 if(runOptimizations)
193 {
194 optimize();
195 }
196
197 if(false)
198 {
John Bauman66b8ab22014-05-06 15:57:45 -0400199 std::string error;
200 raw_fd_ostream file("llvm-dump-opt.txt", error);
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400201 ::module->print(file, 0);
John Bauman89401822014-05-06 15:04:28 -0400202 }
203
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400204 void *entry = ::executionEngine->getPointerToFunction(::function);
Nicolas Capensdaa5d912016-09-28 16:56:36 -0400205 LLVMRoutine *routine = ::routineManager->acquireRoutine(entry);
John Bauman89401822014-05-06 15:04:28 -0400206
207 if(CodeAnalystLogJITCode)
208 {
Nicolas Capensd946e0a2014-06-26 11:31:08 -0400209 CodeAnalystLogJITCode(routine->getEntry(), routine->getCodeSize(), name);
John Bauman89401822014-05-06 15:04:28 -0400210 }
211
212 return routine;
213 }
214
215 void Nucleus::optimize()
216 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400217 static PassManager *passManager = nullptr;
John Bauman66b8ab22014-05-06 15:57:45 -0400218
John Bauman89401822014-05-06 15:04:28 -0400219 if(!passManager)
220 {
221 passManager = new PassManager();
222
223 UnsafeFPMath = true;
224 // NoInfsFPMath = true;
225 // NoNaNsFPMath = true;
226
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400227 passManager->add(new TargetData(*::executionEngine->getTargetData()));
John Bauman89401822014-05-06 15:04:28 -0400228 passManager->add(createScalarReplAggregatesPass());
229
230 for(int pass = 0; pass < 10 && optimization[pass] != Disabled; pass++)
231 {
232 switch(optimization[pass])
233 {
234 case Disabled: break;
235 case CFGSimplification: passManager->add(createCFGSimplificationPass()); break;
236 case LICM: passManager->add(createLICMPass()); break;
237 case AggressiveDCE: passManager->add(createAggressiveDCEPass()); break;
238 case GVN: passManager->add(createGVNPass()); break;
239 case InstructionCombining: passManager->add(createInstructionCombiningPass()); break;
240 case Reassociate: passManager->add(createReassociatePass()); break;
241 case DeadStoreElimination: passManager->add(createDeadStoreEliminationPass()); break;
242 case SCCP: passManager->add(createSCCPPass()); break;
John Bauman19bac1e2014-05-06 15:23:49 -0400243 case ScalarReplAggregates: passManager->add(createScalarReplAggregatesPass()); break;
John Bauman89401822014-05-06 15:04:28 -0400244 default:
245 assert(false);
246 }
247 }
248 }
249
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400250 passManager->run(*::module);
John Bauman89401822014-05-06 15:04:28 -0400251 }
252
John Bauman19bac1e2014-05-06 15:23:49 -0400253 Value *Nucleus::allocateStackVariable(Type *type, int arraySize)
John Bauman89401822014-05-06 15:04:28 -0400254 {
255 // Need to allocate it in the entry block for mem2reg to work
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400256 llvm::BasicBlock &entryBlock = ::function->getEntryBlock();
John Bauman89401822014-05-06 15:04:28 -0400257
258 Instruction *declaration;
259
260 if(arraySize)
261 {
262 declaration = new AllocaInst(type, Nucleus::createConstantInt(arraySize));
263 }
264 else
265 {
266 declaration = new AllocaInst(type, (Value*)0);
267 }
268
269 entryBlock.getInstList().push_front(declaration);
270
Nicolas Capens19336542016-09-26 10:32:29 -0400271 return V(declaration);
John Bauman89401822014-05-06 15:04:28 -0400272 }
273
274 BasicBlock *Nucleus::createBasicBlock()
275 {
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400276 return B(BasicBlock::Create(*::context, "", ::function));
John Bauman89401822014-05-06 15:04:28 -0400277 }
278
279 BasicBlock *Nucleus::getInsertBlock()
280 {
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400281 return B(::builder->GetInsertBlock());
John Bauman89401822014-05-06 15:04:28 -0400282 }
283
284 void Nucleus::setInsertBlock(BasicBlock *basicBlock)
285 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400286 // assert(::builder->GetInsertBlock()->back().isTerminator());
287 return ::builder->SetInsertPoint(basicBlock);
John Bauman89401822014-05-06 15:04:28 -0400288 }
289
Nicolas Capensac230122016-09-20 14:30:06 -0400290 void Nucleus::createFunction(Type *ReturnType, std::vector<Type*> &Params)
John Bauman89401822014-05-06 15:04:28 -0400291 {
Nicolas Capensac230122016-09-20 14:30:06 -0400292 llvm::FunctionType *functionType = llvm::FunctionType::get(ReturnType, T(Params), false);
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400293 ::function = llvm::Function::Create(functionType, llvm::GlobalValue::InternalLinkage, "", ::module);
294 ::function->setCallingConv(llvm::CallingConv::C);
John Bauman89401822014-05-06 15:04:28 -0400295
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400296 ::builder->SetInsertPoint(BasicBlock::Create(*::context, "", ::function));
John Bauman89401822014-05-06 15:04:28 -0400297 }
298
Nicolas Capens19336542016-09-26 10:32:29 -0400299 Value *Nucleus::getArgument(unsigned int index)
John Bauman89401822014-05-06 15:04:28 -0400300 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400301 llvm::Function::arg_iterator args = ::function->arg_begin();
John Bauman89401822014-05-06 15:04:28 -0400302
303 while(index)
304 {
305 args++;
306 index--;
307 }
308
Nicolas Capens19336542016-09-26 10:32:29 -0400309 return V(&*args);
John Bauman89401822014-05-06 15:04:28 -0400310 }
311
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400312 void Nucleus::createRetVoid()
John Bauman89401822014-05-06 15:04:28 -0400313 {
John Bauman66b8ab22014-05-06 15:57:45 -0400314 x86::emms();
315
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400316 ::builder->CreateRetVoid();
John Bauman89401822014-05-06 15:04:28 -0400317 }
318
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400319 void Nucleus::createRet(Value *v)
John Bauman89401822014-05-06 15:04:28 -0400320 {
John Bauman66b8ab22014-05-06 15:57:45 -0400321 x86::emms();
322
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400323 ::builder->CreateRet(v);
John Bauman89401822014-05-06 15:04:28 -0400324 }
325
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400326 void Nucleus::createBr(BasicBlock *dest)
John Bauman89401822014-05-06 15:04:28 -0400327 {
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400328 ::builder->CreateBr(dest);
John Bauman89401822014-05-06 15:04:28 -0400329 }
330
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400331 void Nucleus::createCondBr(Value *cond, BasicBlock *ifTrue, BasicBlock *ifFalse)
John Bauman89401822014-05-06 15:04:28 -0400332 {
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400333 ::builder->CreateCondBr(cond, ifTrue, ifFalse);
John Bauman89401822014-05-06 15:04:28 -0400334 }
335
336 Value *Nucleus::createAdd(Value *lhs, Value *rhs)
337 {
Nicolas Capens19336542016-09-26 10:32:29 -0400338 return V(::builder->CreateAdd(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400339 }
340
341 Value *Nucleus::createSub(Value *lhs, Value *rhs)
342 {
Nicolas Capens19336542016-09-26 10:32:29 -0400343 return V(::builder->CreateSub(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400344 }
345
346 Value *Nucleus::createMul(Value *lhs, Value *rhs)
347 {
Nicolas Capens19336542016-09-26 10:32:29 -0400348 return V(::builder->CreateMul(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400349 }
350
351 Value *Nucleus::createUDiv(Value *lhs, Value *rhs)
352 {
Nicolas Capens19336542016-09-26 10:32:29 -0400353 return V(::builder->CreateUDiv(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400354 }
355
356 Value *Nucleus::createSDiv(Value *lhs, Value *rhs)
357 {
Nicolas Capens19336542016-09-26 10:32:29 -0400358 return V(::builder->CreateSDiv(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400359 }
360
361 Value *Nucleus::createFAdd(Value *lhs, Value *rhs)
362 {
Nicolas Capens19336542016-09-26 10:32:29 -0400363 return V(::builder->CreateFAdd(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400364 }
365
366 Value *Nucleus::createFSub(Value *lhs, Value *rhs)
367 {
Nicolas Capens19336542016-09-26 10:32:29 -0400368 return V(::builder->CreateFSub(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400369 }
370
371 Value *Nucleus::createFMul(Value *lhs, Value *rhs)
372 {
Nicolas Capens19336542016-09-26 10:32:29 -0400373 return V(::builder->CreateFMul(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400374 }
375
376 Value *Nucleus::createFDiv(Value *lhs, Value *rhs)
377 {
Nicolas Capens19336542016-09-26 10:32:29 -0400378 return V(::builder->CreateFDiv(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400379 }
380
381 Value *Nucleus::createURem(Value *lhs, Value *rhs)
382 {
Nicolas Capens19336542016-09-26 10:32:29 -0400383 return V(::builder->CreateURem(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400384 }
385
386 Value *Nucleus::createSRem(Value *lhs, Value *rhs)
387 {
Nicolas Capens19336542016-09-26 10:32:29 -0400388 return V(::builder->CreateSRem(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400389 }
390
391 Value *Nucleus::createFRem(Value *lhs, Value *rhs)
392 {
Nicolas Capens19336542016-09-26 10:32:29 -0400393 return V(::builder->CreateFRem(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400394 }
395
396 Value *Nucleus::createShl(Value *lhs, Value *rhs)
397 {
Nicolas Capens19336542016-09-26 10:32:29 -0400398 return V(::builder->CreateShl(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400399 }
400
401 Value *Nucleus::createLShr(Value *lhs, Value *rhs)
402 {
Nicolas Capens19336542016-09-26 10:32:29 -0400403 return V(::builder->CreateLShr(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400404 }
405
406 Value *Nucleus::createAShr(Value *lhs, Value *rhs)
407 {
Nicolas Capens19336542016-09-26 10:32:29 -0400408 return V(::builder->CreateAShr(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400409 }
410
411 Value *Nucleus::createAnd(Value *lhs, Value *rhs)
412 {
Nicolas Capens19336542016-09-26 10:32:29 -0400413 return V(::builder->CreateAnd(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400414 }
415
416 Value *Nucleus::createOr(Value *lhs, Value *rhs)
417 {
Nicolas Capens19336542016-09-26 10:32:29 -0400418 return V(::builder->CreateOr(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400419 }
420
421 Value *Nucleus::createXor(Value *lhs, Value *rhs)
422 {
Nicolas Capens19336542016-09-26 10:32:29 -0400423 return V(::builder->CreateXor(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400424 }
425
Nicolas Capens19336542016-09-26 10:32:29 -0400426 Value *Nucleus::createNeg(Value *v)
John Bauman89401822014-05-06 15:04:28 -0400427 {
Nicolas Capens19336542016-09-26 10:32:29 -0400428 return V(::builder->CreateNeg(v));
John Bauman89401822014-05-06 15:04:28 -0400429 }
430
Nicolas Capens19336542016-09-26 10:32:29 -0400431 Value *Nucleus::createFNeg(Value *v)
John Bauman89401822014-05-06 15:04:28 -0400432 {
Nicolas Capens19336542016-09-26 10:32:29 -0400433 return V(::builder->CreateFNeg(v));
John Bauman89401822014-05-06 15:04:28 -0400434 }
435
Nicolas Capens19336542016-09-26 10:32:29 -0400436 Value *Nucleus::createNot(Value *v)
John Bauman89401822014-05-06 15:04:28 -0400437 {
Nicolas Capens19336542016-09-26 10:32:29 -0400438 return V(::builder->CreateNot(v));
John Bauman89401822014-05-06 15:04:28 -0400439 }
440
Nicolas Capense12780d2016-09-27 14:18:07 -0400441 Value *Nucleus::createLoad(Value *ptr, Type *type, bool isVolatile, unsigned int align)
John Bauman89401822014-05-06 15:04:28 -0400442 {
Nicolas Capense12780d2016-09-27 14:18:07 -0400443 assert(ptr->getType()->getContainedType(0) == type);
Nicolas Capens19336542016-09-26 10:32:29 -0400444 return V(::builder->Insert(new LoadInst(ptr, "", isVolatile, align)));
John Bauman89401822014-05-06 15:04:28 -0400445 }
446
Nicolas Capens6d738712016-09-30 04:15:22 -0400447 Value *Nucleus::createStore(Value *value, Value *ptr, Type *type, bool isVolatile, unsigned int align)
John Bauman89401822014-05-06 15:04:28 -0400448 {
Nicolas Capens6d738712016-09-30 04:15:22 -0400449 assert(ptr->getType()->getContainedType(0) == type);
Nicolas Capensb955d5b2016-09-28 22:36:28 -0400450 ::builder->Insert(new StoreInst(value, ptr, isVolatile, align));
451 return value;
John Bauman89401822014-05-06 15:04:28 -0400452 }
453
Nicolas Capensd294def2017-01-26 17:44:37 -0800454 Value *Nucleus::createGEP(Value *ptr, Type *type, Value *index, bool unsignedIndex)
John Bauman89401822014-05-06 15:04:28 -0400455 {
Nicolas Capensd294def2017-01-26 17:44:37 -0800456 if(unsignedIndex && sizeof(void*) == 8)
457 {
458 index = createZExt(index, Long::getType());
459 }
460
Nicolas Capens6d738712016-09-30 04:15:22 -0400461 assert(ptr->getType()->getContainedType(0) == type);
Nicolas Capens19336542016-09-26 10:32:29 -0400462 return V(::builder->CreateGEP(ptr, index));
John Bauman89401822014-05-06 15:04:28 -0400463 }
464
John Bauman19bac1e2014-05-06 15:23:49 -0400465 Value *Nucleus::createAtomicAdd(Value *ptr, Value *value)
466 {
Nicolas Capens19336542016-09-26 10:32:29 -0400467 return V(::builder->CreateAtomicRMW(AtomicRMWInst::Add, ptr, value, SequentiallyConsistent));
John Bauman19bac1e2014-05-06 15:23:49 -0400468 }
469
Nicolas Capens19336542016-09-26 10:32:29 -0400470 Value *Nucleus::createTrunc(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400471 {
Nicolas Capens19336542016-09-26 10:32:29 -0400472 return V(::builder->CreateTrunc(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400473 }
474
Nicolas Capens19336542016-09-26 10:32:29 -0400475 Value *Nucleus::createZExt(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400476 {
Nicolas Capens19336542016-09-26 10:32:29 -0400477 return V(::builder->CreateZExt(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400478 }
479
Nicolas Capens19336542016-09-26 10:32:29 -0400480 Value *Nucleus::createSExt(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400481 {
Nicolas Capens19336542016-09-26 10:32:29 -0400482 return V(::builder->CreateSExt(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400483 }
484
Nicolas Capens19336542016-09-26 10:32:29 -0400485 Value *Nucleus::createFPToSI(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400486 {
Nicolas Capens19336542016-09-26 10:32:29 -0400487 return V(::builder->CreateFPToSI(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400488 }
489
Nicolas Capens19336542016-09-26 10:32:29 -0400490 Value *Nucleus::createSIToFP(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400491 {
Nicolas Capens19336542016-09-26 10:32:29 -0400492 return V(::builder->CreateSIToFP(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400493 }
494
Nicolas Capens19336542016-09-26 10:32:29 -0400495 Value *Nucleus::createFPTrunc(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400496 {
Nicolas Capens19336542016-09-26 10:32:29 -0400497 return V(::builder->CreateFPTrunc(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400498 }
499
Nicolas Capens19336542016-09-26 10:32:29 -0400500 Value *Nucleus::createFPExt(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400501 {
Nicolas Capens19336542016-09-26 10:32:29 -0400502 return V(::builder->CreateFPExt(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400503 }
504
Nicolas Capens19336542016-09-26 10:32:29 -0400505 Value *Nucleus::createBitCast(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400506 {
Nicolas Capens19336542016-09-26 10:32:29 -0400507 return V(::builder->CreateBitCast(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400508 }
509
John Bauman89401822014-05-06 15:04:28 -0400510 Value *Nucleus::createICmpEQ(Value *lhs, Value *rhs)
511 {
Nicolas Capens19336542016-09-26 10:32:29 -0400512 return V(::builder->CreateICmpEQ(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400513 }
514
515 Value *Nucleus::createICmpNE(Value *lhs, Value *rhs)
516 {
Nicolas Capens19336542016-09-26 10:32:29 -0400517 return V(::builder->CreateICmpNE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400518 }
519
520 Value *Nucleus::createICmpUGT(Value *lhs, Value *rhs)
521 {
Nicolas Capens19336542016-09-26 10:32:29 -0400522 return V(::builder->CreateICmpUGT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400523 }
524
525 Value *Nucleus::createICmpUGE(Value *lhs, Value *rhs)
526 {
Nicolas Capens19336542016-09-26 10:32:29 -0400527 return V(::builder->CreateICmpUGE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400528 }
529
530 Value *Nucleus::createICmpULT(Value *lhs, Value *rhs)
531 {
Nicolas Capens19336542016-09-26 10:32:29 -0400532 return V(::builder->CreateICmpULT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400533 }
534
535 Value *Nucleus::createICmpULE(Value *lhs, Value *rhs)
536 {
Nicolas Capens19336542016-09-26 10:32:29 -0400537 return V(::builder->CreateICmpULE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400538 }
539
540 Value *Nucleus::createICmpSGT(Value *lhs, Value *rhs)
541 {
Nicolas Capens19336542016-09-26 10:32:29 -0400542 return V(::builder->CreateICmpSGT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400543 }
544
545 Value *Nucleus::createICmpSGE(Value *lhs, Value *rhs)
546 {
Nicolas Capens19336542016-09-26 10:32:29 -0400547 return V(::builder->CreateICmpSGE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400548 }
549
550 Value *Nucleus::createICmpSLT(Value *lhs, Value *rhs)
551 {
Nicolas Capens19336542016-09-26 10:32:29 -0400552 return V(::builder->CreateICmpSLT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400553 }
554
555 Value *Nucleus::createICmpSLE(Value *lhs, Value *rhs)
556 {
Nicolas Capens19336542016-09-26 10:32:29 -0400557 return V(::builder->CreateICmpSLE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400558 }
559
560 Value *Nucleus::createFCmpOEQ(Value *lhs, Value *rhs)
561 {
Nicolas Capens19336542016-09-26 10:32:29 -0400562 return V(::builder->CreateFCmpOEQ(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400563 }
564
565 Value *Nucleus::createFCmpOGT(Value *lhs, Value *rhs)
566 {
Nicolas Capens19336542016-09-26 10:32:29 -0400567 return V(::builder->CreateFCmpOGT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400568 }
569
570 Value *Nucleus::createFCmpOGE(Value *lhs, Value *rhs)
571 {
Nicolas Capens19336542016-09-26 10:32:29 -0400572 return V(::builder->CreateFCmpOGE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400573 }
574
575 Value *Nucleus::createFCmpOLT(Value *lhs, Value *rhs)
576 {
Nicolas Capens19336542016-09-26 10:32:29 -0400577 return V(::builder->CreateFCmpOLT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400578 }
579
580 Value *Nucleus::createFCmpOLE(Value *lhs, Value *rhs)
581 {
Nicolas Capens19336542016-09-26 10:32:29 -0400582 return V(::builder->CreateFCmpOLE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400583 }
584
585 Value *Nucleus::createFCmpONE(Value *lhs, Value *rhs)
586 {
Nicolas Capens19336542016-09-26 10:32:29 -0400587 return V(::builder->CreateFCmpONE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400588 }
589
590 Value *Nucleus::createFCmpORD(Value *lhs, Value *rhs)
591 {
Nicolas Capens19336542016-09-26 10:32:29 -0400592 return V(::builder->CreateFCmpORD(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400593 }
594
595 Value *Nucleus::createFCmpUNO(Value *lhs, Value *rhs)
596 {
Nicolas Capens19336542016-09-26 10:32:29 -0400597 return V(::builder->CreateFCmpUNO(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400598 }
599
600 Value *Nucleus::createFCmpUEQ(Value *lhs, Value *rhs)
601 {
Nicolas Capens19336542016-09-26 10:32:29 -0400602 return V(::builder->CreateFCmpUEQ(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400603 }
604
605 Value *Nucleus::createFCmpUGT(Value *lhs, Value *rhs)
606 {
Nicolas Capens19336542016-09-26 10:32:29 -0400607 return V(::builder->CreateFCmpUGT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400608 }
609
610 Value *Nucleus::createFCmpUGE(Value *lhs, Value *rhs)
611 {
Nicolas Capens19336542016-09-26 10:32:29 -0400612 return V(::builder->CreateFCmpUGE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400613 }
614
615 Value *Nucleus::createFCmpULT(Value *lhs, Value *rhs)
616 {
Nicolas Capens19336542016-09-26 10:32:29 -0400617 return V(::builder->CreateFCmpULT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400618 }
619
620 Value *Nucleus::createFCmpULE(Value *lhs, Value *rhs)
621 {
Nicolas Capens19336542016-09-26 10:32:29 -0400622 return V(::builder->CreateFCmpULE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400623 }
624
625 Value *Nucleus::createFCmpUNE(Value *lhs, Value *rhs)
626 {
Nicolas Capens19336542016-09-26 10:32:29 -0400627 return V(::builder->CreateFCmpULE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400628 }
629
Nicolas Capense95d5342016-09-30 11:37:28 -0400630 Value *Nucleus::createExtractElement(Value *vector, Type *type, int index)
John Bauman89401822014-05-06 15:04:28 -0400631 {
Nicolas Capense95d5342016-09-30 11:37:28 -0400632 assert(vector->getType()->getContainedType(0) == type);
Nicolas Capens19336542016-09-26 10:32:29 -0400633 return V(::builder->CreateExtractElement(vector, createConstantInt(index)));
John Bauman89401822014-05-06 15:04:28 -0400634 }
635
636 Value *Nucleus::createInsertElement(Value *vector, Value *element, int index)
637 {
Nicolas Capens19336542016-09-26 10:32:29 -0400638 return V(::builder->CreateInsertElement(vector, element, createConstantInt(index)));
John Bauman89401822014-05-06 15:04:28 -0400639 }
640
Nicolas Capense89cd582016-09-30 14:23:47 -0400641 Value *Nucleus::createShuffleVector(Value *V1, Value *V2, const int *select)
John Bauman89401822014-05-06 15:04:28 -0400642 {
Nicolas Capense89cd582016-09-30 14:23:47 -0400643 int size = llvm::cast<llvm::VectorType>(V1->getType())->getNumElements();
644 const int maxSize = 16;
645 llvm::Constant *swizzle[maxSize];
646 assert(size <= maxSize);
647
648 for(int i = 0; i < size; i++)
649 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400650 swizzle[i] = llvm::ConstantInt::get(Type::getInt32Ty(*::context), select[i]);
Nicolas Capense89cd582016-09-30 14:23:47 -0400651 }
652
653 llvm::Value *shuffle = llvm::ConstantVector::get(llvm::ArrayRef<llvm::Constant*>(swizzle, size));
654
655 return V(::builder->CreateShuffleVector(V1, V2, shuffle));
John Bauman89401822014-05-06 15:04:28 -0400656 }
657
658 Value *Nucleus::createSelect(Value *C, Value *ifTrue, Value *ifFalse)
659 {
Nicolas Capens19336542016-09-26 10:32:29 -0400660 return V(::builder->CreateSelect(C, ifTrue, ifFalse));
John Bauman89401822014-05-06 15:04:28 -0400661 }
662
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500663 SwitchCases *Nucleus::createSwitch(Value *control, BasicBlock *defaultBranch, unsigned numCases)
John Bauman89401822014-05-06 15:04:28 -0400664 {
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500665 return reinterpret_cast<SwitchCases*>(::builder->CreateSwitch(control, defaultBranch, numCases));
John Bauman89401822014-05-06 15:04:28 -0400666 }
667
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500668 void Nucleus::addSwitchCase(SwitchCases *switchCases, int label, BasicBlock *branch)
John Bauman89401822014-05-06 15:04:28 -0400669 {
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500670 switchCases->addCase(llvm::ConstantInt::get(Type::getInt32Ty(*::context), label, true), branch);
John Bauman89401822014-05-06 15:04:28 -0400671 }
672
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400673 void Nucleus::createUnreachable()
John Bauman89401822014-05-06 15:04:28 -0400674 {
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400675 ::builder->CreateUnreachable();
John Bauman89401822014-05-06 15:04:28 -0400676 }
677
Nicolas Capense95d5342016-09-30 11:37:28 -0400678 static Value *createSwizzle4(Value *val, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -0400679 {
Nicolas Capense89cd582016-09-30 14:23:47 -0400680 int swizzle[4] =
681 {
682 (select >> 0) & 0x03,
683 (select >> 2) & 0x03,
684 (select >> 4) & 0x03,
685 (select >> 6) & 0x03,
686 };
John Bauman89401822014-05-06 15:04:28 -0400687
Nicolas Capense89cd582016-09-30 14:23:47 -0400688 return Nucleus::createShuffleVector(val, val, swizzle);
John Bauman89401822014-05-06 15:04:28 -0400689 }
690
Nicolas Capense95d5342016-09-30 11:37:28 -0400691 static Value *createMask4(Value *lhs, Value *rhs, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -0400692 {
693 bool mask[4] = {false, false, false, false};
694
695 mask[(select >> 0) & 0x03] = true;
696 mask[(select >> 2) & 0x03] = true;
697 mask[(select >> 4) & 0x03] = true;
698 mask[(select >> 6) & 0x03] = true;
699
Nicolas Capense89cd582016-09-30 14:23:47 -0400700 int swizzle[4] =
701 {
702 mask[0] ? 4 : 0,
703 mask[1] ? 5 : 1,
704 mask[2] ? 6 : 2,
705 mask[3] ? 7 : 3,
706 };
John Bauman89401822014-05-06 15:04:28 -0400707
Nicolas Capensa29d6532016-12-05 21:38:09 -0500708 return Nucleus::createShuffleVector(lhs, rhs, swizzle);
John Bauman89401822014-05-06 15:04:28 -0400709 }
710
Nicolas Capensac230122016-09-20 14:30:06 -0400711 Type *Nucleus::getPointerType(Type *ElementType)
John Bauman89401822014-05-06 15:04:28 -0400712 {
Nicolas Capensac230122016-09-20 14:30:06 -0400713 return T(llvm::PointerType::get(ElementType, 0));
John Bauman89401822014-05-06 15:04:28 -0400714 }
715
Nicolas Capens13ac2322016-10-13 14:52:12 -0400716 Value *Nucleus::createNullValue(Type *Ty)
John Bauman89401822014-05-06 15:04:28 -0400717 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400718 return V(llvm::Constant::getNullValue(Ty));
John Bauman89401822014-05-06 15:04:28 -0400719 }
720
Nicolas Capens13ac2322016-10-13 14:52:12 -0400721 Value *Nucleus::createConstantLong(int64_t i)
John Bauman89401822014-05-06 15:04:28 -0400722 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400723 return V(llvm::ConstantInt::get(Type::getInt64Ty(*::context), i, true));
John Bauman89401822014-05-06 15:04:28 -0400724 }
725
Nicolas Capens13ac2322016-10-13 14:52:12 -0400726 Value *Nucleus::createConstantInt(int i)
John Bauman89401822014-05-06 15:04:28 -0400727 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400728 return V(llvm::ConstantInt::get(Type::getInt32Ty(*::context), i, true));
John Bauman89401822014-05-06 15:04:28 -0400729 }
730
Nicolas Capens13ac2322016-10-13 14:52:12 -0400731 Value *Nucleus::createConstantInt(unsigned int i)
John Bauman89401822014-05-06 15:04:28 -0400732 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400733 return V(llvm::ConstantInt::get(Type::getInt32Ty(*::context), i, false));
John Bauman89401822014-05-06 15:04:28 -0400734 }
735
Nicolas Capens13ac2322016-10-13 14:52:12 -0400736 Value *Nucleus::createConstantBool(bool b)
John Bauman89401822014-05-06 15:04:28 -0400737 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400738 return V(llvm::ConstantInt::get(Type::getInt1Ty(*::context), b));
John Bauman89401822014-05-06 15:04:28 -0400739 }
740
Nicolas Capens13ac2322016-10-13 14:52:12 -0400741 Value *Nucleus::createConstantByte(signed char i)
John Bauman89401822014-05-06 15:04:28 -0400742 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400743 return V(llvm::ConstantInt::get(Type::getInt8Ty(*::context), i, true));
John Bauman89401822014-05-06 15:04:28 -0400744 }
745
Nicolas Capens13ac2322016-10-13 14:52:12 -0400746 Value *Nucleus::createConstantByte(unsigned char i)
John Bauman89401822014-05-06 15:04:28 -0400747 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400748 return V(llvm::ConstantInt::get(Type::getInt8Ty(*::context), i, false));
John Bauman89401822014-05-06 15:04:28 -0400749 }
750
Nicolas Capens13ac2322016-10-13 14:52:12 -0400751 Value *Nucleus::createConstantShort(short i)
John Bauman89401822014-05-06 15:04:28 -0400752 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400753 return V(llvm::ConstantInt::get(Type::getInt16Ty(*::context), i, true));
John Bauman89401822014-05-06 15:04:28 -0400754 }
755
Nicolas Capens13ac2322016-10-13 14:52:12 -0400756 Value *Nucleus::createConstantShort(unsigned short i)
John Bauman89401822014-05-06 15:04:28 -0400757 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400758 return V(llvm::ConstantInt::get(Type::getInt16Ty(*::context), i, false));
John Bauman89401822014-05-06 15:04:28 -0400759 }
760
Nicolas Capens13ac2322016-10-13 14:52:12 -0400761 Value *Nucleus::createConstantFloat(float x)
John Bauman89401822014-05-06 15:04:28 -0400762 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400763 return V(llvm::ConstantFP::get(Float::getType(), x));
John Bauman89401822014-05-06 15:04:28 -0400764 }
765
Nicolas Capens13ac2322016-10-13 14:52:12 -0400766 Value *Nucleus::createNullPointer(Type *Ty)
John Bauman89401822014-05-06 15:04:28 -0400767 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400768 return V(llvm::ConstantPointerNull::get(llvm::PointerType::get(Ty, 0)));
John Bauman89401822014-05-06 15:04:28 -0400769 }
770
Nicolas Capens13ac2322016-10-13 14:52:12 -0400771 Value *Nucleus::createConstantVector(const int64_t *constants, Type *type)
John Bauman89401822014-05-06 15:04:28 -0400772 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400773 assert(llvm::isa<VectorType>(type));
774 const int numConstants = llvm::cast<VectorType>(type)->getNumElements();
775 assert(numConstants <= 16);
776 llvm::Constant *constantVector[16];
777
778 for(int i = 0; i < numConstants; i++)
779 {
780 constantVector[i] = llvm::ConstantInt::get(type->getContainedType(0), constants[i]);
781 }
782
783 return V(llvm::ConstantVector::get(llvm::ArrayRef<llvm::Constant*>(constantVector, numConstants)));
784 }
785
786 Value *Nucleus::createConstantVector(const double *constants, Type *type)
787 {
788 assert(llvm::isa<VectorType>(type));
789 const int numConstants = llvm::cast<VectorType>(type)->getNumElements();
790 assert(numConstants <= 8);
791 llvm::Constant *constantVector[8];
792
793 for(int i = 0; i < numConstants; i++)
794 {
795 constantVector[i] = llvm::ConstantFP::get(type->getContainedType(0), constants[i]);
796 }
797
798 return V(llvm::ConstantVector::get(llvm::ArrayRef<llvm::Constant*>(constantVector, numConstants)));
John Bauman89401822014-05-06 15:04:28 -0400799 }
800
John Bauman19bac1e2014-05-06 15:23:49 -0400801 Type *Void::getType()
John Bauman89401822014-05-06 15:04:28 -0400802 {
Nicolas Capensac230122016-09-20 14:30:06 -0400803 return T(llvm::Type::getVoidTy(*::context));
John Bauman89401822014-05-06 15:04:28 -0400804 }
805
Nicolas Capens297d26e2016-11-18 12:52:17 -0500806 class MMX : public LValue<MMX>
Nicolas Capens4f738a12016-09-20 15:46:16 -0400807 {
808 public:
809 static Type *getType();
810 };
811
John Bauman19bac1e2014-05-06 15:23:49 -0400812 Type *MMX::getType()
813 {
Nicolas Capensac230122016-09-20 14:30:06 -0400814 return T(llvm::Type::getX86_MMXTy(*::context));
John Bauman19bac1e2014-05-06 15:23:49 -0400815 }
816
Nicolas Capens81f18302016-01-14 09:32:35 -0500817 Bool::Bool(Argument<Bool> argument)
John Bauman89401822014-05-06 15:04:28 -0400818 {
Nicolas Capens81f18302016-01-14 09:32:35 -0500819 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -0400820 }
821
John Bauman89401822014-05-06 15:04:28 -0400822 Bool::Bool(bool x)
823 {
John Bauman66b8ab22014-05-06 15:57:45 -0400824 storeValue(Nucleus::createConstantBool(x));
John Bauman89401822014-05-06 15:04:28 -0400825 }
826
John Bauman19bac1e2014-05-06 15:23:49 -0400827 Bool::Bool(RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400828 {
John Bauman66b8ab22014-05-06 15:57:45 -0400829 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400830 }
831
832 Bool::Bool(const Bool &rhs)
833 {
John Bauman66b8ab22014-05-06 15:57:45 -0400834 Value *value = rhs.loadValue();
835 storeValue(value);
836 }
John Bauman89401822014-05-06 15:04:28 -0400837
John Bauman66b8ab22014-05-06 15:57:45 -0400838 Bool::Bool(const Reference<Bool> &rhs)
839 {
840 Value *value = rhs.loadValue();
841 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400842 }
843
Nicolas Capens96d4e092016-11-18 14:22:38 -0500844 RValue<Bool> Bool::operator=(RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400845 {
John Bauman66b8ab22014-05-06 15:57:45 -0400846 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400847
848 return rhs;
849 }
850
Nicolas Capens96d4e092016-11-18 14:22:38 -0500851 RValue<Bool> Bool::operator=(const Bool &rhs)
John Bauman89401822014-05-06 15:04:28 -0400852 {
John Bauman66b8ab22014-05-06 15:57:45 -0400853 Value *value = rhs.loadValue();
854 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400855
856 return RValue<Bool>(value);
857 }
858
Nicolas Capens96d4e092016-11-18 14:22:38 -0500859 RValue<Bool> Bool::operator=(const Reference<Bool> &rhs)
John Bauman89401822014-05-06 15:04:28 -0400860 {
John Bauman66b8ab22014-05-06 15:57:45 -0400861 Value *value = rhs.loadValue();
862 storeValue(value);
863
864 return RValue<Bool>(value);
John Bauman89401822014-05-06 15:04:28 -0400865 }
866
John Bauman19bac1e2014-05-06 15:23:49 -0400867 RValue<Bool> operator!(RValue<Bool> val)
John Bauman89401822014-05-06 15:04:28 -0400868 {
869 return RValue<Bool>(Nucleus::createNot(val.value));
870 }
871
John Bauman19bac1e2014-05-06 15:23:49 -0400872 RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400873 {
874 return RValue<Bool>(Nucleus::createAnd(lhs.value, rhs.value));
875 }
876
John Bauman19bac1e2014-05-06 15:23:49 -0400877 RValue<Bool> operator||(RValue<Bool> lhs, RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400878 {
879 return RValue<Bool>(Nucleus::createOr(lhs.value, rhs.value));
880 }
881
John Bauman19bac1e2014-05-06 15:23:49 -0400882 Type *Bool::getType()
John Bauman89401822014-05-06 15:04:28 -0400883 {
Nicolas Capensac230122016-09-20 14:30:06 -0400884 return T(llvm::Type::getInt1Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -0400885 }
886
Nicolas Capens81f18302016-01-14 09:32:35 -0500887 Byte::Byte(Argument<Byte> argument)
John Bauman89401822014-05-06 15:04:28 -0400888 {
Nicolas Capens81f18302016-01-14 09:32:35 -0500889 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -0400890 }
891
John Bauman19bac1e2014-05-06 15:23:49 -0400892 Byte::Byte(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -0400893 {
John Bauman89401822014-05-06 15:04:28 -0400894 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
895
John Bauman66b8ab22014-05-06 15:57:45 -0400896 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -0400897 }
898
Alexis Hetu77dfab42015-11-23 13:31:22 -0500899 Byte::Byte(RValue<UInt> cast)
900 {
901 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
902
903 storeValue(integer);
904 }
905
906 Byte::Byte(RValue<UShort> cast)
907 {
908 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
909
910 storeValue(integer);
911 }
912
John Bauman89401822014-05-06 15:04:28 -0400913 Byte::Byte(int x)
914 {
John Bauman66b8ab22014-05-06 15:57:45 -0400915 storeValue(Nucleus::createConstantByte((unsigned char)x));
John Bauman89401822014-05-06 15:04:28 -0400916 }
917
918 Byte::Byte(unsigned char x)
919 {
John Bauman66b8ab22014-05-06 15:57:45 -0400920 storeValue(Nucleus::createConstantByte(x));
John Bauman89401822014-05-06 15:04:28 -0400921 }
922
John Bauman19bac1e2014-05-06 15:23:49 -0400923 Byte::Byte(RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400924 {
John Bauman66b8ab22014-05-06 15:57:45 -0400925 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400926 }
927
928 Byte::Byte(const Byte &rhs)
929 {
John Bauman66b8ab22014-05-06 15:57:45 -0400930 Value *value = rhs.loadValue();
931 storeValue(value);
932 }
John Bauman89401822014-05-06 15:04:28 -0400933
John Bauman66b8ab22014-05-06 15:57:45 -0400934 Byte::Byte(const Reference<Byte> &rhs)
935 {
936 Value *value = rhs.loadValue();
937 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400938 }
939
Nicolas Capens96d4e092016-11-18 14:22:38 -0500940 RValue<Byte> Byte::operator=(RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400941 {
John Bauman66b8ab22014-05-06 15:57:45 -0400942 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400943
944 return rhs;
945 }
946
Nicolas Capens96445fe2016-12-15 14:45:13 -0500947 RValue<Byte> Byte::operator=(const Byte &rhs)
John Bauman89401822014-05-06 15:04:28 -0400948 {
John Bauman66b8ab22014-05-06 15:57:45 -0400949 Value *value = rhs.loadValue();
950 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400951
952 return RValue<Byte>(value);
953 }
954
Nicolas Capens96d4e092016-11-18 14:22:38 -0500955 RValue<Byte> Byte::operator=(const Reference<Byte> &rhs)
John Bauman89401822014-05-06 15:04:28 -0400956 {
John Bauman66b8ab22014-05-06 15:57:45 -0400957 Value *value = rhs.loadValue();
958 storeValue(value);
959
960 return RValue<Byte>(value);
John Bauman89401822014-05-06 15:04:28 -0400961 }
962
John Bauman19bac1e2014-05-06 15:23:49 -0400963 RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400964 {
965 return RValue<Byte>(Nucleus::createAdd(lhs.value, rhs.value));
966 }
967
John Bauman19bac1e2014-05-06 15:23:49 -0400968 RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400969 {
970 return RValue<Byte>(Nucleus::createSub(lhs.value, rhs.value));
971 }
972
John Bauman19bac1e2014-05-06 15:23:49 -0400973 RValue<Byte> operator*(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400974 {
975 return RValue<Byte>(Nucleus::createMul(lhs.value, rhs.value));
976 }
977
John Bauman19bac1e2014-05-06 15:23:49 -0400978 RValue<Byte> operator/(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400979 {
980 return RValue<Byte>(Nucleus::createUDiv(lhs.value, rhs.value));
981 }
982
John Bauman19bac1e2014-05-06 15:23:49 -0400983 RValue<Byte> operator%(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400984 {
985 return RValue<Byte>(Nucleus::createURem(lhs.value, rhs.value));
986 }
987
John Bauman19bac1e2014-05-06 15:23:49 -0400988 RValue<Byte> operator&(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400989 {
990 return RValue<Byte>(Nucleus::createAnd(lhs.value, rhs.value));
991 }
992
John Bauman19bac1e2014-05-06 15:23:49 -0400993 RValue<Byte> operator|(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400994 {
995 return RValue<Byte>(Nucleus::createOr(lhs.value, rhs.value));
996 }
997
John Bauman19bac1e2014-05-06 15:23:49 -0400998 RValue<Byte> operator^(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400999 {
1000 return RValue<Byte>(Nucleus::createXor(lhs.value, rhs.value));
1001 }
1002
John Bauman19bac1e2014-05-06 15:23:49 -04001003 RValue<Byte> operator<<(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001004 {
1005 return RValue<Byte>(Nucleus::createShl(lhs.value, rhs.value));
1006 }
1007
John Bauman19bac1e2014-05-06 15:23:49 -04001008 RValue<Byte> operator>>(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001009 {
1010 return RValue<Byte>(Nucleus::createLShr(lhs.value, rhs.value));
1011 }
1012
Nicolas Capens96d4e092016-11-18 14:22:38 -05001013 RValue<Byte> operator+=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001014 {
1015 return lhs = lhs + rhs;
1016 }
1017
Nicolas Capens96d4e092016-11-18 14:22:38 -05001018 RValue<Byte> operator-=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001019 {
1020 return lhs = lhs - rhs;
1021 }
1022
Nicolas Capens96d4e092016-11-18 14:22:38 -05001023 RValue<Byte> operator*=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001024 {
1025 return lhs = lhs * rhs;
1026 }
1027
Nicolas Capens96d4e092016-11-18 14:22:38 -05001028 RValue<Byte> operator/=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001029 {
1030 return lhs = lhs / rhs;
1031 }
1032
Nicolas Capens96d4e092016-11-18 14:22:38 -05001033 RValue<Byte> operator%=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001034 {
1035 return lhs = lhs % rhs;
1036 }
1037
Nicolas Capens96d4e092016-11-18 14:22:38 -05001038 RValue<Byte> operator&=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001039 {
1040 return lhs = lhs & rhs;
1041 }
1042
Nicolas Capens96d4e092016-11-18 14:22:38 -05001043 RValue<Byte> operator|=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001044 {
1045 return lhs = lhs | rhs;
1046 }
1047
Nicolas Capens96d4e092016-11-18 14:22:38 -05001048 RValue<Byte> operator^=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001049 {
1050 return lhs = lhs ^ rhs;
1051 }
1052
Nicolas Capens96d4e092016-11-18 14:22:38 -05001053 RValue<Byte> operator<<=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001054 {
1055 return lhs = lhs << rhs;
1056 }
1057
Nicolas Capens96d4e092016-11-18 14:22:38 -05001058 RValue<Byte> operator>>=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001059 {
1060 return lhs = lhs >> rhs;
1061 }
1062
John Bauman19bac1e2014-05-06 15:23:49 -04001063 RValue<Byte> operator+(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001064 {
1065 return val;
1066 }
1067
John Bauman19bac1e2014-05-06 15:23:49 -04001068 RValue<Byte> operator-(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001069 {
1070 return RValue<Byte>(Nucleus::createNeg(val.value));
1071 }
1072
John Bauman19bac1e2014-05-06 15:23:49 -04001073 RValue<Byte> operator~(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001074 {
1075 return RValue<Byte>(Nucleus::createNot(val.value));
1076 }
1077
Nicolas Capens96d4e092016-11-18 14:22:38 -05001078 RValue<Byte> operator++(Byte &val, int) // Post-increment
John Bauman89401822014-05-06 15:04:28 -04001079 {
1080 RValue<Byte> res = val;
1081
Nicolas Capens19336542016-09-26 10:32:29 -04001082 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantByte((unsigned char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001083 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001084
1085 return res;
1086 }
1087
Nicolas Capens96d4e092016-11-18 14:22:38 -05001088 const Byte &operator++(Byte &val) // Pre-increment
John Bauman89401822014-05-06 15:04:28 -04001089 {
Nicolas Capens19336542016-09-26 10:32:29 -04001090 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantByte((unsigned char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001091 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001092
1093 return val;
1094 }
1095
Nicolas Capens96d4e092016-11-18 14:22:38 -05001096 RValue<Byte> operator--(Byte &val, int) // Post-decrement
John Bauman89401822014-05-06 15:04:28 -04001097 {
1098 RValue<Byte> res = val;
1099
Nicolas Capens19336542016-09-26 10:32:29 -04001100 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantByte((unsigned char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001101 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001102
1103 return res;
1104 }
1105
Nicolas Capens96d4e092016-11-18 14:22:38 -05001106 const Byte &operator--(Byte &val) // Pre-decrement
John Bauman89401822014-05-06 15:04:28 -04001107 {
Nicolas Capens19336542016-09-26 10:32:29 -04001108 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantByte((unsigned char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001109 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001110
1111 return val;
1112 }
1113
John Bauman19bac1e2014-05-06 15:23:49 -04001114 RValue<Bool> operator<(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001115 {
1116 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1117 }
1118
John Bauman19bac1e2014-05-06 15:23:49 -04001119 RValue<Bool> operator<=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001120 {
1121 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1122 }
1123
John Bauman19bac1e2014-05-06 15:23:49 -04001124 RValue<Bool> operator>(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001125 {
1126 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1127 }
1128
John Bauman19bac1e2014-05-06 15:23:49 -04001129 RValue<Bool> operator>=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001130 {
1131 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1132 }
1133
John Bauman19bac1e2014-05-06 15:23:49 -04001134 RValue<Bool> operator!=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001135 {
1136 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1137 }
1138
John Bauman19bac1e2014-05-06 15:23:49 -04001139 RValue<Bool> operator==(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001140 {
1141 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1142 }
1143
John Bauman19bac1e2014-05-06 15:23:49 -04001144 Type *Byte::getType()
John Bauman89401822014-05-06 15:04:28 -04001145 {
Nicolas Capensac230122016-09-20 14:30:06 -04001146 return T(llvm::Type::getInt8Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001147 }
1148
Nicolas Capens81f18302016-01-14 09:32:35 -05001149 SByte::SByte(Argument<SByte> argument)
John Bauman89401822014-05-06 15:04:28 -04001150 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001151 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001152 }
1153
Alexis Hetu77dfab42015-11-23 13:31:22 -05001154 SByte::SByte(RValue<Int> cast)
1155 {
1156 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1157
1158 storeValue(integer);
1159 }
1160
1161 SByte::SByte(RValue<Short> cast)
1162 {
1163 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1164
1165 storeValue(integer);
1166 }
1167
John Bauman89401822014-05-06 15:04:28 -04001168 SByte::SByte(signed char x)
1169 {
John Bauman66b8ab22014-05-06 15:57:45 -04001170 storeValue(Nucleus::createConstantByte(x));
John Bauman89401822014-05-06 15:04:28 -04001171 }
1172
John Bauman19bac1e2014-05-06 15:23:49 -04001173 SByte::SByte(RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001174 {
John Bauman66b8ab22014-05-06 15:57:45 -04001175 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001176 }
1177
1178 SByte::SByte(const SByte &rhs)
1179 {
John Bauman66b8ab22014-05-06 15:57:45 -04001180 Value *value = rhs.loadValue();
1181 storeValue(value);
1182 }
John Bauman89401822014-05-06 15:04:28 -04001183
John Bauman66b8ab22014-05-06 15:57:45 -04001184 SByte::SByte(const Reference<SByte> &rhs)
1185 {
1186 Value *value = rhs.loadValue();
1187 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001188 }
1189
Nicolas Capens96d4e092016-11-18 14:22:38 -05001190 RValue<SByte> SByte::operator=(RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001191 {
John Bauman66b8ab22014-05-06 15:57:45 -04001192 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001193
1194 return rhs;
1195 }
1196
Nicolas Capens96d4e092016-11-18 14:22:38 -05001197 RValue<SByte> SByte::operator=(const SByte &rhs)
John Bauman89401822014-05-06 15:04:28 -04001198 {
John Bauman66b8ab22014-05-06 15:57:45 -04001199 Value *value = rhs.loadValue();
1200 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001201
1202 return RValue<SByte>(value);
1203 }
1204
Nicolas Capens96d4e092016-11-18 14:22:38 -05001205 RValue<SByte> SByte::operator=(const Reference<SByte> &rhs)
John Bauman89401822014-05-06 15:04:28 -04001206 {
John Bauman66b8ab22014-05-06 15:57:45 -04001207 Value *value = rhs.loadValue();
1208 storeValue(value);
1209
1210 return RValue<SByte>(value);
John Bauman89401822014-05-06 15:04:28 -04001211 }
1212
John Bauman19bac1e2014-05-06 15:23:49 -04001213 RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001214 {
1215 return RValue<SByte>(Nucleus::createAdd(lhs.value, rhs.value));
1216 }
1217
John Bauman19bac1e2014-05-06 15:23:49 -04001218 RValue<SByte> operator-(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001219 {
1220 return RValue<SByte>(Nucleus::createSub(lhs.value, rhs.value));
1221 }
1222
John Bauman19bac1e2014-05-06 15:23:49 -04001223 RValue<SByte> operator*(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001224 {
1225 return RValue<SByte>(Nucleus::createMul(lhs.value, rhs.value));
1226 }
1227
John Bauman19bac1e2014-05-06 15:23:49 -04001228 RValue<SByte> operator/(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001229 {
1230 return RValue<SByte>(Nucleus::createSDiv(lhs.value, rhs.value));
1231 }
1232
John Bauman19bac1e2014-05-06 15:23:49 -04001233 RValue<SByte> operator%(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001234 {
1235 return RValue<SByte>(Nucleus::createSRem(lhs.value, rhs.value));
1236 }
1237
John Bauman19bac1e2014-05-06 15:23:49 -04001238 RValue<SByte> operator&(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001239 {
1240 return RValue<SByte>(Nucleus::createAnd(lhs.value, rhs.value));
1241 }
1242
John Bauman19bac1e2014-05-06 15:23:49 -04001243 RValue<SByte> operator|(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001244 {
1245 return RValue<SByte>(Nucleus::createOr(lhs.value, rhs.value));
1246 }
1247
John Bauman19bac1e2014-05-06 15:23:49 -04001248 RValue<SByte> operator^(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001249 {
1250 return RValue<SByte>(Nucleus::createXor(lhs.value, rhs.value));
1251 }
1252
John Bauman19bac1e2014-05-06 15:23:49 -04001253 RValue<SByte> operator<<(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001254 {
1255 return RValue<SByte>(Nucleus::createShl(lhs.value, rhs.value));
1256 }
1257
John Bauman19bac1e2014-05-06 15:23:49 -04001258 RValue<SByte> operator>>(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001259 {
1260 return RValue<SByte>(Nucleus::createAShr(lhs.value, rhs.value));
1261 }
1262
Nicolas Capens96d4e092016-11-18 14:22:38 -05001263 RValue<SByte> operator+=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001264 {
1265 return lhs = lhs + rhs;
1266 }
1267
Nicolas Capens96d4e092016-11-18 14:22:38 -05001268 RValue<SByte> operator-=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001269 {
1270 return lhs = lhs - rhs;
1271 }
1272
Nicolas Capens96d4e092016-11-18 14:22:38 -05001273 RValue<SByte> operator*=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001274 {
1275 return lhs = lhs * rhs;
1276 }
1277
Nicolas Capens96d4e092016-11-18 14:22:38 -05001278 RValue<SByte> operator/=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001279 {
1280 return lhs = lhs / rhs;
1281 }
1282
Nicolas Capens96d4e092016-11-18 14:22:38 -05001283 RValue<SByte> operator%=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001284 {
1285 return lhs = lhs % rhs;
1286 }
1287
Nicolas Capens96d4e092016-11-18 14:22:38 -05001288 RValue<SByte> operator&=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001289 {
1290 return lhs = lhs & rhs;
1291 }
1292
Nicolas Capens96d4e092016-11-18 14:22:38 -05001293 RValue<SByte> operator|=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001294 {
1295 return lhs = lhs | rhs;
1296 }
1297
Nicolas Capens96d4e092016-11-18 14:22:38 -05001298 RValue<SByte> operator^=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001299 {
1300 return lhs = lhs ^ rhs;
1301 }
1302
Nicolas Capens96d4e092016-11-18 14:22:38 -05001303 RValue<SByte> operator<<=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001304 {
1305 return lhs = lhs << rhs;
1306 }
1307
Nicolas Capens96d4e092016-11-18 14:22:38 -05001308 RValue<SByte> operator>>=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001309 {
1310 return lhs = lhs >> rhs;
1311 }
1312
John Bauman19bac1e2014-05-06 15:23:49 -04001313 RValue<SByte> operator+(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001314 {
1315 return val;
1316 }
1317
John Bauman19bac1e2014-05-06 15:23:49 -04001318 RValue<SByte> operator-(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001319 {
1320 return RValue<SByte>(Nucleus::createNeg(val.value));
1321 }
1322
John Bauman19bac1e2014-05-06 15:23:49 -04001323 RValue<SByte> operator~(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001324 {
1325 return RValue<SByte>(Nucleus::createNot(val.value));
1326 }
1327
Nicolas Capens96d4e092016-11-18 14:22:38 -05001328 RValue<SByte> operator++(SByte &val, int) // Post-increment
John Bauman89401822014-05-06 15:04:28 -04001329 {
1330 RValue<SByte> res = val;
1331
Nicolas Capens19336542016-09-26 10:32:29 -04001332 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantByte((signed char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001333 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001334
1335 return res;
1336 }
1337
Nicolas Capens96d4e092016-11-18 14:22:38 -05001338 const SByte &operator++(SByte &val) // Pre-increment
John Bauman89401822014-05-06 15:04:28 -04001339 {
Nicolas Capens19336542016-09-26 10:32:29 -04001340 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantByte((signed char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001341 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001342
1343 return val;
1344 }
1345
Nicolas Capens96d4e092016-11-18 14:22:38 -05001346 RValue<SByte> operator--(SByte &val, int) // Post-decrement
John Bauman89401822014-05-06 15:04:28 -04001347 {
1348 RValue<SByte> res = val;
1349
Nicolas Capens19336542016-09-26 10:32:29 -04001350 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantByte((signed char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001351 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001352
1353 return res;
1354 }
1355
Nicolas Capens96d4e092016-11-18 14:22:38 -05001356 const SByte &operator--(SByte &val) // Pre-decrement
John Bauman89401822014-05-06 15:04:28 -04001357 {
Nicolas Capens19336542016-09-26 10:32:29 -04001358 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantByte((signed char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001359 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001360
1361 return val;
1362 }
1363
John Bauman19bac1e2014-05-06 15:23:49 -04001364 RValue<Bool> operator<(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001365 {
1366 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
1367 }
1368
John Bauman19bac1e2014-05-06 15:23:49 -04001369 RValue<Bool> operator<=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001370 {
1371 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
1372 }
1373
John Bauman19bac1e2014-05-06 15:23:49 -04001374 RValue<Bool> operator>(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001375 {
1376 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
1377 }
1378
John Bauman19bac1e2014-05-06 15:23:49 -04001379 RValue<Bool> operator>=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001380 {
1381 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
1382 }
1383
John Bauman19bac1e2014-05-06 15:23:49 -04001384 RValue<Bool> operator!=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001385 {
1386 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1387 }
1388
John Bauman19bac1e2014-05-06 15:23:49 -04001389 RValue<Bool> operator==(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001390 {
1391 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1392 }
1393
John Bauman19bac1e2014-05-06 15:23:49 -04001394 Type *SByte::getType()
John Bauman89401822014-05-06 15:04:28 -04001395 {
Nicolas Capensac230122016-09-20 14:30:06 -04001396 return T(llvm::Type::getInt8Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001397 }
1398
Nicolas Capens81f18302016-01-14 09:32:35 -05001399 Short::Short(Argument<Short> argument)
John Bauman89401822014-05-06 15:04:28 -04001400 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001401 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001402 }
1403
John Bauman19bac1e2014-05-06 15:23:49 -04001404 Short::Short(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04001405 {
John Bauman89401822014-05-06 15:04:28 -04001406 Value *integer = Nucleus::createTrunc(cast.value, Short::getType());
1407
John Bauman66b8ab22014-05-06 15:57:45 -04001408 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04001409 }
1410
John Bauman89401822014-05-06 15:04:28 -04001411 Short::Short(short x)
1412 {
John Bauman66b8ab22014-05-06 15:57:45 -04001413 storeValue(Nucleus::createConstantShort(x));
John Bauman89401822014-05-06 15:04:28 -04001414 }
1415
John Bauman19bac1e2014-05-06 15:23:49 -04001416 Short::Short(RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001417 {
John Bauman66b8ab22014-05-06 15:57:45 -04001418 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001419 }
1420
1421 Short::Short(const Short &rhs)
1422 {
John Bauman66b8ab22014-05-06 15:57:45 -04001423 Value *value = rhs.loadValue();
1424 storeValue(value);
1425 }
John Bauman89401822014-05-06 15:04:28 -04001426
John Bauman66b8ab22014-05-06 15:57:45 -04001427 Short::Short(const Reference<Short> &rhs)
1428 {
1429 Value *value = rhs.loadValue();
1430 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001431 }
1432
Nicolas Capens96d4e092016-11-18 14:22:38 -05001433 RValue<Short> Short::operator=(RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001434 {
John Bauman66b8ab22014-05-06 15:57:45 -04001435 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001436
1437 return rhs;
1438 }
1439
Nicolas Capens96d4e092016-11-18 14:22:38 -05001440 RValue<Short> Short::operator=(const Short &rhs)
John Bauman89401822014-05-06 15:04:28 -04001441 {
John Bauman66b8ab22014-05-06 15:57:45 -04001442 Value *value = rhs.loadValue();
1443 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001444
1445 return RValue<Short>(value);
1446 }
1447
Nicolas Capens96d4e092016-11-18 14:22:38 -05001448 RValue<Short> Short::operator=(const Reference<Short> &rhs)
John Bauman89401822014-05-06 15:04:28 -04001449 {
John Bauman66b8ab22014-05-06 15:57:45 -04001450 Value *value = rhs.loadValue();
1451 storeValue(value);
1452
1453 return RValue<Short>(value);
John Bauman89401822014-05-06 15:04:28 -04001454 }
1455
John Bauman19bac1e2014-05-06 15:23:49 -04001456 RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001457 {
1458 return RValue<Short>(Nucleus::createAdd(lhs.value, rhs.value));
1459 }
1460
John Bauman19bac1e2014-05-06 15:23:49 -04001461 RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001462 {
1463 return RValue<Short>(Nucleus::createSub(lhs.value, rhs.value));
1464 }
1465
John Bauman19bac1e2014-05-06 15:23:49 -04001466 RValue<Short> operator*(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001467 {
1468 return RValue<Short>(Nucleus::createMul(lhs.value, rhs.value));
1469 }
1470
John Bauman19bac1e2014-05-06 15:23:49 -04001471 RValue<Short> operator/(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001472 {
1473 return RValue<Short>(Nucleus::createSDiv(lhs.value, rhs.value));
1474 }
1475
John Bauman19bac1e2014-05-06 15:23:49 -04001476 RValue<Short> operator%(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001477 {
1478 return RValue<Short>(Nucleus::createSRem(lhs.value, rhs.value));
1479 }
1480
John Bauman19bac1e2014-05-06 15:23:49 -04001481 RValue<Short> operator&(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001482 {
1483 return RValue<Short>(Nucleus::createAnd(lhs.value, rhs.value));
1484 }
1485
John Bauman19bac1e2014-05-06 15:23:49 -04001486 RValue<Short> operator|(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001487 {
1488 return RValue<Short>(Nucleus::createOr(lhs.value, rhs.value));
1489 }
1490
John Bauman19bac1e2014-05-06 15:23:49 -04001491 RValue<Short> operator^(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001492 {
1493 return RValue<Short>(Nucleus::createXor(lhs.value, rhs.value));
1494 }
1495
John Bauman19bac1e2014-05-06 15:23:49 -04001496 RValue<Short> operator<<(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001497 {
1498 return RValue<Short>(Nucleus::createShl(lhs.value, rhs.value));
1499 }
1500
John Bauman19bac1e2014-05-06 15:23:49 -04001501 RValue<Short> operator>>(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001502 {
1503 return RValue<Short>(Nucleus::createAShr(lhs.value, rhs.value));
1504 }
1505
Nicolas Capens96d4e092016-11-18 14:22:38 -05001506 RValue<Short> operator+=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001507 {
1508 return lhs = lhs + rhs;
1509 }
1510
Nicolas Capens96d4e092016-11-18 14:22:38 -05001511 RValue<Short> operator-=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001512 {
1513 return lhs = lhs - rhs;
1514 }
1515
Nicolas Capens96d4e092016-11-18 14:22:38 -05001516 RValue<Short> operator*=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001517 {
1518 return lhs = lhs * rhs;
1519 }
1520
Nicolas Capens96d4e092016-11-18 14:22:38 -05001521 RValue<Short> operator/=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001522 {
1523 return lhs = lhs / rhs;
1524 }
1525
Nicolas Capens96d4e092016-11-18 14:22:38 -05001526 RValue<Short> operator%=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001527 {
1528 return lhs = lhs % rhs;
1529 }
1530
Nicolas Capens96d4e092016-11-18 14:22:38 -05001531 RValue<Short> operator&=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001532 {
1533 return lhs = lhs & rhs;
1534 }
1535
Nicolas Capens96d4e092016-11-18 14:22:38 -05001536 RValue<Short> operator|=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001537 {
1538 return lhs = lhs | rhs;
1539 }
1540
Nicolas Capens96d4e092016-11-18 14:22:38 -05001541 RValue<Short> operator^=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001542 {
1543 return lhs = lhs ^ rhs;
1544 }
1545
Nicolas Capens96d4e092016-11-18 14:22:38 -05001546 RValue<Short> operator<<=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001547 {
1548 return lhs = lhs << rhs;
1549 }
1550
Nicolas Capens96d4e092016-11-18 14:22:38 -05001551 RValue<Short> operator>>=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001552 {
1553 return lhs = lhs >> rhs;
1554 }
1555
John Bauman19bac1e2014-05-06 15:23:49 -04001556 RValue<Short> operator+(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001557 {
1558 return val;
1559 }
1560
John Bauman19bac1e2014-05-06 15:23:49 -04001561 RValue<Short> operator-(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001562 {
1563 return RValue<Short>(Nucleus::createNeg(val.value));
1564 }
1565
John Bauman19bac1e2014-05-06 15:23:49 -04001566 RValue<Short> operator~(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001567 {
1568 return RValue<Short>(Nucleus::createNot(val.value));
1569 }
1570
Nicolas Capens96d4e092016-11-18 14:22:38 -05001571 RValue<Short> operator++(Short &val, int) // Post-increment
John Bauman89401822014-05-06 15:04:28 -04001572 {
1573 RValue<Short> res = val;
1574
Nicolas Capens19336542016-09-26 10:32:29 -04001575 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantShort((short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001576 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001577
1578 return res;
1579 }
1580
Nicolas Capens96d4e092016-11-18 14:22:38 -05001581 const Short &operator++(Short &val) // Pre-increment
John Bauman89401822014-05-06 15:04:28 -04001582 {
Nicolas Capens19336542016-09-26 10:32:29 -04001583 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantShort((short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001584 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001585
1586 return val;
1587 }
1588
Nicolas Capens96d4e092016-11-18 14:22:38 -05001589 RValue<Short> operator--(Short &val, int) // Post-decrement
John Bauman89401822014-05-06 15:04:28 -04001590 {
1591 RValue<Short> res = val;
1592
Nicolas Capens19336542016-09-26 10:32:29 -04001593 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantShort((short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001594 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001595
1596 return res;
1597 }
1598
Nicolas Capens96d4e092016-11-18 14:22:38 -05001599 const Short &operator--(Short &val) // Pre-decrement
John Bauman89401822014-05-06 15:04:28 -04001600 {
Nicolas Capens19336542016-09-26 10:32:29 -04001601 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantShort((short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001602 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001603
1604 return val;
1605 }
1606
John Bauman19bac1e2014-05-06 15:23:49 -04001607 RValue<Bool> operator<(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001608 {
1609 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
1610 }
1611
John Bauman19bac1e2014-05-06 15:23:49 -04001612 RValue<Bool> operator<=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001613 {
1614 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
1615 }
1616
John Bauman19bac1e2014-05-06 15:23:49 -04001617 RValue<Bool> operator>(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001618 {
1619 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
1620 }
1621
John Bauman19bac1e2014-05-06 15:23:49 -04001622 RValue<Bool> operator>=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001623 {
1624 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
1625 }
1626
John Bauman19bac1e2014-05-06 15:23:49 -04001627 RValue<Bool> operator!=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001628 {
1629 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1630 }
1631
John Bauman19bac1e2014-05-06 15:23:49 -04001632 RValue<Bool> operator==(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001633 {
1634 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1635 }
1636
John Bauman19bac1e2014-05-06 15:23:49 -04001637 Type *Short::getType()
John Bauman89401822014-05-06 15:04:28 -04001638 {
Nicolas Capensac230122016-09-20 14:30:06 -04001639 return T(llvm::Type::getInt16Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001640 }
1641
Nicolas Capens81f18302016-01-14 09:32:35 -05001642 UShort::UShort(Argument<UShort> argument)
John Bauman89401822014-05-06 15:04:28 -04001643 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001644 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001645 }
1646
Alexis Hetu77dfab42015-11-23 13:31:22 -05001647 UShort::UShort(RValue<UInt> cast)
1648 {
1649 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
1650
1651 storeValue(integer);
1652 }
1653
Alexis Hetu75b650f2015-11-19 17:40:15 -05001654 UShort::UShort(RValue<Int> cast)
1655 {
1656 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
1657
1658 storeValue(integer);
1659 }
1660
John Bauman89401822014-05-06 15:04:28 -04001661 UShort::UShort(unsigned short x)
1662 {
John Bauman66b8ab22014-05-06 15:57:45 -04001663 storeValue(Nucleus::createConstantShort(x));
John Bauman89401822014-05-06 15:04:28 -04001664 }
1665
John Bauman19bac1e2014-05-06 15:23:49 -04001666 UShort::UShort(RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001667 {
John Bauman66b8ab22014-05-06 15:57:45 -04001668 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001669 }
1670
1671 UShort::UShort(const UShort &rhs)
1672 {
John Bauman66b8ab22014-05-06 15:57:45 -04001673 Value *value = rhs.loadValue();
1674 storeValue(value);
1675 }
John Bauman89401822014-05-06 15:04:28 -04001676
John Bauman66b8ab22014-05-06 15:57:45 -04001677 UShort::UShort(const Reference<UShort> &rhs)
1678 {
1679 Value *value = rhs.loadValue();
1680 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001681 }
1682
Nicolas Capens96d4e092016-11-18 14:22:38 -05001683 RValue<UShort> UShort::operator=(RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001684 {
John Bauman66b8ab22014-05-06 15:57:45 -04001685 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001686
1687 return rhs;
1688 }
1689
Nicolas Capens96d4e092016-11-18 14:22:38 -05001690 RValue<UShort> UShort::operator=(const UShort &rhs)
John Bauman89401822014-05-06 15:04:28 -04001691 {
John Bauman66b8ab22014-05-06 15:57:45 -04001692 Value *value = rhs.loadValue();
1693 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001694
1695 return RValue<UShort>(value);
1696 }
1697
Nicolas Capens96d4e092016-11-18 14:22:38 -05001698 RValue<UShort> UShort::operator=(const Reference<UShort> &rhs)
John Bauman89401822014-05-06 15:04:28 -04001699 {
John Bauman66b8ab22014-05-06 15:57:45 -04001700 Value *value = rhs.loadValue();
1701 storeValue(value);
1702
1703 return RValue<UShort>(value);
John Bauman89401822014-05-06 15:04:28 -04001704 }
1705
John Bauman19bac1e2014-05-06 15:23:49 -04001706 RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001707 {
1708 return RValue<UShort>(Nucleus::createAdd(lhs.value, rhs.value));
1709 }
1710
John Bauman19bac1e2014-05-06 15:23:49 -04001711 RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001712 {
1713 return RValue<UShort>(Nucleus::createSub(lhs.value, rhs.value));
1714 }
1715
John Bauman19bac1e2014-05-06 15:23:49 -04001716 RValue<UShort> operator*(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001717 {
1718 return RValue<UShort>(Nucleus::createMul(lhs.value, rhs.value));
1719 }
1720
John Bauman19bac1e2014-05-06 15:23:49 -04001721 RValue<UShort> operator/(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001722 {
1723 return RValue<UShort>(Nucleus::createUDiv(lhs.value, rhs.value));
1724 }
1725
John Bauman19bac1e2014-05-06 15:23:49 -04001726 RValue<UShort> operator%(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001727 {
1728 return RValue<UShort>(Nucleus::createURem(lhs.value, rhs.value));
1729 }
1730
John Bauman19bac1e2014-05-06 15:23:49 -04001731 RValue<UShort> operator&(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001732 {
1733 return RValue<UShort>(Nucleus::createAnd(lhs.value, rhs.value));
1734 }
1735
John Bauman19bac1e2014-05-06 15:23:49 -04001736 RValue<UShort> operator|(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001737 {
1738 return RValue<UShort>(Nucleus::createOr(lhs.value, rhs.value));
1739 }
1740
John Bauman19bac1e2014-05-06 15:23:49 -04001741 RValue<UShort> operator^(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001742 {
1743 return RValue<UShort>(Nucleus::createXor(lhs.value, rhs.value));
1744 }
1745
John Bauman19bac1e2014-05-06 15:23:49 -04001746 RValue<UShort> operator<<(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001747 {
1748 return RValue<UShort>(Nucleus::createShl(lhs.value, rhs.value));
1749 }
1750
John Bauman19bac1e2014-05-06 15:23:49 -04001751 RValue<UShort> operator>>(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001752 {
1753 return RValue<UShort>(Nucleus::createLShr(lhs.value, rhs.value));
1754 }
1755
Nicolas Capens96d4e092016-11-18 14:22:38 -05001756 RValue<UShort> operator+=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001757 {
1758 return lhs = lhs + rhs;
1759 }
1760
Nicolas Capens96d4e092016-11-18 14:22:38 -05001761 RValue<UShort> operator-=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001762 {
1763 return lhs = lhs - rhs;
1764 }
1765
Nicolas Capens96d4e092016-11-18 14:22:38 -05001766 RValue<UShort> operator*=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001767 {
1768 return lhs = lhs * rhs;
1769 }
1770
Nicolas Capens96d4e092016-11-18 14:22:38 -05001771 RValue<UShort> operator/=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001772 {
1773 return lhs = lhs / rhs;
1774 }
1775
Nicolas Capens96d4e092016-11-18 14:22:38 -05001776 RValue<UShort> operator%=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001777 {
1778 return lhs = lhs % rhs;
1779 }
1780
Nicolas Capens96d4e092016-11-18 14:22:38 -05001781 RValue<UShort> operator&=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001782 {
1783 return lhs = lhs & rhs;
1784 }
1785
Nicolas Capens96d4e092016-11-18 14:22:38 -05001786 RValue<UShort> operator|=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001787 {
1788 return lhs = lhs | rhs;
1789 }
1790
Nicolas Capens96d4e092016-11-18 14:22:38 -05001791 RValue<UShort> operator^=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001792 {
1793 return lhs = lhs ^ rhs;
1794 }
1795
Nicolas Capens96d4e092016-11-18 14:22:38 -05001796 RValue<UShort> operator<<=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001797 {
1798 return lhs = lhs << rhs;
1799 }
1800
Nicolas Capens96d4e092016-11-18 14:22:38 -05001801 RValue<UShort> operator>>=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001802 {
1803 return lhs = lhs >> rhs;
1804 }
1805
John Bauman19bac1e2014-05-06 15:23:49 -04001806 RValue<UShort> operator+(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001807 {
1808 return val;
1809 }
1810
John Bauman19bac1e2014-05-06 15:23:49 -04001811 RValue<UShort> operator-(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001812 {
1813 return RValue<UShort>(Nucleus::createNeg(val.value));
1814 }
1815
John Bauman19bac1e2014-05-06 15:23:49 -04001816 RValue<UShort> operator~(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001817 {
1818 return RValue<UShort>(Nucleus::createNot(val.value));
1819 }
1820
Nicolas Capens96d4e092016-11-18 14:22:38 -05001821 RValue<UShort> operator++(UShort &val, int) // Post-increment
John Bauman89401822014-05-06 15:04:28 -04001822 {
1823 RValue<UShort> res = val;
1824
Nicolas Capens19336542016-09-26 10:32:29 -04001825 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantShort((unsigned short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001826 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001827
1828 return res;
1829 }
1830
Nicolas Capens96d4e092016-11-18 14:22:38 -05001831 const UShort &operator++(UShort &val) // Pre-increment
John Bauman89401822014-05-06 15:04:28 -04001832 {
Nicolas Capens19336542016-09-26 10:32:29 -04001833 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantShort((unsigned short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001834 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001835
1836 return val;
1837 }
1838
Nicolas Capens96d4e092016-11-18 14:22:38 -05001839 RValue<UShort> operator--(UShort &val, int) // Post-decrement
John Bauman89401822014-05-06 15:04:28 -04001840 {
1841 RValue<UShort> res = val;
1842
Nicolas Capens19336542016-09-26 10:32:29 -04001843 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantShort((unsigned short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001844 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001845
1846 return res;
1847 }
1848
Nicolas Capens96d4e092016-11-18 14:22:38 -05001849 const UShort &operator--(UShort &val) // Pre-decrement
John Bauman89401822014-05-06 15:04:28 -04001850 {
Nicolas Capens19336542016-09-26 10:32:29 -04001851 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantShort((unsigned short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001852 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001853
1854 return val;
1855 }
1856
John Bauman19bac1e2014-05-06 15:23:49 -04001857 RValue<Bool> operator<(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001858 {
1859 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1860 }
1861
John Bauman19bac1e2014-05-06 15:23:49 -04001862 RValue<Bool> operator<=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001863 {
1864 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1865 }
1866
John Bauman19bac1e2014-05-06 15:23:49 -04001867 RValue<Bool> operator>(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001868 {
1869 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1870 }
1871
John Bauman19bac1e2014-05-06 15:23:49 -04001872 RValue<Bool> operator>=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001873 {
1874 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1875 }
1876
John Bauman19bac1e2014-05-06 15:23:49 -04001877 RValue<Bool> operator!=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001878 {
1879 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1880 }
1881
John Bauman19bac1e2014-05-06 15:23:49 -04001882 RValue<Bool> operator==(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001883 {
1884 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1885 }
1886
John Bauman19bac1e2014-05-06 15:23:49 -04001887 Type *UShort::getType()
John Bauman89401822014-05-06 15:04:28 -04001888 {
Nicolas Capensac230122016-09-20 14:30:06 -04001889 return T(llvm::Type::getInt16Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001890 }
1891
Nicolas Capens16b5f152016-10-13 13:39:01 -04001892 Byte4::Byte4(RValue<Byte8> cast)
1893 {
Nicolas Capens16b5f152016-10-13 13:39:01 -04001894 storeValue(Nucleus::createTrunc(Nucleus::createBitCast(cast.value, Long::getType()), Int::getType()));
1895 }
1896
1897 Byte4::Byte4(const Reference<Byte4> &rhs)
1898 {
Nicolas Capens16b5f152016-10-13 13:39:01 -04001899 Value *value = rhs.loadValue();
1900 storeValue(value);
1901 }
1902
John Bauman19bac1e2014-05-06 15:23:49 -04001903 Type *Byte4::getType()
John Bauman89401822014-05-06 15:04:28 -04001904 {
1905 #if 0
Nicolas Capensac230122016-09-20 14:30:06 -04001906 return T(VectorType::get(Byte::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04001907 #else
1908 return UInt::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
1909 #endif
1910 }
1911
John Bauman19bac1e2014-05-06 15:23:49 -04001912 Type *SByte4::getType()
John Bauman89401822014-05-06 15:04:28 -04001913 {
1914 #if 0
Nicolas Capensac230122016-09-20 14:30:06 -04001915 return T(VectorType::get(SByte::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04001916 #else
1917 return Int::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
1918 #endif
1919 }
1920
Nicolas Capens3bbc5e12016-09-27 10:49:52 -04001921 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 -04001922 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04001923 int64_t constantVector[8] = {x0, x1, x2, x3, x4, x5, x6, x7};
1924 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(Byte::getType(), 8))));
John Bauman89401822014-05-06 15:04:28 -04001925
John Bauman66b8ab22014-05-06 15:57:45 -04001926 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04001927 }
1928
John Bauman19bac1e2014-05-06 15:23:49 -04001929 Byte8::Byte8(RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04001930 {
John Bauman66b8ab22014-05-06 15:57:45 -04001931 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001932 }
1933
1934 Byte8::Byte8(const Byte8 &rhs)
1935 {
John Bauman66b8ab22014-05-06 15:57:45 -04001936 Value *value = rhs.loadValue();
1937 storeValue(value);
1938 }
1939
1940 Byte8::Byte8(const Reference<Byte8> &rhs)
1941 {
John Bauman66b8ab22014-05-06 15:57:45 -04001942 Value *value = rhs.loadValue();
1943 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001944 }
1945
Nicolas Capens96d4e092016-11-18 14:22:38 -05001946 RValue<Byte8> Byte8::operator=(RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04001947 {
John Bauman66b8ab22014-05-06 15:57:45 -04001948 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001949
1950 return rhs;
1951 }
1952
Nicolas Capens96d4e092016-11-18 14:22:38 -05001953 RValue<Byte8> Byte8::operator=(const Byte8 &rhs)
John Bauman89401822014-05-06 15:04:28 -04001954 {
John Bauman66b8ab22014-05-06 15:57:45 -04001955 Value *value = rhs.loadValue();
1956 storeValue(value);
1957
1958 return RValue<Byte8>(value);
1959 }
1960
Nicolas Capens96d4e092016-11-18 14:22:38 -05001961 RValue<Byte8> Byte8::operator=(const Reference<Byte8> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04001962 {
1963 Value *value = rhs.loadValue();
1964 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001965
1966 return RValue<Byte8>(value);
1967 }
1968
John Bauman19bac1e2014-05-06 15:23:49 -04001969 RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04001970 {
John Bauman19bac1e2014-05-06 15:23:49 -04001971 if(CPUID::supportsMMX2())
1972 {
1973 return x86::paddb(lhs, rhs);
1974 }
1975 else
1976 {
1977 return RValue<Byte8>(Nucleus::createAdd(lhs.value, rhs.value));
1978 }
John Bauman89401822014-05-06 15:04:28 -04001979 }
1980
John Bauman19bac1e2014-05-06 15:23:49 -04001981 RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04001982 {
John Bauman19bac1e2014-05-06 15:23:49 -04001983 if(CPUID::supportsMMX2())
1984 {
1985 return x86::psubb(lhs, rhs);
1986 }
1987 else
1988 {
1989 return RValue<Byte8>(Nucleus::createSub(lhs.value, rhs.value));
1990 }
John Bauman89401822014-05-06 15:04:28 -04001991 }
1992
John Bauman19bac1e2014-05-06 15:23:49 -04001993// RValue<Byte8> operator*(RValue<Byte8> lhs, RValue<Byte8> rhs)
1994// {
1995// return RValue<Byte8>(Nucleus::createMul(lhs.value, rhs.value));
1996// }
1997
1998// RValue<Byte8> operator/(RValue<Byte8> lhs, RValue<Byte8> rhs)
1999// {
2000// return RValue<Byte8>(Nucleus::createUDiv(lhs.value, rhs.value));
2001// }
2002
2003// RValue<Byte8> operator%(RValue<Byte8> lhs, RValue<Byte8> rhs)
2004// {
2005// return RValue<Byte8>(Nucleus::createURem(lhs.value, rhs.value));
2006// }
2007
2008 RValue<Byte8> operator&(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002009 {
John Bauman19bac1e2014-05-06 15:23:49 -04002010 if(CPUID::supportsMMX2())
2011 {
2012 return As<Byte8>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
2013 }
2014 else
2015 {
2016 return RValue<Byte8>(Nucleus::createAnd(lhs.value, rhs.value));
2017 }
John Bauman89401822014-05-06 15:04:28 -04002018 }
2019
John Bauman19bac1e2014-05-06 15:23:49 -04002020 RValue<Byte8> operator|(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002021 {
John Bauman19bac1e2014-05-06 15:23:49 -04002022 if(CPUID::supportsMMX2())
2023 {
2024 return As<Byte8>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
2025 }
2026 else
2027 {
2028 return RValue<Byte8>(Nucleus::createOr(lhs.value, rhs.value));
2029 }
John Bauman89401822014-05-06 15:04:28 -04002030 }
2031
John Bauman19bac1e2014-05-06 15:23:49 -04002032 RValue<Byte8> operator^(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002033 {
John Bauman19bac1e2014-05-06 15:23:49 -04002034 if(CPUID::supportsMMX2())
2035 {
2036 return As<Byte8>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
2037 }
2038 else
John Bauman66b8ab22014-05-06 15:57:45 -04002039 {
John Bauman19bac1e2014-05-06 15:23:49 -04002040 return RValue<Byte8>(Nucleus::createXor(lhs.value, rhs.value));
2041 }
John Bauman89401822014-05-06 15:04:28 -04002042 }
2043
John Bauman19bac1e2014-05-06 15:23:49 -04002044// RValue<Byte8> operator<<(RValue<Byte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002045// {
2046// return RValue<Byte8>(Nucleus::createShl(lhs.value, rhs.value));
2047// }
2048
John Bauman19bac1e2014-05-06 15:23:49 -04002049// RValue<Byte8> operator>>(RValue<Byte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002050// {
2051// return RValue<Byte8>(Nucleus::createLShr(lhs.value, rhs.value));
2052// }
2053
Nicolas Capens96d4e092016-11-18 14:22:38 -05002054 RValue<Byte8> operator+=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002055 {
2056 return lhs = lhs + rhs;
2057 }
2058
Nicolas Capens96d4e092016-11-18 14:22:38 -05002059 RValue<Byte8> operator-=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002060 {
2061 return lhs = lhs - rhs;
2062 }
2063
Nicolas Capens96d4e092016-11-18 14:22:38 -05002064// RValue<Byte8> operator*=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002065// {
2066// return lhs = lhs * rhs;
2067// }
John Bauman89401822014-05-06 15:04:28 -04002068
Nicolas Capens96d4e092016-11-18 14:22:38 -05002069// RValue<Byte8> operator/=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002070// {
2071// return lhs = lhs / rhs;
2072// }
John Bauman89401822014-05-06 15:04:28 -04002073
Nicolas Capens96d4e092016-11-18 14:22:38 -05002074// RValue<Byte8> operator%=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002075// {
2076// return lhs = lhs % rhs;
2077// }
John Bauman89401822014-05-06 15:04:28 -04002078
Nicolas Capens96d4e092016-11-18 14:22:38 -05002079 RValue<Byte8> operator&=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002080 {
2081 return lhs = lhs & rhs;
2082 }
2083
Nicolas Capens96d4e092016-11-18 14:22:38 -05002084 RValue<Byte8> operator|=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002085 {
2086 return lhs = lhs | rhs;
2087 }
2088
Nicolas Capens96d4e092016-11-18 14:22:38 -05002089 RValue<Byte8> operator^=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002090 {
2091 return lhs = lhs ^ rhs;
2092 }
2093
Nicolas Capens96d4e092016-11-18 14:22:38 -05002094// RValue<Byte8> operator<<=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002095// {
2096// return lhs = lhs << rhs;
2097// }
2098
Nicolas Capens96d4e092016-11-18 14:22:38 -05002099// RValue<Byte8> operator>>=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002100// {
2101// return lhs = lhs >> rhs;
2102// }
2103
John Bauman19bac1e2014-05-06 15:23:49 -04002104// RValue<Byte8> operator+(RValue<Byte8> val)
2105// {
2106// return val;
2107// }
2108
2109// RValue<Byte8> operator-(RValue<Byte8> val)
2110// {
2111// return RValue<Byte8>(Nucleus::createNeg(val.value));
2112// }
2113
2114 RValue<Byte8> operator~(RValue<Byte8> val)
John Bauman89401822014-05-06 15:04:28 -04002115 {
John Bauman19bac1e2014-05-06 15:23:49 -04002116 if(CPUID::supportsMMX2())
2117 {
Nicolas Capens16b5f152016-10-13 13:39:01 -04002118 return val ^ Byte8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
John Bauman19bac1e2014-05-06 15:23:49 -04002119 }
2120 else
2121 {
2122 return RValue<Byte8>(Nucleus::createNot(val.value));
2123 }
John Bauman89401822014-05-06 15:04:28 -04002124 }
2125
John Bauman19bac1e2014-05-06 15:23:49 -04002126 RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002127 {
2128 return x86::paddusb(x, y);
2129 }
John Bauman66b8ab22014-05-06 15:57:45 -04002130
John Bauman19bac1e2014-05-06 15:23:49 -04002131 RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002132 {
2133 return x86::psubusb(x, y);
2134 }
2135
John Bauman19bac1e2014-05-06 15:23:49 -04002136 RValue<Short4> Unpack(RValue<Byte4> x)
John Bauman89401822014-05-06 15:04:28 -04002137 {
Nicolas Capens19336542016-09-26 10:32:29 -04002138 Value *int2 = Nucleus::createInsertElement(V(UndefValue::get(VectorType::get(Int::getType(), 2))), x.value, 0);
John Bauman19bac1e2014-05-06 15:23:49 -04002139 Value *byte8 = Nucleus::createBitCast(int2, Byte8::getType());
John Bauman89401822014-05-06 15:04:28 -04002140
John Bauman19bac1e2014-05-06 15:23:49 -04002141 return UnpackLow(RValue<Byte8>(byte8), RValue<Byte8>(byte8));
2142 }
John Bauman89401822014-05-06 15:04:28 -04002143
Nicolas Capens411273e2017-01-26 15:13:36 -08002144 RValue<Short4> Unpack(RValue<Byte4> x, RValue<Byte4> y)
2145 {
2146 Value *xx = Nucleus::createInsertElement(V(UndefValue::get(VectorType::get(Int::getType(), 2))), x.value, 0);
2147 Value *yy = Nucleus::createInsertElement(V(UndefValue::get(VectorType::get(Int::getType(), 2))), y.value, 0);
2148
2149 return UnpackLow(As<Byte8>(xx), As<Byte8>(yy));
2150 }
2151
John Bauman19bac1e2014-05-06 15:23:49 -04002152 RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y)
2153 {
2154 if(CPUID::supportsMMX2())
2155 {
2156 return x86::punpcklbw(x, y);
2157 }
2158 else
2159 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002160 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11};
2161 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman19bac1e2014-05-06 15:23:49 -04002162
2163 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2164 }
John Bauman89401822014-05-06 15:04:28 -04002165 }
John Bauman66b8ab22014-05-06 15:57:45 -04002166
John Bauman19bac1e2014-05-06 15:23:49 -04002167 RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002168 {
John Bauman19bac1e2014-05-06 15:23:49 -04002169 if(CPUID::supportsMMX2())
2170 {
2171 return x86::punpckhbw(x, y);
2172 }
2173 else
2174 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002175 int shuffle[8] = {4, 12, 5, 13, 6, 14, 7, 15};
2176 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002177
John Bauman19bac1e2014-05-06 15:23:49 -04002178 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2179 }
John Bauman89401822014-05-06 15:04:28 -04002180 }
2181
John Bauman19bac1e2014-05-06 15:23:49 -04002182 RValue<Int> SignMask(RValue<Byte8> x)
John Bauman89401822014-05-06 15:04:28 -04002183 {
2184 return x86::pmovmskb(x);
2185 }
2186
John Bauman19bac1e2014-05-06 15:23:49 -04002187// RValue<Byte8> CmpGT(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002188// {
2189// return x86::pcmpgtb(x, y); // FIXME: Signedness
2190// }
John Bauman66b8ab22014-05-06 15:57:45 -04002191
John Bauman19bac1e2014-05-06 15:23:49 -04002192 RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002193 {
2194 return x86::pcmpeqb(x, y);
2195 }
2196
John Bauman19bac1e2014-05-06 15:23:49 -04002197 Type *Byte8::getType()
John Bauman89401822014-05-06 15:04:28 -04002198 {
John Bauman19bac1e2014-05-06 15:23:49 -04002199 if(CPUID::supportsMMX2())
2200 {
2201 return MMX::getType();
2202 }
2203 else
2204 {
Nicolas Capensac230122016-09-20 14:30:06 -04002205 return T(VectorType::get(Byte::getType(), 8));
John Bauman19bac1e2014-05-06 15:23:49 -04002206 }
John Bauman89401822014-05-06 15:04:28 -04002207 }
2208
Nicolas Capens3bbc5e12016-09-27 10:49:52 -04002209 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 -04002210 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04002211 int64_t constantVector[8] = {x0, x1, x2, x3, x4, x5, x6, x7};
2212 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(SByte::getType(), 8))));
John Bauman89401822014-05-06 15:04:28 -04002213
John Bauman66b8ab22014-05-06 15:57:45 -04002214 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04002215 }
2216
John Bauman19bac1e2014-05-06 15:23:49 -04002217 SByte8::SByte8(RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002218 {
John Bauman66b8ab22014-05-06 15:57:45 -04002219 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002220 }
2221
2222 SByte8::SByte8(const SByte8 &rhs)
2223 {
John Bauman66b8ab22014-05-06 15:57:45 -04002224 Value *value = rhs.loadValue();
2225 storeValue(value);
2226 }
2227
2228 SByte8::SByte8(const Reference<SByte8> &rhs)
2229 {
John Bauman66b8ab22014-05-06 15:57:45 -04002230 Value *value = rhs.loadValue();
2231 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002232 }
2233
Nicolas Capens96d4e092016-11-18 14:22:38 -05002234 RValue<SByte8> SByte8::operator=(RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002235 {
John Bauman66b8ab22014-05-06 15:57:45 -04002236 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002237
2238 return rhs;
2239 }
2240
Nicolas Capens96d4e092016-11-18 14:22:38 -05002241 RValue<SByte8> SByte8::operator=(const SByte8 &rhs)
John Bauman89401822014-05-06 15:04:28 -04002242 {
John Bauman66b8ab22014-05-06 15:57:45 -04002243 Value *value = rhs.loadValue();
2244 storeValue(value);
2245
2246 return RValue<SByte8>(value);
2247 }
2248
Nicolas Capens96d4e092016-11-18 14:22:38 -05002249 RValue<SByte8> SByte8::operator=(const Reference<SByte8> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04002250 {
2251 Value *value = rhs.loadValue();
2252 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002253
2254 return RValue<SByte8>(value);
2255 }
2256
John Bauman19bac1e2014-05-06 15:23:49 -04002257 RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002258 {
John Bauman19bac1e2014-05-06 15:23:49 -04002259 if(CPUID::supportsMMX2())
2260 {
2261 return As<SByte8>(x86::paddb(As<Byte8>(lhs), As<Byte8>(rhs)));
2262 }
2263 else
2264 {
2265 return RValue<SByte8>(Nucleus::createAdd(lhs.value, rhs.value));
2266 }
John Bauman89401822014-05-06 15:04:28 -04002267 }
2268
John Bauman19bac1e2014-05-06 15:23:49 -04002269 RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002270 {
John Bauman19bac1e2014-05-06 15:23:49 -04002271 if(CPUID::supportsMMX2())
2272 {
2273 return As<SByte8>(x86::psubb(As<Byte8>(lhs), As<Byte8>(rhs)));
2274 }
2275 else
2276 {
2277 return RValue<SByte8>(Nucleus::createSub(lhs.value, rhs.value));
2278 }
John Bauman89401822014-05-06 15:04:28 -04002279 }
2280
John Bauman19bac1e2014-05-06 15:23:49 -04002281// RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs)
2282// {
2283// return RValue<SByte8>(Nucleus::createMul(lhs.value, rhs.value));
2284// }
John Bauman89401822014-05-06 15:04:28 -04002285
John Bauman19bac1e2014-05-06 15:23:49 -04002286// RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs)
2287// {
2288// return RValue<SByte8>(Nucleus::createSDiv(lhs.value, rhs.value));
2289// }
John Bauman89401822014-05-06 15:04:28 -04002290
John Bauman19bac1e2014-05-06 15:23:49 -04002291// RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs)
2292// {
2293// return RValue<SByte8>(Nucleus::createSRem(lhs.value, rhs.value));
2294// }
John Bauman89401822014-05-06 15:04:28 -04002295
John Bauman19bac1e2014-05-06 15:23:49 -04002296 RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002297 {
2298 return RValue<SByte8>(Nucleus::createAnd(lhs.value, rhs.value));
2299 }
2300
John Bauman19bac1e2014-05-06 15:23:49 -04002301 RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002302 {
2303 return RValue<SByte8>(Nucleus::createOr(lhs.value, rhs.value));
2304 }
2305
John Bauman19bac1e2014-05-06 15:23:49 -04002306 RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002307 {
2308 return RValue<SByte8>(Nucleus::createXor(lhs.value, rhs.value));
2309 }
2310
John Bauman19bac1e2014-05-06 15:23:49 -04002311// RValue<SByte8> operator<<(RValue<SByte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002312// {
2313// return RValue<SByte8>(Nucleus::createShl(lhs.value, rhs.value));
2314// }
2315
John Bauman19bac1e2014-05-06 15:23:49 -04002316// RValue<SByte8> operator>>(RValue<SByte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002317// {
2318// return RValue<SByte8>(Nucleus::createAShr(lhs.value, rhs.value));
2319// }
2320
Nicolas Capens96d4e092016-11-18 14:22:38 -05002321 RValue<SByte8> operator+=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002322 {
2323 return lhs = lhs + rhs;
2324 }
2325
Nicolas Capens96d4e092016-11-18 14:22:38 -05002326 RValue<SByte8> operator-=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002327 {
2328 return lhs = lhs - rhs;
2329 }
2330
Nicolas Capens96d4e092016-11-18 14:22:38 -05002331// RValue<SByte8> operator*=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002332// {
2333// return lhs = lhs * rhs;
2334// }
John Bauman89401822014-05-06 15:04:28 -04002335
Nicolas Capens96d4e092016-11-18 14:22:38 -05002336// RValue<SByte8> operator/=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002337// {
2338// return lhs = lhs / rhs;
2339// }
John Bauman89401822014-05-06 15:04:28 -04002340
Nicolas Capens96d4e092016-11-18 14:22:38 -05002341// RValue<SByte8> operator%=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002342// {
2343// return lhs = lhs % rhs;
2344// }
John Bauman89401822014-05-06 15:04:28 -04002345
Nicolas Capens96d4e092016-11-18 14:22:38 -05002346 RValue<SByte8> operator&=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002347 {
2348 return lhs = lhs & rhs;
2349 }
2350
Nicolas Capens96d4e092016-11-18 14:22:38 -05002351 RValue<SByte8> operator|=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002352 {
2353 return lhs = lhs | rhs;
2354 }
2355
Nicolas Capens96d4e092016-11-18 14:22:38 -05002356 RValue<SByte8> operator^=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002357 {
2358 return lhs = lhs ^ rhs;
2359 }
2360
Nicolas Capens96d4e092016-11-18 14:22:38 -05002361// RValue<SByte8> operator<<=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002362// {
2363// return lhs = lhs << rhs;
2364// }
2365
Nicolas Capens96d4e092016-11-18 14:22:38 -05002366// RValue<SByte8> operator>>=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002367// {
2368// return lhs = lhs >> rhs;
2369// }
2370
John Bauman19bac1e2014-05-06 15:23:49 -04002371// RValue<SByte8> operator+(RValue<SByte8> val)
2372// {
2373// return val;
2374// }
2375
2376// RValue<SByte8> operator-(RValue<SByte8> val)
2377// {
2378// return RValue<SByte8>(Nucleus::createNeg(val.value));
2379// }
2380
2381 RValue<SByte8> operator~(RValue<SByte8> val)
John Bauman89401822014-05-06 15:04:28 -04002382 {
John Bauman19bac1e2014-05-06 15:23:49 -04002383 if(CPUID::supportsMMX2())
2384 {
Nicolas Capens16b5f152016-10-13 13:39:01 -04002385 return val ^ SByte8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
John Bauman19bac1e2014-05-06 15:23:49 -04002386 }
2387 else
2388 {
2389 return RValue<SByte8>(Nucleus::createNot(val.value));
2390 }
John Bauman89401822014-05-06 15:04:28 -04002391 }
2392
John Bauman19bac1e2014-05-06 15:23:49 -04002393 RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002394 {
2395 return x86::paddsb(x, y);
2396 }
John Bauman66b8ab22014-05-06 15:57:45 -04002397
John Bauman19bac1e2014-05-06 15:23:49 -04002398 RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002399 {
2400 return x86::psubsb(x, y);
2401 }
2402
John Bauman19bac1e2014-05-06 15:23:49 -04002403 RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002404 {
John Bauman19bac1e2014-05-06 15:23:49 -04002405 if(CPUID::supportsMMX2())
2406 {
2407 return As<Short4>(x86::punpcklbw(As<Byte8>(x), As<Byte8>(y)));
2408 }
2409 else
2410 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002411 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11};
2412 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002413
John Bauman19bac1e2014-05-06 15:23:49 -04002414 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2415 }
John Bauman89401822014-05-06 15:04:28 -04002416 }
John Bauman66b8ab22014-05-06 15:57:45 -04002417
John Bauman19bac1e2014-05-06 15:23:49 -04002418 RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002419 {
John Bauman19bac1e2014-05-06 15:23:49 -04002420 if(CPUID::supportsMMX2())
2421 {
2422 return As<Short4>(x86::punpckhbw(As<Byte8>(x), As<Byte8>(y)));
2423 }
2424 else
2425 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002426 int shuffle[8] = {4, 12, 5, 13, 6, 14, 7, 15};
2427 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002428
John Bauman19bac1e2014-05-06 15:23:49 -04002429 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2430 }
John Bauman89401822014-05-06 15:04:28 -04002431 }
2432
John Bauman19bac1e2014-05-06 15:23:49 -04002433 RValue<Int> SignMask(RValue<SByte8> x)
John Bauman89401822014-05-06 15:04:28 -04002434 {
2435 return x86::pmovmskb(As<Byte8>(x));
2436 }
2437
John Bauman19bac1e2014-05-06 15:23:49 -04002438 RValue<Byte8> CmpGT(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002439 {
2440 return x86::pcmpgtb(x, y);
2441 }
John Bauman66b8ab22014-05-06 15:57:45 -04002442
John Bauman19bac1e2014-05-06 15:23:49 -04002443 RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002444 {
2445 return x86::pcmpeqb(As<Byte8>(x), As<Byte8>(y));
2446 }
2447
John Bauman19bac1e2014-05-06 15:23:49 -04002448 Type *SByte8::getType()
John Bauman89401822014-05-06 15:04:28 -04002449 {
John Bauman19bac1e2014-05-06 15:23:49 -04002450 if(CPUID::supportsMMX2())
2451 {
2452 return MMX::getType();
2453 }
2454 else
2455 {
Nicolas Capensac230122016-09-20 14:30:06 -04002456 return T(VectorType::get(SByte::getType(), 8));
John Bauman19bac1e2014-05-06 15:23:49 -04002457 }
John Bauman89401822014-05-06 15:04:28 -04002458 }
2459
John Bauman19bac1e2014-05-06 15:23:49 -04002460 Byte16::Byte16(RValue<Byte16> rhs)
John Bauman89401822014-05-06 15:04:28 -04002461 {
John Bauman66b8ab22014-05-06 15:57:45 -04002462 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002463 }
2464
2465 Byte16::Byte16(const Byte16 &rhs)
2466 {
John Bauman66b8ab22014-05-06 15:57:45 -04002467 Value *value = rhs.loadValue();
2468 storeValue(value);
2469 }
2470
2471 Byte16::Byte16(const Reference<Byte16> &rhs)
2472 {
John Bauman66b8ab22014-05-06 15:57:45 -04002473 Value *value = rhs.loadValue();
2474 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002475 }
2476
Nicolas Capens96d4e092016-11-18 14:22:38 -05002477 RValue<Byte16> Byte16::operator=(RValue<Byte16> rhs)
John Bauman89401822014-05-06 15:04:28 -04002478 {
John Bauman66b8ab22014-05-06 15:57:45 -04002479 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002480
2481 return rhs;
2482 }
2483
Nicolas Capens96d4e092016-11-18 14:22:38 -05002484 RValue<Byte16> Byte16::operator=(const Byte16 &rhs)
John Bauman89401822014-05-06 15:04:28 -04002485 {
John Bauman66b8ab22014-05-06 15:57:45 -04002486 Value *value = rhs.loadValue();
2487 storeValue(value);
2488
2489 return RValue<Byte16>(value);
2490 }
2491
Nicolas Capens96d4e092016-11-18 14:22:38 -05002492 RValue<Byte16> Byte16::operator=(const Reference<Byte16> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04002493 {
2494 Value *value = rhs.loadValue();
2495 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002496
2497 return RValue<Byte16>(value);
2498 }
2499
John Bauman19bac1e2014-05-06 15:23:49 -04002500 Type *Byte16::getType()
John Bauman89401822014-05-06 15:04:28 -04002501 {
Nicolas Capensac230122016-09-20 14:30:06 -04002502 return T(VectorType::get(Byte::getType(), 16));
John Bauman89401822014-05-06 15:04:28 -04002503 }
2504
John Bauman19bac1e2014-05-06 15:23:49 -04002505 Type *SByte16::getType()
John Bauman89401822014-05-06 15:04:28 -04002506 {
Nicolas Capensac230122016-09-20 14:30:06 -04002507 return T( VectorType::get(SByte::getType(), 16));
John Bauman89401822014-05-06 15:04:28 -04002508 }
2509
Nicolas Capens16b5f152016-10-13 13:39:01 -04002510 Short2::Short2(RValue<Short4> cast)
2511 {
2512 storeValue(Nucleus::createTrunc(Nucleus::createBitCast(cast.value, Long::getType()), UInt::getType()));
2513 }
2514
2515 Type *Short2::getType()
2516 {
2517 #if 0
2518 return T(VectorType::get(Short::getType(), 2));
2519 #else
2520 return UInt::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
2521 #endif
2522 }
2523
2524 UShort2::UShort2(RValue<UShort4> cast)
2525 {
2526 storeValue(Nucleus::createTrunc(Nucleus::createBitCast(cast.value, Long::getType()), UInt::getType()));
2527 }
2528
2529 Type *UShort2::getType()
2530 {
2531 #if 0
2532 return T(VectorType::get(UShort::getType(), 2));
2533 #else
2534 return UInt::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
2535 #endif
2536 }
2537
John Bauman19bac1e2014-05-06 15:23:49 -04002538 Short4::Short4(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04002539 {
John Bauman89401822014-05-06 15:04:28 -04002540 Value *extend = Nucleus::createZExt(cast.value, Long::getType());
John Bauman19bac1e2014-05-06 15:23:49 -04002541 Value *swizzle = Swizzle(RValue<Short4>(extend), 0x00).value;
John Bauman66b8ab22014-05-06 15:57:45 -04002542
2543 storeValue(swizzle);
John Bauman89401822014-05-06 15:04:28 -04002544 }
2545
John Bauman19bac1e2014-05-06 15:23:49 -04002546 Short4::Short4(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04002547 {
John Bauman89401822014-05-06 15:04:28 -04002548 Value *short8 = Nucleus::createBitCast(cast.value, Short8::getType());
2549
2550 #if 0 // FIXME: Check codegen (pshuflw phshufhw pshufd)
2551 Constant *pack[8];
2552 pack[0] = Nucleus::createConstantInt(0);
2553 pack[1] = Nucleus::createConstantInt(2);
2554 pack[2] = Nucleus::createConstantInt(4);
2555 pack[3] = Nucleus::createConstantInt(6);
2556
2557 Value *short4 = Nucleus::createShuffleVector(short8, short8, Nucleus::createConstantVector(pack, 4));
2558 #else
2559 Value *packed;
2560
2561 // FIXME: Use Swizzle<Short8>
2562 if(!CPUID::supportsSSSE3())
2563 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002564 int pshuflw[8] = {0, 2, 0, 2, 4, 5, 6, 7};
2565 int pshufhw[8] = {0, 1, 2, 3, 4, 6, 4, 6};
John Bauman89401822014-05-06 15:04:28 -04002566
Nicolas Capense89cd582016-09-30 14:23:47 -04002567 Value *shuffle1 = Nucleus::createShuffleVector(short8, short8, pshuflw);
2568 Value *shuffle2 = Nucleus::createShuffleVector(shuffle1, shuffle1, pshufhw);
John Bauman89401822014-05-06 15:04:28 -04002569 Value *int4 = Nucleus::createBitCast(shuffle2, Int4::getType());
Nicolas Capense95d5342016-09-30 11:37:28 -04002570 packed = createSwizzle4(int4, 0x88);
John Bauman89401822014-05-06 15:04:28 -04002571 }
2572 else
2573 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002574 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 -04002575 Value *byte16 = Nucleus::createBitCast(cast.value, Byte16::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04002576 packed = Nucleus::createShuffleVector(byte16, byte16, pshufb);
John Bauman89401822014-05-06 15:04:28 -04002577 }
2578
2579 #if 0 // FIXME: No optimal instruction selection
Nicolas Capens22008782016-10-20 01:11:47 -04002580 Value *qword2 = Nucleus::createBitCast(packed, T(VectorType::get(Long::getType(), 2)));
John Bauman89401822014-05-06 15:04:28 -04002581 Value *element = Nucleus::createExtractElement(qword2, 0);
2582 Value *short4 = Nucleus::createBitCast(element, Short4::getType());
2583 #else // FIXME: Requires SSE
2584 Value *int2 = RValue<Int2>(Int2(RValue<Int4>(packed))).value;
2585 Value *short4 = Nucleus::createBitCast(int2, Short4::getType());
2586 #endif
2587 #endif
2588
John Bauman66b8ab22014-05-06 15:57:45 -04002589 storeValue(short4);
John Bauman89401822014-05-06 15:04:28 -04002590 }
2591
John Bauman19bac1e2014-05-06 15:23:49 -04002592// Short4::Short4(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04002593// {
2594// }
2595
John Bauman19bac1e2014-05-06 15:23:49 -04002596 Short4::Short4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04002597 {
John Bauman89401822014-05-06 15:04:28 -04002598 Int4 v4i32 = Int4(cast);
2599 v4i32 = As<Int4>(x86::packssdw(v4i32, v4i32));
John Bauman66b8ab22014-05-06 15:57:45 -04002600
2601 storeValue(As<Short4>(Int2(v4i32)).value);
John Bauman89401822014-05-06 15:04:28 -04002602 }
2603
John Bauman19bac1e2014-05-06 15:23:49 -04002604 Short4::Short4(short xyzw)
2605 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04002606 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
2607 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(Short::getType(), 4))));
John Bauman19bac1e2014-05-06 15:23:49 -04002608
John Bauman66b8ab22014-05-06 15:57:45 -04002609 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman19bac1e2014-05-06 15:23:49 -04002610 }
2611
John Bauman89401822014-05-06 15:04:28 -04002612 Short4::Short4(short x, short y, short z, short w)
2613 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04002614 int64_t constantVector[4] = {x, y, z, w};
2615 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(Short::getType(), 4))));
John Bauman19bac1e2014-05-06 15:23:49 -04002616
John Bauman66b8ab22014-05-06 15:57:45 -04002617 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04002618 }
2619
John Bauman19bac1e2014-05-06 15:23:49 -04002620 Short4::Short4(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002621 {
John Bauman66b8ab22014-05-06 15:57:45 -04002622 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002623 }
2624
2625 Short4::Short4(const Short4 &rhs)
2626 {
John Bauman66b8ab22014-05-06 15:57:45 -04002627 Value *value = rhs.loadValue();
2628 storeValue(value);
2629 }
2630
2631 Short4::Short4(const Reference<Short4> &rhs)
2632 {
John Bauman66b8ab22014-05-06 15:57:45 -04002633 Value *value = rhs.loadValue();
2634 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002635 }
2636
John Bauman19bac1e2014-05-06 15:23:49 -04002637 Short4::Short4(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002638 {
John Bauman66b8ab22014-05-06 15:57:45 -04002639 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002640 }
2641
2642 Short4::Short4(const UShort4 &rhs)
2643 {
John Bauman66b8ab22014-05-06 15:57:45 -04002644 storeValue(rhs.loadValue());
2645 }
2646
2647 Short4::Short4(const Reference<UShort4> &rhs)
2648 {
John Bauman66b8ab22014-05-06 15:57:45 -04002649 storeValue(rhs.loadValue());
John Bauman89401822014-05-06 15:04:28 -04002650 }
2651
Nicolas Capens96d4e092016-11-18 14:22:38 -05002652 RValue<Short4> Short4::operator=(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002653 {
John Bauman66b8ab22014-05-06 15:57:45 -04002654 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002655
2656 return rhs;
2657 }
2658
Nicolas Capens96d4e092016-11-18 14:22:38 -05002659 RValue<Short4> Short4::operator=(const Short4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04002660 {
John Bauman66b8ab22014-05-06 15:57:45 -04002661 Value *value = rhs.loadValue();
2662 storeValue(value);
2663
2664 return RValue<Short4>(value);
2665 }
2666
Nicolas Capens96d4e092016-11-18 14:22:38 -05002667 RValue<Short4> Short4::operator=(const Reference<Short4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04002668 {
2669 Value *value = rhs.loadValue();
2670 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002671
2672 return RValue<Short4>(value);
2673 }
2674
Nicolas Capens96d4e092016-11-18 14:22:38 -05002675 RValue<Short4> Short4::operator=(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002676 {
John Bauman66b8ab22014-05-06 15:57:45 -04002677 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002678
John Bauman66b8ab22014-05-06 15:57:45 -04002679 return RValue<Short4>(rhs);
John Bauman89401822014-05-06 15:04:28 -04002680 }
2681
Nicolas Capens96d4e092016-11-18 14:22:38 -05002682 RValue<Short4> Short4::operator=(const UShort4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04002683 {
John Bauman66b8ab22014-05-06 15:57:45 -04002684 Value *value = rhs.loadValue();
2685 storeValue(value);
2686
2687 return RValue<Short4>(value);
2688 }
2689
Nicolas Capens96d4e092016-11-18 14:22:38 -05002690 RValue<Short4> Short4::operator=(const Reference<UShort4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04002691 {
2692 Value *value = rhs.loadValue();
2693 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002694
2695 return RValue<Short4>(value);
2696 }
2697
John Bauman19bac1e2014-05-06 15:23:49 -04002698 RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002699 {
John Bauman19bac1e2014-05-06 15:23:49 -04002700 if(CPUID::supportsMMX2())
2701 {
2702 return x86::paddw(lhs, rhs);
2703 }
2704 else
2705 {
2706 return RValue<Short4>(Nucleus::createAdd(lhs.value, rhs.value));
2707 }
John Bauman89401822014-05-06 15:04:28 -04002708 }
2709
John Bauman19bac1e2014-05-06 15:23:49 -04002710 RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002711 {
John Bauman19bac1e2014-05-06 15:23:49 -04002712 if(CPUID::supportsMMX2())
2713 {
2714 return x86::psubw(lhs, rhs);
2715 }
2716 else
2717 {
2718 return RValue<Short4>(Nucleus::createSub(lhs.value, rhs.value));
2719 }
John Bauman89401822014-05-06 15:04:28 -04002720 }
2721
John Bauman19bac1e2014-05-06 15:23:49 -04002722 RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002723 {
John Bauman19bac1e2014-05-06 15:23:49 -04002724 if(CPUID::supportsMMX2())
2725 {
2726 return x86::pmullw(lhs, rhs);
2727 }
2728 else
2729 {
2730 return RValue<Short4>(Nucleus::createMul(lhs.value, rhs.value));
2731 }
John Bauman89401822014-05-06 15:04:28 -04002732 }
2733
John Bauman19bac1e2014-05-06 15:23:49 -04002734// RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs)
2735// {
2736// return RValue<Short4>(Nucleus::createSDiv(lhs.value, rhs.value));
2737// }
2738
2739// RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs)
2740// {
2741// return RValue<Short4>(Nucleus::createSRem(lhs.value, rhs.value));
2742// }
2743
2744 RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002745 {
John Bauman19bac1e2014-05-06 15:23:49 -04002746 if(CPUID::supportsMMX2())
2747 {
2748 return x86::pand(lhs, rhs);
2749 }
2750 else
2751 {
2752 return RValue<Short4>(Nucleus::createAnd(lhs.value, rhs.value));
2753 }
John Bauman89401822014-05-06 15:04:28 -04002754 }
2755
John Bauman19bac1e2014-05-06 15:23:49 -04002756 RValue<Short4> operator|(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002757 {
John Bauman19bac1e2014-05-06 15:23:49 -04002758 if(CPUID::supportsMMX2())
2759 {
2760 return x86::por(lhs, rhs);
2761 }
2762 else
2763 {
2764 return RValue<Short4>(Nucleus::createOr(lhs.value, rhs.value));
2765 }
John Bauman89401822014-05-06 15:04:28 -04002766 }
2767
John Bauman19bac1e2014-05-06 15:23:49 -04002768 RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002769 {
John Bauman19bac1e2014-05-06 15:23:49 -04002770 if(CPUID::supportsMMX2())
2771 {
2772 return x86::pxor(lhs, rhs);
2773 }
2774 else
2775 {
2776 return RValue<Short4>(Nucleus::createXor(lhs.value, rhs.value));
2777 }
John Bauman89401822014-05-06 15:04:28 -04002778 }
2779
John Bauman19bac1e2014-05-06 15:23:49 -04002780 RValue<Short4> operator<<(RValue<Short4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002781 {
2782 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
2783
2784 return x86::psllw(lhs, rhs);
2785 }
2786
John Bauman19bac1e2014-05-06 15:23:49 -04002787 RValue<Short4> operator>>(RValue<Short4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002788 {
2789 // return RValue<Short4>(Nucleus::createAShr(lhs.value, rhs.value));
2790
2791 return x86::psraw(lhs, rhs);
2792 }
2793
Nicolas Capens96d4e092016-11-18 14:22:38 -05002794 RValue<Short4> operator+=(Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002795 {
2796 return lhs = lhs + rhs;
2797 }
2798
Nicolas Capens96d4e092016-11-18 14:22:38 -05002799 RValue<Short4> operator-=(Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002800 {
2801 return lhs = lhs - rhs;
2802 }
2803
Nicolas Capens96d4e092016-11-18 14:22:38 -05002804 RValue<Short4> operator*=(Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002805 {
2806 return lhs = lhs * rhs;
2807 }
2808
Nicolas Capens96d4e092016-11-18 14:22:38 -05002809// RValue<Short4> operator/=(Short4 &lhs, RValue<Short4> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002810// {
2811// return lhs = lhs / rhs;
2812// }
John Bauman89401822014-05-06 15:04:28 -04002813
Nicolas Capens96d4e092016-11-18 14:22:38 -05002814// RValue<Short4> operator%=(Short4 &lhs, RValue<Short4> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002815// {
2816// return lhs = lhs % rhs;
2817// }
John Bauman89401822014-05-06 15:04:28 -04002818
Nicolas Capens96d4e092016-11-18 14:22:38 -05002819 RValue<Short4> operator&=(Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002820 {
2821 return lhs = lhs & rhs;
2822 }
2823
Nicolas Capens96d4e092016-11-18 14:22:38 -05002824 RValue<Short4> operator|=(Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002825 {
2826 return lhs = lhs | rhs;
2827 }
2828
Nicolas Capens96d4e092016-11-18 14:22:38 -05002829 RValue<Short4> operator^=(Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002830 {
2831 return lhs = lhs ^ rhs;
2832 }
2833
Nicolas Capens96d4e092016-11-18 14:22:38 -05002834 RValue<Short4> operator<<=(Short4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002835 {
2836 return lhs = lhs << rhs;
2837 }
2838
Nicolas Capens96d4e092016-11-18 14:22:38 -05002839 RValue<Short4> operator>>=(Short4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002840 {
2841 return lhs = lhs >> rhs;
2842 }
2843
John Bauman19bac1e2014-05-06 15:23:49 -04002844// RValue<Short4> operator+(RValue<Short4> val)
2845// {
2846// return val;
2847// }
2848
2849 RValue<Short4> operator-(RValue<Short4> val)
John Bauman89401822014-05-06 15:04:28 -04002850 {
John Bauman19bac1e2014-05-06 15:23:49 -04002851 if(CPUID::supportsMMX2())
2852 {
2853 return Short4(0, 0, 0, 0) - val;
2854 }
2855 else
2856 {
2857 return RValue<Short4>(Nucleus::createNeg(val.value));
2858 }
John Bauman89401822014-05-06 15:04:28 -04002859 }
2860
John Bauman19bac1e2014-05-06 15:23:49 -04002861 RValue<Short4> operator~(RValue<Short4> val)
John Bauman89401822014-05-06 15:04:28 -04002862 {
John Bauman19bac1e2014-05-06 15:23:49 -04002863 if(CPUID::supportsMMX2())
2864 {
2865 return val ^ Short4(0xFFFFu, 0xFFFFu, 0xFFFFu, 0xFFFFu);
2866 }
2867 else
2868 {
2869 return RValue<Short4>(Nucleus::createNot(val.value));
2870 }
John Bauman89401822014-05-06 15:04:28 -04002871 }
2872
John Bauman19bac1e2014-05-06 15:23:49 -04002873 RValue<Short4> RoundShort4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04002874 {
2875 RValue<Int4> v4i32 = x86::cvtps2dq(cast);
Nicolas Capens698633a2015-02-04 00:16:13 -05002876 RValue<Short8> v8i16 = x86::packssdw(v4i32, v4i32);
John Bauman66b8ab22014-05-06 15:57:45 -04002877
Nicolas Capens698633a2015-02-04 00:16:13 -05002878 return As<Short4>(Int2(As<Int4>(v8i16)));
John Bauman89401822014-05-06 15:04:28 -04002879 }
2880
John Bauman19bac1e2014-05-06 15:23:49 -04002881 RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002882 {
2883 return x86::pmaxsw(x, y);
2884 }
2885
John Bauman19bac1e2014-05-06 15:23:49 -04002886 RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002887 {
2888 return x86::pminsw(x, y);
2889 }
2890
John Bauman19bac1e2014-05-06 15:23:49 -04002891 RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002892 {
2893 return x86::paddsw(x, y);
2894 }
2895
John Bauman19bac1e2014-05-06 15:23:49 -04002896 RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002897 {
2898 return x86::psubsw(x, y);
2899 }
2900
John Bauman19bac1e2014-05-06 15:23:49 -04002901 RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002902 {
2903 return x86::pmulhw(x, y);
2904 }
2905
John Bauman19bac1e2014-05-06 15:23:49 -04002906 RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002907 {
2908 return x86::pmaddwd(x, y);
2909 }
2910
John Bauman19bac1e2014-05-06 15:23:49 -04002911 RValue<SByte8> Pack(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002912 {
2913 return x86::packsswb(x, y);
2914 }
2915
John Bauman19bac1e2014-05-06 15:23:49 -04002916 RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002917 {
John Bauman19bac1e2014-05-06 15:23:49 -04002918 if(CPUID::supportsMMX2())
2919 {
2920 return x86::punpcklwd(x, y);
2921 }
2922 else
2923 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002924 int shuffle[4] = {0, 4, 1, 5};
2925 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002926
John Bauman19bac1e2014-05-06 15:23:49 -04002927 return RValue<Int2>(Nucleus::createBitCast(packed, Int2::getType()));
2928 }
John Bauman89401822014-05-06 15:04:28 -04002929 }
2930
John Bauman19bac1e2014-05-06 15:23:49 -04002931 RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002932 {
John Bauman19bac1e2014-05-06 15:23:49 -04002933 if(CPUID::supportsMMX2())
2934 {
2935 return x86::punpckhwd(x, y);
2936 }
2937 else
2938 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002939 int shuffle[4] = {2, 6, 3, 7};
2940 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002941
John Bauman19bac1e2014-05-06 15:23:49 -04002942 return RValue<Int2>(Nucleus::createBitCast(packed, Int2::getType()));
2943 }
John Bauman89401822014-05-06 15:04:28 -04002944 }
2945
John Bauman19bac1e2014-05-06 15:23:49 -04002946 RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04002947 {
John Bauman19bac1e2014-05-06 15:23:49 -04002948 if(CPUID::supportsMMX2())
2949 {
2950 return x86::pshufw(x, select);
2951 }
2952 else
2953 {
Nicolas Capense95d5342016-09-30 11:37:28 -04002954 return RValue<Short4>(createSwizzle4(x.value, select));
John Bauman19bac1e2014-05-06 15:23:49 -04002955 }
John Bauman89401822014-05-06 15:04:28 -04002956 }
2957
John Bauman19bac1e2014-05-06 15:23:49 -04002958 RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i)
John Bauman89401822014-05-06 15:04:28 -04002959 {
John Bauman19bac1e2014-05-06 15:23:49 -04002960 if(CPUID::supportsMMX2())
2961 {
2962 return x86::pinsrw(val, Int(element), i);
2963 }
2964 else
2965 {
2966 return RValue<Short4>(Nucleus::createInsertElement(val.value, element.value, i));
2967 }
John Bauman89401822014-05-06 15:04:28 -04002968 }
2969
John Bauman19bac1e2014-05-06 15:23:49 -04002970 RValue<Short> Extract(RValue<Short4> val, int i)
John Bauman89401822014-05-06 15:04:28 -04002971 {
John Bauman19bac1e2014-05-06 15:23:49 -04002972 if(CPUID::supportsMMX2())
2973 {
2974 return Short(x86::pextrw(val, i));
2975 }
2976 else
2977 {
Nicolas Capense95d5342016-09-30 11:37:28 -04002978 return RValue<Short>(Nucleus::createExtractElement(val.value, Short::getType(), i));
John Bauman19bac1e2014-05-06 15:23:49 -04002979 }
John Bauman89401822014-05-06 15:04:28 -04002980 }
2981
John Bauman19bac1e2014-05-06 15:23:49 -04002982 RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002983 {
2984 return x86::pcmpgtw(x, y);
2985 }
2986
John Bauman19bac1e2014-05-06 15:23:49 -04002987 RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002988 {
2989 return x86::pcmpeqw(x, y);
2990 }
2991
John Bauman19bac1e2014-05-06 15:23:49 -04002992 Type *Short4::getType()
John Bauman89401822014-05-06 15:04:28 -04002993 {
John Bauman19bac1e2014-05-06 15:23:49 -04002994 if(CPUID::supportsMMX2())
2995 {
2996 return MMX::getType();
2997 }
2998 else
2999 {
Nicolas Capensac230122016-09-20 14:30:06 -04003000 return T(VectorType::get(Short::getType(), 4));
John Bauman19bac1e2014-05-06 15:23:49 -04003001 }
John Bauman89401822014-05-06 15:04:28 -04003002 }
3003
John Bauman19bac1e2014-05-06 15:23:49 -04003004 UShort4::UShort4(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04003005 {
John Bauman89401822014-05-06 15:04:28 -04003006 *this = Short4(cast);
3007 }
3008
John Bauman19bac1e2014-05-06 15:23:49 -04003009 UShort4::UShort4(RValue<Float4> cast, bool saturate)
John Bauman89401822014-05-06 15:04:28 -04003010 {
John Bauman89401822014-05-06 15:04:28 -04003011 Float4 sat;
3012
3013 if(saturate)
3014 {
3015 if(CPUID::supportsSSE4_1())
3016 {
3017 sat = Min(cast, Float4(0xFFFF)); // packusdw takes care of 0x0000 saturation
3018 }
3019 else
3020 {
3021 sat = Max(Min(cast, Float4(0xFFFF)), Float4(0x0000));
3022 }
3023 }
3024 else
3025 {
3026 sat = cast;
3027 }
3028
3029 Int4 int4(sat);
3030
3031 if(!saturate || !CPUID::supportsSSE4_1())
3032 {
Nicolas Capens3e7062b2017-01-17 14:01:33 -05003033 *this = Short4(int4);
John Bauman89401822014-05-06 15:04:28 -04003034 }
3035 else
3036 {
Nicolas Capens3e7062b2017-01-17 14:01:33 -05003037 *this = As<Short4>(Int2(As<Int4>(x86::packusdw(int4, int4))));
John Bauman89401822014-05-06 15:04:28 -04003038 }
3039 }
3040
Alexis Hetu90c7ad62016-06-27 11:50:40 -04003041 UShort4::UShort4(unsigned short xyzw)
3042 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04003043 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
3044 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(UShort::getType(), 4))));
Alexis Hetu90c7ad62016-06-27 11:50:40 -04003045
3046 storeValue(Nucleus::createBitCast(vector, getType()));
3047 }
3048
John Bauman89401822014-05-06 15:04:28 -04003049 UShort4::UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w)
3050 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04003051 int64_t constantVector[4] = {x, y, z, w};
3052 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(UShort::getType(), 4))));
John Bauman89401822014-05-06 15:04:28 -04003053
John Bauman66b8ab22014-05-06 15:57:45 -04003054 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04003055 }
3056
John Bauman19bac1e2014-05-06 15:23:49 -04003057 UShort4::UShort4(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003058 {
John Bauman66b8ab22014-05-06 15:57:45 -04003059 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003060 }
3061
3062 UShort4::UShort4(const UShort4 &rhs)
3063 {
John Bauman66b8ab22014-05-06 15:57:45 -04003064 Value *value = rhs.loadValue();
3065 storeValue(value);
3066 }
3067
3068 UShort4::UShort4(const Reference<UShort4> &rhs)
3069 {
John Bauman66b8ab22014-05-06 15:57:45 -04003070 Value *value = rhs.loadValue();
3071 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003072 }
3073
John Bauman19bac1e2014-05-06 15:23:49 -04003074 UShort4::UShort4(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003075 {
John Bauman66b8ab22014-05-06 15:57:45 -04003076 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003077 }
3078
3079 UShort4::UShort4(const Short4 &rhs)
3080 {
John Bauman66b8ab22014-05-06 15:57:45 -04003081 Value *value = rhs.loadValue();
3082 storeValue(value);
3083 }
3084
3085 UShort4::UShort4(const Reference<Short4> &rhs)
3086 {
John Bauman66b8ab22014-05-06 15:57:45 -04003087 Value *value = rhs.loadValue();
3088 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003089 }
3090
Nicolas Capens96d4e092016-11-18 14:22:38 -05003091 RValue<UShort4> UShort4::operator=(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003092 {
John Bauman66b8ab22014-05-06 15:57:45 -04003093 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003094
3095 return rhs;
3096 }
3097
Nicolas Capens96d4e092016-11-18 14:22:38 -05003098 RValue<UShort4> UShort4::operator=(const UShort4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04003099 {
John Bauman66b8ab22014-05-06 15:57:45 -04003100 Value *value = rhs.loadValue();
3101 storeValue(value);
3102
3103 return RValue<UShort4>(value);
3104 }
3105
Nicolas Capens96d4e092016-11-18 14:22:38 -05003106 RValue<UShort4> UShort4::operator=(const Reference<UShort4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04003107 {
3108 Value *value = rhs.loadValue();
3109 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003110
3111 return RValue<UShort4>(value);
3112 }
3113
Nicolas Capens96d4e092016-11-18 14:22:38 -05003114 RValue<UShort4> UShort4::operator=(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003115 {
John Bauman66b8ab22014-05-06 15:57:45 -04003116 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003117
John Bauman66b8ab22014-05-06 15:57:45 -04003118 return RValue<UShort4>(rhs);
John Bauman89401822014-05-06 15:04:28 -04003119 }
3120
Nicolas Capens96d4e092016-11-18 14:22:38 -05003121 RValue<UShort4> UShort4::operator=(const Short4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04003122 {
John Bauman66b8ab22014-05-06 15:57:45 -04003123 Value *value = rhs.loadValue();
3124 storeValue(value);
3125
3126 return RValue<UShort4>(value);
3127 }
3128
Nicolas Capens96d4e092016-11-18 14:22:38 -05003129 RValue<UShort4> UShort4::operator=(const Reference<Short4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04003130 {
3131 Value *value = rhs.loadValue();
3132 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003133
3134 return RValue<UShort4>(value);
3135 }
3136
John Bauman19bac1e2014-05-06 15:23:49 -04003137 RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003138 {
John Bauman19bac1e2014-05-06 15:23:49 -04003139 if(CPUID::supportsMMX2())
3140 {
3141 return As<UShort4>(x86::paddw(As<Short4>(lhs), As<Short4>(rhs)));
3142 }
3143 else
3144 {
3145 return RValue<UShort4>(Nucleus::createAdd(lhs.value, rhs.value));
3146 }
John Bauman89401822014-05-06 15:04:28 -04003147 }
3148
John Bauman19bac1e2014-05-06 15:23:49 -04003149 RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003150 {
John Bauman19bac1e2014-05-06 15:23:49 -04003151 if(CPUID::supportsMMX2())
3152 {
3153 return As<UShort4>(x86::psubw(As<Short4>(lhs), As<Short4>(rhs)));
3154 }
3155 else
3156 {
3157 return RValue<UShort4>(Nucleus::createSub(lhs.value, rhs.value));
3158 }
John Bauman89401822014-05-06 15:04:28 -04003159 }
3160
John Bauman19bac1e2014-05-06 15:23:49 -04003161 RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003162 {
John Bauman19bac1e2014-05-06 15:23:49 -04003163 if(CPUID::supportsMMX2())
3164 {
3165 return As<UShort4>(x86::pmullw(As<Short4>(lhs), As<Short4>(rhs)));
3166 }
3167 else
3168 {
3169 return RValue<UShort4>(Nucleus::createMul(lhs.value, rhs.value));
3170 }
John Bauman89401822014-05-06 15:04:28 -04003171 }
3172
Nicolas Capens16b5f152016-10-13 13:39:01 -04003173 RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs)
3174 {
3175 if(CPUID::supportsMMX2())
3176 {
3177 return As<UShort4>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
3178 }
3179 else
3180 {
3181 return RValue<UShort4>(Nucleus::createAnd(lhs.value, rhs.value));
3182 }
3183 }
3184
3185 RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs)
3186 {
3187 if(CPUID::supportsMMX2())
3188 {
3189 return As<UShort4>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
3190 }
3191 else
3192 {
3193 return RValue<UShort4>(Nucleus::createOr(lhs.value, rhs.value));
3194 }
3195 }
3196
3197 RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs)
3198 {
3199 if(CPUID::supportsMMX2())
3200 {
3201 return As<UShort4>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
3202 }
3203 else
3204 {
3205 return RValue<UShort4>(Nucleus::createXor(lhs.value, rhs.value));
3206 }
3207 }
3208
John Bauman19bac1e2014-05-06 15:23:49 -04003209 RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003210 {
3211 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
3212
3213 return As<UShort4>(x86::psllw(As<Short4>(lhs), rhs));
3214 }
3215
John Bauman19bac1e2014-05-06 15:23:49 -04003216 RValue<UShort4> operator>>(RValue<UShort4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003217 {
3218 // return RValue<Short4>(Nucleus::createLShr(lhs.value, rhs.value));
3219
3220 return x86::psrlw(lhs, rhs);
3221 }
3222
Nicolas Capens96d4e092016-11-18 14:22:38 -05003223 RValue<UShort4> operator<<=(UShort4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003224 {
3225 return lhs = lhs << rhs;
3226 }
3227
Nicolas Capens96d4e092016-11-18 14:22:38 -05003228 RValue<UShort4> operator>>=(UShort4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003229 {
3230 return lhs = lhs >> rhs;
3231 }
3232
John Bauman19bac1e2014-05-06 15:23:49 -04003233 RValue<UShort4> operator~(RValue<UShort4> val)
John Bauman89401822014-05-06 15:04:28 -04003234 {
John Bauman19bac1e2014-05-06 15:23:49 -04003235 if(CPUID::supportsMMX2())
3236 {
3237 return As<UShort4>(As<Short4>(val) ^ Short4(0xFFFFu, 0xFFFFu, 0xFFFFu, 0xFFFFu));
3238 }
3239 else
3240 {
3241 return RValue<UShort4>(Nucleus::createNot(val.value));
3242 }
John Bauman89401822014-05-06 15:04:28 -04003243 }
3244
John Bauman19bac1e2014-05-06 15:23:49 -04003245 RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003246 {
John Bauman66b8ab22014-05-06 15:57:45 -04003247 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 -04003248 }
3249
John Bauman19bac1e2014-05-06 15:23:49 -04003250 RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003251 {
John Bauman66b8ab22014-05-06 15:57:45 -04003252 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 -04003253 }
3254
John Bauman19bac1e2014-05-06 15:23:49 -04003255 RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003256 {
3257 return x86::paddusw(x, y);
3258 }
3259
John Bauman19bac1e2014-05-06 15:23:49 -04003260 RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003261 {
3262 return x86::psubusw(x, y);
3263 }
3264
John Bauman19bac1e2014-05-06 15:23:49 -04003265 RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003266 {
3267 return x86::pmulhuw(x, y);
3268 }
3269
John Bauman19bac1e2014-05-06 15:23:49 -04003270 RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003271 {
3272 return x86::pavgw(x, y);
3273 }
3274
John Bauman19bac1e2014-05-06 15:23:49 -04003275 RValue<Byte8> Pack(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003276 {
3277 return x86::packuswb(x, y);
3278 }
3279
John Bauman19bac1e2014-05-06 15:23:49 -04003280 Type *UShort4::getType()
John Bauman89401822014-05-06 15:04:28 -04003281 {
John Bauman19bac1e2014-05-06 15:23:49 -04003282 if(CPUID::supportsMMX2())
3283 {
3284 return MMX::getType();
3285 }
3286 else
3287 {
Nicolas Capensac230122016-09-20 14:30:06 -04003288 return T(VectorType::get(UShort::getType(), 4));
John Bauman19bac1e2014-05-06 15:23:49 -04003289 }
John Bauman89401822014-05-06 15:04:28 -04003290 }
3291
Nicolas Capens3e7062b2017-01-17 14:01:33 -05003292 Short8::Short8(short c)
3293 {
3294 int64_t constantVector[8] = {c, c, c, c, c, c, c, c};
3295 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3296 }
3297
John Bauman89401822014-05-06 15:04:28 -04003298 Short8::Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7)
3299 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04003300 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
3301 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04003302 }
3303
John Bauman19bac1e2014-05-06 15:23:49 -04003304 Short8::Short8(RValue<Short8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003305 {
John Bauman66b8ab22014-05-06 15:57:45 -04003306 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003307 }
3308
Nicolas Capensef8cd662016-06-30 15:34:40 -04003309 Short8::Short8(const Reference<Short8> &rhs)
3310 {
Nicolas Capensef8cd662016-06-30 15:34:40 -04003311 Value *value = rhs.loadValue();
3312 storeValue(value);
3313 }
3314
Nicolas Capens62abb552016-01-05 12:03:47 -05003315 Short8::Short8(RValue<Short4> lo, RValue<Short4> hi)
3316 {
3317 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
3318 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
3319
Nicolas Capens22008782016-10-20 01:11:47 -04003320 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Nicolas Capens62abb552016-01-05 12:03:47 -05003321 long2 = Nucleus::createInsertElement(long2, loLong, 0);
3322 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
3323 Value *short8 = Nucleus::createBitCast(long2, Short8::getType());
3324
3325 storeValue(short8);
3326 }
3327
John Bauman19bac1e2014-05-06 15:23:49 -04003328 RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003329 {
3330 return RValue<Short8>(Nucleus::createAdd(lhs.value, rhs.value));
3331 }
3332
John Bauman19bac1e2014-05-06 15:23:49 -04003333 RValue<Short8> operator&(RValue<Short8> lhs, RValue<Short8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003334 {
3335 return RValue<Short8>(Nucleus::createAnd(lhs.value, rhs.value));
3336 }
3337
John Bauman19bac1e2014-05-06 15:23:49 -04003338 RValue<Short8> operator<<(RValue<Short8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003339 {
3340 return x86::psllw(lhs, rhs); // FIXME: Fallback required
3341 }
3342
John Bauman19bac1e2014-05-06 15:23:49 -04003343 RValue<Short8> operator>>(RValue<Short8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003344 {
3345 return x86::psraw(lhs, rhs); // FIXME: Fallback required
3346 }
3347
John Bauman19bac1e2014-05-06 15:23:49 -04003348 RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04003349 {
3350 return x86::pmaddwd(x, y); // FIXME: Fallback required
3351 }
3352
Alexis Hetu0f448072016-03-18 10:56:08 -04003353 RValue<Int4> Abs(RValue<Int4> x)
3354 {
3355 if(CPUID::supportsSSSE3())
3356 {
3357 return x86::pabsd(x);
3358 }
3359 else
3360 {
3361 Int4 mask = (x >> 31);
3362 return (mask ^ x) - mask;
3363 }
3364 }
3365
John Bauman19bac1e2014-05-06 15:23:49 -04003366 RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04003367 {
3368 return x86::pmulhw(x, y); // FIXME: Fallback required
3369 }
3370
John Bauman19bac1e2014-05-06 15:23:49 -04003371 Type *Short8::getType()
John Bauman89401822014-05-06 15:04:28 -04003372 {
Nicolas Capensac230122016-09-20 14:30:06 -04003373 return T(VectorType::get(Short::getType(), 8));
John Bauman89401822014-05-06 15:04:28 -04003374 }
3375
Nicolas Capens3e7062b2017-01-17 14:01:33 -05003376 UShort8::UShort8(unsigned short c)
3377 {
3378 int64_t constantVector[8] = {c, c, c, c, c, c, c, c};
3379 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3380 }
3381
John Bauman89401822014-05-06 15:04:28 -04003382 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)
3383 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04003384 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
3385 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04003386 }
3387
John Bauman19bac1e2014-05-06 15:23:49 -04003388 UShort8::UShort8(RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003389 {
John Bauman66b8ab22014-05-06 15:57:45 -04003390 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003391 }
3392
Nicolas Capensef8cd662016-06-30 15:34:40 -04003393 UShort8::UShort8(const Reference<UShort8> &rhs)
3394 {
Nicolas Capensef8cd662016-06-30 15:34:40 -04003395 Value *value = rhs.loadValue();
3396 storeValue(value);
3397 }
3398
Nicolas Capens62abb552016-01-05 12:03:47 -05003399 UShort8::UShort8(RValue<UShort4> lo, RValue<UShort4> hi)
3400 {
3401 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
3402 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
3403
Nicolas Capens22008782016-10-20 01:11:47 -04003404 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Nicolas Capens62abb552016-01-05 12:03:47 -05003405 long2 = Nucleus::createInsertElement(long2, loLong, 0);
3406 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
3407 Value *short8 = Nucleus::createBitCast(long2, Short8::getType());
3408
3409 storeValue(short8);
3410 }
3411
Nicolas Capens96d4e092016-11-18 14:22:38 -05003412 RValue<UShort8> UShort8::operator=(RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003413 {
John Bauman66b8ab22014-05-06 15:57:45 -04003414 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003415
3416 return rhs;
3417 }
3418
Nicolas Capens96d4e092016-11-18 14:22:38 -05003419 RValue<UShort8> UShort8::operator=(const UShort8 &rhs)
John Bauman89401822014-05-06 15:04:28 -04003420 {
John Bauman66b8ab22014-05-06 15:57:45 -04003421 Value *value = rhs.loadValue();
3422 storeValue(value);
3423
3424 return RValue<UShort8>(value);
3425 }
3426
Nicolas Capens96d4e092016-11-18 14:22:38 -05003427 RValue<UShort8> UShort8::operator=(const Reference<UShort8> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04003428 {
3429 Value *value = rhs.loadValue();
3430 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003431
3432 return RValue<UShort8>(value);
3433 }
3434
John Bauman19bac1e2014-05-06 15:23:49 -04003435 RValue<UShort8> operator&(RValue<UShort8> lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003436 {
3437 return RValue<UShort8>(Nucleus::createAnd(lhs.value, rhs.value));
3438 }
3439
John Bauman19bac1e2014-05-06 15:23:49 -04003440 RValue<UShort8> operator<<(RValue<UShort8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003441 {
3442 return As<UShort8>(x86::psllw(As<Short8>(lhs), rhs)); // FIXME: Fallback required
3443 }
3444
John Bauman19bac1e2014-05-06 15:23:49 -04003445 RValue<UShort8> operator>>(RValue<UShort8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003446 {
3447 return x86::psrlw(lhs, rhs); // FIXME: Fallback required
3448 }
3449
John Bauman19bac1e2014-05-06 15:23:49 -04003450 RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003451 {
3452 return RValue<UShort8>(Nucleus::createAdd(lhs.value, rhs.value));
3453 }
3454
John Bauman19bac1e2014-05-06 15:23:49 -04003455 RValue<UShort8> operator*(RValue<UShort8> lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003456 {
3457 return RValue<UShort8>(Nucleus::createMul(lhs.value, rhs.value));
3458 }
3459
Nicolas Capens96d4e092016-11-18 14:22:38 -05003460 RValue<UShort8> operator+=(UShort8 &lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003461 {
3462 return lhs = lhs + rhs;
3463 }
3464
John Bauman19bac1e2014-05-06 15:23:49 -04003465 RValue<UShort8> operator~(RValue<UShort8> val)
John Bauman89401822014-05-06 15:04:28 -04003466 {
3467 return RValue<UShort8>(Nucleus::createNot(val.value));
3468 }
3469
John Bauman19bac1e2014-05-06 15:23:49 -04003470 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 -04003471 {
Nicolas Capense89cd582016-09-30 14:23:47 -04003472 int pshufb[16] =
3473 {
3474 select0 + 0,
3475 select0 + 1,
3476 select1 + 0,
3477 select1 + 1,
3478 select2 + 0,
3479 select2 + 1,
3480 select3 + 0,
3481 select3 + 1,
3482 select4 + 0,
3483 select4 + 1,
3484 select5 + 0,
3485 select5 + 1,
3486 select6 + 0,
3487 select6 + 1,
3488 select7 + 0,
3489 select7 + 1,
3490 };
John Bauman89401822014-05-06 15:04:28 -04003491
3492 Value *byte16 = Nucleus::createBitCast(x.value, Byte16::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04003493 Value *shuffle = Nucleus::createShuffleVector(byte16, byte16, pshufb);
John Bauman89401822014-05-06 15:04:28 -04003494 Value *short8 = Nucleus::createBitCast(shuffle, UShort8::getType());
3495
3496 return RValue<UShort8>(short8);
3497 }
3498
John Bauman19bac1e2014-05-06 15:23:49 -04003499 RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y)
John Bauman89401822014-05-06 15:04:28 -04003500 {
3501 return x86::pmulhuw(x, y); // FIXME: Fallback required
3502 }
3503
John Bauman19bac1e2014-05-06 15:23:49 -04003504 Type *UShort8::getType()
John Bauman89401822014-05-06 15:04:28 -04003505 {
Nicolas Capensac230122016-09-20 14:30:06 -04003506 return T(VectorType::get(UShort::getType(), 8));
John Bauman89401822014-05-06 15:04:28 -04003507 }
3508
Nicolas Capens81f18302016-01-14 09:32:35 -05003509 Int::Int(Argument<Int> argument)
John Bauman89401822014-05-06 15:04:28 -04003510 {
Nicolas Capens81f18302016-01-14 09:32:35 -05003511 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04003512 }
3513
John Bauman19bac1e2014-05-06 15:23:49 -04003514 Int::Int(RValue<Byte> cast)
John Bauman89401822014-05-06 15:04:28 -04003515 {
John Bauman89401822014-05-06 15:04:28 -04003516 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3517
John Bauman66b8ab22014-05-06 15:57:45 -04003518 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003519 }
3520
John Bauman19bac1e2014-05-06 15:23:49 -04003521 Int::Int(RValue<SByte> cast)
John Bauman89401822014-05-06 15:04:28 -04003522 {
John Bauman89401822014-05-06 15:04:28 -04003523 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3524
John Bauman66b8ab22014-05-06 15:57:45 -04003525 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003526 }
3527
John Bauman19bac1e2014-05-06 15:23:49 -04003528 Int::Int(RValue<Short> cast)
John Bauman89401822014-05-06 15:04:28 -04003529 {
John Bauman89401822014-05-06 15:04:28 -04003530 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3531
John Bauman66b8ab22014-05-06 15:57:45 -04003532 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003533 }
3534
John Bauman19bac1e2014-05-06 15:23:49 -04003535 Int::Int(RValue<UShort> cast)
John Bauman89401822014-05-06 15:04:28 -04003536 {
John Bauman89401822014-05-06 15:04:28 -04003537 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3538
John Bauman66b8ab22014-05-06 15:57:45 -04003539 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003540 }
3541
John Bauman19bac1e2014-05-06 15:23:49 -04003542 Int::Int(RValue<Int2> cast)
John Bauman89401822014-05-06 15:04:28 -04003543 {
John Bauman89401822014-05-06 15:04:28 -04003544 *this = Extract(cast, 0);
3545 }
3546
John Bauman19bac1e2014-05-06 15:23:49 -04003547 Int::Int(RValue<Long> cast)
John Bauman89401822014-05-06 15:04:28 -04003548 {
John Bauman89401822014-05-06 15:04:28 -04003549 Value *integer = Nucleus::createTrunc(cast.value, Int::getType());
3550
John Bauman66b8ab22014-05-06 15:57:45 -04003551 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003552 }
3553
John Bauman19bac1e2014-05-06 15:23:49 -04003554 Int::Int(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04003555 {
John Bauman89401822014-05-06 15:04:28 -04003556 Value *integer = Nucleus::createFPToSI(cast.value, Int::getType());
3557
John Bauman66b8ab22014-05-06 15:57:45 -04003558 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003559 }
3560
John Bauman89401822014-05-06 15:04:28 -04003561 Int::Int(int x)
3562 {
John Bauman66b8ab22014-05-06 15:57:45 -04003563 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04003564 }
3565
John Bauman19bac1e2014-05-06 15:23:49 -04003566 Int::Int(RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003567 {
John Bauman66b8ab22014-05-06 15:57:45 -04003568 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003569 }
3570
John Bauman19bac1e2014-05-06 15:23:49 -04003571 Int::Int(RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04003572 {
John Bauman66b8ab22014-05-06 15:57:45 -04003573 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003574 }
3575
3576 Int::Int(const Int &rhs)
3577 {
John Bauman66b8ab22014-05-06 15:57:45 -04003578 Value *value = rhs.loadValue();
3579 storeValue(value);
3580 }
John Bauman89401822014-05-06 15:04:28 -04003581
John Bauman66b8ab22014-05-06 15:57:45 -04003582 Int::Int(const Reference<Int> &rhs)
3583 {
3584 Value *value = rhs.loadValue();
3585 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003586 }
3587
3588 Int::Int(const UInt &rhs)
3589 {
John Bauman66b8ab22014-05-06 15:57:45 -04003590 Value *value = rhs.loadValue();
3591 storeValue(value);
3592 }
John Bauman89401822014-05-06 15:04:28 -04003593
John Bauman66b8ab22014-05-06 15:57:45 -04003594 Int::Int(const Reference<UInt> &rhs)
3595 {
3596 Value *value = rhs.loadValue();
3597 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003598 }
3599
Nicolas Capens96d4e092016-11-18 14:22:38 -05003600 RValue<Int> Int::operator=(int rhs)
John Bauman89401822014-05-06 15:04:28 -04003601 {
John Bauman66b8ab22014-05-06 15:57:45 -04003602 return RValue<Int>(storeValue(Nucleus::createConstantInt(rhs)));
John Bauman89401822014-05-06 15:04:28 -04003603 }
3604
Nicolas Capens96d4e092016-11-18 14:22:38 -05003605 RValue<Int> Int::operator=(RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003606 {
John Bauman66b8ab22014-05-06 15:57:45 -04003607 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003608
3609 return rhs;
3610 }
3611
Nicolas Capens96d4e092016-11-18 14:22:38 -05003612 RValue<Int> Int::operator=(RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04003613 {
John Bauman66b8ab22014-05-06 15:57:45 -04003614 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003615
John Bauman66b8ab22014-05-06 15:57:45 -04003616 return RValue<Int>(rhs);
John Bauman89401822014-05-06 15:04:28 -04003617 }
3618
Nicolas Capens96d4e092016-11-18 14:22:38 -05003619 RValue<Int> Int::operator=(const Int &rhs)
John Bauman89401822014-05-06 15:04:28 -04003620 {
John Bauman66b8ab22014-05-06 15:57:45 -04003621 Value *value = rhs.loadValue();
3622 storeValue(value);
3623
3624 return RValue<Int>(value);
3625 }
3626
Nicolas Capens96d4e092016-11-18 14:22:38 -05003627 RValue<Int> Int::operator=(const Reference<Int> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04003628 {
3629 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 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);
John Bauman89401822014-05-06 15:04:28 -04003639
3640 return RValue<Int>(value);
3641 }
3642
Nicolas Capens96d4e092016-11-18 14:22:38 -05003643 RValue<Int> Int::operator=(const Reference<UInt> &rhs)
John Bauman89401822014-05-06 15:04:28 -04003644 {
John Bauman66b8ab22014-05-06 15:57:45 -04003645 Value *value = rhs.loadValue();
3646 storeValue(value);
3647
3648 return RValue<Int>(value);
John Bauman89401822014-05-06 15:04:28 -04003649 }
3650
John Bauman19bac1e2014-05-06 15:23:49 -04003651 RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003652 {
3653 return RValue<Int>(Nucleus::createAdd(lhs.value, rhs.value));
3654 }
3655
John Bauman19bac1e2014-05-06 15:23:49 -04003656 RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003657 {
3658 return RValue<Int>(Nucleus::createSub(lhs.value, rhs.value));
3659 }
3660
John Bauman19bac1e2014-05-06 15:23:49 -04003661 RValue<Int> operator*(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003662 {
3663 return RValue<Int>(Nucleus::createMul(lhs.value, rhs.value));
3664 }
3665
John Bauman19bac1e2014-05-06 15:23:49 -04003666 RValue<Int> operator/(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003667 {
3668 return RValue<Int>(Nucleus::createSDiv(lhs.value, rhs.value));
3669 }
3670
John Bauman19bac1e2014-05-06 15:23:49 -04003671 RValue<Int> operator%(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003672 {
3673 return RValue<Int>(Nucleus::createSRem(lhs.value, rhs.value));
3674 }
3675
John Bauman19bac1e2014-05-06 15:23:49 -04003676 RValue<Int> operator&(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003677 {
3678 return RValue<Int>(Nucleus::createAnd(lhs.value, rhs.value));
3679 }
3680
John Bauman19bac1e2014-05-06 15:23:49 -04003681 RValue<Int> operator|(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003682 {
3683 return RValue<Int>(Nucleus::createOr(lhs.value, rhs.value));
3684 }
3685
John Bauman19bac1e2014-05-06 15:23:49 -04003686 RValue<Int> operator^(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003687 {
3688 return RValue<Int>(Nucleus::createXor(lhs.value, rhs.value));
3689 }
3690
John Bauman19bac1e2014-05-06 15:23:49 -04003691 RValue<Int> operator<<(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003692 {
3693 return RValue<Int>(Nucleus::createShl(lhs.value, rhs.value));
3694 }
3695
John Bauman19bac1e2014-05-06 15:23:49 -04003696 RValue<Int> operator>>(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003697 {
3698 return RValue<Int>(Nucleus::createAShr(lhs.value, rhs.value));
3699 }
3700
Nicolas Capens96d4e092016-11-18 14:22:38 -05003701 RValue<Int> operator+=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003702 {
3703 return lhs = lhs + rhs;
3704 }
3705
Nicolas Capens96d4e092016-11-18 14:22:38 -05003706 RValue<Int> operator-=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003707 {
3708 return lhs = lhs - rhs;
3709 }
3710
Nicolas Capens96d4e092016-11-18 14:22:38 -05003711 RValue<Int> operator*=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003712 {
3713 return lhs = lhs * rhs;
3714 }
3715
Nicolas Capens96d4e092016-11-18 14:22:38 -05003716 RValue<Int> operator/=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003717 {
3718 return lhs = lhs / rhs;
3719 }
3720
Nicolas Capens96d4e092016-11-18 14:22:38 -05003721 RValue<Int> operator%=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003722 {
3723 return lhs = lhs % rhs;
3724 }
3725
Nicolas Capens96d4e092016-11-18 14:22:38 -05003726 RValue<Int> operator&=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003727 {
3728 return lhs = lhs & rhs;
3729 }
3730
Nicolas Capens96d4e092016-11-18 14:22:38 -05003731 RValue<Int> operator|=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003732 {
3733 return lhs = lhs | rhs;
3734 }
3735
Nicolas Capens96d4e092016-11-18 14:22:38 -05003736 RValue<Int> operator^=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003737 {
3738 return lhs = lhs ^ rhs;
3739 }
3740
Nicolas Capens96d4e092016-11-18 14:22:38 -05003741 RValue<Int> operator<<=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003742 {
3743 return lhs = lhs << rhs;
3744 }
3745
Nicolas Capens96d4e092016-11-18 14:22:38 -05003746 RValue<Int> operator>>=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003747 {
3748 return lhs = lhs >> rhs;
3749 }
3750
John Bauman19bac1e2014-05-06 15:23:49 -04003751 RValue<Int> operator+(RValue<Int> val)
John Bauman89401822014-05-06 15:04:28 -04003752 {
3753 return val;
3754 }
3755
John Bauman19bac1e2014-05-06 15:23:49 -04003756 RValue<Int> operator-(RValue<Int> val)
John Bauman89401822014-05-06 15:04:28 -04003757 {
3758 return RValue<Int>(Nucleus::createNeg(val.value));
3759 }
3760
John Bauman19bac1e2014-05-06 15:23:49 -04003761 RValue<Int> operator~(RValue<Int> val)
John Bauman89401822014-05-06 15:04:28 -04003762 {
3763 return RValue<Int>(Nucleus::createNot(val.value));
3764 }
3765
Nicolas Capens96d4e092016-11-18 14:22:38 -05003766 RValue<Int> operator++(Int &val, int) // Post-increment
John Bauman89401822014-05-06 15:04:28 -04003767 {
3768 RValue<Int> res = val;
3769
Nicolas Capens19336542016-09-26 10:32:29 -04003770 Value *inc = Nucleus::createAdd(res.value, 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 res;
3774 }
3775
Nicolas Capens96d4e092016-11-18 14:22:38 -05003776 const Int &operator++(Int &val) // Pre-increment
John Bauman89401822014-05-06 15:04:28 -04003777 {
Nicolas Capens19336542016-09-26 10:32:29 -04003778 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04003779 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04003780
3781 return val;
3782 }
3783
Nicolas Capens96d4e092016-11-18 14:22:38 -05003784 RValue<Int> operator--(Int &val, int) // Post-decrement
John Bauman89401822014-05-06 15:04:28 -04003785 {
3786 RValue<Int> res = val;
3787
Nicolas Capens19336542016-09-26 10:32:29 -04003788 Value *inc = Nucleus::createSub(res.value, 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 res;
3792 }
3793
Nicolas Capens96d4e092016-11-18 14:22:38 -05003794 const Int &operator--(Int &val) // Pre-decrement
John Bauman89401822014-05-06 15:04:28 -04003795 {
Nicolas Capens19336542016-09-26 10:32:29 -04003796 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04003797 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04003798
3799 return val;
3800 }
3801
John Bauman19bac1e2014-05-06 15:23:49 -04003802 RValue<Bool> operator<(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003803 {
3804 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
3805 }
3806
John Bauman19bac1e2014-05-06 15:23:49 -04003807 RValue<Bool> operator<=(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003808 {
3809 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
3810 }
3811
John Bauman19bac1e2014-05-06 15:23:49 -04003812 RValue<Bool> operator>(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003813 {
3814 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
3815 }
3816
John Bauman19bac1e2014-05-06 15:23:49 -04003817 RValue<Bool> operator>=(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003818 {
3819 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
3820 }
3821
John Bauman19bac1e2014-05-06 15:23:49 -04003822 RValue<Bool> operator!=(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003823 {
3824 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
3825 }
3826
John Bauman19bac1e2014-05-06 15:23:49 -04003827 RValue<Bool> operator==(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003828 {
3829 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
3830 }
3831
John Bauman19bac1e2014-05-06 15:23:49 -04003832 RValue<Int> Max(RValue<Int> x, RValue<Int> y)
3833 {
3834 return IfThenElse(x > y, x, y);
3835 }
3836
3837 RValue<Int> Min(RValue<Int> x, RValue<Int> y)
3838 {
3839 return IfThenElse(x < y, x, y);
3840 }
3841
3842 RValue<Int> Clamp(RValue<Int> x, RValue<Int> min, RValue<Int> max)
3843 {
3844 return Min(Max(x, min), max);
3845 }
3846
3847 RValue<Int> RoundInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04003848 {
3849 return x86::cvtss2si(cast);
3850
John Bauman66b8ab22014-05-06 15:57:45 -04003851 // return IfThenElse(val > 0.0f, Int(val + 0.5f), Int(val - 0.5f));
John Bauman89401822014-05-06 15:04:28 -04003852 }
3853
John Bauman19bac1e2014-05-06 15:23:49 -04003854 Type *Int::getType()
John Bauman89401822014-05-06 15:04:28 -04003855 {
Nicolas Capensac230122016-09-20 14:30:06 -04003856 return T(llvm::Type::getInt32Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04003857 }
3858
John Bauman19bac1e2014-05-06 15:23:49 -04003859 Long::Long(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04003860 {
John Bauman89401822014-05-06 15:04:28 -04003861 Value *integer = Nucleus::createSExt(cast.value, Long::getType());
3862
John Bauman66b8ab22014-05-06 15:57:45 -04003863 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003864 }
3865
John Bauman19bac1e2014-05-06 15:23:49 -04003866 Long::Long(RValue<UInt> cast)
John Bauman89401822014-05-06 15:04:28 -04003867 {
John Bauman89401822014-05-06 15:04:28 -04003868 Value *integer = Nucleus::createZExt(cast.value, Long::getType());
3869
John Bauman66b8ab22014-05-06 15:57:45 -04003870 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003871 }
3872
John Bauman19bac1e2014-05-06 15:23:49 -04003873 Long::Long(RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04003874 {
John Bauman66b8ab22014-05-06 15:57:45 -04003875 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003876 }
3877
Nicolas Capens96d4e092016-11-18 14:22:38 -05003878 RValue<Long> Long::operator=(int64_t rhs)
John Bauman89401822014-05-06 15:04:28 -04003879 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04003880 return RValue<Long>(storeValue(Nucleus::createConstantLong(rhs)));
John Bauman89401822014-05-06 15:04:28 -04003881 }
3882
Nicolas Capens96d4e092016-11-18 14:22:38 -05003883 RValue<Long> Long::operator=(RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04003884 {
John Bauman66b8ab22014-05-06 15:57:45 -04003885 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003886
3887 return rhs;
3888 }
3889
Nicolas Capens96d4e092016-11-18 14:22:38 -05003890 RValue<Long> Long::operator=(const Long &rhs)
John Bauman89401822014-05-06 15:04:28 -04003891 {
John Bauman66b8ab22014-05-06 15:57:45 -04003892 Value *value = rhs.loadValue();
3893 storeValue(value);
3894
3895 return RValue<Long>(value);
3896 }
3897
Nicolas Capens96d4e092016-11-18 14:22:38 -05003898 RValue<Long> Long::operator=(const Reference<Long> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04003899 {
3900 Value *value = rhs.loadValue();
3901 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003902
3903 return RValue<Long>(value);
3904 }
3905
John Bauman19bac1e2014-05-06 15:23:49 -04003906 RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04003907 {
3908 return RValue<Long>(Nucleus::createAdd(lhs.value, rhs.value));
3909 }
3910
John Bauman19bac1e2014-05-06 15:23:49 -04003911 RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04003912 {
3913 return RValue<Long>(Nucleus::createSub(lhs.value, rhs.value));
3914 }
3915
Nicolas Capens96d4e092016-11-18 14:22:38 -05003916 RValue<Long> operator+=(Long &lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04003917 {
3918 return lhs = lhs + rhs;
3919 }
3920
Nicolas Capens96d4e092016-11-18 14:22:38 -05003921 RValue<Long> operator-=(Long &lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04003922 {
3923 return lhs = lhs - rhs;
3924 }
3925
John Bauman66b8ab22014-05-06 15:57:45 -04003926 RValue<Long> AddAtomic(RValue<Pointer<Long> > x, RValue<Long> y)
John Bauman89401822014-05-06 15:04:28 -04003927 {
John Bauman19bac1e2014-05-06 15:23:49 -04003928 return RValue<Long>(Nucleus::createAtomicAdd(x.value, y.value));
John Bauman89401822014-05-06 15:04:28 -04003929 }
3930
John Bauman19bac1e2014-05-06 15:23:49 -04003931 Type *Long::getType()
John Bauman89401822014-05-06 15:04:28 -04003932 {
Nicolas Capensac230122016-09-20 14:30:06 -04003933 return T(llvm::Type::getInt64Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04003934 }
3935
Nicolas Capens81f18302016-01-14 09:32:35 -05003936 UInt::UInt(Argument<UInt> argument)
John Bauman89401822014-05-06 15:04:28 -04003937 {
Nicolas Capens81f18302016-01-14 09:32:35 -05003938 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04003939 }
3940
John Bauman19bac1e2014-05-06 15:23:49 -04003941 UInt::UInt(RValue<UShort> cast)
John Bauman89401822014-05-06 15:04:28 -04003942 {
John Bauman89401822014-05-06 15:04:28 -04003943 Value *integer = Nucleus::createZExt(cast.value, UInt::getType());
3944
John Bauman66b8ab22014-05-06 15:57:45 -04003945 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003946 }
3947
John Bauman19bac1e2014-05-06 15:23:49 -04003948 UInt::UInt(RValue<Long> cast)
John Bauman89401822014-05-06 15:04:28 -04003949 {
John Bauman89401822014-05-06 15:04:28 -04003950 Value *integer = Nucleus::createTrunc(cast.value, UInt::getType());
3951
John Bauman66b8ab22014-05-06 15:57:45 -04003952 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003953 }
3954
John Bauman19bac1e2014-05-06 15:23:49 -04003955 UInt::UInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04003956 {
Alexis Hetu764d1422016-09-28 08:44:22 -04003957 // Note: createFPToUI is broken, must perform conversion using createFPtoSI
3958 // Value *integer = Nucleus::createFPToUI(cast.value, UInt::getType());
John Bauman89401822014-05-06 15:04:28 -04003959
Alexis Hetu764d1422016-09-28 08:44:22 -04003960 // Smallest positive value representable in UInt, but not in Int
3961 const unsigned int ustart = 0x80000000u;
3962 const float ustartf = float(ustart);
3963
3964 // If the value is negative, store 0, otherwise store the result of the conversion
3965 storeValue((~(As<Int>(cast) >> 31) &
3966 // Check if the value can be represented as an Int
3967 IfThenElse(cast >= ustartf,
3968 // If the value is too large, subtract ustart and re-add it after conversion.
3969 As<Int>(As<UInt>(Int(cast - Float(ustartf))) + UInt(ustart)),
3970 // Otherwise, just convert normally
3971 Int(cast))).value);
John Bauman89401822014-05-06 15:04:28 -04003972 }
3973
John Bauman89401822014-05-06 15:04:28 -04003974 UInt::UInt(int x)
3975 {
John Bauman66b8ab22014-05-06 15:57:45 -04003976 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04003977 }
3978
3979 UInt::UInt(unsigned int x)
3980 {
John Bauman66b8ab22014-05-06 15:57:45 -04003981 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04003982 }
3983
John Bauman19bac1e2014-05-06 15:23:49 -04003984 UInt::UInt(RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04003985 {
John Bauman66b8ab22014-05-06 15:57:45 -04003986 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003987 }
3988
John Bauman19bac1e2014-05-06 15:23:49 -04003989 UInt::UInt(RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003990 {
John Bauman66b8ab22014-05-06 15:57:45 -04003991 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003992 }
3993
3994 UInt::UInt(const UInt &rhs)
3995 {
John Bauman66b8ab22014-05-06 15:57:45 -04003996 Value *value = rhs.loadValue();
3997 storeValue(value);
3998 }
John Bauman89401822014-05-06 15:04:28 -04003999
John Bauman66b8ab22014-05-06 15:57:45 -04004000 UInt::UInt(const Reference<UInt> &rhs)
4001 {
4002 Value *value = rhs.loadValue();
4003 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004004 }
4005
4006 UInt::UInt(const Int &rhs)
4007 {
John Bauman66b8ab22014-05-06 15:57:45 -04004008 Value *value = rhs.loadValue();
4009 storeValue(value);
4010 }
John Bauman89401822014-05-06 15:04:28 -04004011
John Bauman66b8ab22014-05-06 15:57:45 -04004012 UInt::UInt(const Reference<Int> &rhs)
4013 {
4014 Value *value = rhs.loadValue();
4015 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004016 }
4017
Nicolas Capens96d4e092016-11-18 14:22:38 -05004018 RValue<UInt> UInt::operator=(unsigned int rhs)
John Bauman89401822014-05-06 15:04:28 -04004019 {
John Bauman66b8ab22014-05-06 15:57:45 -04004020 return RValue<UInt>(storeValue(Nucleus::createConstantInt(rhs)));
John Bauman89401822014-05-06 15:04:28 -04004021 }
4022
Nicolas Capens96d4e092016-11-18 14:22:38 -05004023 RValue<UInt> UInt::operator=(RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004024 {
John Bauman66b8ab22014-05-06 15:57:45 -04004025 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004026
4027 return rhs;
4028 }
4029
Nicolas Capens96d4e092016-11-18 14:22:38 -05004030 RValue<UInt> UInt::operator=(RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004031 {
John Bauman66b8ab22014-05-06 15:57:45 -04004032 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004033
John Bauman66b8ab22014-05-06 15:57:45 -04004034 return RValue<UInt>(rhs);
John Bauman89401822014-05-06 15:04:28 -04004035 }
4036
Nicolas Capens96d4e092016-11-18 14:22:38 -05004037 RValue<UInt> UInt::operator=(const UInt &rhs)
John Bauman89401822014-05-06 15:04:28 -04004038 {
John Bauman66b8ab22014-05-06 15:57:45 -04004039 Value *value = rhs.loadValue();
4040 storeValue(value);
4041
4042 return RValue<UInt>(value);
4043 }
4044
Nicolas Capens96d4e092016-11-18 14:22:38 -05004045 RValue<UInt> UInt::operator=(const Reference<UInt> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04004046 {
4047 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 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);
John Bauman89401822014-05-06 15:04:28 -04004057
4058 return RValue<UInt>(value);
4059 }
4060
Nicolas Capens96d4e092016-11-18 14:22:38 -05004061 RValue<UInt> UInt::operator=(const Reference<Int> &rhs)
John Bauman89401822014-05-06 15:04:28 -04004062 {
John Bauman66b8ab22014-05-06 15:57:45 -04004063 Value *value = rhs.loadValue();
4064 storeValue(value);
4065
4066 return RValue<UInt>(value);
John Bauman89401822014-05-06 15:04:28 -04004067 }
4068
John Bauman19bac1e2014-05-06 15:23:49 -04004069 RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004070 {
4071 return RValue<UInt>(Nucleus::createAdd(lhs.value, rhs.value));
4072 }
4073
John Bauman19bac1e2014-05-06 15:23:49 -04004074 RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004075 {
4076 return RValue<UInt>(Nucleus::createSub(lhs.value, rhs.value));
4077 }
4078
John Bauman19bac1e2014-05-06 15:23:49 -04004079 RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004080 {
4081 return RValue<UInt>(Nucleus::createMul(lhs.value, rhs.value));
4082 }
4083
John Bauman19bac1e2014-05-06 15:23:49 -04004084 RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004085 {
4086 return RValue<UInt>(Nucleus::createUDiv(lhs.value, rhs.value));
4087 }
4088
John Bauman19bac1e2014-05-06 15:23:49 -04004089 RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004090 {
4091 return RValue<UInt>(Nucleus::createURem(lhs.value, rhs.value));
4092 }
4093
John Bauman19bac1e2014-05-06 15:23:49 -04004094 RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004095 {
4096 return RValue<UInt>(Nucleus::createAnd(lhs.value, rhs.value));
4097 }
4098
John Bauman19bac1e2014-05-06 15:23:49 -04004099 RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004100 {
4101 return RValue<UInt>(Nucleus::createOr(lhs.value, rhs.value));
4102 }
4103
John Bauman19bac1e2014-05-06 15:23:49 -04004104 RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004105 {
4106 return RValue<UInt>(Nucleus::createXor(lhs.value, rhs.value));
4107 }
4108
John Bauman19bac1e2014-05-06 15:23:49 -04004109 RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004110 {
4111 return RValue<UInt>(Nucleus::createShl(lhs.value, rhs.value));
4112 }
4113
John Bauman19bac1e2014-05-06 15:23:49 -04004114 RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004115 {
4116 return RValue<UInt>(Nucleus::createLShr(lhs.value, rhs.value));
4117 }
4118
Nicolas Capens96d4e092016-11-18 14:22:38 -05004119 RValue<UInt> operator+=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004120 {
4121 return lhs = lhs + rhs;
4122 }
4123
Nicolas Capens96d4e092016-11-18 14:22:38 -05004124 RValue<UInt> operator-=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004125 {
4126 return lhs = lhs - rhs;
4127 }
4128
Nicolas Capens96d4e092016-11-18 14:22:38 -05004129 RValue<UInt> operator*=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004130 {
4131 return lhs = lhs * rhs;
4132 }
4133
Nicolas Capens96d4e092016-11-18 14:22:38 -05004134 RValue<UInt> operator/=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004135 {
4136 return lhs = lhs / rhs;
4137 }
4138
Nicolas Capens96d4e092016-11-18 14:22:38 -05004139 RValue<UInt> operator%=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004140 {
4141 return lhs = lhs % rhs;
4142 }
4143
Nicolas Capens96d4e092016-11-18 14:22:38 -05004144 RValue<UInt> operator&=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004145 {
4146 return lhs = lhs & rhs;
4147 }
4148
Nicolas Capens96d4e092016-11-18 14:22:38 -05004149 RValue<UInt> operator|=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004150 {
4151 return lhs = lhs | rhs;
4152 }
4153
Nicolas Capens96d4e092016-11-18 14:22:38 -05004154 RValue<UInt> operator^=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004155 {
4156 return lhs = lhs ^ rhs;
4157 }
4158
Nicolas Capens96d4e092016-11-18 14:22:38 -05004159 RValue<UInt> operator<<=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004160 {
4161 return lhs = lhs << rhs;
4162 }
4163
Nicolas Capens96d4e092016-11-18 14:22:38 -05004164 RValue<UInt> operator>>=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004165 {
4166 return lhs = lhs >> rhs;
4167 }
4168
John Bauman19bac1e2014-05-06 15:23:49 -04004169 RValue<UInt> operator+(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004170 {
4171 return val;
4172 }
4173
John Bauman19bac1e2014-05-06 15:23:49 -04004174 RValue<UInt> operator-(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004175 {
4176 return RValue<UInt>(Nucleus::createNeg(val.value));
4177 }
4178
John Bauman19bac1e2014-05-06 15:23:49 -04004179 RValue<UInt> operator~(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004180 {
4181 return RValue<UInt>(Nucleus::createNot(val.value));
4182 }
4183
Nicolas Capens96d4e092016-11-18 14:22:38 -05004184 RValue<UInt> operator++(UInt &val, int) // Post-increment
John Bauman89401822014-05-06 15:04:28 -04004185 {
4186 RValue<UInt> res = val;
4187
Nicolas Capens19336542016-09-26 10:32:29 -04004188 Value *inc = Nucleus::createAdd(res.value, 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 res;
4192 }
4193
Nicolas Capens96d4e092016-11-18 14:22:38 -05004194 const UInt &operator++(UInt &val) // Pre-increment
John Bauman89401822014-05-06 15:04:28 -04004195 {
Nicolas Capens19336542016-09-26 10:32:29 -04004196 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04004197 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004198
4199 return val;
4200 }
4201
Nicolas Capens96d4e092016-11-18 14:22:38 -05004202 RValue<UInt> operator--(UInt &val, int) // Post-decrement
John Bauman89401822014-05-06 15:04:28 -04004203 {
4204 RValue<UInt> res = val;
4205
Nicolas Capens19336542016-09-26 10:32:29 -04004206 Value *inc = Nucleus::createSub(res.value, 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 res;
4210 }
4211
Nicolas Capens96d4e092016-11-18 14:22:38 -05004212 const UInt &operator--(UInt &val) // Pre-decrement
John Bauman89401822014-05-06 15:04:28 -04004213 {
Nicolas Capens19336542016-09-26 10:32:29 -04004214 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04004215 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004216
4217 return val;
4218 }
4219
John Bauman19bac1e2014-05-06 15:23:49 -04004220 RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y)
4221 {
4222 return IfThenElse(x > y, x, y);
4223 }
4224
4225 RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y)
4226 {
4227 return IfThenElse(x < y, x, y);
4228 }
4229
4230 RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max)
4231 {
4232 return Min(Max(x, min), max);
4233 }
4234
4235 RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004236 {
4237 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
4238 }
4239
John Bauman19bac1e2014-05-06 15:23:49 -04004240 RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004241 {
4242 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
4243 }
4244
John Bauman19bac1e2014-05-06 15:23:49 -04004245 RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004246 {
4247 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
4248 }
4249
John Bauman19bac1e2014-05-06 15:23:49 -04004250 RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004251 {
4252 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
4253 }
4254
John Bauman19bac1e2014-05-06 15:23:49 -04004255 RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004256 {
4257 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
4258 }
4259
John Bauman19bac1e2014-05-06 15:23:49 -04004260 RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004261 {
4262 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
4263 }
4264
John Bauman19bac1e2014-05-06 15:23:49 -04004265// RValue<UInt> RoundUInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04004266// {
4267// return x86::cvtss2si(val); // FIXME: Unsigned
4268//
John Bauman66b8ab22014-05-06 15:57:45 -04004269// // return IfThenElse(val > 0.0f, Int(val + 0.5f), Int(val - 0.5f));
John Bauman89401822014-05-06 15:04:28 -04004270// }
4271
John Bauman19bac1e2014-05-06 15:23:49 -04004272 Type *UInt::getType()
John Bauman89401822014-05-06 15:04:28 -04004273 {
Nicolas Capensac230122016-09-20 14:30:06 -04004274 return T(llvm::Type::getInt32Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04004275 }
4276
John Bauman19bac1e2014-05-06 15:23:49 -04004277// Int2::Int2(RValue<Int> cast)
4278// {
John Bauman19bac1e2014-05-06 15:23:49 -04004279// Value *extend = Nucleus::createZExt(cast.value, Long::getType());
4280// Value *vector = Nucleus::createBitCast(extend, Int2::getType());
John Bauman66b8ab22014-05-06 15:57:45 -04004281//
Nicolas Capense89cd582016-09-30 14:23:47 -04004282// int shuffle[2] = {0, 0};
4283// Value *replicate = Nucleus::createShuffleVector(vector, vector, shuffle);
John Bauman19bac1e2014-05-06 15:23:49 -04004284//
John Bauman66b8ab22014-05-06 15:57:45 -04004285// storeValue(replicate);
John Bauman19bac1e2014-05-06 15:23:49 -04004286// }
John Bauman89401822014-05-06 15:04:28 -04004287
John Bauman19bac1e2014-05-06 15:23:49 -04004288 Int2::Int2(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04004289 {
Nicolas Capens22008782016-10-20 01:11:47 -04004290 Value *long2 = Nucleus::createBitCast(cast.value, T(VectorType::get(Long::getType(), 2)));
Nicolas Capense95d5342016-09-30 11:37:28 -04004291 Value *element = Nucleus::createExtractElement(long2, Long::getType(), 0);
John Bauman89401822014-05-06 15:04:28 -04004292 Value *int2 = Nucleus::createBitCast(element, Int2::getType());
4293
John Bauman66b8ab22014-05-06 15:57:45 -04004294 storeValue(int2);
John Bauman89401822014-05-06 15:04:28 -04004295 }
4296
John Bauman89401822014-05-06 15:04:28 -04004297 Int2::Int2(int x, int y)
4298 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04004299 int64_t constantVector[2] = {x, y};
4300 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(Int::getType(), 2))));
John Bauman89401822014-05-06 15:04:28 -04004301
John Bauman66b8ab22014-05-06 15:57:45 -04004302 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04004303 }
4304
John Bauman19bac1e2014-05-06 15:23:49 -04004305 Int2::Int2(RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004306 {
John Bauman66b8ab22014-05-06 15:57:45 -04004307 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004308 }
4309
4310 Int2::Int2(const Int2 &rhs)
4311 {
John Bauman66b8ab22014-05-06 15:57:45 -04004312 Value *value = rhs.loadValue();
4313 storeValue(value);
4314 }
4315
4316 Int2::Int2(const Reference<Int2> &rhs)
4317 {
John Bauman66b8ab22014-05-06 15:57:45 -04004318 Value *value = rhs.loadValue();
4319 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004320 }
4321
Nicolas Capens62abb552016-01-05 12:03:47 -05004322 Int2::Int2(RValue<Int> lo, RValue<Int> hi)
4323 {
Nicolas Capensb40a2562016-01-05 00:08:45 -05004324 if(CPUID::supportsMMX2())
4325 {
4326 // movd mm0, lo
4327 // movd mm1, hi
4328 // punpckldq mm0, mm1
Nicolas Capens45f187a2016-12-02 15:30:56 -05004329
4330 Value *loLong = Nucleus::createInsertElement(V(UndefValue::get(VectorType::get(Int::getType(), 2))), lo.value, 0);
4331 loLong = Nucleus::createInsertElement(loLong, V(ConstantInt::get(Int::getType(), 0)), 1);
4332 Value *hiLong = Nucleus::createInsertElement(V(UndefValue::get(VectorType::get(Int::getType(), 2))), hi.value, 0);
4333 hiLong = Nucleus::createInsertElement(hiLong, V(ConstantInt::get(Int::getType(), 0)), 1);
4334
4335 storeValue(As<Int2>(UnpackLow(As<Int2>(loLong), As<Int2>(hiLong))).value);
Nicolas Capensb40a2562016-01-05 00:08:45 -05004336 }
4337 else
4338 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004339 int shuffle[2] = {0, 1};
4340 Value *packed = Nucleus::createShuffleVector(Nucleus::createBitCast(lo.value, T(VectorType::get(Int::getType(), 1))), Nucleus::createBitCast(hi.value, T(VectorType::get(Int::getType(), 1))), shuffle);
Nicolas Capens05b3d662016-02-25 23:58:33 -05004341
Nicolas Capensb40a2562016-01-05 00:08:45 -05004342 storeValue(Nucleus::createBitCast(packed, Int2::getType()));
4343 }
Nicolas Capens62abb552016-01-05 12:03:47 -05004344 }
4345
Nicolas Capens96d4e092016-11-18 14:22:38 -05004346 RValue<Int2> Int2::operator=(RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004347 {
John Bauman66b8ab22014-05-06 15:57:45 -04004348 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004349
4350 return rhs;
4351 }
4352
Nicolas Capens96d4e092016-11-18 14:22:38 -05004353 RValue<Int2> Int2::operator=(const Int2 &rhs)
John Bauman89401822014-05-06 15:04:28 -04004354 {
John Bauman66b8ab22014-05-06 15:57:45 -04004355 Value *value = rhs.loadValue();
4356 storeValue(value);
4357
4358 return RValue<Int2>(value);
4359 }
4360
Nicolas Capens96d4e092016-11-18 14:22:38 -05004361 RValue<Int2> Int2::operator=(const Reference<Int2> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04004362 {
4363 Value *value = rhs.loadValue();
4364 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004365
4366 return RValue<Int2>(value);
4367 }
4368
John Bauman19bac1e2014-05-06 15:23:49 -04004369 RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004370 {
John Bauman19bac1e2014-05-06 15:23:49 -04004371 if(CPUID::supportsMMX2())
4372 {
4373 return x86::paddd(lhs, rhs);
4374 }
4375 else
4376 {
4377 return RValue<Int2>(Nucleus::createAdd(lhs.value, rhs.value));
4378 }
John Bauman89401822014-05-06 15:04:28 -04004379 }
4380
John Bauman19bac1e2014-05-06 15:23:49 -04004381 RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004382 {
John Bauman19bac1e2014-05-06 15:23:49 -04004383 if(CPUID::supportsMMX2())
4384 {
4385 return x86::psubd(lhs, rhs);
4386 }
4387 else
4388 {
4389 return RValue<Int2>(Nucleus::createSub(lhs.value, rhs.value));
4390 }
John Bauman89401822014-05-06 15:04:28 -04004391 }
4392
John Bauman19bac1e2014-05-06 15:23:49 -04004393// RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs)
4394// {
4395// return RValue<Int2>(Nucleus::createMul(lhs.value, rhs.value));
4396// }
4397
4398// RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs)
4399// {
4400// return RValue<Int2>(Nucleus::createSDiv(lhs.value, rhs.value));
4401// }
4402
4403// RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs)
4404// {
4405// return RValue<Int2>(Nucleus::createSRem(lhs.value, rhs.value));
4406// }
4407
4408 RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004409 {
John Bauman19bac1e2014-05-06 15:23:49 -04004410 if(CPUID::supportsMMX2())
4411 {
4412 return As<Int2>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
4413 }
4414 else
4415 {
4416 return RValue<Int2>(Nucleus::createAnd(lhs.value, rhs.value));
4417 }
John Bauman89401822014-05-06 15:04:28 -04004418 }
4419
John Bauman19bac1e2014-05-06 15:23:49 -04004420 RValue<Int2> operator|(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004421 {
John Bauman19bac1e2014-05-06 15:23:49 -04004422 if(CPUID::supportsMMX2())
4423 {
4424 return As<Int2>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
4425 }
4426 else
4427 {
4428 return RValue<Int2>(Nucleus::createOr(lhs.value, rhs.value));
4429 }
John Bauman89401822014-05-06 15:04:28 -04004430 }
4431
John Bauman19bac1e2014-05-06 15:23:49 -04004432 RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004433 {
John Bauman19bac1e2014-05-06 15:23:49 -04004434 if(CPUID::supportsMMX2())
4435 {
4436 return As<Int2>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
4437 }
4438 else
4439 {
4440 return RValue<Int2>(Nucleus::createXor(lhs.value, rhs.value));
4441 }
John Bauman89401822014-05-06 15:04:28 -04004442 }
4443
John Bauman19bac1e2014-05-06 15:23:49 -04004444 RValue<Int2> operator<<(RValue<Int2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004445 {
4446 // return RValue<Int2>(Nucleus::createShl(lhs.value, rhs.value));
4447
4448 return x86::pslld(lhs, rhs);
4449 }
4450
John Bauman19bac1e2014-05-06 15:23:49 -04004451 RValue<Int2> operator>>(RValue<Int2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004452 {
4453 // return RValue<Int2>(Nucleus::createAShr(lhs.value, rhs.value));
4454
4455 return x86::psrad(lhs, rhs);
4456 }
4457
Nicolas Capens96d4e092016-11-18 14:22:38 -05004458 RValue<Int2> operator+=(Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004459 {
4460 return lhs = lhs + rhs;
4461 }
4462
Nicolas Capens96d4e092016-11-18 14:22:38 -05004463 RValue<Int2> operator-=(Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004464 {
4465 return lhs = lhs - rhs;
4466 }
4467
Nicolas Capens96d4e092016-11-18 14:22:38 -05004468// RValue<Int2> operator*=(Int2 &lhs, RValue<Int2> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04004469// {
4470// return lhs = lhs * rhs;
4471// }
John Bauman89401822014-05-06 15:04:28 -04004472
Nicolas Capens96d4e092016-11-18 14:22:38 -05004473// RValue<Int2> operator/=(Int2 &lhs, RValue<Int2> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04004474// {
4475// return lhs = lhs / rhs;
4476// }
John Bauman89401822014-05-06 15:04:28 -04004477
Nicolas Capens96d4e092016-11-18 14:22:38 -05004478// RValue<Int2> operator%=(Int2 &lhs, RValue<Int2> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04004479// {
4480// return lhs = lhs % rhs;
4481// }
John Bauman89401822014-05-06 15:04:28 -04004482
Nicolas Capens96d4e092016-11-18 14:22:38 -05004483 RValue<Int2> operator&=(Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004484 {
4485 return lhs = lhs & rhs;
4486 }
4487
Nicolas Capens96d4e092016-11-18 14:22:38 -05004488 RValue<Int2> operator|=(Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004489 {
4490 return lhs = lhs | rhs;
4491 }
4492
Nicolas Capens96d4e092016-11-18 14:22:38 -05004493 RValue<Int2> operator^=(Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004494 {
4495 return lhs = lhs ^ rhs;
4496 }
4497
Nicolas Capens96d4e092016-11-18 14:22:38 -05004498 RValue<Int2> operator<<=(Int2 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004499 {
4500 return lhs = lhs << rhs;
4501 }
4502
Nicolas Capens96d4e092016-11-18 14:22:38 -05004503 RValue<Int2> operator>>=(Int2 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004504 {
4505 return lhs = lhs >> rhs;
4506 }
4507
John Bauman19bac1e2014-05-06 15:23:49 -04004508// RValue<Int2> operator+(RValue<Int2> val)
4509// {
4510// return val;
4511// }
4512
4513// RValue<Int2> operator-(RValue<Int2> val)
4514// {
4515// return RValue<Int2>(Nucleus::createNeg(val.value));
4516// }
4517
4518 RValue<Int2> operator~(RValue<Int2> val)
John Bauman89401822014-05-06 15:04:28 -04004519 {
John Bauman19bac1e2014-05-06 15:23:49 -04004520 if(CPUID::supportsMMX2())
4521 {
4522 return val ^ Int2(0xFFFFFFFF, 0xFFFFFFFF);
4523 }
4524 else
4525 {
4526 return RValue<Int2>(Nucleus::createNot(val.value));
4527 }
John Bauman89401822014-05-06 15:04:28 -04004528 }
4529
Nicolas Capens45f187a2016-12-02 15:30:56 -05004530 RValue<Short4> UnpackLow(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04004531 {
John Bauman19bac1e2014-05-06 15:23:49 -04004532 if(CPUID::supportsMMX2())
4533 {
4534 return x86::punpckldq(x, y);
4535 }
4536 else
4537 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004538 int shuffle[2] = {0, 2};
4539 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04004540
Nicolas Capens45f187a2016-12-02 15:30:56 -05004541 return As<Short4>(packed);
John Bauman19bac1e2014-05-06 15:23:49 -04004542 }
John Bauman89401822014-05-06 15:04:28 -04004543 }
John Bauman66b8ab22014-05-06 15:57:45 -04004544
Nicolas Capens45f187a2016-12-02 15:30:56 -05004545 RValue<Short4> UnpackHigh(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04004546 {
John Bauman19bac1e2014-05-06 15:23:49 -04004547 if(CPUID::supportsMMX2())
4548 {
4549 return x86::punpckhdq(x, y);
4550 }
4551 else
4552 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004553 int shuffle[2] = {1, 3};
4554 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04004555
Nicolas Capens45f187a2016-12-02 15:30:56 -05004556 return As<Short4>(packed);
John Bauman19bac1e2014-05-06 15:23:49 -04004557 }
John Bauman89401822014-05-06 15:04:28 -04004558 }
4559
John Bauman19bac1e2014-05-06 15:23:49 -04004560 RValue<Int> Extract(RValue<Int2> val, int i)
John Bauman89401822014-05-06 15:04:28 -04004561 {
4562 if(false) // FIXME: LLVM does not generate optimal code
4563 {
Nicolas Capense95d5342016-09-30 11:37:28 -04004564 return RValue<Int>(Nucleus::createExtractElement(val.value, Int::getType(), i));
John Bauman89401822014-05-06 15:04:28 -04004565 }
4566 else
4567 {
4568 if(i == 0)
4569 {
Nicolas Capense95d5342016-09-30 11:37:28 -04004570 return RValue<Int>(Nucleus::createExtractElement(Nucleus::createBitCast(val.value, T(VectorType::get(Int::getType(), 2))), Int::getType(), 0));
John Bauman89401822014-05-06 15:04:28 -04004571 }
4572 else
4573 {
4574 Int2 val2 = As<Int2>(UnpackHigh(val, val));
4575
4576 return Extract(val2, 0);
4577 }
4578 }
4579 }
4580
Nicolas Capensfff3c9b2015-05-13 23:40:44 -04004581 RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i)
4582 {
Nicolas Capensac230122016-09-20 14:30:06 -04004583 return RValue<Int2>(Nucleus::createBitCast(Nucleus::createInsertElement(Nucleus::createBitCast(val.value, T(VectorType::get(Int::getType(), 2))), element.value, i), Int2::getType()));
Nicolas Capensfff3c9b2015-05-13 23:40:44 -04004584 }
John Bauman89401822014-05-06 15:04:28 -04004585
John Bauman19bac1e2014-05-06 15:23:49 -04004586 Type *Int2::getType()
John Bauman89401822014-05-06 15:04:28 -04004587 {
John Bauman19bac1e2014-05-06 15:23:49 -04004588 if(CPUID::supportsMMX2())
4589 {
4590 return MMX::getType();
4591 }
4592 else
4593 {
Nicolas Capensac230122016-09-20 14:30:06 -04004594 return T(VectorType::get(Int::getType(), 2));
John Bauman19bac1e2014-05-06 15:23:49 -04004595 }
John Bauman89401822014-05-06 15:04:28 -04004596 }
4597
John Bauman89401822014-05-06 15:04:28 -04004598 UInt2::UInt2(unsigned int x, unsigned int y)
4599 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04004600 int64_t constantVector[2] = {x, y};
4601 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(UInt::getType(), 2))));
John Bauman89401822014-05-06 15:04:28 -04004602
John Bauman66b8ab22014-05-06 15:57:45 -04004603 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04004604 }
4605
John Bauman19bac1e2014-05-06 15:23:49 -04004606 UInt2::UInt2(RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004607 {
John Bauman66b8ab22014-05-06 15:57:45 -04004608 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004609 }
4610
4611 UInt2::UInt2(const UInt2 &rhs)
4612 {
John Bauman66b8ab22014-05-06 15:57:45 -04004613 Value *value = rhs.loadValue();
4614 storeValue(value);
4615 }
4616
4617 UInt2::UInt2(const Reference<UInt2> &rhs)
4618 {
John Bauman66b8ab22014-05-06 15:57:45 -04004619 Value *value = rhs.loadValue();
4620 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004621 }
4622
Nicolas Capens96d4e092016-11-18 14:22:38 -05004623 RValue<UInt2> UInt2::operator=(RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004624 {
John Bauman66b8ab22014-05-06 15:57:45 -04004625 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004626
4627 return rhs;
4628 }
4629
Nicolas Capens96d4e092016-11-18 14:22:38 -05004630 RValue<UInt2> UInt2::operator=(const UInt2 &rhs)
John Bauman89401822014-05-06 15:04:28 -04004631 {
John Bauman66b8ab22014-05-06 15:57:45 -04004632 Value *value = rhs.loadValue();
4633 storeValue(value);
4634
4635 return RValue<UInt2>(value);
4636 }
4637
Nicolas Capens96d4e092016-11-18 14:22:38 -05004638 RValue<UInt2> UInt2::operator=(const Reference<UInt2> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04004639 {
4640 Value *value = rhs.loadValue();
4641 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004642
4643 return RValue<UInt2>(value);
4644 }
4645
John Bauman19bac1e2014-05-06 15:23:49 -04004646 RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004647 {
John Bauman19bac1e2014-05-06 15:23:49 -04004648 if(CPUID::supportsMMX2())
4649 {
4650 return As<UInt2>(x86::paddd(As<Int2>(lhs), As<Int2>(rhs)));
4651 }
4652 else
4653 {
4654 return RValue<UInt2>(Nucleus::createAdd(lhs.value, rhs.value));
4655 }
John Bauman89401822014-05-06 15:04:28 -04004656 }
4657
John Bauman19bac1e2014-05-06 15:23:49 -04004658 RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004659 {
John Bauman19bac1e2014-05-06 15:23:49 -04004660 if(CPUID::supportsMMX2())
4661 {
4662 return As<UInt2>(x86::psubd(As<Int2>(lhs), As<Int2>(rhs)));
4663 }
4664 else
4665 {
4666 return RValue<UInt2>(Nucleus::createSub(lhs.value, rhs.value));
4667 }
John Bauman89401822014-05-06 15:04:28 -04004668 }
4669
John Bauman19bac1e2014-05-06 15:23:49 -04004670// RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs)
4671// {
4672// return RValue<UInt2>(Nucleus::createMul(lhs.value, rhs.value));
4673// }
4674
4675// RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs)
4676// {
4677// return RValue<UInt2>(Nucleus::createUDiv(lhs.value, rhs.value));
4678// }
4679
4680// RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs)
4681// {
4682// return RValue<UInt2>(Nucleus::createURem(lhs.value, rhs.value));
4683// }
4684
4685 RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004686 {
John Bauman19bac1e2014-05-06 15:23:49 -04004687 if(CPUID::supportsMMX2())
4688 {
4689 return As<UInt2>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
4690 }
4691 else
4692 {
4693 return RValue<UInt2>(Nucleus::createAnd(lhs.value, rhs.value));
4694 }
John Bauman89401822014-05-06 15:04:28 -04004695 }
4696
John Bauman19bac1e2014-05-06 15:23:49 -04004697 RValue<UInt2> operator|(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004698 {
John Bauman19bac1e2014-05-06 15:23:49 -04004699 if(CPUID::supportsMMX2())
4700 {
4701 return As<UInt2>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
4702 }
4703 else
4704 {
4705 return RValue<UInt2>(Nucleus::createOr(lhs.value, rhs.value));
4706 }
John Bauman89401822014-05-06 15:04:28 -04004707 }
4708
John Bauman19bac1e2014-05-06 15:23:49 -04004709 RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004710 {
John Bauman19bac1e2014-05-06 15:23:49 -04004711 if(CPUID::supportsMMX2())
4712 {
4713 return As<UInt2>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
4714 }
4715 else
4716 {
4717 return RValue<UInt2>(Nucleus::createXor(lhs.value, rhs.value));
4718 }
John Bauman89401822014-05-06 15:04:28 -04004719 }
4720
John Bauman19bac1e2014-05-06 15:23:49 -04004721 RValue<UInt2> operator<<(RValue<UInt2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004722 {
4723 // return RValue<UInt2>(Nucleus::createShl(lhs.value, rhs.value));
4724
4725 return As<UInt2>(x86::pslld(As<Int2>(lhs), rhs));
4726 }
4727
John Bauman19bac1e2014-05-06 15:23:49 -04004728 RValue<UInt2> operator>>(RValue<UInt2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004729 {
4730 // return RValue<UInt2>(Nucleus::createLShr(lhs.value, rhs.value));
4731
4732 return x86::psrld(lhs, rhs);
4733 }
4734
Nicolas Capens96d4e092016-11-18 14:22:38 -05004735 RValue<UInt2> operator+=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004736 {
4737 return lhs = lhs + rhs;
4738 }
4739
Nicolas Capens96d4e092016-11-18 14:22:38 -05004740 RValue<UInt2> operator-=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004741 {
4742 return lhs = lhs - rhs;
4743 }
4744
Nicolas Capens96d4e092016-11-18 14:22:38 -05004745// RValue<UInt2> operator*=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04004746// {
4747// return lhs = lhs * rhs;
4748// }
John Bauman89401822014-05-06 15:04:28 -04004749
Nicolas Capens96d4e092016-11-18 14:22:38 -05004750// RValue<UInt2> operator/=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04004751// {
4752// return lhs = lhs / rhs;
4753// }
John Bauman89401822014-05-06 15:04:28 -04004754
Nicolas Capens96d4e092016-11-18 14:22:38 -05004755// RValue<UInt2> operator%=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04004756// {
4757// return lhs = lhs % rhs;
4758// }
John Bauman89401822014-05-06 15:04:28 -04004759
Nicolas Capens96d4e092016-11-18 14:22:38 -05004760 RValue<UInt2> operator&=(UInt2 &lhs, RValue<UInt2> 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, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004766 {
4767 return lhs = lhs | rhs;
4768 }
4769
Nicolas Capens96d4e092016-11-18 14:22:38 -05004770 RValue<UInt2> operator^=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004771 {
4772 return lhs = lhs ^ rhs;
4773 }
4774
Nicolas Capens96d4e092016-11-18 14:22:38 -05004775 RValue<UInt2> operator<<=(UInt2 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004776 {
4777 return lhs = lhs << rhs;
4778 }
4779
Nicolas Capens96d4e092016-11-18 14:22:38 -05004780 RValue<UInt2> operator>>=(UInt2 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004781 {
4782 return lhs = lhs >> rhs;
4783 }
4784
John Bauman19bac1e2014-05-06 15:23:49 -04004785// RValue<UInt2> operator+(RValue<UInt2> val)
4786// {
4787// return val;
4788// }
4789
4790// RValue<UInt2> operator-(RValue<UInt2> val)
4791// {
4792// return RValue<UInt2>(Nucleus::createNeg(val.value));
4793// }
4794
4795 RValue<UInt2> operator~(RValue<UInt2> val)
John Bauman89401822014-05-06 15:04:28 -04004796 {
John Bauman19bac1e2014-05-06 15:23:49 -04004797 if(CPUID::supportsMMX2())
4798 {
4799 return val ^ UInt2(0xFFFFFFFF, 0xFFFFFFFF);
4800 }
4801 else
4802 {
4803 return RValue<UInt2>(Nucleus::createNot(val.value));
4804 }
John Bauman89401822014-05-06 15:04:28 -04004805 }
4806
John Bauman19bac1e2014-05-06 15:23:49 -04004807 Type *UInt2::getType()
John Bauman89401822014-05-06 15:04:28 -04004808 {
John Bauman19bac1e2014-05-06 15:23:49 -04004809 if(CPUID::supportsMMX2())
4810 {
4811 return MMX::getType();
4812 }
4813 else
4814 {
Nicolas Capensac230122016-09-20 14:30:06 -04004815 return T(VectorType::get(UInt::getType(), 2));
John Bauman19bac1e2014-05-06 15:23:49 -04004816 }
John Bauman89401822014-05-06 15:04:28 -04004817 }
4818
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004819 Int4::Int4(RValue<Byte4> cast)
4820 {
4821 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
Nicolas Capens19336542016-09-26 10:32:29 -04004822 Value *a = Nucleus::createInsertElement(V(UndefValue::get(Int4::getType())), x, 0);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004823
4824 Value *e;
4825
4826 if (CPUID::supportsSSE4_1())
4827 {
4828 e = x86::pmovzxbd(RValue<Int4>(a)).value;
4829 }
4830 else
4831 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004832 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 -04004833 Value *b = Nucleus::createBitCast(a, Byte16::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04004834 Value *c = Nucleus::createShuffleVector(b, V(Nucleus::createNullValue(Byte16::getType())), swizzle);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004835
Nicolas Capense89cd582016-09-30 14:23:47 -04004836 int swizzle2[8] = {0, 8, 1, 9, 2, 10, 3, 11};
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004837 Value *d = Nucleus::createBitCast(c, Short8::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04004838 e = Nucleus::createShuffleVector(d, V(Nucleus::createNullValue(Short8::getType())), swizzle2);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004839 }
4840
4841 Value *f = Nucleus::createBitCast(e, Int4::getType());
4842 storeValue(f);
4843 }
4844
4845 Int4::Int4(RValue<SByte4> cast)
4846 {
4847 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
Nicolas Capens19336542016-09-26 10:32:29 -04004848 Value *a = Nucleus::createInsertElement(V(UndefValue::get(Int4::getType())), x, 0);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004849
4850 Value *g;
4851
4852 if (CPUID::supportsSSE4_1())
4853 {
4854 g = x86::pmovsxbd(RValue<Int4>(a)).value;
4855 }
4856 else
4857 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004858 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 -04004859 Value *b = Nucleus::createBitCast(a, Byte16::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04004860 Value *c = Nucleus::createShuffleVector(b, b, swizzle);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004861
Nicolas Capense89cd582016-09-30 14:23:47 -04004862 int swizzle2[8] = {0, 0, 1, 1, 2, 2, 3, 3};
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004863 Value *d = Nucleus::createBitCast(c, Short8::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04004864 Value *e = Nucleus::createShuffleVector(d, d, swizzle2);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004865
4866 Value *f = Nucleus::createBitCast(e, Int4::getType());
4867 // g = Nucleus::createAShr(f, Nucleus::createConstantInt(24));
4868 g = x86::psrad(RValue<Int4>(f), 24).value;
4869 }
4870
4871 storeValue(g);
4872 }
4873
John Bauman19bac1e2014-05-06 15:23:49 -04004874 Int4::Int4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04004875 {
John Bauman89401822014-05-06 15:04:28 -04004876 Value *xyzw = Nucleus::createFPToSI(cast.value, Int4::getType());
John Bauman89401822014-05-06 15:04:28 -04004877
John Bauman66b8ab22014-05-06 15:57:45 -04004878 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04004879 }
4880
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004881 Int4::Int4(RValue<Short4> cast)
4882 {
Nicolas Capens22008782016-10-20 01:11:47 -04004883 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004884 Value *element = Nucleus::createBitCast(cast.value, Long::getType());
4885 long2 = Nucleus::createInsertElement(long2, element, 0);
4886 RValue<Int4> vector = RValue<Int4>(Nucleus::createBitCast(long2, Int4::getType()));
Nicolas Capens05b3d662016-02-25 23:58:33 -05004887
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004888 if(CPUID::supportsSSE4_1())
4889 {
4890 storeValue(x86::pmovsxwd(vector).value);
4891 }
4892 else
4893 {
4894 Value *b = Nucleus::createBitCast(vector.value, Short8::getType());
4895
Nicolas Capense89cd582016-09-30 14:23:47 -04004896 int swizzle[8] = {0, 0, 1, 1, 2, 2, 3, 3};
4897 Value *c = Nucleus::createShuffleVector(b, b, swizzle);
Nicolas Capens6ce5c332015-10-28 01:58:18 -04004898 Value *d = Nucleus::createBitCast(c, Int4::getType());
4899 storeValue(d);
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004900
4901 // Each Short is packed into each Int in the (Short | Short) format.
4902 // Shifting by 16 will retrieve the original Short value.
Nicolas Capensf549e3b2017-01-24 08:53:47 -08004903 // Shifting an Int will propagate the sign bit, which will work
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004904 // for both positive and negative values of a Short.
4905 *this >>= 16;
4906 }
4907 }
4908
4909 Int4::Int4(RValue<UShort4> cast)
4910 {
Nicolas Capens22008782016-10-20 01:11:47 -04004911 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004912 Value *element = Nucleus::createBitCast(cast.value, Long::getType());
4913 long2 = Nucleus::createInsertElement(long2, element, 0);
4914 RValue<Int4> vector = RValue<Int4>(Nucleus::createBitCast(long2, Int4::getType()));
4915
4916 if(CPUID::supportsSSE4_1())
4917 {
4918 storeValue(x86::pmovzxwd(RValue<Int4>(vector)).value);
4919 }
4920 else
4921 {
4922 Value *b = Nucleus::createBitCast(vector.value, Short8::getType());
4923
Nicolas Capense89cd582016-09-30 14:23:47 -04004924 int swizzle[8] = {0, 8, 1, 9, 2, 10, 3, 11};
4925 Value *c = Nucleus::createShuffleVector(b, V(Nucleus::createNullValue(Short8::getType())), swizzle);
Nicolas Capens6ce5c332015-10-28 01:58:18 -04004926 Value *d = Nucleus::createBitCast(c, Int4::getType());
4927 storeValue(d);
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004928 }
4929 }
4930
John Bauman89401822014-05-06 15:04:28 -04004931 Int4::Int4(int xyzw)
4932 {
4933 constant(xyzw, xyzw, xyzw, xyzw);
4934 }
4935
4936 Int4::Int4(int x, int yzw)
4937 {
4938 constant(x, yzw, yzw, yzw);
4939 }
4940
4941 Int4::Int4(int x, int y, int zw)
4942 {
4943 constant(x, y, zw, zw);
4944 }
4945
4946 Int4::Int4(int x, int y, int z, int w)
4947 {
4948 constant(x, y, z, w);
4949 }
4950
4951 void Int4::constant(int x, int y, int z, int w)
4952 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04004953 int64_t constantVector[4] = {x, y, z, w};
4954 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04004955 }
4956
John Bauman19bac1e2014-05-06 15:23:49 -04004957 Int4::Int4(RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04004958 {
John Bauman66b8ab22014-05-06 15:57:45 -04004959 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004960 }
4961
4962 Int4::Int4(const Int4 &rhs)
4963 {
John Bauman66b8ab22014-05-06 15:57:45 -04004964 Value *value = rhs.loadValue();
4965 storeValue(value);
4966 }
4967
4968 Int4::Int4(const Reference<Int4> &rhs)
4969 {
John Bauman66b8ab22014-05-06 15:57:45 -04004970 Value *value = rhs.loadValue();
4971 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004972 }
4973
John Bauman19bac1e2014-05-06 15:23:49 -04004974 Int4::Int4(RValue<UInt4> rhs)
4975 {
John Bauman66b8ab22014-05-06 15:57:45 -04004976 storeValue(rhs.value);
John Bauman19bac1e2014-05-06 15:23:49 -04004977 }
4978
4979 Int4::Int4(const UInt4 &rhs)
4980 {
John Bauman66b8ab22014-05-06 15:57:45 -04004981 Value *value = rhs.loadValue();
4982 storeValue(value);
4983 }
4984
4985 Int4::Int4(const Reference<UInt4> &rhs)
4986 {
John Bauman66b8ab22014-05-06 15:57:45 -04004987 Value *value = rhs.loadValue();
4988 storeValue(value);
John Bauman19bac1e2014-05-06 15:23:49 -04004989 }
4990
Nicolas Capens62abb552016-01-05 12:03:47 -05004991 Int4::Int4(RValue<Int2> lo, RValue<Int2> hi)
4992 {
4993 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
4994 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
4995
Nicolas Capens22008782016-10-20 01:11:47 -04004996 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Nicolas Capens62abb552016-01-05 12:03:47 -05004997 long2 = Nucleus::createInsertElement(long2, loLong, 0);
4998 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
4999 Value *int4 = Nucleus::createBitCast(long2, Int4::getType());
5000
5001 storeValue(int4);
5002 }
5003
Nicolas Capens24c8cf02016-08-15 15:33:14 -04005004 Int4::Int4(RValue<Int> rhs)
5005 {
Nicolas Capens24c8cf02016-08-15 15:33:14 -04005006 Value *vector = loadValue();
5007 Value *insert = Nucleus::createInsertElement(vector, rhs.value, 0);
5008
Nicolas Capense89cd582016-09-30 14:23:47 -04005009 int swizzle[4] = {0, 0, 0, 0};
5010 Value *replicate = Nucleus::createShuffleVector(insert, insert, swizzle);
Nicolas Capens24c8cf02016-08-15 15:33:14 -04005011
5012 storeValue(replicate);
5013 }
5014
5015 Int4::Int4(const Int &rhs)
5016 {
Nicolas Capens24c8cf02016-08-15 15:33:14 -04005017 *this = RValue<Int>(rhs.loadValue());
5018 }
5019
5020 Int4::Int4(const Reference<Int> &rhs)
5021 {
Nicolas Capens24c8cf02016-08-15 15:33:14 -04005022 *this = RValue<Int>(rhs.loadValue());
5023 }
5024
Nicolas Capens96d4e092016-11-18 14:22:38 -05005025 RValue<Int4> Int4::operator=(RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005026 {
John Bauman66b8ab22014-05-06 15:57:45 -04005027 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005028
5029 return rhs;
5030 }
5031
Nicolas Capens96d4e092016-11-18 14:22:38 -05005032 RValue<Int4> Int4::operator=(const Int4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04005033 {
John Bauman66b8ab22014-05-06 15:57:45 -04005034 Value *value = rhs.loadValue();
5035 storeValue(value);
5036
5037 return RValue<Int4>(value);
5038 }
5039
Nicolas Capens96d4e092016-11-18 14:22:38 -05005040 RValue<Int4> Int4::operator=(const Reference<Int4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04005041 {
5042 Value *value = rhs.loadValue();
5043 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005044
5045 return RValue<Int4>(value);
5046 }
5047
John Bauman19bac1e2014-05-06 15:23:49 -04005048 RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005049 {
5050 return RValue<Int4>(Nucleus::createAdd(lhs.value, rhs.value));
5051 }
5052
John Bauman19bac1e2014-05-06 15:23:49 -04005053 RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005054 {
5055 return RValue<Int4>(Nucleus::createSub(lhs.value, rhs.value));
5056 }
5057
John Bauman19bac1e2014-05-06 15:23:49 -04005058 RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005059 {
5060 return RValue<Int4>(Nucleus::createMul(lhs.value, rhs.value));
5061 }
5062
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005063 RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs)
5064 {
5065 return RValue<Int4>(Nucleus::createSDiv(lhs.value, rhs.value));
5066 }
John Bauman89401822014-05-06 15:04:28 -04005067
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005068 RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs)
5069 {
5070 return RValue<Int4>(Nucleus::createSRem(lhs.value, rhs.value));
5071 }
John Bauman89401822014-05-06 15:04:28 -04005072
John Bauman19bac1e2014-05-06 15:23:49 -04005073 RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005074 {
5075 return RValue<Int4>(Nucleus::createAnd(lhs.value, rhs.value));
5076 }
5077
John Bauman19bac1e2014-05-06 15:23:49 -04005078 RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005079 {
5080 return RValue<Int4>(Nucleus::createOr(lhs.value, rhs.value));
5081 }
5082
John Bauman19bac1e2014-05-06 15:23:49 -04005083 RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005084 {
5085 return RValue<Int4>(Nucleus::createXor(lhs.value, rhs.value));
5086 }
5087
John Bauman19bac1e2014-05-06 15:23:49 -04005088 RValue<Int4> operator<<(RValue<Int4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005089 {
John Bauman89401822014-05-06 15:04:28 -04005090 return x86::pslld(lhs, rhs);
5091 }
5092
John Bauman19bac1e2014-05-06 15:23:49 -04005093 RValue<Int4> operator>>(RValue<Int4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005094 {
John Bauman89401822014-05-06 15:04:28 -04005095 return x86::psrad(lhs, rhs);
5096 }
5097
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005098 RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs)
5099 {
5100 return RValue<Int4>(Nucleus::createShl(lhs.value, rhs.value));
5101 }
5102
5103 RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs)
5104 {
5105 return RValue<Int4>(Nucleus::createAShr(lhs.value, rhs.value));
5106 }
5107
Nicolas Capens96d4e092016-11-18 14:22:38 -05005108 RValue<Int4> operator+=(Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005109 {
5110 return lhs = lhs + rhs;
5111 }
5112
Nicolas Capens96d4e092016-11-18 14:22:38 -05005113 RValue<Int4> operator-=(Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005114 {
5115 return lhs = lhs - rhs;
5116 }
5117
Nicolas Capens96d4e092016-11-18 14:22:38 -05005118 RValue<Int4> operator*=(Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005119 {
5120 return lhs = lhs * rhs;
5121 }
5122
Nicolas Capens96d4e092016-11-18 14:22:38 -05005123// RValue<Int4> operator/=(Int4 &lhs, RValue<Int4> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04005124// {
5125// return lhs = lhs / rhs;
5126// }
John Bauman89401822014-05-06 15:04:28 -04005127
Nicolas Capens96d4e092016-11-18 14:22:38 -05005128// RValue<Int4> operator%=(Int4 &lhs, RValue<Int4> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04005129// {
5130// return lhs = lhs % rhs;
5131// }
John Bauman89401822014-05-06 15:04:28 -04005132
Nicolas Capens96d4e092016-11-18 14:22:38 -05005133 RValue<Int4> operator&=(Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005134 {
5135 return lhs = lhs & rhs;
5136 }
5137
Nicolas Capens96d4e092016-11-18 14:22:38 -05005138 RValue<Int4> operator|=(Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005139 {
5140 return lhs = lhs | rhs;
5141 }
5142
Nicolas Capens96d4e092016-11-18 14:22:38 -05005143 RValue<Int4> operator^=(Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005144 {
5145 return lhs = lhs ^ rhs;
5146 }
5147
Nicolas Capens96d4e092016-11-18 14:22:38 -05005148 RValue<Int4> operator<<=(Int4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005149 {
5150 return lhs = lhs << rhs;
5151 }
5152
Nicolas Capens96d4e092016-11-18 14:22:38 -05005153 RValue<Int4> operator>>=(Int4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005154 {
5155 return lhs = lhs >> rhs;
5156 }
5157
John Bauman19bac1e2014-05-06 15:23:49 -04005158 RValue<Int4> operator+(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005159 {
5160 return val;
5161 }
5162
John Bauman19bac1e2014-05-06 15:23:49 -04005163 RValue<Int4> operator-(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005164 {
5165 return RValue<Int4>(Nucleus::createNeg(val.value));
5166 }
5167
John Bauman19bac1e2014-05-06 15:23:49 -04005168 RValue<Int4> operator~(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005169 {
5170 return RValue<Int4>(Nucleus::createNot(val.value));
5171 }
5172
John Bauman19bac1e2014-05-06 15:23:49 -04005173 RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y)
5174 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005175 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
Alexis Hetufb603992016-04-26 11:50:40 -04005176 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5177 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
5178 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005179 }
5180
5181 RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y)
5182 {
5183 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLT(x.value, y.value), Int4::getType()));
5184 }
5185
5186 RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y)
5187 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005188 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5189 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5190 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLE(x.value, y.value), Int4::getType()));
5191 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGT(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005192 }
5193
5194 RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y)
5195 {
5196 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
5197 }
5198
5199 RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y)
5200 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005201 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5202 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5203 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGE(x.value, y.value), Int4::getType()));
5204 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLT(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005205 }
5206
5207 RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y)
5208 {
5209 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGT(x.value, y.value), Int4::getType()));
5210 }
5211
5212 RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y)
5213 {
5214 if(CPUID::supportsSSE4_1())
5215 {
5216 return x86::pmaxsd(x, y);
5217 }
5218 else
5219 {
5220 RValue<Int4> greater = CmpNLE(x, y);
5221 return x & greater | y & ~greater;
5222 }
5223 }
5224
5225 RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y)
5226 {
5227 if(CPUID::supportsSSE4_1())
5228 {
5229 return x86::pminsd(x, y);
5230 }
5231 else
5232 {
5233 RValue<Int4> less = CmpLT(x, y);
5234 return x & less | y & ~less;
5235 }
5236 }
5237
5238 RValue<Int4> RoundInt(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005239 {
5240 return x86::cvtps2dq(cast);
5241 }
5242
John Bauman19bac1e2014-05-06 15:23:49 -04005243 RValue<Short8> Pack(RValue<Int4> x, RValue<Int4> y)
John Bauman89401822014-05-06 15:04:28 -04005244 {
5245 return x86::packssdw(x, y);
5246 }
5247
John Bauman19bac1e2014-05-06 15:23:49 -04005248 RValue<Int> Extract(RValue<Int4> x, int i)
John Bauman89401822014-05-06 15:04:28 -04005249 {
Nicolas Capense95d5342016-09-30 11:37:28 -04005250 return RValue<Int>(Nucleus::createExtractElement(x.value, Int::getType(), i));
John Bauman89401822014-05-06 15:04:28 -04005251 }
5252
John Bauman19bac1e2014-05-06 15:23:49 -04005253 RValue<Int4> Insert(RValue<Int4> x, RValue<Int> element, int i)
John Bauman89401822014-05-06 15:04:28 -04005254 {
5255 return RValue<Int4>(Nucleus::createInsertElement(x.value, element.value, i));
5256 }
5257
John Bauman19bac1e2014-05-06 15:23:49 -04005258 RValue<Int> SignMask(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04005259 {
5260 return x86::movmskps(As<Float4>(x));
5261 }
5262
John Bauman19bac1e2014-05-06 15:23:49 -04005263 RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04005264 {
Nicolas Capense95d5342016-09-30 11:37:28 -04005265 return RValue<Int4>(createSwizzle4(x.value, select));
John Bauman89401822014-05-06 15:04:28 -04005266 }
5267
John Bauman19bac1e2014-05-06 15:23:49 -04005268 Type *Int4::getType()
John Bauman89401822014-05-06 15:04:28 -04005269 {
Nicolas Capensac230122016-09-20 14:30:06 -04005270 return T(VectorType::get(Int::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04005271 }
5272
John Bauman19bac1e2014-05-06 15:23:49 -04005273 UInt4::UInt4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005274 {
Alexis Hetu764d1422016-09-28 08:44:22 -04005275 // Note: createFPToUI is broken, must perform conversion using createFPtoSI
5276 // Value *xyzw = Nucleus::createFPToUI(cast.value, UInt4::getType());
John Bauman89401822014-05-06 15:04:28 -04005277
Alexis Hetu764d1422016-09-28 08:44:22 -04005278 // Smallest positive value representable in UInt, but not in Int
5279 const unsigned int ustart = 0x80000000u;
5280 const float ustartf = float(ustart);
5281
5282 // Check if the value can be represented as an Int
5283 Int4 uiValue = CmpNLT(cast, Float4(ustartf));
5284 // If the value is too large, subtract ustart and re-add it after conversion.
5285 uiValue = (uiValue & As<Int4>(As<UInt4>(Int4(cast - Float4(ustartf))) + UInt4(ustart))) |
5286 // Otherwise, just convert normally
5287 (~uiValue & Int4(cast));
5288 // If the value is negative, store 0, otherwise store the result of the conversion
5289 storeValue((~(As<Int4>(cast) >> 31) & uiValue).value);
John Bauman89401822014-05-06 15:04:28 -04005290 }
5291
John Bauman19bac1e2014-05-06 15:23:49 -04005292 UInt4::UInt4(int xyzw)
5293 {
5294 constant(xyzw, xyzw, xyzw, xyzw);
5295 }
5296
5297 UInt4::UInt4(int x, int yzw)
5298 {
5299 constant(x, yzw, yzw, yzw);
5300 }
5301
5302 UInt4::UInt4(int x, int y, int zw)
5303 {
5304 constant(x, y, zw, zw);
5305 }
5306
5307 UInt4::UInt4(int x, int y, int z, int w)
5308 {
5309 constant(x, y, z, w);
5310 }
5311
5312 void UInt4::constant(int x, int y, int z, int w)
John Bauman89401822014-05-06 15:04:28 -04005313 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04005314 int64_t constantVector[4] = {x, y, z, w};
5315 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04005316 }
5317
John Bauman19bac1e2014-05-06 15:23:49 -04005318 UInt4::UInt4(RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005319 {
John Bauman66b8ab22014-05-06 15:57:45 -04005320 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005321 }
5322
5323 UInt4::UInt4(const UInt4 &rhs)
5324 {
John Bauman66b8ab22014-05-06 15:57:45 -04005325 Value *value = rhs.loadValue();
5326 storeValue(value);
5327 }
5328
5329 UInt4::UInt4(const Reference<UInt4> &rhs)
5330 {
John Bauman66b8ab22014-05-06 15:57:45 -04005331 Value *value = rhs.loadValue();
5332 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005333 }
5334
John Bauman19bac1e2014-05-06 15:23:49 -04005335 UInt4::UInt4(RValue<Int4> rhs)
5336 {
John Bauman66b8ab22014-05-06 15:57:45 -04005337 storeValue(rhs.value);
John Bauman19bac1e2014-05-06 15:23:49 -04005338 }
5339
5340 UInt4::UInt4(const Int4 &rhs)
5341 {
John Bauman66b8ab22014-05-06 15:57:45 -04005342 Value *value = rhs.loadValue();
5343 storeValue(value);
5344 }
5345
5346 UInt4::UInt4(const Reference<Int4> &rhs)
5347 {
John Bauman66b8ab22014-05-06 15:57:45 -04005348 Value *value = rhs.loadValue();
5349 storeValue(value);
John Bauman19bac1e2014-05-06 15:23:49 -04005350 }
5351
Nicolas Capens62abb552016-01-05 12:03:47 -05005352 UInt4::UInt4(RValue<UInt2> lo, RValue<UInt2> hi)
5353 {
5354 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
5355 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
5356
Nicolas Capens22008782016-10-20 01:11:47 -04005357 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Nicolas Capens62abb552016-01-05 12:03:47 -05005358 long2 = Nucleus::createInsertElement(long2, loLong, 0);
5359 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
5360 Value *uint4 = Nucleus::createBitCast(long2, Int4::getType());
5361
5362 storeValue(uint4);
5363 }
5364
Nicolas Capens96d4e092016-11-18 14:22:38 -05005365 RValue<UInt4> UInt4::operator=(RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005366 {
John Bauman66b8ab22014-05-06 15:57:45 -04005367 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005368
5369 return rhs;
5370 }
5371
Nicolas Capens96d4e092016-11-18 14:22:38 -05005372 RValue<UInt4> UInt4::operator=(const UInt4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04005373 {
John Bauman66b8ab22014-05-06 15:57:45 -04005374 Value *value = rhs.loadValue();
5375 storeValue(value);
5376
5377 return RValue<UInt4>(value);
5378 }
5379
Nicolas Capens96d4e092016-11-18 14:22:38 -05005380 RValue<UInt4> UInt4::operator=(const Reference<UInt4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04005381 {
5382 Value *value = rhs.loadValue();
5383 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005384
5385 return RValue<UInt4>(value);
5386 }
5387
John Bauman19bac1e2014-05-06 15:23:49 -04005388 RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005389 {
5390 return RValue<UInt4>(Nucleus::createAdd(lhs.value, rhs.value));
5391 }
5392
John Bauman19bac1e2014-05-06 15:23:49 -04005393 RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005394 {
5395 return RValue<UInt4>(Nucleus::createSub(lhs.value, rhs.value));
5396 }
5397
John Bauman19bac1e2014-05-06 15:23:49 -04005398 RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005399 {
5400 return RValue<UInt4>(Nucleus::createMul(lhs.value, rhs.value));
5401 }
5402
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005403 RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs)
5404 {
5405 return RValue<UInt4>(Nucleus::createUDiv(lhs.value, rhs.value));
5406 }
John Bauman89401822014-05-06 15:04:28 -04005407
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005408 RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs)
5409 {
5410 return RValue<UInt4>(Nucleus::createURem(lhs.value, rhs.value));
5411 }
John Bauman89401822014-05-06 15:04:28 -04005412
John Bauman19bac1e2014-05-06 15:23:49 -04005413 RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005414 {
5415 return RValue<UInt4>(Nucleus::createAnd(lhs.value, rhs.value));
5416 }
5417
John Bauman19bac1e2014-05-06 15:23:49 -04005418 RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005419 {
5420 return RValue<UInt4>(Nucleus::createOr(lhs.value, rhs.value));
5421 }
5422
John Bauman19bac1e2014-05-06 15:23:49 -04005423 RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005424 {
5425 return RValue<UInt4>(Nucleus::createXor(lhs.value, rhs.value));
5426 }
5427
John Bauman19bac1e2014-05-06 15:23:49 -04005428 RValue<UInt4> operator<<(RValue<UInt4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005429 {
John Bauman89401822014-05-06 15:04:28 -04005430 return As<UInt4>(x86::pslld(As<Int4>(lhs), rhs));
5431 }
5432
John Bauman19bac1e2014-05-06 15:23:49 -04005433 RValue<UInt4> operator>>(RValue<UInt4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005434 {
John Bauman89401822014-05-06 15:04:28 -04005435 return x86::psrld(lhs, rhs);
5436 }
5437
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005438 RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs)
5439 {
5440 return RValue<UInt4>(Nucleus::createShl(lhs.value, rhs.value));
5441 }
5442
5443 RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs)
5444 {
5445 return RValue<UInt4>(Nucleus::createLShr(lhs.value, rhs.value));
5446 }
5447
Nicolas Capens96d4e092016-11-18 14:22:38 -05005448 RValue<UInt4> operator+=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005449 {
5450 return lhs = lhs + rhs;
5451 }
5452
Nicolas Capens96d4e092016-11-18 14:22:38 -05005453 RValue<UInt4> operator-=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005454 {
5455 return lhs = lhs - rhs;
5456 }
5457
Nicolas Capens96d4e092016-11-18 14:22:38 -05005458 RValue<UInt4> operator*=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005459 {
5460 return lhs = lhs * rhs;
5461 }
5462
Nicolas Capens96d4e092016-11-18 14:22:38 -05005463// RValue<UInt4> operator/=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04005464// {
5465// return lhs = lhs / rhs;
5466// }
John Bauman89401822014-05-06 15:04:28 -04005467
Nicolas Capens96d4e092016-11-18 14:22:38 -05005468// RValue<UInt4> operator%=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04005469// {
5470// return lhs = lhs % rhs;
5471// }
John Bauman89401822014-05-06 15:04:28 -04005472
Nicolas Capens96d4e092016-11-18 14:22:38 -05005473 RValue<UInt4> operator&=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005474 {
5475 return lhs = lhs & rhs;
5476 }
5477
Nicolas Capens96d4e092016-11-18 14:22:38 -05005478 RValue<UInt4> operator|=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005479 {
5480 return lhs = lhs | rhs;
5481 }
5482
Nicolas Capens96d4e092016-11-18 14:22:38 -05005483 RValue<UInt4> operator^=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005484 {
5485 return lhs = lhs ^ rhs;
5486 }
5487
Nicolas Capens96d4e092016-11-18 14:22:38 -05005488 RValue<UInt4> operator<<=(UInt4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005489 {
5490 return lhs = lhs << rhs;
5491 }
5492
Nicolas Capens96d4e092016-11-18 14:22:38 -05005493 RValue<UInt4> operator>>=(UInt4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005494 {
5495 return lhs = lhs >> rhs;
5496 }
5497
John Bauman19bac1e2014-05-06 15:23:49 -04005498 RValue<UInt4> operator+(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04005499 {
5500 return val;
5501 }
5502
John Bauman19bac1e2014-05-06 15:23:49 -04005503 RValue<UInt4> operator-(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04005504 {
5505 return RValue<UInt4>(Nucleus::createNeg(val.value));
5506 }
5507
John Bauman19bac1e2014-05-06 15:23:49 -04005508 RValue<UInt4> operator~(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04005509 {
5510 return RValue<UInt4>(Nucleus::createNot(val.value));
5511 }
5512
John Bauman19bac1e2014-05-06 15:23:49 -04005513 RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y)
5514 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005515 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
Alexis Hetufb603992016-04-26 11:50:40 -04005516 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5517 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
5518 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005519 }
5520
5521 RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y)
5522 {
5523 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULT(x.value, y.value), Int4::getType()));
5524 }
5525
5526 RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y)
5527 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005528 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5529 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5530 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULE(x.value, y.value), Int4::getType()));
5531 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGT(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005532 }
5533
5534 RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y)
5535 {
5536 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
5537 }
5538
5539 RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y)
5540 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005541 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5542 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5543 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGE(x.value, y.value), Int4::getType()));
5544 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULT(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005545 }
5546
5547 RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y)
5548 {
5549 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGT(x.value, y.value), Int4::getType()));
5550 }
5551
5552 RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y)
5553 {
5554 if(CPUID::supportsSSE4_1())
5555 {
5556 return x86::pmaxud(x, y);
5557 }
5558 else
5559 {
5560 RValue<UInt4> greater = CmpNLE(x, y);
5561 return x & greater | y & ~greater;
5562 }
5563 }
5564
5565 RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y)
5566 {
5567 if(CPUID::supportsSSE4_1())
5568 {
5569 return x86::pminud(x, y);
5570 }
5571 else
5572 {
5573 RValue<UInt4> less = CmpLT(x, y);
5574 return x & less | y & ~less;
5575 }
5576 }
5577
5578 RValue<UShort8> Pack(RValue<UInt4> x, RValue<UInt4> y)
John Bauman89401822014-05-06 15:04:28 -04005579 {
Nicolas Capens3e7062b2017-01-17 14:01:33 -05005580 return x86::packusdw(As<Int4>(x), As<Int4>(y));
John Bauman89401822014-05-06 15:04:28 -04005581 }
5582
John Bauman19bac1e2014-05-06 15:23:49 -04005583 Type *UInt4::getType()
John Bauman89401822014-05-06 15:04:28 -04005584 {
Nicolas Capensac230122016-09-20 14:30:06 -04005585 return T(VectorType::get(UInt::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04005586 }
5587
John Bauman19bac1e2014-05-06 15:23:49 -04005588 Float::Float(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04005589 {
John Bauman89401822014-05-06 15:04:28 -04005590 Value *integer = Nucleus::createSIToFP(cast.value, Float::getType());
5591
John Bauman66b8ab22014-05-06 15:57:45 -04005592 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04005593 }
5594
John Bauman89401822014-05-06 15:04:28 -04005595 Float::Float(float x)
5596 {
John Bauman66b8ab22014-05-06 15:57:45 -04005597 storeValue(Nucleus::createConstantFloat(x));
John Bauman89401822014-05-06 15:04:28 -04005598 }
5599
John Bauman19bac1e2014-05-06 15:23:49 -04005600 Float::Float(RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005601 {
John Bauman66b8ab22014-05-06 15:57:45 -04005602 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005603 }
5604
5605 Float::Float(const Float &rhs)
5606 {
John Bauman66b8ab22014-05-06 15:57:45 -04005607 Value *value = rhs.loadValue();
5608 storeValue(value);
5609 }
John Bauman89401822014-05-06 15:04:28 -04005610
John Bauman66b8ab22014-05-06 15:57:45 -04005611 Float::Float(const Reference<Float> &rhs)
5612 {
5613 Value *value = rhs.loadValue();
5614 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005615 }
5616
Nicolas Capens96d4e092016-11-18 14:22:38 -05005617 RValue<Float> Float::operator=(RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005618 {
John Bauman66b8ab22014-05-06 15:57:45 -04005619 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005620
5621 return rhs;
5622 }
5623
Nicolas Capens96d4e092016-11-18 14:22:38 -05005624 RValue<Float> Float::operator=(const Float &rhs)
John Bauman89401822014-05-06 15:04:28 -04005625 {
John Bauman66b8ab22014-05-06 15:57:45 -04005626 Value *value = rhs.loadValue();
5627 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005628
5629 return RValue<Float>(value);
5630 }
5631
Nicolas Capens96d4e092016-11-18 14:22:38 -05005632 RValue<Float> Float::operator=(const Reference<Float> &rhs)
John Bauman89401822014-05-06 15:04:28 -04005633 {
John Bauman66b8ab22014-05-06 15:57:45 -04005634 Value *value = rhs.loadValue();
5635 storeValue(value);
5636
5637 return RValue<Float>(value);
John Bauman89401822014-05-06 15:04:28 -04005638 }
5639
John Bauman19bac1e2014-05-06 15:23:49 -04005640 RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005641 {
5642 return RValue<Float>(Nucleus::createFAdd(lhs.value, rhs.value));
5643 }
5644
John Bauman19bac1e2014-05-06 15:23:49 -04005645 RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005646 {
5647 return RValue<Float>(Nucleus::createFSub(lhs.value, rhs.value));
5648 }
5649
John Bauman19bac1e2014-05-06 15:23:49 -04005650 RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005651 {
5652 return RValue<Float>(Nucleus::createFMul(lhs.value, rhs.value));
5653 }
5654
John Bauman19bac1e2014-05-06 15:23:49 -04005655 RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005656 {
5657 return RValue<Float>(Nucleus::createFDiv(lhs.value, rhs.value));
5658 }
5659
Nicolas Capens96d4e092016-11-18 14:22:38 -05005660 RValue<Float> operator+=(Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005661 {
5662 return lhs = lhs + rhs;
5663 }
5664
Nicolas Capens96d4e092016-11-18 14:22:38 -05005665 RValue<Float> operator-=(Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005666 {
5667 return lhs = lhs - rhs;
5668 }
5669
Nicolas Capens96d4e092016-11-18 14:22:38 -05005670 RValue<Float> operator*=(Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005671 {
5672 return lhs = lhs * rhs;
5673 }
5674
Nicolas Capens96d4e092016-11-18 14:22:38 -05005675 RValue<Float> operator/=(Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005676 {
5677 return lhs = lhs / rhs;
5678 }
5679
John Bauman19bac1e2014-05-06 15:23:49 -04005680 RValue<Float> operator+(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04005681 {
5682 return val;
5683 }
5684
John Bauman19bac1e2014-05-06 15:23:49 -04005685 RValue<Float> operator-(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04005686 {
5687 return RValue<Float>(Nucleus::createFNeg(val.value));
5688 }
5689
John Bauman19bac1e2014-05-06 15:23:49 -04005690 RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005691 {
5692 return RValue<Bool>(Nucleus::createFCmpOLT(lhs.value, rhs.value));
5693 }
5694
John Bauman19bac1e2014-05-06 15:23:49 -04005695 RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005696 {
5697 return RValue<Bool>(Nucleus::createFCmpOLE(lhs.value, rhs.value));
5698 }
5699
John Bauman19bac1e2014-05-06 15:23:49 -04005700 RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005701 {
5702 return RValue<Bool>(Nucleus::createFCmpOGT(lhs.value, rhs.value));
5703 }
5704
John Bauman19bac1e2014-05-06 15:23:49 -04005705 RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005706 {
5707 return RValue<Bool>(Nucleus::createFCmpOGE(lhs.value, rhs.value));
5708 }
5709
John Bauman19bac1e2014-05-06 15:23:49 -04005710 RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005711 {
5712 return RValue<Bool>(Nucleus::createFCmpONE(lhs.value, rhs.value));
5713 }
5714
John Bauman19bac1e2014-05-06 15:23:49 -04005715 RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005716 {
5717 return RValue<Bool>(Nucleus::createFCmpOEQ(lhs.value, rhs.value));
5718 }
5719
John Bauman19bac1e2014-05-06 15:23:49 -04005720 RValue<Float> Abs(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04005721 {
John Bauman66b8ab22014-05-06 15:57:45 -04005722 return IfThenElse(x > 0.0f, x, -x);
John Bauman89401822014-05-06 15:04:28 -04005723 }
5724
John Bauman19bac1e2014-05-06 15:23:49 -04005725 RValue<Float> Max(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04005726 {
5727 return IfThenElse(x > y, x, y);
5728 }
5729
John Bauman19bac1e2014-05-06 15:23:49 -04005730 RValue<Float> Min(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04005731 {
5732 return IfThenElse(x < y, x, y);
5733 }
5734
Nicolas Capens05b3d662016-02-25 23:58:33 -05005735 RValue<Float> Rcp_pp(RValue<Float> x, bool exactAtPow2)
John Bauman89401822014-05-06 15:04:28 -04005736 {
Nicolas Capens05b3d662016-02-25 23:58:33 -05005737 if(exactAtPow2)
5738 {
5739 // rcpss uses a piecewise-linear approximation which minimizes the relative error
5740 // but is not exact at power-of-two values. Rectify by multiplying by the inverse.
5741 return x86::rcpss(x) * Float(1.0f / _mm_cvtss_f32(_mm_rcp_ss(_mm_set_ps1(1.0f))));
5742 }
5743 else
5744 {
5745 return x86::rcpss(x);
5746 }
John Bauman89401822014-05-06 15:04:28 -04005747 }
John Bauman66b8ab22014-05-06 15:57:45 -04005748
John Bauman19bac1e2014-05-06 15:23:49 -04005749 RValue<Float> RcpSqrt_pp(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04005750 {
5751 return x86::rsqrtss(x);
5752 }
5753
John Bauman19bac1e2014-05-06 15:23:49 -04005754 RValue<Float> Sqrt(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04005755 {
5756 return x86::sqrtss(x);
5757 }
5758
John Bauman19bac1e2014-05-06 15:23:49 -04005759 RValue<Float> Round(RValue<Float> x)
5760 {
5761 if(CPUID::supportsSSE4_1())
5762 {
5763 return x86::roundss(x, 0);
5764 }
5765 else
5766 {
5767 return Float4(Round(Float4(x))).x;
5768 }
5769 }
5770
5771 RValue<Float> Trunc(RValue<Float> x)
5772 {
5773 if(CPUID::supportsSSE4_1())
5774 {
5775 return x86::roundss(x, 3);
5776 }
5777 else
5778 {
5779 return Float(Int(x)); // Rounded toward zero
5780 }
5781 }
5782
5783 RValue<Float> Frac(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04005784 {
5785 if(CPUID::supportsSSE4_1())
5786 {
5787 return x - x86::floorss(x);
5788 }
5789 else
5790 {
John Bauman19bac1e2014-05-06 15:23:49 -04005791 return Float4(Frac(Float4(x))).x;
John Bauman89401822014-05-06 15:04:28 -04005792 }
5793 }
5794
John Bauman19bac1e2014-05-06 15:23:49 -04005795 RValue<Float> Floor(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04005796 {
5797 if(CPUID::supportsSSE4_1())
5798 {
5799 return x86::floorss(x);
5800 }
5801 else
5802 {
5803 return Float4(Floor(Float4(x))).x;
5804 }
5805 }
5806
John Bauman19bac1e2014-05-06 15:23:49 -04005807 RValue<Float> Ceil(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04005808 {
John Bauman19bac1e2014-05-06 15:23:49 -04005809 if(CPUID::supportsSSE4_1())
5810 {
5811 return x86::ceilss(x);
5812 }
5813 else
5814 {
5815 return Float4(Ceil(Float4(x))).x;
5816 }
John Bauman89401822014-05-06 15:04:28 -04005817 }
5818
John Bauman19bac1e2014-05-06 15:23:49 -04005819 Type *Float::getType()
John Bauman89401822014-05-06 15:04:28 -04005820 {
Nicolas Capensac230122016-09-20 14:30:06 -04005821 return T(llvm::Type::getFloatTy(*::context));
John Bauman89401822014-05-06 15:04:28 -04005822 }
5823
John Bauman19bac1e2014-05-06 15:23:49 -04005824 Float2::Float2(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005825 {
Nicolas Capens22008782016-10-20 01:11:47 -04005826 Value *int64x2 = Nucleus::createBitCast(cast.value, T(VectorType::get(Long::getType(), 2)));
Nicolas Capense95d5342016-09-30 11:37:28 -04005827 Value *int64 = Nucleus::createExtractElement(int64x2, Long::getType(), 0);
John Bauman89401822014-05-06 15:04:28 -04005828 Value *float2 = Nucleus::createBitCast(int64, Float2::getType());
5829
John Bauman66b8ab22014-05-06 15:57:45 -04005830 storeValue(float2);
John Bauman89401822014-05-06 15:04:28 -04005831 }
5832
John Bauman19bac1e2014-05-06 15:23:49 -04005833 Type *Float2::getType()
John Bauman89401822014-05-06 15:04:28 -04005834 {
Nicolas Capensac230122016-09-20 14:30:06 -04005835 return T(VectorType::get(Float::getType(), 2));
John Bauman89401822014-05-06 15:04:28 -04005836 }
5837
Nicolas Capensa25311a2017-01-16 17:19:00 -05005838 Float4::Float4(RValue<Byte4> cast) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005839 {
John Bauman89401822014-05-06 15:04:28 -04005840 #if 0
5841 Value *xyzw = Nucleus::createUIToFP(cast.value, Float4::getType()); // FIXME: Crashes
5842 #elif 0
John Bauman66b8ab22014-05-06 15:57:45 -04005843 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04005844
5845 Value *i8x = Nucleus::createExtractElement(cast.value, 0);
5846 Value *f32x = Nucleus::createUIToFP(i8x, Float::getType());
5847 Value *x = Nucleus::createInsertElement(vector, f32x, 0);
5848
Nicolas Capens19336542016-09-26 10:32:29 -04005849 Value *i8y = Nucleus::createExtractElement(cast.value, V(Nucleus::createConstantInt(1)));
John Bauman89401822014-05-06 15:04:28 -04005850 Value *f32y = Nucleus::createUIToFP(i8y, Float::getType());
Nicolas Capens19336542016-09-26 10:32:29 -04005851 Value *xy = Nucleus::createInsertElement(x, f32y, V(Nucleus::createConstantInt(1)));
John Bauman89401822014-05-06 15:04:28 -04005852
5853 Value *i8z = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(2));
5854 Value *f32z = Nucleus::createUIToFP(i8z, Float::getType());
5855 Value *xyz = Nucleus::createInsertElement(xy, f32z, Nucleus::createConstantInt(2));
5856
5857 Value *i8w = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(3));
5858 Value *f32w = Nucleus::createUIToFP(i8w, Float::getType());
5859 Value *xyzw = Nucleus::createInsertElement(xyz, f32w, Nucleus::createConstantInt(3));
5860 #else
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005861 Value *a = Int4(cast).loadValue();
5862 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04005863 #endif
John Bauman66b8ab22014-05-06 15:57:45 -04005864
5865 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04005866 }
5867
Nicolas Capensa25311a2017-01-16 17:19:00 -05005868 Float4::Float4(RValue<SByte4> cast) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005869 {
John Bauman89401822014-05-06 15:04:28 -04005870 #if 0
5871 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType()); // FIXME: Crashes
5872 #elif 0
John Bauman66b8ab22014-05-06 15:57:45 -04005873 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04005874
5875 Value *i8x = Nucleus::createExtractElement(cast.value, 0);
5876 Value *f32x = Nucleus::createSIToFP(i8x, Float::getType());
5877 Value *x = Nucleus::createInsertElement(vector, f32x, 0);
5878
Nicolas Capens19336542016-09-26 10:32:29 -04005879 Value *i8y = Nucleus::createExtractElement(cast.value, V(Nucleus::createConstantInt(1)));
John Bauman89401822014-05-06 15:04:28 -04005880 Value *f32y = Nucleus::createSIToFP(i8y, Float::getType());
Nicolas Capens19336542016-09-26 10:32:29 -04005881 Value *xy = Nucleus::createInsertElement(x, f32y, V(Nucleus::createConstantInt(1)));
John Bauman89401822014-05-06 15:04:28 -04005882
5883 Value *i8z = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(2));
5884 Value *f32z = Nucleus::createSIToFP(i8z, Float::getType());
5885 Value *xyz = Nucleus::createInsertElement(xy, f32z, Nucleus::createConstantInt(2));
5886
5887 Value *i8w = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(3));
5888 Value *f32w = Nucleus::createSIToFP(i8w, Float::getType());
5889 Value *xyzw = Nucleus::createInsertElement(xyz, f32w, Nucleus::createConstantInt(3));
5890 #else
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005891 Value *a = Int4(cast).loadValue();
5892 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04005893 #endif
John Bauman66b8ab22014-05-06 15:57:45 -04005894
5895 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04005896 }
5897
Nicolas Capensa25311a2017-01-16 17:19:00 -05005898 Float4::Float4(RValue<Short4> cast) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005899 {
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005900 Int4 c(cast);
5901 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
John Bauman89401822014-05-06 15:04:28 -04005902 }
5903
Nicolas Capensa25311a2017-01-16 17:19:00 -05005904 Float4::Float4(RValue<UShort4> cast) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005905 {
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005906 Int4 c(cast);
5907 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
John Bauman89401822014-05-06 15:04:28 -04005908 }
5909
Nicolas Capensa25311a2017-01-16 17:19:00 -05005910 Float4::Float4(RValue<Int4> cast) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005911 {
John Bauman89401822014-05-06 15:04:28 -04005912 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04005913
John Bauman66b8ab22014-05-06 15:57:45 -04005914 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04005915 }
5916
Nicolas Capensa25311a2017-01-16 17:19:00 -05005917 Float4::Float4(RValue<UInt4> cast) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005918 {
Nicolas Capens96445fe2016-12-15 14:45:13 -05005919 RValue<Float4> result = Float4(Int4(cast & UInt4(0x7FFFFFFF))) +
5920 As<Float4>((As<Int4>(cast) >> 31) & As<Int4>(Float4(0x80000000u)));
John Bauman89401822014-05-06 15:04:28 -04005921
Nicolas Capens96445fe2016-12-15 14:45:13 -05005922 storeValue(result.value);
John Bauman89401822014-05-06 15:04:28 -04005923 }
5924
Nicolas Capensa25311a2017-01-16 17:19:00 -05005925 Float4::Float4() : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005926 {
John Bauman89401822014-05-06 15:04:28 -04005927 }
John Bauman66b8ab22014-05-06 15:57:45 -04005928
Nicolas Capensa25311a2017-01-16 17:19:00 -05005929 Float4::Float4(float xyzw) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005930 {
5931 constant(xyzw, xyzw, xyzw, xyzw);
5932 }
5933
Nicolas Capensa25311a2017-01-16 17:19:00 -05005934 Float4::Float4(float x, float yzw) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005935 {
5936 constant(x, yzw, yzw, yzw);
5937 }
5938
Nicolas Capensa25311a2017-01-16 17:19:00 -05005939 Float4::Float4(float x, float y, float zw) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005940 {
5941 constant(x, y, zw, zw);
5942 }
5943
Nicolas Capensa25311a2017-01-16 17:19:00 -05005944 Float4::Float4(float x, float y, float z, float w) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005945 {
5946 constant(x, y, z, w);
5947 }
5948
5949 void Float4::constant(float x, float y, float z, float w)
5950 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04005951 double constantVector[4] = {x, y, z, w};
5952 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04005953 }
5954
Nicolas Capensa25311a2017-01-16 17:19:00 -05005955 Float4::Float4(RValue<Float4> rhs) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005956 {
John Bauman66b8ab22014-05-06 15:57:45 -04005957 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005958 }
5959
Nicolas Capensa25311a2017-01-16 17:19:00 -05005960 Float4::Float4(const Float4 &rhs) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005961 {
John Bauman66b8ab22014-05-06 15:57:45 -04005962 Value *value = rhs.loadValue();
5963 storeValue(value);
5964 }
5965
Nicolas Capensa25311a2017-01-16 17:19:00 -05005966 Float4::Float4(const Reference<Float4> &rhs) : FloatXYZW(this)
John Bauman66b8ab22014-05-06 15:57:45 -04005967 {
John Bauman66b8ab22014-05-06 15:57:45 -04005968 Value *value = rhs.loadValue();
5969 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005970 }
5971
Nicolas Capensa25311a2017-01-16 17:19:00 -05005972 Float4::Float4(RValue<Float> rhs) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005973 {
John Bauman66b8ab22014-05-06 15:57:45 -04005974 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04005975 Value *insert = Nucleus::createInsertElement(vector, rhs.value, 0);
5976
Nicolas Capense89cd582016-09-30 14:23:47 -04005977 int swizzle[4] = {0, 0, 0, 0};
5978 Value *replicate = Nucleus::createShuffleVector(insert, insert, swizzle);
John Bauman89401822014-05-06 15:04:28 -04005979
John Bauman66b8ab22014-05-06 15:57:45 -04005980 storeValue(replicate);
John Bauman89401822014-05-06 15:04:28 -04005981 }
5982
Nicolas Capensa25311a2017-01-16 17:19:00 -05005983 Float4::Float4(const Float &rhs) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005984 {
John Bauman66b8ab22014-05-06 15:57:45 -04005985 *this = RValue<Float>(rhs.loadValue());
5986 }
John Bauman89401822014-05-06 15:04:28 -04005987
Nicolas Capensa25311a2017-01-16 17:19:00 -05005988 Float4::Float4(const Reference<Float> &rhs) : FloatXYZW(this)
John Bauman66b8ab22014-05-06 15:57:45 -04005989 {
John Bauman66b8ab22014-05-06 15:57:45 -04005990 *this = RValue<Float>(rhs.loadValue());
John Bauman89401822014-05-06 15:04:28 -04005991 }
5992
Nicolas Capens96d4e092016-11-18 14:22:38 -05005993 RValue<Float4> Float4::operator=(float x)
John Bauman89401822014-05-06 15:04:28 -04005994 {
5995 return *this = Float4(x, x, x, x);
5996 }
5997
Nicolas Capens96d4e092016-11-18 14:22:38 -05005998 RValue<Float4> Float4::operator=(RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005999 {
John Bauman66b8ab22014-05-06 15:57:45 -04006000 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04006001
6002 return rhs;
6003 }
6004
Nicolas Capens96d4e092016-11-18 14:22:38 -05006005 RValue<Float4> Float4::operator=(const Float4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04006006 {
John Bauman66b8ab22014-05-06 15:57:45 -04006007 Value *value = rhs.loadValue();
6008 storeValue(value);
6009
6010 return RValue<Float4>(value);
6011 }
6012
Nicolas Capens96d4e092016-11-18 14:22:38 -05006013 RValue<Float4> Float4::operator=(const Reference<Float4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04006014 {
6015 Value *value = rhs.loadValue();
6016 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04006017
6018 return RValue<Float4>(value);
6019 }
6020
Nicolas Capens96d4e092016-11-18 14:22:38 -05006021 RValue<Float4> Float4::operator=(RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006022 {
6023 return *this = Float4(rhs);
6024 }
6025
Nicolas Capens96d4e092016-11-18 14:22:38 -05006026 RValue<Float4> Float4::operator=(const Float &rhs)
John Bauman89401822014-05-06 15:04:28 -04006027 {
6028 return *this = Float4(rhs);
6029 }
6030
Nicolas Capens96d4e092016-11-18 14:22:38 -05006031 RValue<Float4> Float4::operator=(const Reference<Float> &rhs)
John Bauman89401822014-05-06 15:04:28 -04006032 {
John Bauman66b8ab22014-05-06 15:57:45 -04006033 return *this = Float4(rhs);
John Bauman89401822014-05-06 15:04:28 -04006034 }
6035
John Bauman19bac1e2014-05-06 15:23:49 -04006036 RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006037 {
6038 return RValue<Float4>(Nucleus::createFAdd(lhs.value, rhs.value));
6039 }
6040
John Bauman19bac1e2014-05-06 15:23:49 -04006041 RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006042 {
6043 return RValue<Float4>(Nucleus::createFSub(lhs.value, rhs.value));
6044 }
6045
John Bauman19bac1e2014-05-06 15:23:49 -04006046 RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006047 {
6048 return RValue<Float4>(Nucleus::createFMul(lhs.value, rhs.value));
6049 }
6050
John Bauman19bac1e2014-05-06 15:23:49 -04006051 RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006052 {
6053 return RValue<Float4>(Nucleus::createFDiv(lhs.value, rhs.value));
6054 }
6055
John Bauman19bac1e2014-05-06 15:23:49 -04006056 RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006057 {
6058 return RValue<Float4>(Nucleus::createFRem(lhs.value, rhs.value));
6059 }
6060
Nicolas Capens96d4e092016-11-18 14:22:38 -05006061 RValue<Float4> operator+=(Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006062 {
6063 return lhs = lhs + rhs;
6064 }
6065
Nicolas Capens96d4e092016-11-18 14:22:38 -05006066 RValue<Float4> operator-=(Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006067 {
6068 return lhs = lhs - rhs;
6069 }
6070
Nicolas Capens96d4e092016-11-18 14:22:38 -05006071 RValue<Float4> operator*=(Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006072 {
6073 return lhs = lhs * rhs;
6074 }
6075
Nicolas Capens96d4e092016-11-18 14:22:38 -05006076 RValue<Float4> operator/=(Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006077 {
6078 return lhs = lhs / rhs;
6079 }
6080
Nicolas Capens96d4e092016-11-18 14:22:38 -05006081 RValue<Float4> operator%=(Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006082 {
6083 return lhs = lhs % rhs;
6084 }
6085
John Bauman19bac1e2014-05-06 15:23:49 -04006086 RValue<Float4> operator+(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006087 {
6088 return val;
6089 }
6090
John Bauman19bac1e2014-05-06 15:23:49 -04006091 RValue<Float4> operator-(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006092 {
6093 return RValue<Float4>(Nucleus::createFNeg(val.value));
6094 }
6095
John Bauman19bac1e2014-05-06 15:23:49 -04006096 RValue<Float4> Abs(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006097 {
6098 Value *vector = Nucleus::createBitCast(x.value, Int4::getType());
Nicolas Capens13ac2322016-10-13 14:52:12 -04006099 int64_t constantVector[4] = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF};
6100 Value *result = Nucleus::createAnd(vector, V(Nucleus::createConstantVector(constantVector, Int4::getType())));
John Bauman89401822014-05-06 15:04:28 -04006101
6102 return RValue<Float4>(Nucleus::createBitCast(result, Float4::getType()));
6103 }
6104
John Bauman19bac1e2014-05-06 15:23:49 -04006105 RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006106 {
6107 return x86::maxps(x, y);
6108 }
6109
John Bauman19bac1e2014-05-06 15:23:49 -04006110 RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006111 {
6112 return x86::minps(x, y);
6113 }
6114
Nicolas Capens05b3d662016-02-25 23:58:33 -05006115 RValue<Float4> Rcp_pp(RValue<Float4> x, bool exactAtPow2)
John Bauman89401822014-05-06 15:04:28 -04006116 {
Nicolas Capens05b3d662016-02-25 23:58:33 -05006117 if(exactAtPow2)
6118 {
6119 // rcpps uses a piecewise-linear approximation which minimizes the relative error
6120 // but is not exact at power-of-two values. Rectify by multiplying by the inverse.
6121 return x86::rcpps(x) * Float4(1.0f / _mm_cvtss_f32(_mm_rcp_ss(_mm_set_ps1(1.0f))));
6122 }
6123 else
6124 {
6125 return x86::rcpps(x);
6126 }
John Bauman89401822014-05-06 15:04:28 -04006127 }
John Bauman66b8ab22014-05-06 15:57:45 -04006128
John Bauman19bac1e2014-05-06 15:23:49 -04006129 RValue<Float4> RcpSqrt_pp(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006130 {
6131 return x86::rsqrtps(x);
6132 }
6133
John Bauman19bac1e2014-05-06 15:23:49 -04006134 RValue<Float4> Sqrt(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006135 {
6136 return x86::sqrtps(x);
6137 }
6138
Nicolas Capensc94ab742016-11-08 15:15:31 -05006139 RValue<Float4> Insert(RValue<Float4> val, RValue<Float> element, int i)
John Bauman89401822014-05-06 15:04:28 -04006140 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05006141 return RValue<Float4>(Nucleus::createInsertElement(val.value, element.value, i));
John Bauman89401822014-05-06 15:04:28 -04006142 }
6143
John Bauman19bac1e2014-05-06 15:23:49 -04006144 RValue<Float> Extract(RValue<Float4> x, int i)
John Bauman89401822014-05-06 15:04:28 -04006145 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006146 return RValue<Float>(Nucleus::createExtractElement(x.value, Float::getType(), i));
John Bauman89401822014-05-06 15:04:28 -04006147 }
6148
John Bauman19bac1e2014-05-06 15:23:49 -04006149 RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04006150 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006151 return RValue<Float4>(createSwizzle4(x.value, select));
John Bauman89401822014-05-06 15:04:28 -04006152 }
6153
John Bauman19bac1e2014-05-06 15:23:49 -04006154 RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006155 {
Nicolas Capense89cd582016-09-30 14:23:47 -04006156 int shuffle[4] =
6157 {
6158 ((imm >> 0) & 0x03) + 0,
6159 ((imm >> 2) & 0x03) + 0,
6160 ((imm >> 4) & 0x03) + 4,
6161 ((imm >> 6) & 0x03) + 4,
6162 };
John Bauman89401822014-05-06 15:04:28 -04006163
Nicolas Capense89cd582016-09-30 14:23:47 -04006164 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
John Bauman89401822014-05-06 15:04:28 -04006165 }
6166
John Bauman19bac1e2014-05-06 15:23:49 -04006167 RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006168 {
Nicolas Capense89cd582016-09-30 14:23:47 -04006169 int shuffle[4] = {0, 4, 1, 5};
6170 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
John Bauman89401822014-05-06 15:04:28 -04006171 }
6172
John Bauman19bac1e2014-05-06 15:23:49 -04006173 RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006174 {
Nicolas Capense89cd582016-09-30 14:23:47 -04006175 int shuffle[4] = {2, 6, 3, 7};
6176 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
John Bauman89401822014-05-06 15:04:28 -04006177 }
John Bauman66b8ab22014-05-06 15:57:45 -04006178
John Bauman19bac1e2014-05-06 15:23:49 -04006179 RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04006180 {
John Bauman66b8ab22014-05-06 15:57:45 -04006181 Value *vector = lhs.loadValue();
Nicolas Capense95d5342016-09-30 11:37:28 -04006182 Value *shuffle = createMask4(vector, rhs.value, select);
John Bauman66b8ab22014-05-06 15:57:45 -04006183 lhs.storeValue(shuffle);
John Bauman89401822014-05-06 15:04:28 -04006184
6185 return RValue<Float4>(shuffle);
6186 }
6187
John Bauman19bac1e2014-05-06 15:23:49 -04006188 RValue<Int> SignMask(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006189 {
6190 return x86::movmskps(x);
6191 }
6192
John Bauman19bac1e2014-05-06 15:23:49 -04006193 RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006194 {
6195 // return As<Int4>(x86::cmpeqps(x, y));
6196 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOEQ(x.value, y.value), Int4::getType()));
6197 }
6198
John Bauman19bac1e2014-05-06 15:23:49 -04006199 RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006200 {
6201 // return As<Int4>(x86::cmpltps(x, y));
6202 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOLT(x.value, y.value), Int4::getType()));
6203 }
6204
John Bauman19bac1e2014-05-06 15:23:49 -04006205 RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006206 {
6207 // return As<Int4>(x86::cmpleps(x, y));
6208 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOLE(x.value, y.value), Int4::getType()));
6209 }
6210
John Bauman19bac1e2014-05-06 15:23:49 -04006211 RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006212 {
6213 // return As<Int4>(x86::cmpneqps(x, y));
6214 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpONE(x.value, y.value), Int4::getType()));
6215 }
6216
John Bauman19bac1e2014-05-06 15:23:49 -04006217 RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006218 {
6219 // return As<Int4>(x86::cmpnltps(x, y));
6220 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOGE(x.value, y.value), Int4::getType()));
6221 }
6222
John Bauman19bac1e2014-05-06 15:23:49 -04006223 RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006224 {
6225 // return As<Int4>(x86::cmpnleps(x, y));
6226 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOGT(x.value, y.value), Int4::getType()));
6227 }
6228
John Bauman19bac1e2014-05-06 15:23:49 -04006229 RValue<Float4> Round(RValue<Float4> x)
6230 {
6231 if(CPUID::supportsSSE4_1())
6232 {
6233 return x86::roundps(x, 0);
6234 }
6235 else
6236 {
6237 return Float4(RoundInt(x));
6238 }
6239 }
6240
6241 RValue<Float4> Trunc(RValue<Float4> x)
6242 {
6243 if(CPUID::supportsSSE4_1())
6244 {
6245 return x86::roundps(x, 3);
6246 }
6247 else
6248 {
6249 return Float4(Int4(x)); // Rounded toward zero
6250 }
6251 }
6252
6253 RValue<Float4> Frac(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006254 {
6255 if(CPUID::supportsSSE4_1())
6256 {
6257 return x - x86::floorps(x);
6258 }
6259 else
6260 {
John Bauman19bac1e2014-05-06 15:23:49 -04006261 Float4 frc = x - Float4(Int4(x)); // Signed fractional part
John Bauman89401822014-05-06 15:04:28 -04006262
John Bauman19bac1e2014-05-06 15:23:49 -04006263 return frc + As<Float4>(As<Int4>(CmpNLE(Float4(0.0f), frc)) & As<Int4>(Float4(1, 1, 1, 1)));
John Bauman89401822014-05-06 15:04:28 -04006264 }
6265 }
6266
John Bauman19bac1e2014-05-06 15:23:49 -04006267 RValue<Float4> Floor(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006268 {
6269 if(CPUID::supportsSSE4_1())
6270 {
6271 return x86::floorps(x);
6272 }
6273 else
6274 {
John Bauman19bac1e2014-05-06 15:23:49 -04006275 return x - Frac(x);
John Bauman89401822014-05-06 15:04:28 -04006276 }
6277 }
6278
John Bauman19bac1e2014-05-06 15:23:49 -04006279 RValue<Float4> Ceil(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006280 {
John Bauman19bac1e2014-05-06 15:23:49 -04006281 if(CPUID::supportsSSE4_1())
6282 {
6283 return x86::ceilps(x);
6284 }
6285 else
6286 {
6287 return -Floor(-x);
6288 }
John Bauman89401822014-05-06 15:04:28 -04006289 }
6290
John Bauman19bac1e2014-05-06 15:23:49 -04006291 Type *Float4::getType()
John Bauman89401822014-05-06 15:04:28 -04006292 {
Nicolas Capensac230122016-09-20 14:30:06 -04006293 return T(VectorType::get(Float::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04006294 }
6295
Nicolas Capens81f18302016-01-14 09:32:35 -05006296 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006297 {
Nicolas Capensd294def2017-01-26 17:44:37 -08006298 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), V(Nucleus::createConstantInt(offset)), false));
John Bauman89401822014-05-06 15:04:28 -04006299 }
6300
Nicolas Capens81f18302016-01-14 09:32:35 -05006301 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006302 {
Nicolas Capensd294def2017-01-26 17:44:37 -08006303 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value, false));
John Bauman89401822014-05-06 15:04:28 -04006304 }
6305
Nicolas Capens81f18302016-01-14 09:32:35 -05006306 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006307 {
Nicolas Capensd294def2017-01-26 17:44:37 -08006308 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value, true));
John Bauman89401822014-05-06 15:04:28 -04006309 }
6310
Nicolas Capens96d4e092016-11-18 14:22:38 -05006311 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006312 {
6313 return lhs = lhs + offset;
6314 }
6315
Nicolas Capens96d4e092016-11-18 14:22:38 -05006316 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006317 {
6318 return lhs = lhs + offset;
6319 }
6320
Nicolas Capens96d4e092016-11-18 14:22:38 -05006321 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006322 {
6323 return lhs = lhs + offset;
6324 }
6325
Nicolas Capens81f18302016-01-14 09:32:35 -05006326 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006327 {
6328 return lhs + -offset;
6329 }
6330
Nicolas Capens81f18302016-01-14 09:32:35 -05006331 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006332 {
6333 return lhs + -offset;
6334 }
6335
Nicolas Capens81f18302016-01-14 09:32:35 -05006336 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006337 {
6338 return lhs + -offset;
6339 }
6340
Nicolas Capens96d4e092016-11-18 14:22:38 -05006341 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006342 {
6343 return lhs = lhs - offset;
6344 }
6345
Nicolas Capens96d4e092016-11-18 14:22:38 -05006346 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006347 {
6348 return lhs = lhs - offset;
6349 }
6350
Nicolas Capens96d4e092016-11-18 14:22:38 -05006351 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006352 {
6353 return lhs = lhs - offset;
6354 }
6355
6356 void Return()
6357 {
John Bauman89401822014-05-06 15:04:28 -04006358 Nucleus::createRetVoid();
6359 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
John Bauman19bac1e2014-05-06 15:23:49 -04006360 Nucleus::createUnreachable();
6361 }
6362
Nicolas Capenseb253d02016-11-18 14:40:40 -05006363 void Return(RValue<Int> ret)
John Bauman19bac1e2014-05-06 15:23:49 -04006364 {
Nicolas Capenseb253d02016-11-18 14:40:40 -05006365 Nucleus::createRet(ret.value);
John Bauman89401822014-05-06 15:04:28 -04006366 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
John Bauman19bac1e2014-05-06 15:23:49 -04006367 Nucleus::createUnreachable();
John Bauman89401822014-05-06 15:04:28 -04006368 }
6369
John Bauman19bac1e2014-05-06 15:23:49 -04006370 bool branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB)
John Bauman89401822014-05-06 15:04:28 -04006371 {
6372 Nucleus::createCondBr(cmp.value, bodyBB, endBB);
John Bauman66b8ab22014-05-06 15:57:45 -04006373 Nucleus::setInsertBlock(bodyBB);
6374
John Bauman89401822014-05-06 15:04:28 -04006375 return true;
6376 }
6377
John Bauman89401822014-05-06 15:04:28 -04006378 RValue<Long> Ticks()
6379 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006380 llvm::Function *rdtsc = Intrinsic::getDeclaration(::module, Intrinsic::readcyclecounter);
John Bauman89401822014-05-06 15:04:28 -04006381
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006382 return RValue<Long>(V(::builder->CreateCall(rdtsc)));
John Bauman89401822014-05-06 15:04:28 -04006383 }
John Bauman89401822014-05-06 15:04:28 -04006384}
6385
6386namespace sw
6387{
6388 namespace x86
6389 {
John Bauman19bac1e2014-05-06 15:23:49 -04006390 RValue<Int> cvtss2si(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006391 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006392 llvm::Function *cvtss2si = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cvtss2si);
John Bauman66b8ab22014-05-06 15:57:45 -04006393
John Bauman89401822014-05-06 15:04:28 -04006394 Float4 vector;
6395 vector.x = val;
6396
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006397 return RValue<Int>(V(::builder->CreateCall(cvtss2si, RValue<Float4>(vector).value)));
John Bauman89401822014-05-06 15:04:28 -04006398 }
6399
John Bauman19bac1e2014-05-06 15:23:49 -04006400 RValue<Int2> cvtps2pi(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006401 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006402 llvm::Function *cvtps2pi = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cvtps2pi);
John Bauman89401822014-05-06 15:04:28 -04006403
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006404 return RValue<Int2>(V(::builder->CreateCall(cvtps2pi, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006405 }
6406
John Bauman19bac1e2014-05-06 15:23:49 -04006407 RValue<Int2> cvttps2pi(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006408 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006409 llvm::Function *cvttps2pi = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cvttps2pi);
John Bauman89401822014-05-06 15:04:28 -04006410
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006411 return RValue<Int2>(V(::builder->CreateCall(cvttps2pi, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006412 }
6413
John Bauman19bac1e2014-05-06 15:23:49 -04006414 RValue<Int4> cvtps2dq(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006415 {
6416 if(CPUID::supportsSSE2())
6417 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006418 llvm::Function *cvtps2dq = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_cvtps2dq);
John Bauman89401822014-05-06 15:04:28 -04006419
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006420 return RValue<Int4>(V(::builder->CreateCall(cvtps2dq, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006421 }
6422 else
6423 {
6424 Int2 lo = x86::cvtps2pi(val);
6425 Int2 hi = x86::cvtps2pi(Swizzle(val, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04006426
Nicolas Capens62abb552016-01-05 12:03:47 -05006427 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04006428 }
6429 }
6430
John Bauman19bac1e2014-05-06 15:23:49 -04006431 RValue<Float> rcpss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006432 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006433 llvm::Function *rcpss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rcp_ss);
John Bauman89401822014-05-06 15:04:28 -04006434
Nicolas Capens19336542016-09-26 10:32:29 -04006435 Value *vector = Nucleus::createInsertElement(V(UndefValue::get(Float4::getType())), val.value, 0);
John Bauman66b8ab22014-05-06 15:57:45 -04006436
Nicolas Capense95d5342016-09-30 11:37:28 -04006437 return RValue<Float>(Nucleus::createExtractElement(V(::builder->CreateCall(rcpss, vector)), Float::getType(), 0));
John Bauman89401822014-05-06 15:04:28 -04006438 }
6439
John Bauman19bac1e2014-05-06 15:23:49 -04006440 RValue<Float> sqrtss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006441 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006442 llvm::Function *sqrtss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_sqrt_ss);
John Bauman89401822014-05-06 15:04:28 -04006443
Nicolas Capens19336542016-09-26 10:32:29 -04006444 Value *vector = Nucleus::createInsertElement(V(UndefValue::get(Float4::getType())), val.value, 0);
John Bauman66b8ab22014-05-06 15:57:45 -04006445
Nicolas Capense95d5342016-09-30 11:37:28 -04006446 return RValue<Float>(Nucleus::createExtractElement(V(::builder->CreateCall(sqrtss, vector)), Float::getType(), 0));
John Bauman89401822014-05-06 15:04:28 -04006447 }
6448
John Bauman19bac1e2014-05-06 15:23:49 -04006449 RValue<Float> rsqrtss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006450 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006451 llvm::Function *rsqrtss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rsqrt_ss);
John Bauman66b8ab22014-05-06 15:57:45 -04006452
Nicolas Capens19336542016-09-26 10:32:29 -04006453 Value *vector = Nucleus::createInsertElement(V(UndefValue::get(Float4::getType())), val.value, 0);
John Bauman89401822014-05-06 15:04:28 -04006454
Nicolas Capense95d5342016-09-30 11:37:28 -04006455 return RValue<Float>(Nucleus::createExtractElement(V(::builder->CreateCall(rsqrtss, vector)), Float::getType(), 0));
John Bauman89401822014-05-06 15:04:28 -04006456 }
6457
John Bauman19bac1e2014-05-06 15:23:49 -04006458 RValue<Float4> rcpps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006459 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006460 llvm::Function *rcpps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rcp_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04006461
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006462 return RValue<Float4>(V(::builder->CreateCall(rcpps, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006463 }
6464
John Bauman19bac1e2014-05-06 15:23:49 -04006465 RValue<Float4> sqrtps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006466 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006467 llvm::Function *sqrtps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_sqrt_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04006468
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006469 return RValue<Float4>(V(::builder->CreateCall(sqrtps, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006470 }
6471
John Bauman19bac1e2014-05-06 15:23:49 -04006472 RValue<Float4> rsqrtps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006473 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006474 llvm::Function *rsqrtps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rsqrt_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04006475
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006476 return RValue<Float4>(V(::builder->CreateCall(rsqrtps, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006477 }
6478
John Bauman19bac1e2014-05-06 15:23:49 -04006479 RValue<Float4> maxps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006480 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006481 llvm::Function *maxps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_max_ps);
John Bauman89401822014-05-06 15:04:28 -04006482
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006483 return RValue<Float4>(V(::builder->CreateCall2(maxps, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04006484 }
6485
John Bauman19bac1e2014-05-06 15:23:49 -04006486 RValue<Float4> minps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006487 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006488 llvm::Function *minps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_min_ps);
John Bauman89401822014-05-06 15:04:28 -04006489
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006490 return RValue<Float4>(V(::builder->CreateCall2(minps, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04006491 }
6492
John Bauman19bac1e2014-05-06 15:23:49 -04006493 RValue<Float> roundss(RValue<Float> val, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006494 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006495 llvm::Function *roundss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_round_ss);
John Bauman89401822014-05-06 15:04:28 -04006496
Nicolas Capens19336542016-09-26 10:32:29 -04006497 Value *undef = V(UndefValue::get(Float4::getType()));
John Bauman89401822014-05-06 15:04:28 -04006498 Value *vector = Nucleus::createInsertElement(undef, val.value, 0);
6499
Nicolas Capense95d5342016-09-30 11:37:28 -04006500 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 -04006501 }
6502
John Bauman19bac1e2014-05-06 15:23:49 -04006503 RValue<Float> floorss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006504 {
6505 return roundss(val, 1);
6506 }
6507
John Bauman19bac1e2014-05-06 15:23:49 -04006508 RValue<Float> ceilss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006509 {
6510 return roundss(val, 2);
6511 }
6512
John Bauman19bac1e2014-05-06 15:23:49 -04006513 RValue<Float4> roundps(RValue<Float4> val, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006514 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006515 llvm::Function *roundps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_round_ps);
John Bauman89401822014-05-06 15:04:28 -04006516
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006517 return RValue<Float4>(V(::builder->CreateCall2(roundps, val.value, V(Nucleus::createConstantInt(imm)))));
John Bauman89401822014-05-06 15:04:28 -04006518 }
6519
John Bauman19bac1e2014-05-06 15:23:49 -04006520 RValue<Float4> floorps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006521 {
6522 return roundps(val, 1);
6523 }
6524
John Bauman19bac1e2014-05-06 15:23:49 -04006525 RValue<Float4> ceilps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006526 {
6527 return roundps(val, 2);
6528 }
6529
John Bauman19bac1e2014-05-06 15:23:49 -04006530 RValue<Float4> cmpps(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006531 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006532 llvm::Function *cmpps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cmp_ps);
John Bauman89401822014-05-06 15:04:28 -04006533
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006534 return RValue<Float4>(V(::builder->CreateCall3(cmpps, x.value, y.value, V(Nucleus::createConstantByte(imm)))));
John Bauman89401822014-05-06 15:04:28 -04006535 }
6536
John Bauman19bac1e2014-05-06 15:23:49 -04006537 RValue<Float4> cmpeqps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006538 {
6539 return cmpps(x, y, 0);
6540 }
6541
John Bauman19bac1e2014-05-06 15:23:49 -04006542 RValue<Float4> cmpltps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006543 {
6544 return cmpps(x, y, 1);
6545 }
6546
John Bauman19bac1e2014-05-06 15:23:49 -04006547 RValue<Float4> cmpleps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006548 {
6549 return cmpps(x, y, 2);
6550 }
6551
John Bauman19bac1e2014-05-06 15:23:49 -04006552 RValue<Float4> cmpunordps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006553 {
6554 return cmpps(x, y, 3);
6555 }
6556
John Bauman19bac1e2014-05-06 15:23:49 -04006557 RValue<Float4> cmpneqps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006558 {
6559 return cmpps(x, y, 4);
6560 }
6561
John Bauman19bac1e2014-05-06 15:23:49 -04006562 RValue<Float4> cmpnltps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006563 {
6564 return cmpps(x, y, 5);
6565 }
6566
John Bauman19bac1e2014-05-06 15:23:49 -04006567 RValue<Float4> cmpnleps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006568 {
6569 return cmpps(x, y, 6);
6570 }
6571
John Bauman19bac1e2014-05-06 15:23:49 -04006572 RValue<Float4> cmpordps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006573 {
6574 return cmpps(x, y, 7);
6575 }
6576
John Bauman19bac1e2014-05-06 15:23:49 -04006577 RValue<Float> cmpss(RValue<Float> x, RValue<Float> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006578 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006579 llvm::Function *cmpss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cmp_ss);
John Bauman89401822014-05-06 15:04:28 -04006580
Nicolas Capens19336542016-09-26 10:32:29 -04006581 Value *vector1 = Nucleus::createInsertElement(V(UndefValue::get(Float4::getType())), x.value, 0);
6582 Value *vector2 = Nucleus::createInsertElement(V(UndefValue::get(Float4::getType())), y.value, 0);
John Bauman89401822014-05-06 15:04:28 -04006583
Nicolas Capense95d5342016-09-30 11:37:28 -04006584 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 -04006585 }
6586
John Bauman19bac1e2014-05-06 15:23:49 -04006587 RValue<Float> cmpeqss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006588 {
6589 return cmpss(x, y, 0);
6590 }
6591
John Bauman19bac1e2014-05-06 15:23:49 -04006592 RValue<Float> cmpltss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006593 {
6594 return cmpss(x, y, 1);
6595 }
6596
John Bauman19bac1e2014-05-06 15:23:49 -04006597 RValue<Float> cmpless(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006598 {
6599 return cmpss(x, y, 2);
6600 }
6601
John Bauman19bac1e2014-05-06 15:23:49 -04006602 RValue<Float> cmpunordss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006603 {
6604 return cmpss(x, y, 3);
6605 }
6606
John Bauman19bac1e2014-05-06 15:23:49 -04006607 RValue<Float> cmpneqss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006608 {
6609 return cmpss(x, y, 4);
6610 }
6611
John Bauman19bac1e2014-05-06 15:23:49 -04006612 RValue<Float> cmpnltss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006613 {
6614 return cmpss(x, y, 5);
6615 }
6616
John Bauman19bac1e2014-05-06 15:23:49 -04006617 RValue<Float> cmpnless(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006618 {
6619 return cmpss(x, y, 6);
6620 }
6621
John Bauman19bac1e2014-05-06 15:23:49 -04006622 RValue<Float> cmpordss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006623 {
6624 return cmpss(x, y, 7);
6625 }
6626
Alexis Hetu0f448072016-03-18 10:56:08 -04006627 RValue<Int4> pabsd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04006628 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006629 llvm::Function *pabsd = Intrinsic::getDeclaration(::module, Intrinsic::x86_ssse3_pabs_d_128);
John Bauman89401822014-05-06 15:04:28 -04006630
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006631 return RValue<Int4>(V(::builder->CreateCall(pabsd, x.value)));
John Bauman89401822014-05-06 15:04:28 -04006632 }
6633
John Bauman19bac1e2014-05-06 15:23:49 -04006634 RValue<Short4> paddsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006635 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006636 llvm::Function *paddsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padds_w);
John Bauman89401822014-05-06 15:04:28 -04006637
Nicolas Capens70dfff42016-10-27 10:20:28 -04006638 return As<Short4>(V(::builder->CreateCall2(paddsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006639 }
John Bauman66b8ab22014-05-06 15:57:45 -04006640
John Bauman19bac1e2014-05-06 15:23:49 -04006641 RValue<Short4> psubsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006642 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006643 llvm::Function *psubsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubs_w);
John Bauman89401822014-05-06 15:04:28 -04006644
Nicolas Capens70dfff42016-10-27 10:20:28 -04006645 return As<Short4>(V(::builder->CreateCall2(psubsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006646 }
6647
John Bauman19bac1e2014-05-06 15:23:49 -04006648 RValue<UShort4> paddusw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04006649 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006650 llvm::Function *paddusw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_paddus_w);
John Bauman89401822014-05-06 15:04:28 -04006651
Nicolas Capens70dfff42016-10-27 10:20:28 -04006652 return As<UShort4>(V(::builder->CreateCall2(paddusw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006653 }
John Bauman66b8ab22014-05-06 15:57:45 -04006654
John Bauman19bac1e2014-05-06 15:23:49 -04006655 RValue<UShort4> psubusw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04006656 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006657 llvm::Function *psubusw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubus_w);
John Bauman89401822014-05-06 15:04:28 -04006658
Nicolas Capens70dfff42016-10-27 10:20:28 -04006659 return As<UShort4>(V(::builder->CreateCall2(psubusw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006660 }
6661
John Bauman19bac1e2014-05-06 15:23:49 -04006662 RValue<SByte8> paddsb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04006663 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006664 llvm::Function *paddsb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padds_b);
John Bauman89401822014-05-06 15:04:28 -04006665
Nicolas Capens70dfff42016-10-27 10:20:28 -04006666 return As<SByte8>(V(::builder->CreateCall2(paddsb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006667 }
John Bauman66b8ab22014-05-06 15:57:45 -04006668
John Bauman19bac1e2014-05-06 15:23:49 -04006669 RValue<SByte8> psubsb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04006670 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006671 llvm::Function *psubsb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubs_b);
John Bauman89401822014-05-06 15:04:28 -04006672
Nicolas Capens70dfff42016-10-27 10:20:28 -04006673 return As<SByte8>(V(::builder->CreateCall2(psubsb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006674 }
John Bauman66b8ab22014-05-06 15:57:45 -04006675
John Bauman19bac1e2014-05-06 15:23:49 -04006676 RValue<Byte8> paddusb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04006677 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006678 llvm::Function *paddusb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_paddus_b);
John Bauman89401822014-05-06 15:04:28 -04006679
Nicolas Capens70dfff42016-10-27 10:20:28 -04006680 return As<Byte8>(V(::builder->CreateCall2(paddusb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006681 }
John Bauman66b8ab22014-05-06 15:57:45 -04006682
John Bauman19bac1e2014-05-06 15:23:49 -04006683 RValue<Byte8> psubusb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04006684 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006685 llvm::Function *psubusb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubus_b);
John Bauman89401822014-05-06 15:04:28 -04006686
Nicolas Capens70dfff42016-10-27 10:20:28 -04006687 return As<Byte8>(V(::builder->CreateCall2(psubusb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006688 }
6689
John Bauman19bac1e2014-05-06 15:23:49 -04006690 RValue<Short4> paddw(RValue<Short4> x, RValue<Short4> y)
6691 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006692 llvm::Function *paddw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padd_w);
John Bauman19bac1e2014-05-06 15:23:49 -04006693
Nicolas Capens70dfff42016-10-27 10:20:28 -04006694 return As<Short4>(V(::builder->CreateCall2(paddw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006695 }
6696
6697 RValue<Short4> psubw(RValue<Short4> x, RValue<Short4> y)
6698 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006699 llvm::Function *psubw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psub_w);
John Bauman19bac1e2014-05-06 15:23:49 -04006700
Nicolas Capens70dfff42016-10-27 10:20:28 -04006701 return As<Short4>(V(::builder->CreateCall2(psubw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006702 }
6703
6704 RValue<Short4> pmullw(RValue<Short4> x, RValue<Short4> y)
6705 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006706 llvm::Function *pmullw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmull_w);
John Bauman19bac1e2014-05-06 15:23:49 -04006707
Nicolas Capens70dfff42016-10-27 10:20:28 -04006708 return As<Short4>(V(::builder->CreateCall2(pmullw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006709 }
6710
6711 RValue<Short4> pand(RValue<Short4> x, RValue<Short4> y)
6712 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006713 llvm::Function *pand = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pand);
John Bauman19bac1e2014-05-06 15:23:49 -04006714
Nicolas Capens70dfff42016-10-27 10:20:28 -04006715 return As<Short4>(V(::builder->CreateCall2(pand, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006716 }
6717
6718 RValue<Short4> por(RValue<Short4> x, RValue<Short4> y)
6719 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006720 llvm::Function *por = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_por);
John Bauman19bac1e2014-05-06 15:23:49 -04006721
Nicolas Capens70dfff42016-10-27 10:20:28 -04006722 return As<Short4>(V(::builder->CreateCall2(por, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006723 }
6724
6725 RValue<Short4> pxor(RValue<Short4> x, RValue<Short4> y)
6726 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006727 llvm::Function *pxor = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pxor);
John Bauman19bac1e2014-05-06 15:23:49 -04006728
Nicolas Capens70dfff42016-10-27 10:20:28 -04006729 return As<Short4>(V(::builder->CreateCall2(pxor, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006730 }
6731
6732 RValue<Short4> pshufw(RValue<Short4> x, unsigned char y)
6733 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006734 llvm::Function *pshufw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_pshuf_w);
John Bauman19bac1e2014-05-06 15:23:49 -04006735
Nicolas Capens70dfff42016-10-27 10:20:28 -04006736 return As<Short4>(V(::builder->CreateCall2(pshufw, As<MMX>(x).value, V(Nucleus::createConstantByte(y)))));
John Bauman19bac1e2014-05-06 15:23:49 -04006737 }
6738
6739 RValue<Int2> punpcklwd(RValue<Short4> x, RValue<Short4> y)
6740 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006741 llvm::Function *punpcklwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpcklwd);
John Bauman19bac1e2014-05-06 15:23:49 -04006742
Nicolas Capens70dfff42016-10-27 10:20:28 -04006743 return As<Int2>(V(::builder->CreateCall2(punpcklwd, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006744 }
6745
6746 RValue<Int2> punpckhwd(RValue<Short4> x, RValue<Short4> y)
6747 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006748 llvm::Function *punpckhwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckhwd);
John Bauman19bac1e2014-05-06 15:23:49 -04006749
Nicolas Capens70dfff42016-10-27 10:20:28 -04006750 return As<Int2>(V(::builder->CreateCall2(punpckhwd, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006751 }
6752
6753 RValue<Short4> pinsrw(RValue<Short4> x, RValue<Int> y, unsigned int i)
6754 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006755 llvm::Function *pinsrw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pinsr_w);
John Bauman19bac1e2014-05-06 15:23:49 -04006756
Nicolas Capens70dfff42016-10-27 10:20:28 -04006757 return As<Short4>(V(::builder->CreateCall3(pinsrw, As<MMX>(x).value, y.value, V(Nucleus::createConstantInt(i)))));
John Bauman19bac1e2014-05-06 15:23:49 -04006758 }
6759
6760 RValue<Int> pextrw(RValue<Short4> x, unsigned int i)
6761 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006762 llvm::Function *pextrw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pextr_w);
John Bauman19bac1e2014-05-06 15:23:49 -04006763
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006764 return RValue<Int>(V(::builder->CreateCall2(pextrw, As<MMX>(x).value, V(Nucleus::createConstantInt(i)))));
John Bauman19bac1e2014-05-06 15:23:49 -04006765 }
6766
Nicolas Capens45f187a2016-12-02 15:30:56 -05006767 RValue<Short4> punpckldq(RValue<Int2> x, RValue<Int2> y)
John Bauman19bac1e2014-05-06 15:23:49 -04006768 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006769 llvm::Function *punpckldq = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckldq);
John Bauman19bac1e2014-05-06 15:23:49 -04006770
Nicolas Capens45f187a2016-12-02 15:30:56 -05006771 return As<Short4>(V(::builder->CreateCall2(punpckldq, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006772 }
6773
Nicolas Capens45f187a2016-12-02 15:30:56 -05006774 RValue<Short4> punpckhdq(RValue<Int2> x, RValue<Int2> y)
John Bauman19bac1e2014-05-06 15:23:49 -04006775 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006776 llvm::Function *punpckhdq = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckhdq);
John Bauman19bac1e2014-05-06 15:23:49 -04006777
Nicolas Capens45f187a2016-12-02 15:30:56 -05006778 return As<Short4>(V(::builder->CreateCall2(punpckhdq, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006779 }
6780
6781 RValue<Short4> punpcklbw(RValue<Byte8> x, RValue<Byte8> y)
6782 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006783 llvm::Function *punpcklbw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpcklbw);
John Bauman19bac1e2014-05-06 15:23:49 -04006784
Nicolas Capens70dfff42016-10-27 10:20:28 -04006785 return As<Short4>(V(::builder->CreateCall2(punpcklbw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006786 }
6787
6788 RValue<Short4> punpckhbw(RValue<Byte8> x, RValue<Byte8> y)
6789 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006790 llvm::Function *punpckhbw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckhbw);
John Bauman19bac1e2014-05-06 15:23:49 -04006791
Nicolas Capens70dfff42016-10-27 10:20:28 -04006792 return As<Short4>(V(::builder->CreateCall2(punpckhbw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006793 }
6794
6795 RValue<Byte8> paddb(RValue<Byte8> x, RValue<Byte8> y)
6796 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006797 llvm::Function *paddb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padd_b);
John Bauman19bac1e2014-05-06 15:23:49 -04006798
Nicolas Capens70dfff42016-10-27 10:20:28 -04006799 return As<Byte8>(V(::builder->CreateCall2(paddb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006800 }
6801
6802 RValue<Byte8> psubb(RValue<Byte8> x, RValue<Byte8> y)
6803 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006804 llvm::Function *psubb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psub_b);
John Bauman19bac1e2014-05-06 15:23:49 -04006805
Nicolas Capens70dfff42016-10-27 10:20:28 -04006806 return As<Byte8>(V(::builder->CreateCall2(psubb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006807 }
6808
6809 RValue<Int2> paddd(RValue<Int2> x, RValue<Int2> y)
6810 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006811 llvm::Function *paddd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padd_d);
John Bauman19bac1e2014-05-06 15:23:49 -04006812
Nicolas Capens70dfff42016-10-27 10:20:28 -04006813 return As<Int2>(V(::builder->CreateCall2(paddd, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006814 }
6815
6816 RValue<Int2> psubd(RValue<Int2> x, RValue<Int2> y)
6817 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006818 llvm::Function *psubd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psub_d);
John Bauman19bac1e2014-05-06 15:23:49 -04006819
Nicolas Capens70dfff42016-10-27 10:20:28 -04006820 return As<Int2>(V(::builder->CreateCall2(psubd, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006821 }
6822
6823 RValue<UShort4> pavgw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04006824 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006825 llvm::Function *pavgw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pavg_w);
John Bauman89401822014-05-06 15:04:28 -04006826
Nicolas Capens70dfff42016-10-27 10:20:28 -04006827 return As<UShort4>(V(::builder->CreateCall2(pavgw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006828 }
6829
John Bauman19bac1e2014-05-06 15:23:49 -04006830 RValue<Short4> pmaxsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006831 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006832 llvm::Function *pmaxsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmaxs_w);
John Bauman89401822014-05-06 15:04:28 -04006833
Nicolas Capens70dfff42016-10-27 10:20:28 -04006834 return As<Short4>(V(::builder->CreateCall2(pmaxsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006835 }
6836
John Bauman19bac1e2014-05-06 15:23:49 -04006837 RValue<Short4> pminsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006838 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006839 llvm::Function *pminsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmins_w);
John Bauman89401822014-05-06 15:04:28 -04006840
Nicolas Capens70dfff42016-10-27 10:20:28 -04006841 return As<Short4>(V(::builder->CreateCall2(pminsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006842 }
6843
John Bauman19bac1e2014-05-06 15:23:49 -04006844 RValue<Short4> pcmpgtw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006845 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006846 llvm::Function *pcmpgtw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpgt_w);
John Bauman89401822014-05-06 15:04:28 -04006847
Nicolas Capens70dfff42016-10-27 10:20:28 -04006848 return As<Short4>(V(::builder->CreateCall2(pcmpgtw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006849 }
6850
John Bauman19bac1e2014-05-06 15:23:49 -04006851 RValue<Short4> pcmpeqw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006852 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006853 llvm::Function *pcmpeqw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpeq_w);
John Bauman89401822014-05-06 15:04:28 -04006854
Nicolas Capens70dfff42016-10-27 10:20:28 -04006855 return As<Short4>(V(::builder->CreateCall2(pcmpeqw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006856 }
6857
John Bauman19bac1e2014-05-06 15:23:49 -04006858 RValue<Byte8> pcmpgtb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04006859 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006860 llvm::Function *pcmpgtb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpgt_b);
John Bauman89401822014-05-06 15:04:28 -04006861
Nicolas Capens70dfff42016-10-27 10:20:28 -04006862 return As<Byte8>(V(::builder->CreateCall2(pcmpgtb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006863 }
6864
John Bauman19bac1e2014-05-06 15:23:49 -04006865 RValue<Byte8> pcmpeqb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04006866 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006867 llvm::Function *pcmpeqb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpeq_b);
John Bauman89401822014-05-06 15:04:28 -04006868
Nicolas Capens70dfff42016-10-27 10:20:28 -04006869 return As<Byte8>(V(::builder->CreateCall2(pcmpeqb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006870 }
6871
John Bauman19bac1e2014-05-06 15:23:49 -04006872 RValue<Short4> packssdw(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04006873 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006874 llvm::Function *packssdw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_packssdw);
John Bauman89401822014-05-06 15:04:28 -04006875
Nicolas Capens70dfff42016-10-27 10:20:28 -04006876 return As<Short4>(V(::builder->CreateCall2(packssdw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006877 }
6878
John Bauman19bac1e2014-05-06 15:23:49 -04006879 RValue<Short8> packssdw(RValue<Int4> x, RValue<Int4> y)
John Bauman89401822014-05-06 15:04:28 -04006880 {
6881 if(CPUID::supportsSSE2())
6882 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006883 llvm::Function *packssdw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_packssdw_128);
John Bauman89401822014-05-06 15:04:28 -04006884
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006885 return RValue<Short8>(V(::builder->CreateCall2(packssdw, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04006886 }
6887 else
6888 {
6889 Int2 loX = Int2(x);
6890 Int2 hiX = Int2(Swizzle(x, 0xEE));
6891
6892 Int2 loY = Int2(y);
6893 Int2 hiY = Int2(Swizzle(y, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04006894
John Bauman89401822014-05-06 15:04:28 -04006895 Short4 lo = x86::packssdw(loX, hiX);
6896 Short4 hi = x86::packssdw(loY, hiY);
John Bauman66b8ab22014-05-06 15:57:45 -04006897
Nicolas Capens62abb552016-01-05 12:03:47 -05006898 return Short8(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04006899 }
6900 }
6901
John Bauman19bac1e2014-05-06 15:23:49 -04006902 RValue<SByte8> packsswb(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006903 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006904 llvm::Function *packsswb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_packsswb);
John Bauman89401822014-05-06 15:04:28 -04006905
Nicolas Capens70dfff42016-10-27 10:20:28 -04006906 return As<SByte8>(V(::builder->CreateCall2(packsswb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006907 }
6908
John Bauman19bac1e2014-05-06 15:23:49 -04006909 RValue<Byte8> packuswb(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04006910 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006911 llvm::Function *packuswb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_packuswb);
John Bauman89401822014-05-06 15:04:28 -04006912
Nicolas Capens70dfff42016-10-27 10:20:28 -04006913 return As<Byte8>(V(::builder->CreateCall2(packuswb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006914 }
6915
Nicolas Capens3e7062b2017-01-17 14:01:33 -05006916 RValue<UShort8> packusdw(RValue<Int4> x, RValue<Int4> y)
John Bauman89401822014-05-06 15:04:28 -04006917 {
6918 if(CPUID::supportsSSE4_1())
6919 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006920 llvm::Function *packusdw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_packusdw);
John Bauman66b8ab22014-05-06 15:57:45 -04006921
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006922 return RValue<UShort8>(V(::builder->CreateCall2(packusdw, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04006923 }
6924 else
6925 {
Nicolas Capens3e7062b2017-01-17 14:01:33 -05006926 RValue<Int4> bx = (x & ~(x >> 31)) - Int4(0x8000);
6927 RValue<Int4> by = (y & ~(y >> 31)) - Int4(0x8000);
6928
6929 return As<UShort8>(packssdw(bx, by) + Short8(0x8000u));
John Bauman89401822014-05-06 15:04:28 -04006930 }
6931 }
6932
John Bauman19bac1e2014-05-06 15:23:49 -04006933 RValue<UShort4> psrlw(RValue<UShort4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006934 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006935 llvm::Function *psrlw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrli_w);
John Bauman89401822014-05-06 15:04:28 -04006936
Nicolas Capens70dfff42016-10-27 10:20:28 -04006937 return As<UShort4>(V(::builder->CreateCall2(psrlw, As<MMX>(x).value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006938 }
6939
John Bauman19bac1e2014-05-06 15:23:49 -04006940 RValue<UShort8> psrlw(RValue<UShort8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006941 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006942 llvm::Function *psrlw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrli_w);
John Bauman89401822014-05-06 15:04:28 -04006943
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006944 return RValue<UShort8>(V(::builder->CreateCall2(psrlw, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006945 }
6946
John Bauman19bac1e2014-05-06 15:23:49 -04006947 RValue<Short4> psraw(RValue<Short4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006948 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006949 llvm::Function *psraw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrai_w);
John Bauman89401822014-05-06 15:04:28 -04006950
Nicolas Capens70dfff42016-10-27 10:20:28 -04006951 return As<Short4>(V(::builder->CreateCall2(psraw, As<MMX>(x).value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006952 }
6953
John Bauman19bac1e2014-05-06 15:23:49 -04006954 RValue<Short8> psraw(RValue<Short8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006955 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006956 llvm::Function *psraw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrai_w);
John Bauman89401822014-05-06 15:04:28 -04006957
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006958 return RValue<Short8>(V(::builder->CreateCall2(psraw, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006959 }
6960
John Bauman19bac1e2014-05-06 15:23:49 -04006961 RValue<Short4> psllw(RValue<Short4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006962 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006963 llvm::Function *psllw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pslli_w);
John Bauman89401822014-05-06 15:04:28 -04006964
Nicolas Capens70dfff42016-10-27 10:20:28 -04006965 return As<Short4>(V(::builder->CreateCall2(psllw, As<MMX>(x).value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006966 }
6967
John Bauman19bac1e2014-05-06 15:23:49 -04006968 RValue<Short8> psllw(RValue<Short8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006969 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006970 llvm::Function *psllw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pslli_w);
John Bauman89401822014-05-06 15:04:28 -04006971
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006972 return RValue<Short8>(V(::builder->CreateCall2(psllw, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006973 }
6974
John Bauman19bac1e2014-05-06 15:23:49 -04006975 RValue<Int2> pslld(RValue<Int2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006976 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006977 llvm::Function *pslld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pslli_d);
John Bauman89401822014-05-06 15:04:28 -04006978
Nicolas Capens70dfff42016-10-27 10:20:28 -04006979 return As<Int2>(V(::builder->CreateCall2(pslld, As<MMX>(x).value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006980 }
6981
John Bauman19bac1e2014-05-06 15:23:49 -04006982 RValue<Int4> pslld(RValue<Int4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006983 {
6984 if(CPUID::supportsSSE2())
6985 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006986 llvm::Function *pslld = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pslli_d);
John Bauman89401822014-05-06 15:04:28 -04006987
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006988 return RValue<Int4>(V(::builder->CreateCall2(pslld, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006989 }
6990 else
6991 {
6992 Int2 lo = Int2(x);
6993 Int2 hi = Int2(Swizzle(x, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04006994
John Bauman89401822014-05-06 15:04:28 -04006995 lo = x86::pslld(lo, y);
6996 hi = x86::pslld(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04006997
Nicolas Capens62abb552016-01-05 12:03:47 -05006998 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04006999 }
7000 }
7001
John Bauman19bac1e2014-05-06 15:23:49 -04007002 RValue<Int2> psrad(RValue<Int2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007003 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007004 llvm::Function *psrad = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrai_d);
John Bauman89401822014-05-06 15:04:28 -04007005
Nicolas Capens70dfff42016-10-27 10:20:28 -04007006 return As<Int2>(V(::builder->CreateCall2(psrad, As<MMX>(x).value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007007 }
7008
John Bauman19bac1e2014-05-06 15:23:49 -04007009 RValue<Int4> psrad(RValue<Int4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007010 {
7011 if(CPUID::supportsSSE2())
7012 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007013 llvm::Function *psrad = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrai_d);
John Bauman89401822014-05-06 15:04:28 -04007014
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007015 return RValue<Int4>(V(::builder->CreateCall2(psrad, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007016 }
7017 else
7018 {
7019 Int2 lo = Int2(x);
7020 Int2 hi = Int2(Swizzle(x, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04007021
John Bauman89401822014-05-06 15:04:28 -04007022 lo = x86::psrad(lo, y);
7023 hi = x86::psrad(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04007024
Nicolas Capens62abb552016-01-05 12:03:47 -05007025 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007026 }
7027 }
7028
John Bauman19bac1e2014-05-06 15:23:49 -04007029 RValue<UInt2> psrld(RValue<UInt2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007030 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007031 llvm::Function *psrld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrli_d);
John Bauman89401822014-05-06 15:04:28 -04007032
Nicolas Capens70dfff42016-10-27 10:20:28 -04007033 return As<UInt2>(V(::builder->CreateCall2(psrld, As<MMX>(x).value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007034 }
7035
John Bauman19bac1e2014-05-06 15:23:49 -04007036 RValue<UInt4> psrld(RValue<UInt4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007037 {
7038 if(CPUID::supportsSSE2())
7039 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007040 llvm::Function *psrld = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrli_d);
John Bauman89401822014-05-06 15:04:28 -04007041
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007042 return RValue<UInt4>(V(::builder->CreateCall2(psrld, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007043 }
7044 else
7045 {
7046 UInt2 lo = As<UInt2>(Int2(As<Int4>(x)));
7047 UInt2 hi = As<UInt2>(Int2(Swizzle(As<Int4>(x), 0xEE)));
John Bauman66b8ab22014-05-06 15:57:45 -04007048
John Bauman89401822014-05-06 15:04:28 -04007049 lo = x86::psrld(lo, y);
7050 hi = x86::psrld(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04007051
Nicolas Capens62abb552016-01-05 12:03:47 -05007052 return UInt4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007053 }
7054 }
7055
John Bauman19bac1e2014-05-06 15:23:49 -04007056 RValue<Int4> pmaxsd(RValue<Int4> x, RValue<Int4> y)
7057 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007058 llvm::Function *pmaxsd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmaxsd);
John Bauman19bac1e2014-05-06 15:23:49 -04007059
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007060 return RValue<Int4>(V(::builder->CreateCall2(pmaxsd, x.value, y.value)));
John Bauman19bac1e2014-05-06 15:23:49 -04007061 }
7062
7063 RValue<Int4> pminsd(RValue<Int4> x, RValue<Int4> y)
7064 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007065 llvm::Function *pminsd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pminsd);
John Bauman19bac1e2014-05-06 15:23:49 -04007066
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007067 return RValue<Int4>(V(::builder->CreateCall2(pminsd, x.value, y.value)));
John Bauman19bac1e2014-05-06 15:23:49 -04007068 }
7069
7070 RValue<UInt4> pmaxud(RValue<UInt4> x, RValue<UInt4> y)
7071 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007072 llvm::Function *pmaxud = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmaxud);
John Bauman19bac1e2014-05-06 15:23:49 -04007073
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007074 return RValue<UInt4>(V(::builder->CreateCall2(pmaxud, x.value, y.value)));
John Bauman19bac1e2014-05-06 15:23:49 -04007075 }
7076
7077 RValue<UInt4> pminud(RValue<UInt4> x, RValue<UInt4> y)
7078 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007079 llvm::Function *pminud = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pminud);
John Bauman19bac1e2014-05-06 15:23:49 -04007080
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007081 return RValue<UInt4>(V(::builder->CreateCall2(pminud, x.value, y.value)));
John Bauman19bac1e2014-05-06 15:23:49 -04007082 }
7083
7084 RValue<Short4> pmulhw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007085 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007086 llvm::Function *pmulhw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmulh_w);
John Bauman89401822014-05-06 15:04:28 -04007087
Nicolas Capens70dfff42016-10-27 10:20:28 -04007088 return As<Short4>(V(::builder->CreateCall2(pmulhw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007089 }
7090
John Bauman19bac1e2014-05-06 15:23:49 -04007091 RValue<UShort4> pmulhuw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007092 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007093 llvm::Function *pmulhuw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmulhu_w);
John Bauman89401822014-05-06 15:04:28 -04007094
Nicolas Capens70dfff42016-10-27 10:20:28 -04007095 return As<UShort4>(V(::builder->CreateCall2(pmulhuw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007096 }
7097
John Bauman19bac1e2014-05-06 15:23:49 -04007098 RValue<Int2> pmaddwd(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007099 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007100 llvm::Function *pmaddwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmadd_wd);
John Bauman89401822014-05-06 15:04:28 -04007101
Nicolas Capens70dfff42016-10-27 10:20:28 -04007102 return As<Int2>(V(::builder->CreateCall2(pmaddwd, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007103 }
7104
John Bauman19bac1e2014-05-06 15:23:49 -04007105 RValue<Short8> pmulhw(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04007106 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007107 llvm::Function *pmulhw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pmulh_w);
John Bauman89401822014-05-06 15:04:28 -04007108
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007109 return RValue<Short8>(V(::builder->CreateCall2(pmulhw, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04007110 }
7111
John Bauman19bac1e2014-05-06 15:23:49 -04007112 RValue<UShort8> pmulhuw(RValue<UShort8> x, RValue<UShort8> y)
John Bauman89401822014-05-06 15:04:28 -04007113 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007114 llvm::Function *pmulhuw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pmulhu_w);
John Bauman89401822014-05-06 15:04:28 -04007115
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007116 return RValue<UShort8>(V(::builder->CreateCall2(pmulhuw, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04007117 }
7118
John Bauman19bac1e2014-05-06 15:23:49 -04007119 RValue<Int4> pmaddwd(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04007120 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007121 llvm::Function *pmaddwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pmadd_wd);
John Bauman89401822014-05-06 15:04:28 -04007122
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007123 return RValue<Int4>(V(::builder->CreateCall2(pmaddwd, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04007124 }
7125
John Bauman19bac1e2014-05-06 15:23:49 -04007126 RValue<Int> movmskps(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04007127 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007128 llvm::Function *movmskps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_movmsk_ps);
John Bauman89401822014-05-06 15:04:28 -04007129
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007130 return RValue<Int>(V(::builder->CreateCall(movmskps, x.value)));
John Bauman89401822014-05-06 15:04:28 -04007131 }
7132
John Bauman19bac1e2014-05-06 15:23:49 -04007133 RValue<Int> pmovmskb(RValue<Byte8> x)
John Bauman89401822014-05-06 15:04:28 -04007134 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007135 llvm::Function *pmovmskb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmovmskb);
John Bauman89401822014-05-06 15:04:28 -04007136
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007137 return RValue<Int>(V(::builder->CreateCall(pmovmskb, As<MMX>(x).value)));
John Bauman89401822014-05-06 15:04:28 -04007138 }
7139
Nicolas Capens81f18302016-01-14 09:32:35 -05007140 //RValue<Int2> movd(RValue<Pointer<Int>> x)
John Bauman89401822014-05-06 15:04:28 -04007141 //{
7142 // Value *element = Nucleus::createLoad(x.value);
7143
7144 //// Value *int2 = UndefValue::get(Int2::getType());
7145 //// int2 = Nucleus::createInsertElement(int2, element, ConstantInt::get(Int::getType(), 0));
7146
7147 // Value *int2 = Nucleus::createBitCast(Nucleus::createZExt(element, Long::getType()), Int2::getType());
7148
7149 // return RValue<Int2>(int2);
7150 //}
7151
John Bauman19bac1e2014-05-06 15:23:49 -04007152 //RValue<Int2> movdq2q(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007153 //{
Nicolas Capens22008782016-10-20 01:11:47 -04007154 // Value *long2 = Nucleus::createBitCast(x.value, T(VectorType::get(Long::getType(), 2)));
John Bauman89401822014-05-06 15:04:28 -04007155 // Value *element = Nucleus::createExtractElement(long2, ConstantInt::get(Int::getType(), 0));
7156
7157 // return RValue<Int2>(Nucleus::createBitCast(element, Int2::getType()));
7158 //}
7159
John Bauman19bac1e2014-05-06 15:23:49 -04007160 RValue<Int4> pmovzxbd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007161 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007162 llvm::Function *pmovzxbd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovzxbd);
John Bauman66b8ab22014-05-06 15:57:45 -04007163
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007164 return RValue<Int4>(V(::builder->CreateCall(pmovzxbd, Nucleus::createBitCast(x.value, Byte16::getType()))));
John Bauman89401822014-05-06 15:04:28 -04007165 }
7166
John Bauman19bac1e2014-05-06 15:23:49 -04007167 RValue<Int4> pmovsxbd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007168 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007169 llvm::Function *pmovsxbd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovsxbd);
John Bauman66b8ab22014-05-06 15:57:45 -04007170
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007171 return RValue<Int4>(V(::builder->CreateCall(pmovsxbd, Nucleus::createBitCast(x.value, SByte16::getType()))));
John Bauman89401822014-05-06 15:04:28 -04007172 }
7173
John Bauman19bac1e2014-05-06 15:23:49 -04007174 RValue<Int4> pmovzxwd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007175 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007176 llvm::Function *pmovzxwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovzxwd);
John Bauman66b8ab22014-05-06 15:57:45 -04007177
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007178 return RValue<Int4>(V(::builder->CreateCall(pmovzxwd, Nucleus::createBitCast(x.value, UShort8::getType()))));
John Bauman89401822014-05-06 15:04:28 -04007179 }
7180
John Bauman19bac1e2014-05-06 15:23:49 -04007181 RValue<Int4> pmovsxwd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007182 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007183 llvm::Function *pmovsxwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovsxwd);
John Bauman66b8ab22014-05-06 15:57:45 -04007184
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007185 return RValue<Int4>(V(::builder->CreateCall(pmovsxwd, Nucleus::createBitCast(x.value, Short8::getType()))));
John Bauman89401822014-05-06 15:04:28 -04007186 }
7187
7188 void emms()
7189 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007190 llvm::Function *emms = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_emms);
John Bauman89401822014-05-06 15:04:28 -04007191
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007192 V(::builder->CreateCall(emms));
John Bauman89401822014-05-06 15:04:28 -04007193 }
7194 }
7195}