blob: 26521d3a668183bc73ec82e322ac7c09c20d3c3b [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
71 sw::BackoffLock 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 Capensc8b67a42016-09-25 15:02:52 -040082 class BasicBlock : public llvm::BasicBlock {};
Nicolas Capensac230122016-09-20 14:30:06 -040083
84 inline Type *T(llvm::Type *t)
85 {
86 return reinterpret_cast<Type*>(t);
87 }
88
Nicolas Capens19336542016-09-26 10:32:29 -040089 inline Value *V(llvm::Value *t)
90 {
91 return reinterpret_cast<Value*>(t);
92 }
93
Nicolas Capensac230122016-09-20 14:30:06 -040094 inline std::vector<llvm::Type*> &T(std::vector<Type*> &t)
95 {
96 return reinterpret_cast<std::vector<llvm::Type*>&>(t);
97 }
98
Nicolas Capensc8b67a42016-09-25 15:02:52 -040099 inline BasicBlock *B(llvm::BasicBlock *t)
100 {
101 return reinterpret_cast<BasicBlock*>(t);
102 }
103
John Bauman89401822014-05-06 15:04:28 -0400104 Nucleus::Nucleus()
105 {
Nicolas Capens3bbc5e12016-09-27 10:49:52 -0400106 ::codegenMutex.lock(); // Reactor and LLVM are currently not thread safe
Nicolas Capensb7ea9842015-04-01 10:54:59 -0400107
John Bauman19bac1e2014-05-06 15:23:49 -0400108 InitializeNativeTarget();
John Bauman89401822014-05-06 15:04:28 -0400109 JITEmitDebugInfo = false;
110
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400111 if(!::context)
John Bauman89401822014-05-06 15:04:28 -0400112 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400113 ::context = new LLVMContext();
John Bauman89401822014-05-06 15:04:28 -0400114 }
115
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400116 ::module = new Module("", *::context);
Nicolas Capensdaa5d912016-09-28 16:56:36 -0400117 ::routineManager = new LLVMRoutineManager();
John Bauman66b8ab22014-05-06 15:57:45 -0400118
John Bauman89401822014-05-06 15:04:28 -0400119 #if defined(__x86_64__)
120 const char *architecture = "x86-64";
121 #else
122 const char *architecture = "x86";
123 #endif
124
125 SmallVector<std::string, 1> MAttrs;
126 MAttrs.push_back(CPUID::supportsMMX() ? "+mmx" : "-mmx");
127 MAttrs.push_back(CPUID::supportsCMOV() ? "+cmov" : "-cmov");
128 MAttrs.push_back(CPUID::supportsSSE() ? "+sse" : "-sse");
129 MAttrs.push_back(CPUID::supportsSSE2() ? "+sse2" : "-sse2");
130 MAttrs.push_back(CPUID::supportsSSE3() ? "+sse3" : "-sse3");
131 MAttrs.push_back(CPUID::supportsSSSE3() ? "+ssse3" : "-ssse3");
132 MAttrs.push_back(CPUID::supportsSSE4_1() ? "+sse41" : "-sse41");
133
John Bauman19bac1e2014-05-06 15:23:49 -0400134 std::string error;
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400135 TargetMachine *targetMachine = EngineBuilder::selectTarget(::module, architecture, "", MAttrs, Reloc::Default, CodeModel::JITDefault, &error);
136 ::executionEngine = JIT::createJIT(::module, 0, ::routineManager, CodeGenOpt::Aggressive, true, targetMachine);
John Bauman89401822014-05-06 15:04:28 -0400137
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400138 if(!::builder)
John Bauman89401822014-05-06 15:04:28 -0400139 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400140 ::builder = new IRBuilder<>(*::context);
John Bauman89401822014-05-06 15:04:28 -0400141
John Bauman66b8ab22014-05-06 15:57:45 -0400142 #if defined(_WIN32)
143 HMODULE CodeAnalyst = LoadLibrary("CAJitNtfyLib.dll");
144 if(CodeAnalyst)
145 {
146 CodeAnalystInitialize = (bool(*)())GetProcAddress(CodeAnalyst, "CAJIT_Initialize");
147 CodeAnalystCompleteJITLog = (void(*)())GetProcAddress(CodeAnalyst, "CAJIT_CompleteJITLog");
148 CodeAnalystLogJITCode = (bool(*)(const void*, unsigned int, const wchar_t*))GetProcAddress(CodeAnalyst, "CAJIT_LogJITCode");
149
150 CodeAnalystInitialize();
151 }
152 #endif
John Bauman89401822014-05-06 15:04:28 -0400153 }
154 }
155
156 Nucleus::~Nucleus()
157 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400158 delete ::executionEngine;
159 ::executionEngine = nullptr;
John Bauman89401822014-05-06 15:04:28 -0400160
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400161 ::routineManager = nullptr;
162 ::function = nullptr;
163 ::module = nullptr;
Nicolas Capensb7ea9842015-04-01 10:54:59 -0400164
Nicolas Capens3bbc5e12016-09-27 10:49:52 -0400165 ::codegenMutex.unlock();
John Bauman89401822014-05-06 15:04:28 -0400166 }
167
168 Routine *Nucleus::acquireRoutine(const wchar_t *name, bool runOptimizations)
169 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400170 if(::builder->GetInsertBlock()->empty() || !::builder->GetInsertBlock()->back().isTerminator())
John Bauman19bac1e2014-05-06 15:23:49 -0400171 {
Nicolas Capensac230122016-09-20 14:30:06 -0400172 llvm::Type *type = ::function->getReturnType();
John Bauman19bac1e2014-05-06 15:23:49 -0400173
174 if(type->isVoidTy())
175 {
176 createRetVoid();
177 }
178 else
179 {
Nicolas Capens19336542016-09-26 10:32:29 -0400180 createRet(V(UndefValue::get(type)));
John Bauman19bac1e2014-05-06 15:23:49 -0400181 }
182 }
John Bauman89401822014-05-06 15:04:28 -0400183
184 if(false)
185 {
John Bauman66b8ab22014-05-06 15:57:45 -0400186 std::string error;
187 raw_fd_ostream file("llvm-dump-unopt.txt", error);
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400188 ::module->print(file, 0);
John Bauman89401822014-05-06 15:04:28 -0400189 }
190
191 if(runOptimizations)
192 {
193 optimize();
194 }
195
196 if(false)
197 {
John Bauman66b8ab22014-05-06 15:57:45 -0400198 std::string error;
199 raw_fd_ostream file("llvm-dump-opt.txt", error);
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400200 ::module->print(file, 0);
John Bauman89401822014-05-06 15:04:28 -0400201 }
202
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400203 void *entry = ::executionEngine->getPointerToFunction(::function);
Nicolas Capensdaa5d912016-09-28 16:56:36 -0400204 LLVMRoutine *routine = ::routineManager->acquireRoutine(entry);
John Bauman89401822014-05-06 15:04:28 -0400205
206 if(CodeAnalystLogJITCode)
207 {
Nicolas Capensd946e0a2014-06-26 11:31:08 -0400208 CodeAnalystLogJITCode(routine->getEntry(), routine->getCodeSize(), name);
John Bauman89401822014-05-06 15:04:28 -0400209 }
210
211 return routine;
212 }
213
214 void Nucleus::optimize()
215 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400216 static PassManager *passManager = nullptr;
John Bauman66b8ab22014-05-06 15:57:45 -0400217
John Bauman89401822014-05-06 15:04:28 -0400218 if(!passManager)
219 {
220 passManager = new PassManager();
221
222 UnsafeFPMath = true;
223 // NoInfsFPMath = true;
224 // NoNaNsFPMath = true;
225
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400226 passManager->add(new TargetData(*::executionEngine->getTargetData()));
John Bauman89401822014-05-06 15:04:28 -0400227 passManager->add(createScalarReplAggregatesPass());
228
229 for(int pass = 0; pass < 10 && optimization[pass] != Disabled; pass++)
230 {
231 switch(optimization[pass])
232 {
233 case Disabled: break;
234 case CFGSimplification: passManager->add(createCFGSimplificationPass()); break;
235 case LICM: passManager->add(createLICMPass()); break;
236 case AggressiveDCE: passManager->add(createAggressiveDCEPass()); break;
237 case GVN: passManager->add(createGVNPass()); break;
238 case InstructionCombining: passManager->add(createInstructionCombiningPass()); break;
239 case Reassociate: passManager->add(createReassociatePass()); break;
240 case DeadStoreElimination: passManager->add(createDeadStoreEliminationPass()); break;
241 case SCCP: passManager->add(createSCCPPass()); break;
John Bauman19bac1e2014-05-06 15:23:49 -0400242 case ScalarReplAggregates: passManager->add(createScalarReplAggregatesPass()); break;
John Bauman89401822014-05-06 15:04:28 -0400243 default:
244 assert(false);
245 }
246 }
247 }
248
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400249 passManager->run(*::module);
John Bauman89401822014-05-06 15:04:28 -0400250 }
251
John Bauman19bac1e2014-05-06 15:23:49 -0400252 Value *Nucleus::allocateStackVariable(Type *type, int arraySize)
John Bauman89401822014-05-06 15:04:28 -0400253 {
254 // Need to allocate it in the entry block for mem2reg to work
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400255 llvm::BasicBlock &entryBlock = ::function->getEntryBlock();
John Bauman89401822014-05-06 15:04:28 -0400256
257 Instruction *declaration;
258
259 if(arraySize)
260 {
261 declaration = new AllocaInst(type, Nucleus::createConstantInt(arraySize));
262 }
263 else
264 {
265 declaration = new AllocaInst(type, (Value*)0);
266 }
267
268 entryBlock.getInstList().push_front(declaration);
269
Nicolas Capens19336542016-09-26 10:32:29 -0400270 return V(declaration);
John Bauman89401822014-05-06 15:04:28 -0400271 }
272
273 BasicBlock *Nucleus::createBasicBlock()
274 {
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400275 return B(BasicBlock::Create(*::context, "", ::function));
John Bauman89401822014-05-06 15:04:28 -0400276 }
277
278 BasicBlock *Nucleus::getInsertBlock()
279 {
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400280 return B(::builder->GetInsertBlock());
John Bauman89401822014-05-06 15:04:28 -0400281 }
282
283 void Nucleus::setInsertBlock(BasicBlock *basicBlock)
284 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400285 // assert(::builder->GetInsertBlock()->back().isTerminator());
286 return ::builder->SetInsertPoint(basicBlock);
John Bauman89401822014-05-06 15:04:28 -0400287 }
288
289 BasicBlock *Nucleus::getPredecessor(BasicBlock *basicBlock)
290 {
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400291 return B(*pred_begin(basicBlock));
John Bauman89401822014-05-06 15:04:28 -0400292 }
293
Nicolas Capensac230122016-09-20 14:30:06 -0400294 void Nucleus::createFunction(Type *ReturnType, std::vector<Type*> &Params)
John Bauman89401822014-05-06 15:04:28 -0400295 {
Nicolas Capensac230122016-09-20 14:30:06 -0400296 llvm::FunctionType *functionType = llvm::FunctionType::get(ReturnType, T(Params), false);
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400297 ::function = llvm::Function::Create(functionType, llvm::GlobalValue::InternalLinkage, "", ::module);
298 ::function->setCallingConv(llvm::CallingConv::C);
John Bauman89401822014-05-06 15:04:28 -0400299
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400300 ::builder->SetInsertPoint(BasicBlock::Create(*::context, "", ::function));
John Bauman89401822014-05-06 15:04:28 -0400301 }
302
Nicolas Capens19336542016-09-26 10:32:29 -0400303 Value *Nucleus::getArgument(unsigned int index)
John Bauman89401822014-05-06 15:04:28 -0400304 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400305 llvm::Function::arg_iterator args = ::function->arg_begin();
John Bauman89401822014-05-06 15:04:28 -0400306
307 while(index)
308 {
309 args++;
310 index--;
311 }
312
Nicolas Capens19336542016-09-26 10:32:29 -0400313 return V(&*args);
John Bauman89401822014-05-06 15:04:28 -0400314 }
315
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400316 void Nucleus::createRetVoid()
John Bauman89401822014-05-06 15:04:28 -0400317 {
John Bauman66b8ab22014-05-06 15:57:45 -0400318 x86::emms();
319
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400320 ::builder->CreateRetVoid();
John Bauman89401822014-05-06 15:04:28 -0400321 }
322
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400323 void Nucleus::createRet(Value *v)
John Bauman89401822014-05-06 15:04:28 -0400324 {
John Bauman66b8ab22014-05-06 15:57:45 -0400325 x86::emms();
326
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400327 ::builder->CreateRet(v);
John Bauman89401822014-05-06 15:04:28 -0400328 }
329
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400330 void Nucleus::createBr(BasicBlock *dest)
John Bauman89401822014-05-06 15:04:28 -0400331 {
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400332 ::builder->CreateBr(dest);
John Bauman89401822014-05-06 15:04:28 -0400333 }
334
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400335 void Nucleus::createCondBr(Value *cond, BasicBlock *ifTrue, BasicBlock *ifFalse)
John Bauman89401822014-05-06 15:04:28 -0400336 {
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400337 ::builder->CreateCondBr(cond, ifTrue, ifFalse);
John Bauman89401822014-05-06 15:04:28 -0400338 }
339
340 Value *Nucleus::createAdd(Value *lhs, Value *rhs)
341 {
Nicolas Capens19336542016-09-26 10:32:29 -0400342 return V(::builder->CreateAdd(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400343 }
344
345 Value *Nucleus::createSub(Value *lhs, Value *rhs)
346 {
Nicolas Capens19336542016-09-26 10:32:29 -0400347 return V(::builder->CreateSub(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400348 }
349
350 Value *Nucleus::createMul(Value *lhs, Value *rhs)
351 {
Nicolas Capens19336542016-09-26 10:32:29 -0400352 return V(::builder->CreateMul(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400353 }
354
355 Value *Nucleus::createUDiv(Value *lhs, Value *rhs)
356 {
Nicolas Capens19336542016-09-26 10:32:29 -0400357 return V(::builder->CreateUDiv(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400358 }
359
360 Value *Nucleus::createSDiv(Value *lhs, Value *rhs)
361 {
Nicolas Capens19336542016-09-26 10:32:29 -0400362 return V(::builder->CreateSDiv(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400363 }
364
365 Value *Nucleus::createFAdd(Value *lhs, Value *rhs)
366 {
Nicolas Capens19336542016-09-26 10:32:29 -0400367 return V(::builder->CreateFAdd(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400368 }
369
370 Value *Nucleus::createFSub(Value *lhs, Value *rhs)
371 {
Nicolas Capens19336542016-09-26 10:32:29 -0400372 return V(::builder->CreateFSub(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400373 }
374
375 Value *Nucleus::createFMul(Value *lhs, Value *rhs)
376 {
Nicolas Capens19336542016-09-26 10:32:29 -0400377 return V(::builder->CreateFMul(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400378 }
379
380 Value *Nucleus::createFDiv(Value *lhs, Value *rhs)
381 {
Nicolas Capens19336542016-09-26 10:32:29 -0400382 return V(::builder->CreateFDiv(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400383 }
384
385 Value *Nucleus::createURem(Value *lhs, Value *rhs)
386 {
Nicolas Capens19336542016-09-26 10:32:29 -0400387 return V(::builder->CreateURem(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400388 }
389
390 Value *Nucleus::createSRem(Value *lhs, Value *rhs)
391 {
Nicolas Capens19336542016-09-26 10:32:29 -0400392 return V(::builder->CreateSRem(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400393 }
394
395 Value *Nucleus::createFRem(Value *lhs, Value *rhs)
396 {
Nicolas Capens19336542016-09-26 10:32:29 -0400397 return V(::builder->CreateFRem(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400398 }
399
400 Value *Nucleus::createShl(Value *lhs, Value *rhs)
401 {
Nicolas Capens19336542016-09-26 10:32:29 -0400402 return V(::builder->CreateShl(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400403 }
404
405 Value *Nucleus::createLShr(Value *lhs, Value *rhs)
406 {
Nicolas Capens19336542016-09-26 10:32:29 -0400407 return V(::builder->CreateLShr(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400408 }
409
410 Value *Nucleus::createAShr(Value *lhs, Value *rhs)
411 {
Nicolas Capens19336542016-09-26 10:32:29 -0400412 return V(::builder->CreateAShr(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400413 }
414
415 Value *Nucleus::createAnd(Value *lhs, Value *rhs)
416 {
Nicolas Capens19336542016-09-26 10:32:29 -0400417 return V(::builder->CreateAnd(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400418 }
419
420 Value *Nucleus::createOr(Value *lhs, Value *rhs)
421 {
Nicolas Capens19336542016-09-26 10:32:29 -0400422 return V(::builder->CreateOr(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400423 }
424
425 Value *Nucleus::createXor(Value *lhs, Value *rhs)
426 {
Nicolas Capens19336542016-09-26 10:32:29 -0400427 return V(::builder->CreateXor(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400428 }
429
Nicolas Capens19336542016-09-26 10:32:29 -0400430 Value *Nucleus::createNeg(Value *v)
John Bauman89401822014-05-06 15:04:28 -0400431 {
Nicolas Capens19336542016-09-26 10:32:29 -0400432 return V(::builder->CreateNeg(v));
John Bauman89401822014-05-06 15:04:28 -0400433 }
434
Nicolas Capens19336542016-09-26 10:32:29 -0400435 Value *Nucleus::createFNeg(Value *v)
John Bauman89401822014-05-06 15:04:28 -0400436 {
Nicolas Capens19336542016-09-26 10:32:29 -0400437 return V(::builder->CreateFNeg(v));
John Bauman89401822014-05-06 15:04:28 -0400438 }
439
Nicolas Capens19336542016-09-26 10:32:29 -0400440 Value *Nucleus::createNot(Value *v)
John Bauman89401822014-05-06 15:04:28 -0400441 {
Nicolas Capens19336542016-09-26 10:32:29 -0400442 return V(::builder->CreateNot(v));
John Bauman89401822014-05-06 15:04:28 -0400443 }
444
Nicolas Capense12780d2016-09-27 14:18:07 -0400445 Value *Nucleus::createLoad(Value *ptr, Type *type, bool isVolatile, unsigned int align)
John Bauman89401822014-05-06 15:04:28 -0400446 {
Nicolas Capense12780d2016-09-27 14:18:07 -0400447 assert(ptr->getType()->getContainedType(0) == type);
Nicolas Capens19336542016-09-26 10:32:29 -0400448 return V(::builder->Insert(new LoadInst(ptr, "", isVolatile, align)));
John Bauman89401822014-05-06 15:04:28 -0400449 }
450
Nicolas Capens6d738712016-09-30 04:15:22 -0400451 Value *Nucleus::createStore(Value *value, Value *ptr, Type *type, bool isVolatile, unsigned int align)
John Bauman89401822014-05-06 15:04:28 -0400452 {
Nicolas Capens6d738712016-09-30 04:15:22 -0400453 assert(ptr->getType()->getContainedType(0) == type);
Nicolas Capensb955d5b2016-09-28 22:36:28 -0400454 ::builder->Insert(new StoreInst(value, ptr, isVolatile, align));
455 return value;
John Bauman89401822014-05-06 15:04:28 -0400456 }
457
Nicolas Capens6d738712016-09-30 04:15:22 -0400458 Value *Nucleus::createGEP(Value *ptr, Type *type, Value *index)
John Bauman89401822014-05-06 15:04:28 -0400459 {
Nicolas Capens6d738712016-09-30 04:15:22 -0400460 assert(ptr->getType()->getContainedType(0) == type);
Nicolas Capens19336542016-09-26 10:32:29 -0400461 return V(::builder->CreateGEP(ptr, index));
John Bauman89401822014-05-06 15:04:28 -0400462 }
463
John Bauman19bac1e2014-05-06 15:23:49 -0400464 Value *Nucleus::createAtomicAdd(Value *ptr, Value *value)
465 {
Nicolas Capens19336542016-09-26 10:32:29 -0400466 return V(::builder->CreateAtomicRMW(AtomicRMWInst::Add, ptr, value, SequentiallyConsistent));
John Bauman19bac1e2014-05-06 15:23:49 -0400467 }
468
Nicolas Capens19336542016-09-26 10:32:29 -0400469 Value *Nucleus::createTrunc(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400470 {
Nicolas Capens19336542016-09-26 10:32:29 -0400471 return V(::builder->CreateTrunc(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400472 }
473
Nicolas Capens19336542016-09-26 10:32:29 -0400474 Value *Nucleus::createZExt(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400475 {
Nicolas Capens19336542016-09-26 10:32:29 -0400476 return V(::builder->CreateZExt(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400477 }
478
Nicolas Capens19336542016-09-26 10:32:29 -0400479 Value *Nucleus::createSExt(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400480 {
Nicolas Capens19336542016-09-26 10:32:29 -0400481 return V(::builder->CreateSExt(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400482 }
483
Nicolas Capens19336542016-09-26 10:32:29 -0400484 Value *Nucleus::createFPToSI(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400485 {
Nicolas Capens19336542016-09-26 10:32:29 -0400486 return V(::builder->CreateFPToSI(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400487 }
488
Nicolas Capens19336542016-09-26 10:32:29 -0400489 Value *Nucleus::createUIToFP(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400490 {
Nicolas Capens19336542016-09-26 10:32:29 -0400491 return V(::builder->CreateUIToFP(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400492 }
493
Nicolas Capens19336542016-09-26 10:32:29 -0400494 Value *Nucleus::createSIToFP(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400495 {
Nicolas Capens19336542016-09-26 10:32:29 -0400496 return V(::builder->CreateSIToFP(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400497 }
498
Nicolas Capens19336542016-09-26 10:32:29 -0400499 Value *Nucleus::createFPTrunc(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400500 {
Nicolas Capens19336542016-09-26 10:32:29 -0400501 return V(::builder->CreateFPTrunc(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400502 }
503
Nicolas Capens19336542016-09-26 10:32:29 -0400504 Value *Nucleus::createFPExt(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400505 {
Nicolas Capens19336542016-09-26 10:32:29 -0400506 return V(::builder->CreateFPExt(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400507 }
508
Nicolas Capens19336542016-09-26 10:32:29 -0400509 Value *Nucleus::createBitCast(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400510 {
Nicolas Capens19336542016-09-26 10:32:29 -0400511 return V(::builder->CreateBitCast(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400512 }
513
Nicolas Capens19336542016-09-26 10:32:29 -0400514 Value *Nucleus::createIntCast(Value *v, Type *destType, bool isSigned)
John Bauman89401822014-05-06 15:04:28 -0400515 {
Nicolas Capens19336542016-09-26 10:32:29 -0400516 return V(::builder->CreateIntCast(v, destType, isSigned));
John Bauman89401822014-05-06 15:04:28 -0400517 }
518
519 Value *Nucleus::createICmpEQ(Value *lhs, Value *rhs)
520 {
Nicolas Capens19336542016-09-26 10:32:29 -0400521 return V(::builder->CreateICmpEQ(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400522 }
523
524 Value *Nucleus::createICmpNE(Value *lhs, Value *rhs)
525 {
Nicolas Capens19336542016-09-26 10:32:29 -0400526 return V(::builder->CreateICmpNE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400527 }
528
529 Value *Nucleus::createICmpUGT(Value *lhs, Value *rhs)
530 {
Nicolas Capens19336542016-09-26 10:32:29 -0400531 return V(::builder->CreateICmpUGT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400532 }
533
534 Value *Nucleus::createICmpUGE(Value *lhs, Value *rhs)
535 {
Nicolas Capens19336542016-09-26 10:32:29 -0400536 return V(::builder->CreateICmpUGE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400537 }
538
539 Value *Nucleus::createICmpULT(Value *lhs, Value *rhs)
540 {
Nicolas Capens19336542016-09-26 10:32:29 -0400541 return V(::builder->CreateICmpULT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400542 }
543
544 Value *Nucleus::createICmpULE(Value *lhs, Value *rhs)
545 {
Nicolas Capens19336542016-09-26 10:32:29 -0400546 return V(::builder->CreateICmpULE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400547 }
548
549 Value *Nucleus::createICmpSGT(Value *lhs, Value *rhs)
550 {
Nicolas Capens19336542016-09-26 10:32:29 -0400551 return V(::builder->CreateICmpSGT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400552 }
553
554 Value *Nucleus::createICmpSGE(Value *lhs, Value *rhs)
555 {
Nicolas Capens19336542016-09-26 10:32:29 -0400556 return V(::builder->CreateICmpSGE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400557 }
558
559 Value *Nucleus::createICmpSLT(Value *lhs, Value *rhs)
560 {
Nicolas Capens19336542016-09-26 10:32:29 -0400561 return V(::builder->CreateICmpSLT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400562 }
563
564 Value *Nucleus::createICmpSLE(Value *lhs, Value *rhs)
565 {
Nicolas Capens19336542016-09-26 10:32:29 -0400566 return V(::builder->CreateICmpSLE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400567 }
568
569 Value *Nucleus::createFCmpOEQ(Value *lhs, Value *rhs)
570 {
Nicolas Capens19336542016-09-26 10:32:29 -0400571 return V(::builder->CreateFCmpOEQ(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400572 }
573
574 Value *Nucleus::createFCmpOGT(Value *lhs, Value *rhs)
575 {
Nicolas Capens19336542016-09-26 10:32:29 -0400576 return V(::builder->CreateFCmpOGT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400577 }
578
579 Value *Nucleus::createFCmpOGE(Value *lhs, Value *rhs)
580 {
Nicolas Capens19336542016-09-26 10:32:29 -0400581 return V(::builder->CreateFCmpOGE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400582 }
583
584 Value *Nucleus::createFCmpOLT(Value *lhs, Value *rhs)
585 {
Nicolas Capens19336542016-09-26 10:32:29 -0400586 return V(::builder->CreateFCmpOLT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400587 }
588
589 Value *Nucleus::createFCmpOLE(Value *lhs, Value *rhs)
590 {
Nicolas Capens19336542016-09-26 10:32:29 -0400591 return V(::builder->CreateFCmpOLE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400592 }
593
594 Value *Nucleus::createFCmpONE(Value *lhs, Value *rhs)
595 {
Nicolas Capens19336542016-09-26 10:32:29 -0400596 return V(::builder->CreateFCmpONE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400597 }
598
599 Value *Nucleus::createFCmpORD(Value *lhs, Value *rhs)
600 {
Nicolas Capens19336542016-09-26 10:32:29 -0400601 return V(::builder->CreateFCmpORD(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400602 }
603
604 Value *Nucleus::createFCmpUNO(Value *lhs, Value *rhs)
605 {
Nicolas Capens19336542016-09-26 10:32:29 -0400606 return V(::builder->CreateFCmpUNO(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400607 }
608
609 Value *Nucleus::createFCmpUEQ(Value *lhs, Value *rhs)
610 {
Nicolas Capens19336542016-09-26 10:32:29 -0400611 return V(::builder->CreateFCmpUEQ(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400612 }
613
614 Value *Nucleus::createFCmpUGT(Value *lhs, Value *rhs)
615 {
Nicolas Capens19336542016-09-26 10:32:29 -0400616 return V(::builder->CreateFCmpUGT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400617 }
618
619 Value *Nucleus::createFCmpUGE(Value *lhs, Value *rhs)
620 {
Nicolas Capens19336542016-09-26 10:32:29 -0400621 return V(::builder->CreateFCmpUGE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400622 }
623
624 Value *Nucleus::createFCmpULT(Value *lhs, Value *rhs)
625 {
Nicolas Capens19336542016-09-26 10:32:29 -0400626 return V(::builder->CreateFCmpULT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400627 }
628
629 Value *Nucleus::createFCmpULE(Value *lhs, Value *rhs)
630 {
Nicolas Capens19336542016-09-26 10:32:29 -0400631 return V(::builder->CreateFCmpULE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400632 }
633
634 Value *Nucleus::createFCmpUNE(Value *lhs, Value *rhs)
635 {
Nicolas Capens19336542016-09-26 10:32:29 -0400636 return V(::builder->CreateFCmpULE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400637 }
638
Nicolas Capense95d5342016-09-30 11:37:28 -0400639 Value *Nucleus::createExtractElement(Value *vector, Type *type, int index)
John Bauman89401822014-05-06 15:04:28 -0400640 {
Nicolas Capense95d5342016-09-30 11:37:28 -0400641 assert(vector->getType()->getContainedType(0) == type);
Nicolas Capens19336542016-09-26 10:32:29 -0400642 return V(::builder->CreateExtractElement(vector, createConstantInt(index)));
John Bauman89401822014-05-06 15:04:28 -0400643 }
644
645 Value *Nucleus::createInsertElement(Value *vector, Value *element, int index)
646 {
Nicolas Capens19336542016-09-26 10:32:29 -0400647 return V(::builder->CreateInsertElement(vector, element, createConstantInt(index)));
John Bauman89401822014-05-06 15:04:28 -0400648 }
649
Nicolas Capense89cd582016-09-30 14:23:47 -0400650 Value *Nucleus::createShuffleVector(Value *V1, Value *V2, const int *select)
John Bauman89401822014-05-06 15:04:28 -0400651 {
Nicolas Capense89cd582016-09-30 14:23:47 -0400652 int size = llvm::cast<llvm::VectorType>(V1->getType())->getNumElements();
653 const int maxSize = 16;
654 llvm::Constant *swizzle[maxSize];
655 assert(size <= maxSize);
656
657 for(int i = 0; i < size; i++)
658 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400659 swizzle[i] = llvm::ConstantInt::get(Type::getInt32Ty(*::context), select[i]);
Nicolas Capense89cd582016-09-30 14:23:47 -0400660 }
661
662 llvm::Value *shuffle = llvm::ConstantVector::get(llvm::ArrayRef<llvm::Constant*>(swizzle, size));
663
664 return V(::builder->CreateShuffleVector(V1, V2, shuffle));
John Bauman89401822014-05-06 15:04:28 -0400665 }
666
667 Value *Nucleus::createSelect(Value *C, Value *ifTrue, Value *ifFalse)
668 {
Nicolas Capens19336542016-09-26 10:32:29 -0400669 return V(::builder->CreateSelect(C, ifTrue, ifFalse));
John Bauman89401822014-05-06 15:04:28 -0400670 }
671
Nicolas Capens19336542016-09-26 10:32:29 -0400672 Value *Nucleus::createSwitch(Value *v, BasicBlock *Dest, unsigned NumCases)
John Bauman89401822014-05-06 15:04:28 -0400673 {
Nicolas Capens19336542016-09-26 10:32:29 -0400674 return V(::builder->CreateSwitch(v, Dest, NumCases));
John Bauman89401822014-05-06 15:04:28 -0400675 }
676
Nicolas Capens19336542016-09-26 10:32:29 -0400677 void Nucleus::addSwitchCase(Value *Switch, int Case, BasicBlock *Branch)
John Bauman89401822014-05-06 15:04:28 -0400678 {
Nicolas Capens19336542016-09-26 10:32:29 -0400679 reinterpret_cast<SwitchInst*>(Switch)->addCase(llvm::ConstantInt::get(Type::getInt32Ty(*::context), Case, true), Branch);
John Bauman89401822014-05-06 15:04:28 -0400680 }
681
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400682 void Nucleus::createUnreachable()
John Bauman89401822014-05-06 15:04:28 -0400683 {
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400684 ::builder->CreateUnreachable();
John Bauman89401822014-05-06 15:04:28 -0400685 }
686
Nicolas Capense95d5342016-09-30 11:37:28 -0400687 static Value *createSwizzle4(Value *val, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -0400688 {
Nicolas Capense89cd582016-09-30 14:23:47 -0400689 int swizzle[4] =
690 {
691 (select >> 0) & 0x03,
692 (select >> 2) & 0x03,
693 (select >> 4) & 0x03,
694 (select >> 6) & 0x03,
695 };
John Bauman89401822014-05-06 15:04:28 -0400696
Nicolas Capense89cd582016-09-30 14:23:47 -0400697 return Nucleus::createShuffleVector(val, val, swizzle);
John Bauman89401822014-05-06 15:04:28 -0400698 }
699
Nicolas Capense95d5342016-09-30 11:37:28 -0400700 static Value *createMask4(Value *lhs, Value *rhs, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -0400701 {
702 bool mask[4] = {false, false, false, false};
703
704 mask[(select >> 0) & 0x03] = true;
705 mask[(select >> 2) & 0x03] = true;
706 mask[(select >> 4) & 0x03] = true;
707 mask[(select >> 6) & 0x03] = true;
708
Nicolas Capense89cd582016-09-30 14:23:47 -0400709 int swizzle[4] =
710 {
711 mask[0] ? 4 : 0,
712 mask[1] ? 5 : 1,
713 mask[2] ? 6 : 2,
714 mask[3] ? 7 : 3,
715 };
John Bauman89401822014-05-06 15:04:28 -0400716
Nicolas Capense89cd582016-09-30 14:23:47 -0400717 Value *shuffle = Nucleus::createShuffleVector(lhs, rhs, swizzle);
John Bauman89401822014-05-06 15:04:28 -0400718
719 return shuffle;
720 }
721
Nicolas Capens73dd7a22016-10-20 13:20:34 -0400722 Value *Nucleus::createConstantPointer(const void *address, Type *Ty, unsigned int align)
John Bauman89401822014-05-06 15:04:28 -0400723 {
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400724 const GlobalValue *existingGlobal = ::executionEngine->getGlobalValueAtAddress(const_cast<void*>(address)); // FIXME: Const
John Bauman89401822014-05-06 15:04:28 -0400725
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400726 if(existingGlobal)
727 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400728 return (Value*)existingGlobal;
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400729 }
John Bauman89401822014-05-06 15:04:28 -0400730
Nicolas Capens73dd7a22016-10-20 13:20:34 -0400731 llvm::GlobalValue *global = new llvm::GlobalVariable(*::module, Ty, true, llvm::GlobalValue::ExternalLinkage, 0, "");
732 global->setAlignment(align);
John Bauman89401822014-05-06 15:04:28 -0400733
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400734 ::executionEngine->addGlobalMapping(global, const_cast<void*>(address));
735
Nicolas Capens13ac2322016-10-13 14:52:12 -0400736 return V(global);
John Bauman89401822014-05-06 15:04:28 -0400737 }
738
Nicolas Capensac230122016-09-20 14:30:06 -0400739 Type *Nucleus::getPointerType(Type *ElementType)
John Bauman89401822014-05-06 15:04:28 -0400740 {
Nicolas Capensac230122016-09-20 14:30:06 -0400741 return T(llvm::PointerType::get(ElementType, 0));
John Bauman89401822014-05-06 15:04:28 -0400742 }
743
Nicolas Capens13ac2322016-10-13 14:52:12 -0400744 Value *Nucleus::createNullValue(Type *Ty)
John Bauman89401822014-05-06 15:04:28 -0400745 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400746 return V(llvm::Constant::getNullValue(Ty));
John Bauman89401822014-05-06 15:04:28 -0400747 }
748
Nicolas Capens13ac2322016-10-13 14:52:12 -0400749 Value *Nucleus::createConstantLong(int64_t i)
John Bauman89401822014-05-06 15:04:28 -0400750 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400751 return V(llvm::ConstantInt::get(Type::getInt64Ty(*::context), i, true));
John Bauman89401822014-05-06 15:04:28 -0400752 }
753
Nicolas Capens13ac2322016-10-13 14:52:12 -0400754 Value *Nucleus::createConstantInt(int i)
John Bauman89401822014-05-06 15:04:28 -0400755 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400756 return V(llvm::ConstantInt::get(Type::getInt32Ty(*::context), i, true));
John Bauman89401822014-05-06 15:04:28 -0400757 }
758
Nicolas Capens13ac2322016-10-13 14:52:12 -0400759 Value *Nucleus::createConstantInt(unsigned int i)
John Bauman89401822014-05-06 15:04:28 -0400760 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400761 return V(llvm::ConstantInt::get(Type::getInt32Ty(*::context), i, false));
John Bauman89401822014-05-06 15:04:28 -0400762 }
763
Nicolas Capens13ac2322016-10-13 14:52:12 -0400764 Value *Nucleus::createConstantBool(bool b)
John Bauman89401822014-05-06 15:04:28 -0400765 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400766 return V(llvm::ConstantInt::get(Type::getInt1Ty(*::context), b));
John Bauman89401822014-05-06 15:04:28 -0400767 }
768
Nicolas Capens13ac2322016-10-13 14:52:12 -0400769 Value *Nucleus::createConstantByte(signed char i)
John Bauman89401822014-05-06 15:04:28 -0400770 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400771 return V(llvm::ConstantInt::get(Type::getInt8Ty(*::context), i, true));
John Bauman89401822014-05-06 15:04:28 -0400772 }
773
Nicolas Capens13ac2322016-10-13 14:52:12 -0400774 Value *Nucleus::createConstantByte(unsigned char i)
John Bauman89401822014-05-06 15:04:28 -0400775 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400776 return V(llvm::ConstantInt::get(Type::getInt8Ty(*::context), i, false));
John Bauman89401822014-05-06 15:04:28 -0400777 }
778
Nicolas Capens13ac2322016-10-13 14:52:12 -0400779 Value *Nucleus::createConstantShort(short i)
John Bauman89401822014-05-06 15:04:28 -0400780 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400781 return V(llvm::ConstantInt::get(Type::getInt16Ty(*::context), i, true));
John Bauman89401822014-05-06 15:04:28 -0400782 }
783
Nicolas Capens13ac2322016-10-13 14:52:12 -0400784 Value *Nucleus::createConstantShort(unsigned short i)
John Bauman89401822014-05-06 15:04:28 -0400785 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400786 return V(llvm::ConstantInt::get(Type::getInt16Ty(*::context), i, false));
John Bauman89401822014-05-06 15:04:28 -0400787 }
788
Nicolas Capens13ac2322016-10-13 14:52:12 -0400789 Value *Nucleus::createConstantFloat(float x)
John Bauman89401822014-05-06 15:04:28 -0400790 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400791 return V(llvm::ConstantFP::get(Float::getType(), x));
John Bauman89401822014-05-06 15:04:28 -0400792 }
793
Nicolas Capens13ac2322016-10-13 14:52:12 -0400794 Value *Nucleus::createNullPointer(Type *Ty)
John Bauman89401822014-05-06 15:04:28 -0400795 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400796 return V(llvm::ConstantPointerNull::get(llvm::PointerType::get(Ty, 0)));
John Bauman89401822014-05-06 15:04:28 -0400797 }
798
Nicolas Capens13ac2322016-10-13 14:52:12 -0400799 Value *Nucleus::createConstantVector(const int64_t *constants, Type *type)
John Bauman89401822014-05-06 15:04:28 -0400800 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400801 assert(llvm::isa<VectorType>(type));
802 const int numConstants = llvm::cast<VectorType>(type)->getNumElements();
803 assert(numConstants <= 16);
804 llvm::Constant *constantVector[16];
805
806 for(int i = 0; i < numConstants; i++)
807 {
808 constantVector[i] = llvm::ConstantInt::get(type->getContainedType(0), constants[i]);
809 }
810
811 return V(llvm::ConstantVector::get(llvm::ArrayRef<llvm::Constant*>(constantVector, numConstants)));
812 }
813
814 Value *Nucleus::createConstantVector(const double *constants, Type *type)
815 {
816 assert(llvm::isa<VectorType>(type));
817 const int numConstants = llvm::cast<VectorType>(type)->getNumElements();
818 assert(numConstants <= 8);
819 llvm::Constant *constantVector[8];
820
821 for(int i = 0; i < numConstants; i++)
822 {
823 constantVector[i] = llvm::ConstantFP::get(type->getContainedType(0), constants[i]);
824 }
825
826 return V(llvm::ConstantVector::get(llvm::ArrayRef<llvm::Constant*>(constantVector, numConstants)));
John Bauman89401822014-05-06 15:04:28 -0400827 }
828
John Bauman19bac1e2014-05-06 15:23:49 -0400829 Type *Void::getType()
John Bauman89401822014-05-06 15:04:28 -0400830 {
Nicolas Capensac230122016-09-20 14:30:06 -0400831 return T(llvm::Type::getVoidTy(*::context));
John Bauman89401822014-05-06 15:04:28 -0400832 }
833
Nicolas Capens4f738a12016-09-20 15:46:16 -0400834 class MMX : public Variable<MMX>
835 {
836 public:
837 static Type *getType();
838 };
839
John Bauman19bac1e2014-05-06 15:23:49 -0400840 Type *MMX::getType()
841 {
Nicolas Capensac230122016-09-20 14:30:06 -0400842 return T(llvm::Type::getX86_MMXTy(*::context));
John Bauman19bac1e2014-05-06 15:23:49 -0400843 }
844
Nicolas Capens81f18302016-01-14 09:32:35 -0500845 Bool::Bool(Argument<Bool> argument)
John Bauman89401822014-05-06 15:04:28 -0400846 {
Nicolas Capens81f18302016-01-14 09:32:35 -0500847 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -0400848 }
849
850 Bool::Bool()
851 {
John Bauman89401822014-05-06 15:04:28 -0400852 }
853
854 Bool::Bool(bool x)
855 {
John Bauman66b8ab22014-05-06 15:57:45 -0400856 storeValue(Nucleus::createConstantBool(x));
John Bauman89401822014-05-06 15:04:28 -0400857 }
858
John Bauman19bac1e2014-05-06 15:23:49 -0400859 Bool::Bool(RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400860 {
John Bauman66b8ab22014-05-06 15:57:45 -0400861 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400862 }
863
864 Bool::Bool(const Bool &rhs)
865 {
John Bauman66b8ab22014-05-06 15:57:45 -0400866 Value *value = rhs.loadValue();
867 storeValue(value);
868 }
John Bauman89401822014-05-06 15:04:28 -0400869
John Bauman66b8ab22014-05-06 15:57:45 -0400870 Bool::Bool(const Reference<Bool> &rhs)
871 {
872 Value *value = rhs.loadValue();
873 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400874 }
875
John Bauman19bac1e2014-05-06 15:23:49 -0400876 RValue<Bool> Bool::operator=(RValue<Bool> rhs) const
John Bauman89401822014-05-06 15:04:28 -0400877 {
John Bauman66b8ab22014-05-06 15:57:45 -0400878 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400879
880 return rhs;
881 }
882
883 RValue<Bool> Bool::operator=(const Bool &rhs) const
884 {
John Bauman66b8ab22014-05-06 15:57:45 -0400885 Value *value = rhs.loadValue();
886 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400887
888 return RValue<Bool>(value);
889 }
890
John Bauman66b8ab22014-05-06 15:57:45 -0400891 RValue<Bool> Bool::operator=(const Reference<Bool> &rhs) const
John Bauman89401822014-05-06 15:04:28 -0400892 {
John Bauman66b8ab22014-05-06 15:57:45 -0400893 Value *value = rhs.loadValue();
894 storeValue(value);
895
896 return RValue<Bool>(value);
John Bauman89401822014-05-06 15:04:28 -0400897 }
898
John Bauman19bac1e2014-05-06 15:23:49 -0400899 RValue<Bool> operator!(RValue<Bool> val)
John Bauman89401822014-05-06 15:04:28 -0400900 {
901 return RValue<Bool>(Nucleus::createNot(val.value));
902 }
903
John Bauman19bac1e2014-05-06 15:23:49 -0400904 RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400905 {
906 return RValue<Bool>(Nucleus::createAnd(lhs.value, rhs.value));
907 }
908
John Bauman19bac1e2014-05-06 15:23:49 -0400909 RValue<Bool> operator||(RValue<Bool> lhs, RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400910 {
911 return RValue<Bool>(Nucleus::createOr(lhs.value, rhs.value));
912 }
913
John Bauman19bac1e2014-05-06 15:23:49 -0400914 Type *Bool::getType()
John Bauman89401822014-05-06 15:04:28 -0400915 {
Nicolas Capensac230122016-09-20 14:30:06 -0400916 return T(llvm::Type::getInt1Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -0400917 }
918
Nicolas Capens81f18302016-01-14 09:32:35 -0500919 Byte::Byte(Argument<Byte> argument)
John Bauman89401822014-05-06 15:04:28 -0400920 {
Nicolas Capens81f18302016-01-14 09:32:35 -0500921 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -0400922 }
923
John Bauman19bac1e2014-05-06 15:23:49 -0400924 Byte::Byte(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -0400925 {
John Bauman89401822014-05-06 15:04:28 -0400926 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
927
John Bauman66b8ab22014-05-06 15:57:45 -0400928 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -0400929 }
930
Alexis Hetu77dfab42015-11-23 13:31:22 -0500931 Byte::Byte(RValue<UInt> cast)
932 {
933 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
934
935 storeValue(integer);
936 }
937
938 Byte::Byte(RValue<UShort> cast)
939 {
940 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
941
942 storeValue(integer);
943 }
944
John Bauman89401822014-05-06 15:04:28 -0400945 Byte::Byte()
946 {
John Bauman89401822014-05-06 15:04:28 -0400947 }
948
949 Byte::Byte(int x)
950 {
John Bauman66b8ab22014-05-06 15:57:45 -0400951 storeValue(Nucleus::createConstantByte((unsigned char)x));
John Bauman89401822014-05-06 15:04:28 -0400952 }
953
954 Byte::Byte(unsigned char x)
955 {
John Bauman66b8ab22014-05-06 15:57:45 -0400956 storeValue(Nucleus::createConstantByte(x));
John Bauman89401822014-05-06 15:04:28 -0400957 }
958
John Bauman19bac1e2014-05-06 15:23:49 -0400959 Byte::Byte(RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400960 {
John Bauman66b8ab22014-05-06 15:57:45 -0400961 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400962 }
963
964 Byte::Byte(const Byte &rhs)
965 {
John Bauman66b8ab22014-05-06 15:57:45 -0400966 Value *value = rhs.loadValue();
967 storeValue(value);
968 }
John Bauman89401822014-05-06 15:04:28 -0400969
John Bauman66b8ab22014-05-06 15:57:45 -0400970 Byte::Byte(const Reference<Byte> &rhs)
971 {
972 Value *value = rhs.loadValue();
973 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400974 }
975
John Bauman19bac1e2014-05-06 15:23:49 -0400976 RValue<Byte> Byte::operator=(RValue<Byte> rhs) const
John Bauman89401822014-05-06 15:04:28 -0400977 {
John Bauman66b8ab22014-05-06 15:57:45 -0400978 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400979
980 return rhs;
981 }
982
983 RValue<Byte> Byte::operator=(const Byte &rhs) const
984 {
John Bauman66b8ab22014-05-06 15:57:45 -0400985 Value *value = rhs.loadValue();
986 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400987
988 return RValue<Byte>(value);
989 }
990
John Bauman66b8ab22014-05-06 15:57:45 -0400991 RValue<Byte> Byte::operator=(const Reference<Byte> &rhs) const
John Bauman89401822014-05-06 15:04:28 -0400992 {
John Bauman66b8ab22014-05-06 15:57:45 -0400993 Value *value = rhs.loadValue();
994 storeValue(value);
995
996 return RValue<Byte>(value);
John Bauman89401822014-05-06 15:04:28 -0400997 }
998
John Bauman19bac1e2014-05-06 15:23:49 -0400999 RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001000 {
1001 return RValue<Byte>(Nucleus::createAdd(lhs.value, rhs.value));
1002 }
1003
John Bauman19bac1e2014-05-06 15:23:49 -04001004 RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001005 {
1006 return RValue<Byte>(Nucleus::createSub(lhs.value, rhs.value));
1007 }
1008
John Bauman19bac1e2014-05-06 15:23:49 -04001009 RValue<Byte> operator*(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001010 {
1011 return RValue<Byte>(Nucleus::createMul(lhs.value, rhs.value));
1012 }
1013
John Bauman19bac1e2014-05-06 15:23:49 -04001014 RValue<Byte> operator/(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001015 {
1016 return RValue<Byte>(Nucleus::createUDiv(lhs.value, rhs.value));
1017 }
1018
John Bauman19bac1e2014-05-06 15:23:49 -04001019 RValue<Byte> operator%(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001020 {
1021 return RValue<Byte>(Nucleus::createURem(lhs.value, rhs.value));
1022 }
1023
John Bauman19bac1e2014-05-06 15:23:49 -04001024 RValue<Byte> operator&(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001025 {
1026 return RValue<Byte>(Nucleus::createAnd(lhs.value, rhs.value));
1027 }
1028
John Bauman19bac1e2014-05-06 15:23:49 -04001029 RValue<Byte> operator|(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001030 {
1031 return RValue<Byte>(Nucleus::createOr(lhs.value, rhs.value));
1032 }
1033
John Bauman19bac1e2014-05-06 15:23:49 -04001034 RValue<Byte> operator^(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001035 {
1036 return RValue<Byte>(Nucleus::createXor(lhs.value, rhs.value));
1037 }
1038
John Bauman19bac1e2014-05-06 15:23:49 -04001039 RValue<Byte> operator<<(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001040 {
1041 return RValue<Byte>(Nucleus::createShl(lhs.value, rhs.value));
1042 }
1043
John Bauman19bac1e2014-05-06 15:23:49 -04001044 RValue<Byte> operator>>(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001045 {
1046 return RValue<Byte>(Nucleus::createLShr(lhs.value, rhs.value));
1047 }
1048
John Bauman19bac1e2014-05-06 15:23:49 -04001049 RValue<Byte> operator+=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001050 {
1051 return lhs = lhs + rhs;
1052 }
1053
John Bauman19bac1e2014-05-06 15:23:49 -04001054 RValue<Byte> operator-=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001055 {
1056 return lhs = lhs - rhs;
1057 }
1058
John Bauman19bac1e2014-05-06 15:23:49 -04001059 RValue<Byte> operator*=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001060 {
1061 return lhs = lhs * rhs;
1062 }
1063
John Bauman19bac1e2014-05-06 15:23:49 -04001064 RValue<Byte> operator/=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001065 {
1066 return lhs = lhs / rhs;
1067 }
1068
John Bauman19bac1e2014-05-06 15:23:49 -04001069 RValue<Byte> operator%=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001070 {
1071 return lhs = lhs % rhs;
1072 }
1073
John Bauman19bac1e2014-05-06 15:23:49 -04001074 RValue<Byte> operator&=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001075 {
1076 return lhs = lhs & rhs;
1077 }
1078
John Bauman19bac1e2014-05-06 15:23:49 -04001079 RValue<Byte> operator|=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001080 {
1081 return lhs = lhs | rhs;
1082 }
1083
John Bauman19bac1e2014-05-06 15:23:49 -04001084 RValue<Byte> operator^=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001085 {
1086 return lhs = lhs ^ rhs;
1087 }
1088
John Bauman19bac1e2014-05-06 15:23:49 -04001089 RValue<Byte> operator<<=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001090 {
1091 return lhs = lhs << rhs;
1092 }
1093
John Bauman19bac1e2014-05-06 15:23:49 -04001094 RValue<Byte> operator>>=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001095 {
1096 return lhs = lhs >> rhs;
1097 }
1098
John Bauman19bac1e2014-05-06 15:23:49 -04001099 RValue<Byte> operator+(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001100 {
1101 return val;
1102 }
1103
John Bauman19bac1e2014-05-06 15:23:49 -04001104 RValue<Byte> operator-(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001105 {
1106 return RValue<Byte>(Nucleus::createNeg(val.value));
1107 }
1108
John Bauman19bac1e2014-05-06 15:23:49 -04001109 RValue<Byte> operator~(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001110 {
1111 return RValue<Byte>(Nucleus::createNot(val.value));
1112 }
1113
1114 RValue<Byte> operator++(const Byte &val, int) // Post-increment
1115 {
1116 RValue<Byte> res = val;
1117
Nicolas Capens19336542016-09-26 10:32:29 -04001118 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantByte((unsigned char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001119 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001120
1121 return res;
1122 }
1123
1124 const Byte &operator++(const Byte &val) // Pre-increment
1125 {
Nicolas Capens19336542016-09-26 10:32:29 -04001126 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantByte((unsigned char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001127 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001128
1129 return val;
1130 }
1131
1132 RValue<Byte> operator--(const Byte &val, int) // Post-decrement
1133 {
1134 RValue<Byte> res = val;
1135
Nicolas Capens19336542016-09-26 10:32:29 -04001136 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantByte((unsigned char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001137 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001138
1139 return res;
1140 }
1141
1142 const Byte &operator--(const Byte &val) // Pre-decrement
1143 {
Nicolas Capens19336542016-09-26 10:32:29 -04001144 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantByte((unsigned char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001145 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001146
1147 return val;
1148 }
1149
John Bauman19bac1e2014-05-06 15:23:49 -04001150 RValue<Bool> operator<(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001151 {
1152 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1153 }
1154
John Bauman19bac1e2014-05-06 15:23:49 -04001155 RValue<Bool> operator<=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001156 {
1157 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1158 }
1159
John Bauman19bac1e2014-05-06 15:23:49 -04001160 RValue<Bool> operator>(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001161 {
1162 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1163 }
1164
John Bauman19bac1e2014-05-06 15:23:49 -04001165 RValue<Bool> operator>=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001166 {
1167 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1168 }
1169
John Bauman19bac1e2014-05-06 15:23:49 -04001170 RValue<Bool> operator!=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001171 {
1172 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1173 }
1174
John Bauman19bac1e2014-05-06 15:23:49 -04001175 RValue<Bool> operator==(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001176 {
1177 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1178 }
1179
John Bauman19bac1e2014-05-06 15:23:49 -04001180 Type *Byte::getType()
John Bauman89401822014-05-06 15:04:28 -04001181 {
Nicolas Capensac230122016-09-20 14:30:06 -04001182 return T(llvm::Type::getInt8Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001183 }
1184
Nicolas Capens81f18302016-01-14 09:32:35 -05001185 SByte::SByte(Argument<SByte> argument)
John Bauman89401822014-05-06 15:04:28 -04001186 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001187 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001188 }
1189
Alexis Hetu77dfab42015-11-23 13:31:22 -05001190 SByte::SByte(RValue<Int> cast)
1191 {
1192 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1193
1194 storeValue(integer);
1195 }
1196
1197 SByte::SByte(RValue<Short> cast)
1198 {
1199 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1200
1201 storeValue(integer);
1202 }
1203
John Bauman89401822014-05-06 15:04:28 -04001204 SByte::SByte()
1205 {
John Bauman89401822014-05-06 15:04:28 -04001206 }
1207
1208 SByte::SByte(signed char x)
1209 {
John Bauman66b8ab22014-05-06 15:57:45 -04001210 storeValue(Nucleus::createConstantByte(x));
John Bauman89401822014-05-06 15:04:28 -04001211 }
1212
John Bauman19bac1e2014-05-06 15:23:49 -04001213 SByte::SByte(RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001214 {
John Bauman66b8ab22014-05-06 15:57:45 -04001215 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001216 }
1217
1218 SByte::SByte(const SByte &rhs)
1219 {
John Bauman66b8ab22014-05-06 15:57:45 -04001220 Value *value = rhs.loadValue();
1221 storeValue(value);
1222 }
John Bauman89401822014-05-06 15:04:28 -04001223
John Bauman66b8ab22014-05-06 15:57:45 -04001224 SByte::SByte(const Reference<SByte> &rhs)
1225 {
1226 Value *value = rhs.loadValue();
1227 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001228 }
1229
John Bauman19bac1e2014-05-06 15:23:49 -04001230 RValue<SByte> SByte::operator=(RValue<SByte> rhs) const
John Bauman89401822014-05-06 15:04:28 -04001231 {
John Bauman66b8ab22014-05-06 15:57:45 -04001232 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001233
1234 return rhs;
1235 }
1236
1237 RValue<SByte> SByte::operator=(const SByte &rhs) const
1238 {
John Bauman66b8ab22014-05-06 15:57:45 -04001239 Value *value = rhs.loadValue();
1240 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001241
1242 return RValue<SByte>(value);
1243 }
1244
John Bauman66b8ab22014-05-06 15:57:45 -04001245 RValue<SByte> SByte::operator=(const Reference<SByte> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04001246 {
John Bauman66b8ab22014-05-06 15:57:45 -04001247 Value *value = rhs.loadValue();
1248 storeValue(value);
1249
1250 return RValue<SByte>(value);
John Bauman89401822014-05-06 15:04:28 -04001251 }
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::createAdd(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::createSub(lhs.value, rhs.value));
1261 }
1262
John Bauman19bac1e2014-05-06 15:23:49 -04001263 RValue<SByte> operator*(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001264 {
1265 return RValue<SByte>(Nucleus::createMul(lhs.value, rhs.value));
1266 }
1267
John Bauman19bac1e2014-05-06 15:23:49 -04001268 RValue<SByte> operator/(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001269 {
1270 return RValue<SByte>(Nucleus::createSDiv(lhs.value, rhs.value));
1271 }
1272
John Bauman19bac1e2014-05-06 15:23:49 -04001273 RValue<SByte> operator%(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001274 {
1275 return RValue<SByte>(Nucleus::createSRem(lhs.value, rhs.value));
1276 }
1277
John Bauman19bac1e2014-05-06 15:23:49 -04001278 RValue<SByte> operator&(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001279 {
1280 return RValue<SByte>(Nucleus::createAnd(lhs.value, rhs.value));
1281 }
1282
John Bauman19bac1e2014-05-06 15:23:49 -04001283 RValue<SByte> operator|(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001284 {
1285 return RValue<SByte>(Nucleus::createOr(lhs.value, rhs.value));
1286 }
1287
John Bauman19bac1e2014-05-06 15:23:49 -04001288 RValue<SByte> operator^(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001289 {
1290 return RValue<SByte>(Nucleus::createXor(lhs.value, rhs.value));
1291 }
1292
John Bauman19bac1e2014-05-06 15:23:49 -04001293 RValue<SByte> operator<<(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001294 {
1295 return RValue<SByte>(Nucleus::createShl(lhs.value, rhs.value));
1296 }
1297
John Bauman19bac1e2014-05-06 15:23:49 -04001298 RValue<SByte> operator>>(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001299 {
1300 return RValue<SByte>(Nucleus::createAShr(lhs.value, rhs.value));
1301 }
1302
John Bauman19bac1e2014-05-06 15:23:49 -04001303 RValue<SByte> operator+=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001304 {
1305 return lhs = lhs + rhs;
1306 }
1307
John Bauman19bac1e2014-05-06 15:23:49 -04001308 RValue<SByte> operator-=(const 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*=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001314 {
1315 return lhs = lhs * rhs;
1316 }
1317
John Bauman19bac1e2014-05-06 15:23:49 -04001318 RValue<SByte> operator/=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001319 {
1320 return lhs = lhs / rhs;
1321 }
1322
John Bauman19bac1e2014-05-06 15:23:49 -04001323 RValue<SByte> operator%=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001324 {
1325 return lhs = lhs % rhs;
1326 }
1327
John Bauman19bac1e2014-05-06 15:23:49 -04001328 RValue<SByte> operator&=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001329 {
1330 return lhs = lhs & rhs;
1331 }
1332
John Bauman19bac1e2014-05-06 15:23:49 -04001333 RValue<SByte> operator|=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001334 {
1335 return lhs = lhs | rhs;
1336 }
1337
John Bauman19bac1e2014-05-06 15:23:49 -04001338 RValue<SByte> operator^=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001339 {
1340 return lhs = lhs ^ rhs;
1341 }
1342
John Bauman19bac1e2014-05-06 15:23:49 -04001343 RValue<SByte> operator<<=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001344 {
1345 return lhs = lhs << rhs;
1346 }
1347
John Bauman19bac1e2014-05-06 15:23:49 -04001348 RValue<SByte> operator>>=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001349 {
1350 return lhs = lhs >> rhs;
1351 }
1352
John Bauman19bac1e2014-05-06 15:23:49 -04001353 RValue<SByte> operator+(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001354 {
1355 return val;
1356 }
1357
John Bauman19bac1e2014-05-06 15:23:49 -04001358 RValue<SByte> operator-(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001359 {
1360 return RValue<SByte>(Nucleus::createNeg(val.value));
1361 }
1362
John Bauman19bac1e2014-05-06 15:23:49 -04001363 RValue<SByte> operator~(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001364 {
1365 return RValue<SByte>(Nucleus::createNot(val.value));
1366 }
1367
1368 RValue<SByte> operator++(const SByte &val, int) // Post-increment
1369 {
1370 RValue<SByte> res = val;
1371
Nicolas Capens19336542016-09-26 10:32:29 -04001372 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantByte((signed char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001373 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001374
1375 return res;
1376 }
1377
1378 const SByte &operator++(const SByte &val) // Pre-increment
1379 {
Nicolas Capens19336542016-09-26 10:32:29 -04001380 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantByte((signed char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001381 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001382
1383 return val;
1384 }
1385
1386 RValue<SByte> operator--(const SByte &val, int) // Post-decrement
1387 {
1388 RValue<SByte> res = val;
1389
Nicolas Capens19336542016-09-26 10:32:29 -04001390 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantByte((signed char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001391 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001392
1393 return res;
1394 }
1395
1396 const SByte &operator--(const SByte &val) // Pre-decrement
1397 {
Nicolas Capens19336542016-09-26 10:32:29 -04001398 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantByte((signed char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001399 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001400
1401 return val;
1402 }
1403
John Bauman19bac1e2014-05-06 15:23:49 -04001404 RValue<Bool> operator<(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001405 {
1406 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
1407 }
1408
John Bauman19bac1e2014-05-06 15:23:49 -04001409 RValue<Bool> operator<=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001410 {
1411 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
1412 }
1413
John Bauman19bac1e2014-05-06 15:23:49 -04001414 RValue<Bool> operator>(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001415 {
1416 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
1417 }
1418
John Bauman19bac1e2014-05-06 15:23:49 -04001419 RValue<Bool> operator>=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001420 {
1421 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
1422 }
1423
John Bauman19bac1e2014-05-06 15:23:49 -04001424 RValue<Bool> operator!=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001425 {
1426 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1427 }
1428
John Bauman19bac1e2014-05-06 15:23:49 -04001429 RValue<Bool> operator==(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001430 {
1431 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1432 }
1433
John Bauman19bac1e2014-05-06 15:23:49 -04001434 Type *SByte::getType()
John Bauman89401822014-05-06 15:04:28 -04001435 {
Nicolas Capensac230122016-09-20 14:30:06 -04001436 return T(llvm::Type::getInt8Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001437 }
1438
Nicolas Capens81f18302016-01-14 09:32:35 -05001439 Short::Short(Argument<Short> argument)
John Bauman89401822014-05-06 15:04:28 -04001440 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001441 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001442 }
1443
John Bauman19bac1e2014-05-06 15:23:49 -04001444 Short::Short(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04001445 {
John Bauman89401822014-05-06 15:04:28 -04001446 Value *integer = Nucleus::createTrunc(cast.value, Short::getType());
1447
John Bauman66b8ab22014-05-06 15:57:45 -04001448 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04001449 }
1450
1451 Short::Short()
1452 {
John Bauman89401822014-05-06 15:04:28 -04001453 }
1454
1455 Short::Short(short x)
1456 {
John Bauman66b8ab22014-05-06 15:57:45 -04001457 storeValue(Nucleus::createConstantShort(x));
John Bauman89401822014-05-06 15:04:28 -04001458 }
1459
John Bauman19bac1e2014-05-06 15:23:49 -04001460 Short::Short(RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001461 {
John Bauman66b8ab22014-05-06 15:57:45 -04001462 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001463 }
1464
1465 Short::Short(const Short &rhs)
1466 {
John Bauman66b8ab22014-05-06 15:57:45 -04001467 Value *value = rhs.loadValue();
1468 storeValue(value);
1469 }
John Bauman89401822014-05-06 15:04:28 -04001470
John Bauman66b8ab22014-05-06 15:57:45 -04001471 Short::Short(const Reference<Short> &rhs)
1472 {
1473 Value *value = rhs.loadValue();
1474 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001475 }
1476
John Bauman19bac1e2014-05-06 15:23:49 -04001477 RValue<Short> Short::operator=(RValue<Short> rhs) const
John Bauman89401822014-05-06 15:04:28 -04001478 {
John Bauman66b8ab22014-05-06 15:57:45 -04001479 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001480
1481 return rhs;
1482 }
1483
1484 RValue<Short> Short::operator=(const Short &rhs) const
1485 {
John Bauman66b8ab22014-05-06 15:57:45 -04001486 Value *value = rhs.loadValue();
1487 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001488
1489 return RValue<Short>(value);
1490 }
1491
John Bauman66b8ab22014-05-06 15:57:45 -04001492 RValue<Short> Short::operator=(const Reference<Short> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04001493 {
John Bauman66b8ab22014-05-06 15:57:45 -04001494 Value *value = rhs.loadValue();
1495 storeValue(value);
1496
1497 return RValue<Short>(value);
John Bauman89401822014-05-06 15:04:28 -04001498 }
1499
John Bauman19bac1e2014-05-06 15:23:49 -04001500 RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001501 {
1502 return RValue<Short>(Nucleus::createAdd(lhs.value, rhs.value));
1503 }
1504
John Bauman19bac1e2014-05-06 15:23:49 -04001505 RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001506 {
1507 return RValue<Short>(Nucleus::createSub(lhs.value, rhs.value));
1508 }
1509
John Bauman19bac1e2014-05-06 15:23:49 -04001510 RValue<Short> operator*(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001511 {
1512 return RValue<Short>(Nucleus::createMul(lhs.value, rhs.value));
1513 }
1514
John Bauman19bac1e2014-05-06 15:23:49 -04001515 RValue<Short> operator/(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001516 {
1517 return RValue<Short>(Nucleus::createSDiv(lhs.value, rhs.value));
1518 }
1519
John Bauman19bac1e2014-05-06 15:23:49 -04001520 RValue<Short> operator%(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001521 {
1522 return RValue<Short>(Nucleus::createSRem(lhs.value, rhs.value));
1523 }
1524
John Bauman19bac1e2014-05-06 15:23:49 -04001525 RValue<Short> operator&(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001526 {
1527 return RValue<Short>(Nucleus::createAnd(lhs.value, rhs.value));
1528 }
1529
John Bauman19bac1e2014-05-06 15:23:49 -04001530 RValue<Short> operator|(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001531 {
1532 return RValue<Short>(Nucleus::createOr(lhs.value, rhs.value));
1533 }
1534
John Bauman19bac1e2014-05-06 15:23:49 -04001535 RValue<Short> operator^(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001536 {
1537 return RValue<Short>(Nucleus::createXor(lhs.value, rhs.value));
1538 }
1539
John Bauman19bac1e2014-05-06 15:23:49 -04001540 RValue<Short> operator<<(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001541 {
1542 return RValue<Short>(Nucleus::createShl(lhs.value, rhs.value));
1543 }
1544
John Bauman19bac1e2014-05-06 15:23:49 -04001545 RValue<Short> operator>>(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001546 {
1547 return RValue<Short>(Nucleus::createAShr(lhs.value, rhs.value));
1548 }
1549
John Bauman19bac1e2014-05-06 15:23:49 -04001550 RValue<Short> operator+=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001551 {
1552 return lhs = lhs + rhs;
1553 }
1554
John Bauman19bac1e2014-05-06 15:23:49 -04001555 RValue<Short> operator-=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001556 {
1557 return lhs = lhs - rhs;
1558 }
1559
John Bauman19bac1e2014-05-06 15:23:49 -04001560 RValue<Short> operator*=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001561 {
1562 return lhs = lhs * rhs;
1563 }
1564
John Bauman19bac1e2014-05-06 15:23:49 -04001565 RValue<Short> operator/=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001566 {
1567 return lhs = lhs / rhs;
1568 }
1569
John Bauman19bac1e2014-05-06 15:23:49 -04001570 RValue<Short> operator%=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001571 {
1572 return lhs = lhs % rhs;
1573 }
1574
John Bauman19bac1e2014-05-06 15:23:49 -04001575 RValue<Short> operator&=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001576 {
1577 return lhs = lhs & rhs;
1578 }
1579
John Bauman19bac1e2014-05-06 15:23:49 -04001580 RValue<Short> operator|=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001581 {
1582 return lhs = lhs | rhs;
1583 }
1584
John Bauman19bac1e2014-05-06 15:23:49 -04001585 RValue<Short> operator^=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001586 {
1587 return lhs = lhs ^ rhs;
1588 }
1589
John Bauman19bac1e2014-05-06 15:23:49 -04001590 RValue<Short> operator<<=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001591 {
1592 return lhs = lhs << rhs;
1593 }
1594
John Bauman19bac1e2014-05-06 15:23:49 -04001595 RValue<Short> operator>>=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001596 {
1597 return lhs = lhs >> rhs;
1598 }
1599
John Bauman19bac1e2014-05-06 15:23:49 -04001600 RValue<Short> operator+(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001601 {
1602 return val;
1603 }
1604
John Bauman19bac1e2014-05-06 15:23:49 -04001605 RValue<Short> operator-(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001606 {
1607 return RValue<Short>(Nucleus::createNeg(val.value));
1608 }
1609
John Bauman19bac1e2014-05-06 15:23:49 -04001610 RValue<Short> operator~(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001611 {
1612 return RValue<Short>(Nucleus::createNot(val.value));
1613 }
1614
1615 RValue<Short> operator++(const Short &val, int) // Post-increment
1616 {
1617 RValue<Short> res = val;
1618
Nicolas Capens19336542016-09-26 10:32:29 -04001619 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantShort((short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001620 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001621
1622 return res;
1623 }
1624
1625 const Short &operator++(const Short &val) // Pre-increment
1626 {
Nicolas Capens19336542016-09-26 10:32:29 -04001627 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantShort((short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001628 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001629
1630 return val;
1631 }
1632
1633 RValue<Short> operator--(const Short &val, int) // Post-decrement
1634 {
1635 RValue<Short> res = val;
1636
Nicolas Capens19336542016-09-26 10:32:29 -04001637 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantShort((short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001638 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001639
1640 return res;
1641 }
1642
1643 const Short &operator--(const Short &val) // Pre-decrement
1644 {
Nicolas Capens19336542016-09-26 10:32:29 -04001645 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantShort((short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001646 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001647
1648 return val;
1649 }
1650
John Bauman19bac1e2014-05-06 15:23:49 -04001651 RValue<Bool> operator<(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001652 {
1653 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
1654 }
1655
John Bauman19bac1e2014-05-06 15:23:49 -04001656 RValue<Bool> operator<=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001657 {
1658 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
1659 }
1660
John Bauman19bac1e2014-05-06 15:23:49 -04001661 RValue<Bool> operator>(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001662 {
1663 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
1664 }
1665
John Bauman19bac1e2014-05-06 15:23:49 -04001666 RValue<Bool> operator>=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001667 {
1668 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
1669 }
1670
John Bauman19bac1e2014-05-06 15:23:49 -04001671 RValue<Bool> operator!=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001672 {
1673 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1674 }
1675
John Bauman19bac1e2014-05-06 15:23:49 -04001676 RValue<Bool> operator==(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001677 {
1678 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1679 }
1680
John Bauman19bac1e2014-05-06 15:23:49 -04001681 Type *Short::getType()
John Bauman89401822014-05-06 15:04:28 -04001682 {
Nicolas Capensac230122016-09-20 14:30:06 -04001683 return T(llvm::Type::getInt16Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001684 }
1685
Nicolas Capens81f18302016-01-14 09:32:35 -05001686 UShort::UShort(Argument<UShort> argument)
John Bauman89401822014-05-06 15:04:28 -04001687 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001688 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001689 }
1690
Alexis Hetu77dfab42015-11-23 13:31:22 -05001691 UShort::UShort(RValue<UInt> cast)
1692 {
1693 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
1694
1695 storeValue(integer);
1696 }
1697
Alexis Hetu75b650f2015-11-19 17:40:15 -05001698 UShort::UShort(RValue<Int> cast)
1699 {
1700 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
1701
1702 storeValue(integer);
1703 }
1704
John Bauman89401822014-05-06 15:04:28 -04001705 UShort::UShort()
1706 {
John Bauman89401822014-05-06 15:04:28 -04001707 }
1708
1709 UShort::UShort(unsigned short x)
1710 {
John Bauman66b8ab22014-05-06 15:57:45 -04001711 storeValue(Nucleus::createConstantShort(x));
John Bauman89401822014-05-06 15:04:28 -04001712 }
1713
John Bauman19bac1e2014-05-06 15:23:49 -04001714 UShort::UShort(RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001715 {
John Bauman66b8ab22014-05-06 15:57:45 -04001716 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001717 }
1718
1719 UShort::UShort(const UShort &rhs)
1720 {
John Bauman66b8ab22014-05-06 15:57:45 -04001721 Value *value = rhs.loadValue();
1722 storeValue(value);
1723 }
John Bauman89401822014-05-06 15:04:28 -04001724
John Bauman66b8ab22014-05-06 15:57:45 -04001725 UShort::UShort(const Reference<UShort> &rhs)
1726 {
1727 Value *value = rhs.loadValue();
1728 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001729 }
1730
John Bauman19bac1e2014-05-06 15:23:49 -04001731 RValue<UShort> UShort::operator=(RValue<UShort> rhs) const
John Bauman89401822014-05-06 15:04:28 -04001732 {
John Bauman66b8ab22014-05-06 15:57:45 -04001733 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001734
1735 return rhs;
1736 }
1737
1738 RValue<UShort> UShort::operator=(const UShort &rhs) const
1739 {
John Bauman66b8ab22014-05-06 15:57:45 -04001740 Value *value = rhs.loadValue();
1741 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001742
1743 return RValue<UShort>(value);
1744 }
1745
John Bauman66b8ab22014-05-06 15:57:45 -04001746 RValue<UShort> UShort::operator=(const Reference<UShort> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04001747 {
John Bauman66b8ab22014-05-06 15:57:45 -04001748 Value *value = rhs.loadValue();
1749 storeValue(value);
1750
1751 return RValue<UShort>(value);
John Bauman89401822014-05-06 15:04:28 -04001752 }
1753
John Bauman19bac1e2014-05-06 15:23:49 -04001754 RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001755 {
1756 return RValue<UShort>(Nucleus::createAdd(lhs.value, rhs.value));
1757 }
1758
John Bauman19bac1e2014-05-06 15:23:49 -04001759 RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001760 {
1761 return RValue<UShort>(Nucleus::createSub(lhs.value, rhs.value));
1762 }
1763
John Bauman19bac1e2014-05-06 15:23:49 -04001764 RValue<UShort> operator*(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001765 {
1766 return RValue<UShort>(Nucleus::createMul(lhs.value, rhs.value));
1767 }
1768
John Bauman19bac1e2014-05-06 15:23:49 -04001769 RValue<UShort> operator/(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001770 {
1771 return RValue<UShort>(Nucleus::createUDiv(lhs.value, rhs.value));
1772 }
1773
John Bauman19bac1e2014-05-06 15:23:49 -04001774 RValue<UShort> operator%(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001775 {
1776 return RValue<UShort>(Nucleus::createURem(lhs.value, rhs.value));
1777 }
1778
John Bauman19bac1e2014-05-06 15:23:49 -04001779 RValue<UShort> operator&(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001780 {
1781 return RValue<UShort>(Nucleus::createAnd(lhs.value, rhs.value));
1782 }
1783
John Bauman19bac1e2014-05-06 15:23:49 -04001784 RValue<UShort> operator|(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001785 {
1786 return RValue<UShort>(Nucleus::createOr(lhs.value, rhs.value));
1787 }
1788
John Bauman19bac1e2014-05-06 15:23:49 -04001789 RValue<UShort> operator^(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001790 {
1791 return RValue<UShort>(Nucleus::createXor(lhs.value, rhs.value));
1792 }
1793
John Bauman19bac1e2014-05-06 15:23:49 -04001794 RValue<UShort> operator<<(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001795 {
1796 return RValue<UShort>(Nucleus::createShl(lhs.value, rhs.value));
1797 }
1798
John Bauman19bac1e2014-05-06 15:23:49 -04001799 RValue<UShort> operator>>(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001800 {
1801 return RValue<UShort>(Nucleus::createLShr(lhs.value, rhs.value));
1802 }
1803
John Bauman19bac1e2014-05-06 15:23:49 -04001804 RValue<UShort> operator+=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001805 {
1806 return lhs = lhs + rhs;
1807 }
1808
John Bauman19bac1e2014-05-06 15:23:49 -04001809 RValue<UShort> operator-=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001810 {
1811 return lhs = lhs - rhs;
1812 }
1813
John Bauman19bac1e2014-05-06 15:23:49 -04001814 RValue<UShort> operator*=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001815 {
1816 return lhs = lhs * rhs;
1817 }
1818
John Bauman19bac1e2014-05-06 15:23:49 -04001819 RValue<UShort> operator/=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001820 {
1821 return lhs = lhs / rhs;
1822 }
1823
John Bauman19bac1e2014-05-06 15:23:49 -04001824 RValue<UShort> operator%=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001825 {
1826 return lhs = lhs % rhs;
1827 }
1828
John Bauman19bac1e2014-05-06 15:23:49 -04001829 RValue<UShort> operator&=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001830 {
1831 return lhs = lhs & rhs;
1832 }
1833
John Bauman19bac1e2014-05-06 15:23:49 -04001834 RValue<UShort> operator|=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001835 {
1836 return lhs = lhs | rhs;
1837 }
1838
John Bauman19bac1e2014-05-06 15:23:49 -04001839 RValue<UShort> operator^=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001840 {
1841 return lhs = lhs ^ rhs;
1842 }
1843
John Bauman19bac1e2014-05-06 15:23:49 -04001844 RValue<UShort> operator<<=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001845 {
1846 return lhs = lhs << rhs;
1847 }
1848
John Bauman19bac1e2014-05-06 15:23:49 -04001849 RValue<UShort> operator>>=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001850 {
1851 return lhs = lhs >> rhs;
1852 }
1853
John Bauman19bac1e2014-05-06 15:23:49 -04001854 RValue<UShort> operator+(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001855 {
1856 return val;
1857 }
1858
John Bauman19bac1e2014-05-06 15:23:49 -04001859 RValue<UShort> operator-(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001860 {
1861 return RValue<UShort>(Nucleus::createNeg(val.value));
1862 }
1863
John Bauman19bac1e2014-05-06 15:23:49 -04001864 RValue<UShort> operator~(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001865 {
1866 return RValue<UShort>(Nucleus::createNot(val.value));
1867 }
1868
1869 RValue<UShort> operator++(const UShort &val, int) // Post-increment
1870 {
1871 RValue<UShort> res = val;
1872
Nicolas Capens19336542016-09-26 10:32:29 -04001873 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantShort((unsigned short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001874 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001875
1876 return res;
1877 }
1878
1879 const UShort &operator++(const UShort &val) // Pre-increment
1880 {
Nicolas Capens19336542016-09-26 10:32:29 -04001881 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantShort((unsigned short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001882 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001883
1884 return val;
1885 }
1886
1887 RValue<UShort> operator--(const UShort &val, int) // Post-decrement
1888 {
1889 RValue<UShort> res = val;
1890
Nicolas Capens19336542016-09-26 10:32:29 -04001891 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantShort((unsigned short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001892 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001893
1894 return res;
1895 }
1896
1897 const UShort &operator--(const UShort &val) // Pre-decrement
1898 {
Nicolas Capens19336542016-09-26 10:32:29 -04001899 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantShort((unsigned short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001900 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001901
1902 return val;
1903 }
1904
John Bauman19bac1e2014-05-06 15:23:49 -04001905 RValue<Bool> operator<(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001906 {
1907 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1908 }
1909
John Bauman19bac1e2014-05-06 15:23:49 -04001910 RValue<Bool> operator<=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001911 {
1912 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1913 }
1914
John Bauman19bac1e2014-05-06 15:23:49 -04001915 RValue<Bool> operator>(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001916 {
1917 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1918 }
1919
John Bauman19bac1e2014-05-06 15:23:49 -04001920 RValue<Bool> operator>=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001921 {
1922 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1923 }
1924
John Bauman19bac1e2014-05-06 15:23:49 -04001925 RValue<Bool> operator!=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001926 {
1927 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1928 }
1929
John Bauman19bac1e2014-05-06 15:23:49 -04001930 RValue<Bool> operator==(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001931 {
1932 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1933 }
1934
John Bauman19bac1e2014-05-06 15:23:49 -04001935 Type *UShort::getType()
John Bauman89401822014-05-06 15:04:28 -04001936 {
Nicolas Capensac230122016-09-20 14:30:06 -04001937 return T(llvm::Type::getInt16Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001938 }
1939
Nicolas Capens16b5f152016-10-13 13:39:01 -04001940 Byte4::Byte4(RValue<Byte8> cast)
1941 {
1942 // xyzw.parent = this;
1943
1944 storeValue(Nucleus::createTrunc(Nucleus::createBitCast(cast.value, Long::getType()), Int::getType()));
1945 }
1946
1947 Byte4::Byte4(const Reference<Byte4> &rhs)
1948 {
1949 // xyzw.parent = this;
1950
1951 Value *value = rhs.loadValue();
1952 storeValue(value);
1953 }
1954
John Bauman19bac1e2014-05-06 15:23:49 -04001955 Type *Byte4::getType()
John Bauman89401822014-05-06 15:04:28 -04001956 {
1957 #if 0
Nicolas Capensac230122016-09-20 14:30:06 -04001958 return T(VectorType::get(Byte::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04001959 #else
1960 return UInt::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
1961 #endif
1962 }
1963
John Bauman19bac1e2014-05-06 15:23:49 -04001964 Type *SByte4::getType()
John Bauman89401822014-05-06 15:04:28 -04001965 {
1966 #if 0
Nicolas Capensac230122016-09-20 14:30:06 -04001967 return T(VectorType::get(SByte::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04001968 #else
1969 return Int::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
1970 #endif
1971 }
1972
1973 Byte8::Byte8()
1974 {
1975 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04001976 }
1977
Nicolas Capens3bbc5e12016-09-27 10:49:52 -04001978 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 -04001979 {
1980 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04001981
Nicolas Capens13ac2322016-10-13 14:52:12 -04001982 int64_t constantVector[8] = {x0, x1, x2, x3, x4, x5, x6, x7};
1983 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(Byte::getType(), 8))));
John Bauman89401822014-05-06 15:04:28 -04001984
John Bauman66b8ab22014-05-06 15:57:45 -04001985 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04001986 }
1987
John Bauman19bac1e2014-05-06 15:23:49 -04001988 Byte8::Byte8(RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04001989 {
1990 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04001991
John Bauman66b8ab22014-05-06 15:57:45 -04001992 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001993 }
1994
1995 Byte8::Byte8(const Byte8 &rhs)
1996 {
1997 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04001998
John Bauman66b8ab22014-05-06 15:57:45 -04001999 Value *value = rhs.loadValue();
2000 storeValue(value);
2001 }
2002
2003 Byte8::Byte8(const Reference<Byte8> &rhs)
2004 {
2005 // xyzw.parent = this;
2006
2007 Value *value = rhs.loadValue();
2008 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002009 }
2010
John Bauman19bac1e2014-05-06 15:23:49 -04002011 RValue<Byte8> Byte8::operator=(RValue<Byte8> rhs) const
John Bauman89401822014-05-06 15:04:28 -04002012 {
John Bauman66b8ab22014-05-06 15:57:45 -04002013 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002014
2015 return rhs;
2016 }
2017
2018 RValue<Byte8> Byte8::operator=(const Byte8 &rhs) const
2019 {
John Bauman66b8ab22014-05-06 15:57:45 -04002020 Value *value = rhs.loadValue();
2021 storeValue(value);
2022
2023 return RValue<Byte8>(value);
2024 }
2025
2026 RValue<Byte8> Byte8::operator=(const Reference<Byte8> &rhs) const
2027 {
2028 Value *value = rhs.loadValue();
2029 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002030
2031 return RValue<Byte8>(value);
2032 }
2033
John Bauman19bac1e2014-05-06 15:23:49 -04002034 RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002035 {
John Bauman19bac1e2014-05-06 15:23:49 -04002036 if(CPUID::supportsMMX2())
2037 {
2038 return x86::paddb(lhs, rhs);
2039 }
2040 else
2041 {
2042 return RValue<Byte8>(Nucleus::createAdd(lhs.value, rhs.value));
2043 }
John Bauman89401822014-05-06 15:04:28 -04002044 }
2045
John Bauman19bac1e2014-05-06 15:23:49 -04002046 RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002047 {
John Bauman19bac1e2014-05-06 15:23:49 -04002048 if(CPUID::supportsMMX2())
2049 {
2050 return x86::psubb(lhs, rhs);
2051 }
2052 else
2053 {
2054 return RValue<Byte8>(Nucleus::createSub(lhs.value, rhs.value));
2055 }
John Bauman89401822014-05-06 15:04:28 -04002056 }
2057
John Bauman19bac1e2014-05-06 15:23:49 -04002058// RValue<Byte8> operator*(RValue<Byte8> lhs, RValue<Byte8> rhs)
2059// {
2060// return RValue<Byte8>(Nucleus::createMul(lhs.value, rhs.value));
2061// }
2062
2063// RValue<Byte8> operator/(RValue<Byte8> lhs, RValue<Byte8> rhs)
2064// {
2065// return RValue<Byte8>(Nucleus::createUDiv(lhs.value, rhs.value));
2066// }
2067
2068// RValue<Byte8> operator%(RValue<Byte8> lhs, RValue<Byte8> rhs)
2069// {
2070// return RValue<Byte8>(Nucleus::createURem(lhs.value, rhs.value));
2071// }
2072
2073 RValue<Byte8> operator&(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002074 {
John Bauman19bac1e2014-05-06 15:23:49 -04002075 if(CPUID::supportsMMX2())
2076 {
2077 return As<Byte8>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
2078 }
2079 else
2080 {
2081 return RValue<Byte8>(Nucleus::createAnd(lhs.value, rhs.value));
2082 }
John Bauman89401822014-05-06 15:04:28 -04002083 }
2084
John Bauman19bac1e2014-05-06 15:23:49 -04002085 RValue<Byte8> operator|(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002086 {
John Bauman19bac1e2014-05-06 15:23:49 -04002087 if(CPUID::supportsMMX2())
2088 {
2089 return As<Byte8>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
2090 }
2091 else
2092 {
2093 return RValue<Byte8>(Nucleus::createOr(lhs.value, rhs.value));
2094 }
John Bauman89401822014-05-06 15:04:28 -04002095 }
2096
John Bauman19bac1e2014-05-06 15:23:49 -04002097 RValue<Byte8> operator^(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002098 {
John Bauman19bac1e2014-05-06 15:23:49 -04002099 if(CPUID::supportsMMX2())
2100 {
2101 return As<Byte8>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
2102 }
2103 else
John Bauman66b8ab22014-05-06 15:57:45 -04002104 {
John Bauman19bac1e2014-05-06 15:23:49 -04002105 return RValue<Byte8>(Nucleus::createXor(lhs.value, rhs.value));
2106 }
John Bauman89401822014-05-06 15:04:28 -04002107 }
2108
John Bauman19bac1e2014-05-06 15:23:49 -04002109// RValue<Byte8> operator<<(RValue<Byte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002110// {
2111// return RValue<Byte8>(Nucleus::createShl(lhs.value, rhs.value));
2112// }
2113
John Bauman19bac1e2014-05-06 15:23:49 -04002114// RValue<Byte8> operator>>(RValue<Byte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002115// {
2116// return RValue<Byte8>(Nucleus::createLShr(lhs.value, rhs.value));
2117// }
2118
John Bauman19bac1e2014-05-06 15:23:49 -04002119 RValue<Byte8> operator+=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002120 {
2121 return lhs = lhs + rhs;
2122 }
2123
John Bauman19bac1e2014-05-06 15:23:49 -04002124 RValue<Byte8> operator-=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002125 {
2126 return lhs = lhs - rhs;
2127 }
2128
John Bauman19bac1e2014-05-06 15:23:49 -04002129// RValue<Byte8> operator*=(const Byte8 &lhs, RValue<Byte8> rhs)
2130// {
2131// return lhs = lhs * rhs;
2132// }
John Bauman89401822014-05-06 15:04:28 -04002133
John Bauman19bac1e2014-05-06 15:23:49 -04002134// RValue<Byte8> operator/=(const Byte8 &lhs, RValue<Byte8> rhs)
2135// {
2136// return lhs = lhs / rhs;
2137// }
John Bauman89401822014-05-06 15:04:28 -04002138
John Bauman19bac1e2014-05-06 15:23:49 -04002139// RValue<Byte8> operator%=(const Byte8 &lhs, RValue<Byte8> rhs)
2140// {
2141// return lhs = lhs % rhs;
2142// }
John Bauman89401822014-05-06 15:04:28 -04002143
John Bauman19bac1e2014-05-06 15:23:49 -04002144 RValue<Byte8> operator&=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002145 {
2146 return lhs = lhs & rhs;
2147 }
2148
John Bauman19bac1e2014-05-06 15:23:49 -04002149 RValue<Byte8> operator|=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002150 {
2151 return lhs = lhs | rhs;
2152 }
2153
John Bauman19bac1e2014-05-06 15:23:49 -04002154 RValue<Byte8> operator^=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002155 {
2156 return lhs = lhs ^ rhs;
2157 }
2158
John Bauman19bac1e2014-05-06 15:23:49 -04002159// RValue<Byte8> operator<<=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002160// {
2161// return lhs = lhs << rhs;
2162// }
2163
John Bauman19bac1e2014-05-06 15:23:49 -04002164// RValue<Byte8> operator>>=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002165// {
2166// return lhs = lhs >> rhs;
2167// }
2168
John Bauman19bac1e2014-05-06 15:23:49 -04002169// RValue<Byte8> operator+(RValue<Byte8> val)
2170// {
2171// return val;
2172// }
2173
2174// RValue<Byte8> operator-(RValue<Byte8> val)
2175// {
2176// return RValue<Byte8>(Nucleus::createNeg(val.value));
2177// }
2178
2179 RValue<Byte8> operator~(RValue<Byte8> val)
John Bauman89401822014-05-06 15:04:28 -04002180 {
John Bauman19bac1e2014-05-06 15:23:49 -04002181 if(CPUID::supportsMMX2())
2182 {
Nicolas Capens16b5f152016-10-13 13:39:01 -04002183 return val ^ Byte8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
John Bauman19bac1e2014-05-06 15:23:49 -04002184 }
2185 else
2186 {
2187 return RValue<Byte8>(Nucleus::createNot(val.value));
2188 }
John Bauman89401822014-05-06 15:04:28 -04002189 }
2190
John Bauman19bac1e2014-05-06 15:23:49 -04002191 RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002192 {
2193 return x86::paddusb(x, y);
2194 }
John Bauman66b8ab22014-05-06 15:57:45 -04002195
John Bauman19bac1e2014-05-06 15:23:49 -04002196 RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002197 {
2198 return x86::psubusb(x, y);
2199 }
2200
John Bauman19bac1e2014-05-06 15:23:49 -04002201 RValue<Short4> Unpack(RValue<Byte4> x)
John Bauman89401822014-05-06 15:04:28 -04002202 {
Nicolas Capens19336542016-09-26 10:32:29 -04002203 Value *int2 = Nucleus::createInsertElement(V(UndefValue::get(VectorType::get(Int::getType(), 2))), x.value, 0);
John Bauman19bac1e2014-05-06 15:23:49 -04002204 Value *byte8 = Nucleus::createBitCast(int2, Byte8::getType());
John Bauman89401822014-05-06 15:04:28 -04002205
John Bauman19bac1e2014-05-06 15:23:49 -04002206 return UnpackLow(RValue<Byte8>(byte8), RValue<Byte8>(byte8));
2207 }
John Bauman89401822014-05-06 15:04:28 -04002208
John Bauman19bac1e2014-05-06 15:23:49 -04002209 RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y)
2210 {
2211 if(CPUID::supportsMMX2())
2212 {
2213 return x86::punpcklbw(x, y);
2214 }
2215 else
2216 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002217 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11};
2218 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman19bac1e2014-05-06 15:23:49 -04002219
2220 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2221 }
John Bauman89401822014-05-06 15:04:28 -04002222 }
John Bauman66b8ab22014-05-06 15:57:45 -04002223
John Bauman19bac1e2014-05-06 15:23:49 -04002224 RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002225 {
John Bauman19bac1e2014-05-06 15:23:49 -04002226 if(CPUID::supportsMMX2())
2227 {
2228 return x86::punpckhbw(x, y);
2229 }
2230 else
2231 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002232 int shuffle[8] = {4, 12, 5, 13, 6, 14, 7, 15};
2233 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002234
John Bauman19bac1e2014-05-06 15:23:49 -04002235 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2236 }
John Bauman89401822014-05-06 15:04:28 -04002237 }
2238
John Bauman19bac1e2014-05-06 15:23:49 -04002239 RValue<Int> SignMask(RValue<Byte8> x)
John Bauman89401822014-05-06 15:04:28 -04002240 {
2241 return x86::pmovmskb(x);
2242 }
2243
John Bauman19bac1e2014-05-06 15:23:49 -04002244// RValue<Byte8> CmpGT(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002245// {
2246// return x86::pcmpgtb(x, y); // FIXME: Signedness
2247// }
John Bauman66b8ab22014-05-06 15:57:45 -04002248
John Bauman19bac1e2014-05-06 15:23:49 -04002249 RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002250 {
2251 return x86::pcmpeqb(x, y);
2252 }
2253
John Bauman19bac1e2014-05-06 15:23:49 -04002254 Type *Byte8::getType()
John Bauman89401822014-05-06 15:04:28 -04002255 {
John Bauman19bac1e2014-05-06 15:23:49 -04002256 if(CPUID::supportsMMX2())
2257 {
2258 return MMX::getType();
2259 }
2260 else
2261 {
Nicolas Capensac230122016-09-20 14:30:06 -04002262 return T(VectorType::get(Byte::getType(), 8));
John Bauman19bac1e2014-05-06 15:23:49 -04002263 }
John Bauman89401822014-05-06 15:04:28 -04002264 }
2265
2266 SByte8::SByte8()
2267 {
2268 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002269 }
2270
Nicolas Capens3bbc5e12016-09-27 10:49:52 -04002271 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 -04002272 {
2273 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002274
Nicolas Capens13ac2322016-10-13 14:52:12 -04002275 int64_t constantVector[8] = {x0, x1, x2, x3, x4, x5, x6, x7};
2276 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(SByte::getType(), 8))));
John Bauman89401822014-05-06 15:04:28 -04002277
John Bauman66b8ab22014-05-06 15:57:45 -04002278 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04002279 }
2280
John Bauman19bac1e2014-05-06 15:23:49 -04002281 SByte8::SByte8(RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002282 {
2283 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002284
John Bauman66b8ab22014-05-06 15:57:45 -04002285 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002286 }
2287
2288 SByte8::SByte8(const SByte8 &rhs)
2289 {
2290 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002291
John Bauman66b8ab22014-05-06 15:57:45 -04002292 Value *value = rhs.loadValue();
2293 storeValue(value);
2294 }
2295
2296 SByte8::SByte8(const Reference<SByte8> &rhs)
2297 {
2298 // xyzw.parent = this;
2299
2300 Value *value = rhs.loadValue();
2301 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002302 }
2303
John Bauman19bac1e2014-05-06 15:23:49 -04002304 RValue<SByte8> SByte8::operator=(RValue<SByte8> rhs) const
John Bauman89401822014-05-06 15:04:28 -04002305 {
John Bauman66b8ab22014-05-06 15:57:45 -04002306 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002307
2308 return rhs;
2309 }
2310
2311 RValue<SByte8> SByte8::operator=(const SByte8 &rhs) const
2312 {
John Bauman66b8ab22014-05-06 15:57:45 -04002313 Value *value = rhs.loadValue();
2314 storeValue(value);
2315
2316 return RValue<SByte8>(value);
2317 }
2318
2319 RValue<SByte8> SByte8::operator=(const Reference<SByte8> &rhs) const
2320 {
2321 Value *value = rhs.loadValue();
2322 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002323
2324 return RValue<SByte8>(value);
2325 }
2326
John Bauman19bac1e2014-05-06 15:23:49 -04002327 RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002328 {
John Bauman19bac1e2014-05-06 15:23:49 -04002329 if(CPUID::supportsMMX2())
2330 {
2331 return As<SByte8>(x86::paddb(As<Byte8>(lhs), As<Byte8>(rhs)));
2332 }
2333 else
2334 {
2335 return RValue<SByte8>(Nucleus::createAdd(lhs.value, rhs.value));
2336 }
John Bauman89401822014-05-06 15:04:28 -04002337 }
2338
John Bauman19bac1e2014-05-06 15:23:49 -04002339 RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002340 {
John Bauman19bac1e2014-05-06 15:23:49 -04002341 if(CPUID::supportsMMX2())
2342 {
2343 return As<SByte8>(x86::psubb(As<Byte8>(lhs), As<Byte8>(rhs)));
2344 }
2345 else
2346 {
2347 return RValue<SByte8>(Nucleus::createSub(lhs.value, rhs.value));
2348 }
John Bauman89401822014-05-06 15:04:28 -04002349 }
2350
John Bauman19bac1e2014-05-06 15:23:49 -04002351// RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs)
2352// {
2353// return RValue<SByte8>(Nucleus::createMul(lhs.value, rhs.value));
2354// }
John Bauman89401822014-05-06 15:04:28 -04002355
John Bauman19bac1e2014-05-06 15:23:49 -04002356// RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs)
2357// {
2358// return RValue<SByte8>(Nucleus::createSDiv(lhs.value, rhs.value));
2359// }
John Bauman89401822014-05-06 15:04:28 -04002360
John Bauman19bac1e2014-05-06 15:23:49 -04002361// RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs)
2362// {
2363// return RValue<SByte8>(Nucleus::createSRem(lhs.value, rhs.value));
2364// }
John Bauman89401822014-05-06 15:04:28 -04002365
John Bauman19bac1e2014-05-06 15:23:49 -04002366 RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002367 {
2368 return RValue<SByte8>(Nucleus::createAnd(lhs.value, rhs.value));
2369 }
2370
John Bauman19bac1e2014-05-06 15:23:49 -04002371 RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002372 {
2373 return RValue<SByte8>(Nucleus::createOr(lhs.value, rhs.value));
2374 }
2375
John Bauman19bac1e2014-05-06 15:23:49 -04002376 RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002377 {
2378 return RValue<SByte8>(Nucleus::createXor(lhs.value, rhs.value));
2379 }
2380
John Bauman19bac1e2014-05-06 15:23:49 -04002381// RValue<SByte8> operator<<(RValue<SByte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002382// {
2383// return RValue<SByte8>(Nucleus::createShl(lhs.value, rhs.value));
2384// }
2385
John Bauman19bac1e2014-05-06 15:23:49 -04002386// RValue<SByte8> operator>>(RValue<SByte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002387// {
2388// return RValue<SByte8>(Nucleus::createAShr(lhs.value, rhs.value));
2389// }
2390
John Bauman19bac1e2014-05-06 15:23:49 -04002391 RValue<SByte8> operator+=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002392 {
2393 return lhs = lhs + rhs;
2394 }
2395
John Bauman19bac1e2014-05-06 15:23:49 -04002396 RValue<SByte8> operator-=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002397 {
2398 return lhs = lhs - rhs;
2399 }
2400
John Bauman19bac1e2014-05-06 15:23:49 -04002401// RValue<SByte8> operator*=(const SByte8 &lhs, RValue<SByte8> rhs)
2402// {
2403// return lhs = lhs * rhs;
2404// }
John Bauman89401822014-05-06 15:04:28 -04002405
John Bauman19bac1e2014-05-06 15:23:49 -04002406// RValue<SByte8> operator/=(const SByte8 &lhs, RValue<SByte8> rhs)
2407// {
2408// return lhs = lhs / rhs;
2409// }
John Bauman89401822014-05-06 15:04:28 -04002410
John Bauman19bac1e2014-05-06 15:23:49 -04002411// RValue<SByte8> operator%=(const SByte8 &lhs, RValue<SByte8> rhs)
2412// {
2413// return lhs = lhs % rhs;
2414// }
John Bauman89401822014-05-06 15:04:28 -04002415
John Bauman19bac1e2014-05-06 15:23:49 -04002416 RValue<SByte8> operator&=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002417 {
2418 return lhs = lhs & rhs;
2419 }
2420
John Bauman19bac1e2014-05-06 15:23:49 -04002421 RValue<SByte8> operator|=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002422 {
2423 return lhs = lhs | rhs;
2424 }
2425
John Bauman19bac1e2014-05-06 15:23:49 -04002426 RValue<SByte8> operator^=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002427 {
2428 return lhs = lhs ^ rhs;
2429 }
2430
John Bauman19bac1e2014-05-06 15:23:49 -04002431// RValue<SByte8> operator<<=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002432// {
2433// return lhs = lhs << rhs;
2434// }
2435
John Bauman19bac1e2014-05-06 15:23:49 -04002436// RValue<SByte8> operator>>=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002437// {
2438// return lhs = lhs >> rhs;
2439// }
2440
John Bauman19bac1e2014-05-06 15:23:49 -04002441// RValue<SByte8> operator+(RValue<SByte8> val)
2442// {
2443// return val;
2444// }
2445
2446// RValue<SByte8> operator-(RValue<SByte8> val)
2447// {
2448// return RValue<SByte8>(Nucleus::createNeg(val.value));
2449// }
2450
2451 RValue<SByte8> operator~(RValue<SByte8> val)
John Bauman89401822014-05-06 15:04:28 -04002452 {
John Bauman19bac1e2014-05-06 15:23:49 -04002453 if(CPUID::supportsMMX2())
2454 {
Nicolas Capens16b5f152016-10-13 13:39:01 -04002455 return val ^ SByte8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
John Bauman19bac1e2014-05-06 15:23:49 -04002456 }
2457 else
2458 {
2459 return RValue<SByte8>(Nucleus::createNot(val.value));
2460 }
John Bauman89401822014-05-06 15:04:28 -04002461 }
2462
John Bauman19bac1e2014-05-06 15:23:49 -04002463 RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002464 {
2465 return x86::paddsb(x, y);
2466 }
John Bauman66b8ab22014-05-06 15:57:45 -04002467
John Bauman19bac1e2014-05-06 15:23:49 -04002468 RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002469 {
2470 return x86::psubsb(x, y);
2471 }
2472
John Bauman19bac1e2014-05-06 15:23:49 -04002473 RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002474 {
John Bauman19bac1e2014-05-06 15:23:49 -04002475 if(CPUID::supportsMMX2())
2476 {
2477 return As<Short4>(x86::punpcklbw(As<Byte8>(x), As<Byte8>(y)));
2478 }
2479 else
2480 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002481 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11};
2482 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002483
John Bauman19bac1e2014-05-06 15:23:49 -04002484 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2485 }
John Bauman89401822014-05-06 15:04:28 -04002486 }
John Bauman66b8ab22014-05-06 15:57:45 -04002487
John Bauman19bac1e2014-05-06 15:23:49 -04002488 RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002489 {
John Bauman19bac1e2014-05-06 15:23:49 -04002490 if(CPUID::supportsMMX2())
2491 {
2492 return As<Short4>(x86::punpckhbw(As<Byte8>(x), As<Byte8>(y)));
2493 }
2494 else
2495 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002496 int shuffle[8] = {4, 12, 5, 13, 6, 14, 7, 15};
2497 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002498
John Bauman19bac1e2014-05-06 15:23:49 -04002499 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2500 }
John Bauman89401822014-05-06 15:04:28 -04002501 }
2502
John Bauman19bac1e2014-05-06 15:23:49 -04002503 RValue<Int> SignMask(RValue<SByte8> x)
John Bauman89401822014-05-06 15:04:28 -04002504 {
2505 return x86::pmovmskb(As<Byte8>(x));
2506 }
2507
John Bauman19bac1e2014-05-06 15:23:49 -04002508 RValue<Byte8> CmpGT(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002509 {
2510 return x86::pcmpgtb(x, y);
2511 }
John Bauman66b8ab22014-05-06 15:57:45 -04002512
John Bauman19bac1e2014-05-06 15:23:49 -04002513 RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002514 {
2515 return x86::pcmpeqb(As<Byte8>(x), As<Byte8>(y));
2516 }
2517
John Bauman19bac1e2014-05-06 15:23:49 -04002518 Type *SByte8::getType()
John Bauman89401822014-05-06 15:04:28 -04002519 {
John Bauman19bac1e2014-05-06 15:23:49 -04002520 if(CPUID::supportsMMX2())
2521 {
2522 return MMX::getType();
2523 }
2524 else
2525 {
Nicolas Capensac230122016-09-20 14:30:06 -04002526 return T(VectorType::get(SByte::getType(), 8));
John Bauman19bac1e2014-05-06 15:23:49 -04002527 }
John Bauman89401822014-05-06 15:04:28 -04002528 }
2529
John Bauman19bac1e2014-05-06 15:23:49 -04002530 Byte16::Byte16(RValue<Byte16> rhs)
John Bauman89401822014-05-06 15:04:28 -04002531 {
2532 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002533
John Bauman66b8ab22014-05-06 15:57:45 -04002534 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002535 }
2536
2537 Byte16::Byte16(const Byte16 &rhs)
2538 {
2539 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002540
John Bauman66b8ab22014-05-06 15:57:45 -04002541 Value *value = rhs.loadValue();
2542 storeValue(value);
2543 }
2544
2545 Byte16::Byte16(const Reference<Byte16> &rhs)
2546 {
2547 // xyzw.parent = this;
2548
2549 Value *value = rhs.loadValue();
2550 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002551 }
2552
John Bauman19bac1e2014-05-06 15:23:49 -04002553 RValue<Byte16> Byte16::operator=(RValue<Byte16> rhs) const
John Bauman89401822014-05-06 15:04:28 -04002554 {
John Bauman66b8ab22014-05-06 15:57:45 -04002555 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002556
2557 return rhs;
2558 }
2559
2560 RValue<Byte16> Byte16::operator=(const Byte16 &rhs) const
2561 {
John Bauman66b8ab22014-05-06 15:57:45 -04002562 Value *value = rhs.loadValue();
2563 storeValue(value);
2564
2565 return RValue<Byte16>(value);
2566 }
2567
2568 RValue<Byte16> Byte16::operator=(const Reference<Byte16> &rhs) const
2569 {
2570 Value *value = rhs.loadValue();
2571 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002572
2573 return RValue<Byte16>(value);
2574 }
2575
John Bauman19bac1e2014-05-06 15:23:49 -04002576 Type *Byte16::getType()
John Bauman89401822014-05-06 15:04:28 -04002577 {
Nicolas Capensac230122016-09-20 14:30:06 -04002578 return T(VectorType::get(Byte::getType(), 16));
John Bauman89401822014-05-06 15:04:28 -04002579 }
2580
John Bauman19bac1e2014-05-06 15:23:49 -04002581 Type *SByte16::getType()
John Bauman89401822014-05-06 15:04:28 -04002582 {
Nicolas Capensac230122016-09-20 14:30:06 -04002583 return T( VectorType::get(SByte::getType(), 16));
John Bauman89401822014-05-06 15:04:28 -04002584 }
2585
Nicolas Capens16b5f152016-10-13 13:39:01 -04002586 Short2::Short2(RValue<Short4> cast)
2587 {
2588 storeValue(Nucleus::createTrunc(Nucleus::createBitCast(cast.value, Long::getType()), UInt::getType()));
2589 }
2590
2591 Type *Short2::getType()
2592 {
2593 #if 0
2594 return T(VectorType::get(Short::getType(), 2));
2595 #else
2596 return UInt::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
2597 #endif
2598 }
2599
2600 UShort2::UShort2(RValue<UShort4> cast)
2601 {
2602 storeValue(Nucleus::createTrunc(Nucleus::createBitCast(cast.value, Long::getType()), UInt::getType()));
2603 }
2604
2605 Type *UShort2::getType()
2606 {
2607 #if 0
2608 return T(VectorType::get(UShort::getType(), 2));
2609 #else
2610 return UInt::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
2611 #endif
2612 }
2613
John Bauman19bac1e2014-05-06 15:23:49 -04002614 Short4::Short4(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04002615 {
John Bauman89401822014-05-06 15:04:28 -04002616 Value *extend = Nucleus::createZExt(cast.value, Long::getType());
John Bauman19bac1e2014-05-06 15:23:49 -04002617 Value *swizzle = Swizzle(RValue<Short4>(extend), 0x00).value;
John Bauman66b8ab22014-05-06 15:57:45 -04002618
2619 storeValue(swizzle);
John Bauman89401822014-05-06 15:04:28 -04002620 }
2621
John Bauman19bac1e2014-05-06 15:23:49 -04002622 Short4::Short4(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04002623 {
John Bauman89401822014-05-06 15:04:28 -04002624 Value *short8 = Nucleus::createBitCast(cast.value, Short8::getType());
2625
2626 #if 0 // FIXME: Check codegen (pshuflw phshufhw pshufd)
2627 Constant *pack[8];
2628 pack[0] = Nucleus::createConstantInt(0);
2629 pack[1] = Nucleus::createConstantInt(2);
2630 pack[2] = Nucleus::createConstantInt(4);
2631 pack[3] = Nucleus::createConstantInt(6);
2632
2633 Value *short4 = Nucleus::createShuffleVector(short8, short8, Nucleus::createConstantVector(pack, 4));
2634 #else
2635 Value *packed;
2636
2637 // FIXME: Use Swizzle<Short8>
2638 if(!CPUID::supportsSSSE3())
2639 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002640 int pshuflw[8] = {0, 2, 0, 2, 4, 5, 6, 7};
2641 int pshufhw[8] = {0, 1, 2, 3, 4, 6, 4, 6};
John Bauman89401822014-05-06 15:04:28 -04002642
Nicolas Capense89cd582016-09-30 14:23:47 -04002643 Value *shuffle1 = Nucleus::createShuffleVector(short8, short8, pshuflw);
2644 Value *shuffle2 = Nucleus::createShuffleVector(shuffle1, shuffle1, pshufhw);
John Bauman89401822014-05-06 15:04:28 -04002645 Value *int4 = Nucleus::createBitCast(shuffle2, Int4::getType());
Nicolas Capense95d5342016-09-30 11:37:28 -04002646 packed = createSwizzle4(int4, 0x88);
John Bauman89401822014-05-06 15:04:28 -04002647 }
2648 else
2649 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002650 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 -04002651 Value *byte16 = Nucleus::createBitCast(cast.value, Byte16::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04002652 packed = Nucleus::createShuffleVector(byte16, byte16, pshufb);
John Bauman89401822014-05-06 15:04:28 -04002653 }
2654
2655 #if 0 // FIXME: No optimal instruction selection
Nicolas Capens22008782016-10-20 01:11:47 -04002656 Value *qword2 = Nucleus::createBitCast(packed, T(VectorType::get(Long::getType(), 2)));
John Bauman89401822014-05-06 15:04:28 -04002657 Value *element = Nucleus::createExtractElement(qword2, 0);
2658 Value *short4 = Nucleus::createBitCast(element, Short4::getType());
2659 #else // FIXME: Requires SSE
2660 Value *int2 = RValue<Int2>(Int2(RValue<Int4>(packed))).value;
2661 Value *short4 = Nucleus::createBitCast(int2, Short4::getType());
2662 #endif
2663 #endif
2664
John Bauman66b8ab22014-05-06 15:57:45 -04002665 storeValue(short4);
John Bauman89401822014-05-06 15:04:28 -04002666 }
2667
John Bauman19bac1e2014-05-06 15:23:49 -04002668// Short4::Short4(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04002669// {
2670// }
2671
John Bauman19bac1e2014-05-06 15:23:49 -04002672 Short4::Short4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04002673 {
John Bauman89401822014-05-06 15:04:28 -04002674 Int4 v4i32 = Int4(cast);
2675 v4i32 = As<Int4>(x86::packssdw(v4i32, v4i32));
John Bauman66b8ab22014-05-06 15:57:45 -04002676
2677 storeValue(As<Short4>(Int2(v4i32)).value);
John Bauman89401822014-05-06 15:04:28 -04002678 }
2679
2680 Short4::Short4()
2681 {
2682 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002683 }
2684
John Bauman19bac1e2014-05-06 15:23:49 -04002685 Short4::Short4(short xyzw)
2686 {
2687 // xyzw.parent = this;
John Bauman19bac1e2014-05-06 15:23:49 -04002688
Nicolas Capens13ac2322016-10-13 14:52:12 -04002689 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
2690 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(Short::getType(), 4))));
John Bauman19bac1e2014-05-06 15:23:49 -04002691
John Bauman66b8ab22014-05-06 15:57:45 -04002692 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman19bac1e2014-05-06 15:23:49 -04002693 }
2694
John Bauman89401822014-05-06 15:04:28 -04002695 Short4::Short4(short x, short y, short z, short w)
2696 {
2697 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002698
Nicolas Capens13ac2322016-10-13 14:52:12 -04002699 int64_t constantVector[4] = {x, y, z, w};
2700 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(Short::getType(), 4))));
John Bauman19bac1e2014-05-06 15:23:49 -04002701
John Bauman66b8ab22014-05-06 15:57:45 -04002702 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04002703 }
2704
John Bauman19bac1e2014-05-06 15:23:49 -04002705 Short4::Short4(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002706 {
2707 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002708
John Bauman66b8ab22014-05-06 15:57:45 -04002709 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002710 }
2711
2712 Short4::Short4(const Short4 &rhs)
2713 {
2714 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002715
John Bauman66b8ab22014-05-06 15:57:45 -04002716 Value *value = rhs.loadValue();
2717 storeValue(value);
2718 }
2719
2720 Short4::Short4(const Reference<Short4> &rhs)
2721 {
2722 // xyzw.parent = this;
2723
2724 Value *value = rhs.loadValue();
2725 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002726 }
2727
John Bauman19bac1e2014-05-06 15:23:49 -04002728 Short4::Short4(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002729 {
2730 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002731
John Bauman66b8ab22014-05-06 15:57:45 -04002732 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002733 }
2734
2735 Short4::Short4(const UShort4 &rhs)
2736 {
2737 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002738
John Bauman66b8ab22014-05-06 15:57:45 -04002739 storeValue(rhs.loadValue());
2740 }
2741
2742 Short4::Short4(const Reference<UShort4> &rhs)
2743 {
2744 // xyzw.parent = this;
2745
2746 storeValue(rhs.loadValue());
John Bauman89401822014-05-06 15:04:28 -04002747 }
2748
John Bauman19bac1e2014-05-06 15:23:49 -04002749 RValue<Short4> Short4::operator=(RValue<Short4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04002750 {
John Bauman66b8ab22014-05-06 15:57:45 -04002751 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002752
2753 return rhs;
2754 }
2755
2756 RValue<Short4> Short4::operator=(const Short4 &rhs) const
2757 {
John Bauman66b8ab22014-05-06 15:57:45 -04002758 Value *value = rhs.loadValue();
2759 storeValue(value);
2760
2761 return RValue<Short4>(value);
2762 }
2763
2764 RValue<Short4> Short4::operator=(const Reference<Short4> &rhs) const
2765 {
2766 Value *value = rhs.loadValue();
2767 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002768
2769 return RValue<Short4>(value);
2770 }
2771
John Bauman19bac1e2014-05-06 15:23:49 -04002772 RValue<Short4> Short4::operator=(RValue<UShort4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04002773 {
John Bauman66b8ab22014-05-06 15:57:45 -04002774 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002775
John Bauman66b8ab22014-05-06 15:57:45 -04002776 return RValue<Short4>(rhs);
John Bauman89401822014-05-06 15:04:28 -04002777 }
2778
2779 RValue<Short4> Short4::operator=(const UShort4 &rhs) const
2780 {
John Bauman66b8ab22014-05-06 15:57:45 -04002781 Value *value = rhs.loadValue();
2782 storeValue(value);
2783
2784 return RValue<Short4>(value);
2785 }
2786
2787 RValue<Short4> Short4::operator=(const Reference<UShort4> &rhs) const
2788 {
2789 Value *value = rhs.loadValue();
2790 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002791
2792 return RValue<Short4>(value);
2793 }
2794
John Bauman19bac1e2014-05-06 15:23:49 -04002795 RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002796 {
John Bauman19bac1e2014-05-06 15:23:49 -04002797 if(CPUID::supportsMMX2())
2798 {
2799 return x86::paddw(lhs, rhs);
2800 }
2801 else
2802 {
2803 return RValue<Short4>(Nucleus::createAdd(lhs.value, rhs.value));
2804 }
John Bauman89401822014-05-06 15:04:28 -04002805 }
2806
John Bauman19bac1e2014-05-06 15:23:49 -04002807 RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002808 {
John Bauman19bac1e2014-05-06 15:23:49 -04002809 if(CPUID::supportsMMX2())
2810 {
2811 return x86::psubw(lhs, rhs);
2812 }
2813 else
2814 {
2815 return RValue<Short4>(Nucleus::createSub(lhs.value, rhs.value));
2816 }
John Bauman89401822014-05-06 15:04:28 -04002817 }
2818
John Bauman19bac1e2014-05-06 15:23:49 -04002819 RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002820 {
John Bauman19bac1e2014-05-06 15:23:49 -04002821 if(CPUID::supportsMMX2())
2822 {
2823 return x86::pmullw(lhs, rhs);
2824 }
2825 else
2826 {
2827 return RValue<Short4>(Nucleus::createMul(lhs.value, rhs.value));
2828 }
John Bauman89401822014-05-06 15:04:28 -04002829 }
2830
John Bauman19bac1e2014-05-06 15:23:49 -04002831// RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs)
2832// {
2833// return RValue<Short4>(Nucleus::createSDiv(lhs.value, rhs.value));
2834// }
2835
2836// RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs)
2837// {
2838// return RValue<Short4>(Nucleus::createSRem(lhs.value, rhs.value));
2839// }
2840
2841 RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002842 {
John Bauman19bac1e2014-05-06 15:23:49 -04002843 if(CPUID::supportsMMX2())
2844 {
2845 return x86::pand(lhs, rhs);
2846 }
2847 else
2848 {
2849 return RValue<Short4>(Nucleus::createAnd(lhs.value, rhs.value));
2850 }
John Bauman89401822014-05-06 15:04:28 -04002851 }
2852
John Bauman19bac1e2014-05-06 15:23:49 -04002853 RValue<Short4> operator|(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002854 {
John Bauman19bac1e2014-05-06 15:23:49 -04002855 if(CPUID::supportsMMX2())
2856 {
2857 return x86::por(lhs, rhs);
2858 }
2859 else
2860 {
2861 return RValue<Short4>(Nucleus::createOr(lhs.value, rhs.value));
2862 }
John Bauman89401822014-05-06 15:04:28 -04002863 }
2864
John Bauman19bac1e2014-05-06 15:23:49 -04002865 RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002866 {
John Bauman19bac1e2014-05-06 15:23:49 -04002867 if(CPUID::supportsMMX2())
2868 {
2869 return x86::pxor(lhs, rhs);
2870 }
2871 else
2872 {
2873 return RValue<Short4>(Nucleus::createXor(lhs.value, rhs.value));
2874 }
John Bauman89401822014-05-06 15:04:28 -04002875 }
2876
John Bauman19bac1e2014-05-06 15:23:49 -04002877 RValue<Short4> operator<<(RValue<Short4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002878 {
2879 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
2880
2881 return x86::psllw(lhs, rhs);
2882 }
2883
John Bauman19bac1e2014-05-06 15:23:49 -04002884 RValue<Short4> operator>>(RValue<Short4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002885 {
2886 // return RValue<Short4>(Nucleus::createAShr(lhs.value, rhs.value));
2887
2888 return x86::psraw(lhs, rhs);
2889 }
2890
John Bauman19bac1e2014-05-06 15:23:49 -04002891 RValue<Short4> operator<<(RValue<Short4> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04002892 {
2893 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
2894
2895 return x86::psllw(lhs, rhs);
2896 }
2897
John Bauman19bac1e2014-05-06 15:23:49 -04002898 RValue<Short4> operator>>(RValue<Short4> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04002899 {
2900 // return RValue<Short4>(Nucleus::createAShr(lhs.value, rhs.value));
2901
2902 return x86::psraw(lhs, rhs);
2903 }
2904
John Bauman19bac1e2014-05-06 15:23:49 -04002905 RValue<Short4> operator+=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002906 {
2907 return lhs = lhs + rhs;
2908 }
2909
John Bauman19bac1e2014-05-06 15:23:49 -04002910 RValue<Short4> operator-=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002911 {
2912 return lhs = lhs - rhs;
2913 }
2914
John Bauman19bac1e2014-05-06 15:23:49 -04002915 RValue<Short4> operator*=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002916 {
2917 return lhs = lhs * rhs;
2918 }
2919
John Bauman19bac1e2014-05-06 15:23:49 -04002920// RValue<Short4> operator/=(const Short4 &lhs, RValue<Short4> rhs)
2921// {
2922// return lhs = lhs / rhs;
2923// }
John Bauman89401822014-05-06 15:04:28 -04002924
John Bauman19bac1e2014-05-06 15:23:49 -04002925// RValue<Short4> operator%=(const Short4 &lhs, RValue<Short4> rhs)
2926// {
2927// return lhs = lhs % rhs;
2928// }
John Bauman89401822014-05-06 15:04:28 -04002929
John Bauman19bac1e2014-05-06 15:23:49 -04002930 RValue<Short4> operator&=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002931 {
2932 return lhs = lhs & rhs;
2933 }
2934
John Bauman19bac1e2014-05-06 15:23:49 -04002935 RValue<Short4> operator|=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002936 {
2937 return lhs = lhs | rhs;
2938 }
2939
John Bauman19bac1e2014-05-06 15:23:49 -04002940 RValue<Short4> operator^=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002941 {
2942 return lhs = lhs ^ rhs;
2943 }
2944
2945 RValue<Short4> operator<<=(const Short4 &lhs, unsigned char rhs)
2946 {
2947 return lhs = lhs << rhs;
2948 }
2949
2950 RValue<Short4> operator>>=(const Short4 &lhs, unsigned char rhs)
2951 {
2952 return lhs = lhs >> rhs;
2953 }
2954
John Bauman19bac1e2014-05-06 15:23:49 -04002955 RValue<Short4> operator<<=(const Short4 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04002956 {
2957 return lhs = lhs << rhs;
2958 }
2959
John Bauman19bac1e2014-05-06 15:23:49 -04002960 RValue<Short4> operator>>=(const Short4 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04002961 {
2962 return lhs = lhs >> rhs;
2963 }
2964
John Bauman19bac1e2014-05-06 15:23:49 -04002965// RValue<Short4> operator+(RValue<Short4> val)
2966// {
2967// return val;
2968// }
2969
2970 RValue<Short4> operator-(RValue<Short4> val)
John Bauman89401822014-05-06 15:04:28 -04002971 {
John Bauman19bac1e2014-05-06 15:23:49 -04002972 if(CPUID::supportsMMX2())
2973 {
2974 return Short4(0, 0, 0, 0) - val;
2975 }
2976 else
2977 {
2978 return RValue<Short4>(Nucleus::createNeg(val.value));
2979 }
John Bauman89401822014-05-06 15:04:28 -04002980 }
2981
John Bauman19bac1e2014-05-06 15:23:49 -04002982 RValue<Short4> operator~(RValue<Short4> val)
John Bauman89401822014-05-06 15:04:28 -04002983 {
John Bauman19bac1e2014-05-06 15:23:49 -04002984 if(CPUID::supportsMMX2())
2985 {
2986 return val ^ Short4(0xFFFFu, 0xFFFFu, 0xFFFFu, 0xFFFFu);
2987 }
2988 else
2989 {
2990 return RValue<Short4>(Nucleus::createNot(val.value));
2991 }
John Bauman89401822014-05-06 15:04:28 -04002992 }
2993
John Bauman19bac1e2014-05-06 15:23:49 -04002994 RValue<Short4> RoundShort4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04002995 {
2996 RValue<Int4> v4i32 = x86::cvtps2dq(cast);
Nicolas Capens698633a2015-02-04 00:16:13 -05002997 RValue<Short8> v8i16 = x86::packssdw(v4i32, v4i32);
John Bauman66b8ab22014-05-06 15:57:45 -04002998
Nicolas Capens698633a2015-02-04 00:16:13 -05002999 return As<Short4>(Int2(As<Int4>(v8i16)));
John Bauman89401822014-05-06 15:04:28 -04003000 }
3001
John Bauman19bac1e2014-05-06 15:23:49 -04003002 RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003003 {
3004 return x86::pmaxsw(x, y);
3005 }
3006
John Bauman19bac1e2014-05-06 15:23:49 -04003007 RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003008 {
3009 return x86::pminsw(x, y);
3010 }
3011
John Bauman19bac1e2014-05-06 15:23:49 -04003012 RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003013 {
3014 return x86::paddsw(x, y);
3015 }
3016
John Bauman19bac1e2014-05-06 15:23:49 -04003017 RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003018 {
3019 return x86::psubsw(x, y);
3020 }
3021
John Bauman19bac1e2014-05-06 15:23:49 -04003022 RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003023 {
3024 return x86::pmulhw(x, y);
3025 }
3026
John Bauman19bac1e2014-05-06 15:23:49 -04003027 RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003028 {
3029 return x86::pmaddwd(x, y);
3030 }
3031
John Bauman19bac1e2014-05-06 15:23:49 -04003032 RValue<SByte8> Pack(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003033 {
3034 return x86::packsswb(x, y);
3035 }
3036
John Bauman19bac1e2014-05-06 15:23:49 -04003037 RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003038 {
John Bauman19bac1e2014-05-06 15:23:49 -04003039 if(CPUID::supportsMMX2())
3040 {
3041 return x86::punpcklwd(x, y);
3042 }
3043 else
3044 {
Nicolas Capense89cd582016-09-30 14:23:47 -04003045 int shuffle[4] = {0, 4, 1, 5};
3046 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04003047
John Bauman19bac1e2014-05-06 15:23:49 -04003048 return RValue<Int2>(Nucleus::createBitCast(packed, Int2::getType()));
3049 }
John Bauman89401822014-05-06 15:04:28 -04003050 }
3051
John Bauman19bac1e2014-05-06 15:23:49 -04003052 RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003053 {
John Bauman19bac1e2014-05-06 15:23:49 -04003054 if(CPUID::supportsMMX2())
3055 {
3056 return x86::punpckhwd(x, y);
3057 }
3058 else
3059 {
Nicolas Capense89cd582016-09-30 14:23:47 -04003060 int shuffle[4] = {2, 6, 3, 7};
3061 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04003062
John Bauman19bac1e2014-05-06 15:23:49 -04003063 return RValue<Int2>(Nucleus::createBitCast(packed, Int2::getType()));
3064 }
John Bauman89401822014-05-06 15:04:28 -04003065 }
3066
John Bauman19bac1e2014-05-06 15:23:49 -04003067 RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04003068 {
John Bauman19bac1e2014-05-06 15:23:49 -04003069 if(CPUID::supportsMMX2())
3070 {
3071 return x86::pshufw(x, select);
3072 }
3073 else
3074 {
Nicolas Capense95d5342016-09-30 11:37:28 -04003075 return RValue<Short4>(createSwizzle4(x.value, select));
John Bauman19bac1e2014-05-06 15:23:49 -04003076 }
John Bauman89401822014-05-06 15:04:28 -04003077 }
3078
John Bauman19bac1e2014-05-06 15:23:49 -04003079 RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i)
John Bauman89401822014-05-06 15:04:28 -04003080 {
John Bauman19bac1e2014-05-06 15:23:49 -04003081 if(CPUID::supportsMMX2())
3082 {
3083 return x86::pinsrw(val, Int(element), i);
3084 }
3085 else
3086 {
3087 return RValue<Short4>(Nucleus::createInsertElement(val.value, element.value, i));
3088 }
John Bauman89401822014-05-06 15:04:28 -04003089 }
3090
John Bauman19bac1e2014-05-06 15:23:49 -04003091 RValue<Short> Extract(RValue<Short4> val, int i)
John Bauman89401822014-05-06 15:04:28 -04003092 {
John Bauman19bac1e2014-05-06 15:23:49 -04003093 if(CPUID::supportsMMX2())
3094 {
3095 return Short(x86::pextrw(val, i));
3096 }
3097 else
3098 {
Nicolas Capense95d5342016-09-30 11:37:28 -04003099 return RValue<Short>(Nucleus::createExtractElement(val.value, Short::getType(), i));
John Bauman19bac1e2014-05-06 15:23:49 -04003100 }
John Bauman89401822014-05-06 15:04:28 -04003101 }
3102
John Bauman19bac1e2014-05-06 15:23:49 -04003103 RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003104 {
3105 return x86::pcmpgtw(x, y);
3106 }
3107
John Bauman19bac1e2014-05-06 15:23:49 -04003108 RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003109 {
3110 return x86::pcmpeqw(x, y);
3111 }
3112
John Bauman19bac1e2014-05-06 15:23:49 -04003113 Type *Short4::getType()
John Bauman89401822014-05-06 15:04:28 -04003114 {
John Bauman19bac1e2014-05-06 15:23:49 -04003115 if(CPUID::supportsMMX2())
3116 {
3117 return MMX::getType();
3118 }
3119 else
3120 {
Nicolas Capensac230122016-09-20 14:30:06 -04003121 return T(VectorType::get(Short::getType(), 4));
John Bauman19bac1e2014-05-06 15:23:49 -04003122 }
John Bauman89401822014-05-06 15:04:28 -04003123 }
3124
John Bauman19bac1e2014-05-06 15:23:49 -04003125 UShort4::UShort4(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04003126 {
John Bauman89401822014-05-06 15:04:28 -04003127 *this = Short4(cast);
3128 }
3129
John Bauman19bac1e2014-05-06 15:23:49 -04003130 UShort4::UShort4(RValue<Float4> cast, bool saturate)
John Bauman89401822014-05-06 15:04:28 -04003131 {
John Bauman89401822014-05-06 15:04:28 -04003132 Float4 sat;
3133
3134 if(saturate)
3135 {
3136 if(CPUID::supportsSSE4_1())
3137 {
3138 sat = Min(cast, Float4(0xFFFF)); // packusdw takes care of 0x0000 saturation
3139 }
3140 else
3141 {
3142 sat = Max(Min(cast, Float4(0xFFFF)), Float4(0x0000));
3143 }
3144 }
3145 else
3146 {
3147 sat = cast;
3148 }
3149
3150 Int4 int4(sat);
3151
3152 if(!saturate || !CPUID::supportsSSE4_1())
3153 {
3154 *this = Short4(Int4(int4));
3155 }
3156 else
3157 {
3158 *this = As<Short4>(Int2(As<Int4>(x86::packusdw(As<UInt4>(int4), As<UInt4>(int4)))));
3159 }
3160 }
3161
3162 UShort4::UShort4()
3163 {
3164 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003165 }
3166
Alexis Hetu90c7ad62016-06-27 11:50:40 -04003167 UShort4::UShort4(unsigned short xyzw)
3168 {
3169 // xyzw.parent = this;
3170
Nicolas Capens13ac2322016-10-13 14:52:12 -04003171 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
3172 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(UShort::getType(), 4))));
Alexis Hetu90c7ad62016-06-27 11:50:40 -04003173
3174 storeValue(Nucleus::createBitCast(vector, getType()));
3175 }
3176
John Bauman89401822014-05-06 15:04:28 -04003177 UShort4::UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w)
3178 {
3179 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003180
Nicolas Capens13ac2322016-10-13 14:52:12 -04003181 int64_t constantVector[4] = {x, y, z, w};
3182 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(UShort::getType(), 4))));
John Bauman89401822014-05-06 15:04:28 -04003183
John Bauman66b8ab22014-05-06 15:57:45 -04003184 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04003185 }
3186
John Bauman19bac1e2014-05-06 15:23:49 -04003187 UShort4::UShort4(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003188 {
3189 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003190
John Bauman66b8ab22014-05-06 15:57:45 -04003191 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003192 }
3193
3194 UShort4::UShort4(const UShort4 &rhs)
3195 {
3196 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003197
John Bauman66b8ab22014-05-06 15:57:45 -04003198 Value *value = rhs.loadValue();
3199 storeValue(value);
3200 }
3201
3202 UShort4::UShort4(const Reference<UShort4> &rhs)
3203 {
3204 // xyzw.parent = this;
3205
3206 Value *value = rhs.loadValue();
3207 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003208 }
3209
John Bauman19bac1e2014-05-06 15:23:49 -04003210 UShort4::UShort4(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003211 {
3212 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003213
John Bauman66b8ab22014-05-06 15:57:45 -04003214 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003215 }
3216
3217 UShort4::UShort4(const Short4 &rhs)
3218 {
3219 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003220
John Bauman66b8ab22014-05-06 15:57:45 -04003221 Value *value = rhs.loadValue();
3222 storeValue(value);
3223 }
3224
3225 UShort4::UShort4(const Reference<Short4> &rhs)
3226 {
3227 // xyzw.parent = this;
3228
3229 Value *value = rhs.loadValue();
3230 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003231 }
3232
John Bauman19bac1e2014-05-06 15:23:49 -04003233 RValue<UShort4> UShort4::operator=(RValue<UShort4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04003234 {
John Bauman66b8ab22014-05-06 15:57:45 -04003235 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003236
3237 return rhs;
3238 }
3239
3240 RValue<UShort4> UShort4::operator=(const UShort4 &rhs) const
3241 {
John Bauman66b8ab22014-05-06 15:57:45 -04003242 Value *value = rhs.loadValue();
3243 storeValue(value);
3244
3245 return RValue<UShort4>(value);
3246 }
3247
3248 RValue<UShort4> UShort4::operator=(const Reference<UShort4> &rhs) const
3249 {
3250 Value *value = rhs.loadValue();
3251 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003252
3253 return RValue<UShort4>(value);
3254 }
3255
John Bauman19bac1e2014-05-06 15:23:49 -04003256 RValue<UShort4> UShort4::operator=(RValue<Short4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04003257 {
John Bauman66b8ab22014-05-06 15:57:45 -04003258 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003259
John Bauman66b8ab22014-05-06 15:57:45 -04003260 return RValue<UShort4>(rhs);
John Bauman89401822014-05-06 15:04:28 -04003261 }
3262
3263 RValue<UShort4> UShort4::operator=(const Short4 &rhs) const
3264 {
John Bauman66b8ab22014-05-06 15:57:45 -04003265 Value *value = rhs.loadValue();
3266 storeValue(value);
3267
3268 return RValue<UShort4>(value);
3269 }
3270
3271 RValue<UShort4> UShort4::operator=(const Reference<Short4> &rhs) const
3272 {
3273 Value *value = rhs.loadValue();
3274 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003275
3276 return RValue<UShort4>(value);
3277 }
3278
John Bauman19bac1e2014-05-06 15:23:49 -04003279 RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003280 {
John Bauman19bac1e2014-05-06 15:23:49 -04003281 if(CPUID::supportsMMX2())
3282 {
3283 return As<UShort4>(x86::paddw(As<Short4>(lhs), As<Short4>(rhs)));
3284 }
3285 else
3286 {
3287 return RValue<UShort4>(Nucleus::createAdd(lhs.value, rhs.value));
3288 }
John Bauman89401822014-05-06 15:04:28 -04003289 }
3290
John Bauman19bac1e2014-05-06 15:23:49 -04003291 RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003292 {
John Bauman19bac1e2014-05-06 15:23:49 -04003293 if(CPUID::supportsMMX2())
3294 {
3295 return As<UShort4>(x86::psubw(As<Short4>(lhs), As<Short4>(rhs)));
3296 }
3297 else
3298 {
3299 return RValue<UShort4>(Nucleus::createSub(lhs.value, rhs.value));
3300 }
John Bauman89401822014-05-06 15:04:28 -04003301 }
3302
John Bauman19bac1e2014-05-06 15:23:49 -04003303 RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003304 {
John Bauman19bac1e2014-05-06 15:23:49 -04003305 if(CPUID::supportsMMX2())
3306 {
3307 return As<UShort4>(x86::pmullw(As<Short4>(lhs), As<Short4>(rhs)));
3308 }
3309 else
3310 {
3311 return RValue<UShort4>(Nucleus::createMul(lhs.value, rhs.value));
3312 }
John Bauman89401822014-05-06 15:04:28 -04003313 }
3314
Nicolas Capens16b5f152016-10-13 13:39:01 -04003315 RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs)
3316 {
3317 if(CPUID::supportsMMX2())
3318 {
3319 return As<UShort4>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
3320 }
3321 else
3322 {
3323 return RValue<UShort4>(Nucleus::createAnd(lhs.value, rhs.value));
3324 }
3325 }
3326
3327 RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs)
3328 {
3329 if(CPUID::supportsMMX2())
3330 {
3331 return As<UShort4>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
3332 }
3333 else
3334 {
3335 return RValue<UShort4>(Nucleus::createOr(lhs.value, rhs.value));
3336 }
3337 }
3338
3339 RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs)
3340 {
3341 if(CPUID::supportsMMX2())
3342 {
3343 return As<UShort4>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
3344 }
3345 else
3346 {
3347 return RValue<UShort4>(Nucleus::createXor(lhs.value, rhs.value));
3348 }
3349 }
3350
John Bauman19bac1e2014-05-06 15:23:49 -04003351 RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003352 {
3353 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
3354
3355 return As<UShort4>(x86::psllw(As<Short4>(lhs), rhs));
3356 }
3357
John Bauman19bac1e2014-05-06 15:23:49 -04003358 RValue<UShort4> operator>>(RValue<UShort4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003359 {
3360 // return RValue<Short4>(Nucleus::createLShr(lhs.value, rhs.value));
3361
3362 return x86::psrlw(lhs, rhs);
3363 }
3364
John Bauman19bac1e2014-05-06 15:23:49 -04003365 RValue<UShort4> operator<<(RValue<UShort4> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04003366 {
3367 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
3368
3369 return As<UShort4>(x86::psllw(As<Short4>(lhs), rhs));
3370 }
3371
John Bauman19bac1e2014-05-06 15:23:49 -04003372 RValue<UShort4> operator>>(RValue<UShort4> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04003373 {
3374 // return RValue<Short4>(Nucleus::createLShr(lhs.value, rhs.value));
3375
3376 return x86::psrlw(lhs, rhs);
3377 }
3378
3379 RValue<UShort4> operator<<=(const UShort4 &lhs, unsigned char rhs)
3380 {
3381 return lhs = lhs << rhs;
3382 }
3383
3384 RValue<UShort4> operator>>=(const UShort4 &lhs, unsigned char rhs)
3385 {
3386 return lhs = lhs >> rhs;
3387 }
3388
John Bauman19bac1e2014-05-06 15:23:49 -04003389 RValue<UShort4> operator<<=(const UShort4 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04003390 {
3391 return lhs = lhs << rhs;
3392 }
3393
John Bauman19bac1e2014-05-06 15:23:49 -04003394 RValue<UShort4> operator>>=(const UShort4 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04003395 {
3396 return lhs = lhs >> rhs;
3397 }
3398
John Bauman19bac1e2014-05-06 15:23:49 -04003399 RValue<UShort4> operator~(RValue<UShort4> val)
John Bauman89401822014-05-06 15:04:28 -04003400 {
John Bauman19bac1e2014-05-06 15:23:49 -04003401 if(CPUID::supportsMMX2())
3402 {
3403 return As<UShort4>(As<Short4>(val) ^ Short4(0xFFFFu, 0xFFFFu, 0xFFFFu, 0xFFFFu));
3404 }
3405 else
3406 {
3407 return RValue<UShort4>(Nucleus::createNot(val.value));
3408 }
John Bauman89401822014-05-06 15:04:28 -04003409 }
3410
John Bauman19bac1e2014-05-06 15:23:49 -04003411 RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003412 {
John Bauman66b8ab22014-05-06 15:57:45 -04003413 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 -04003414 }
3415
John Bauman19bac1e2014-05-06 15:23:49 -04003416 RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003417 {
John Bauman66b8ab22014-05-06 15:57:45 -04003418 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 -04003419 }
3420
John Bauman19bac1e2014-05-06 15:23:49 -04003421 RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003422 {
3423 return x86::paddusw(x, y);
3424 }
3425
John Bauman19bac1e2014-05-06 15:23:49 -04003426 RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003427 {
3428 return x86::psubusw(x, y);
3429 }
3430
John Bauman19bac1e2014-05-06 15:23:49 -04003431 RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003432 {
3433 return x86::pmulhuw(x, y);
3434 }
3435
John Bauman19bac1e2014-05-06 15:23:49 -04003436 RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003437 {
3438 return x86::pavgw(x, y);
3439 }
3440
John Bauman19bac1e2014-05-06 15:23:49 -04003441 RValue<Byte8> Pack(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003442 {
3443 return x86::packuswb(x, y);
3444 }
3445
John Bauman19bac1e2014-05-06 15:23:49 -04003446 Type *UShort4::getType()
John Bauman89401822014-05-06 15:04:28 -04003447 {
John Bauman19bac1e2014-05-06 15:23:49 -04003448 if(CPUID::supportsMMX2())
3449 {
3450 return MMX::getType();
3451 }
3452 else
3453 {
Nicolas Capensac230122016-09-20 14:30:06 -04003454 return T(VectorType::get(UShort::getType(), 4));
John Bauman19bac1e2014-05-06 15:23:49 -04003455 }
John Bauman89401822014-05-06 15:04:28 -04003456 }
3457
3458 Short8::Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7)
3459 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04003460 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
3461 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04003462 }
3463
John Bauman19bac1e2014-05-06 15:23:49 -04003464 Short8::Short8(RValue<Short8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003465 {
John Bauman66b8ab22014-05-06 15:57:45 -04003466 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003467 }
3468
Nicolas Capensef8cd662016-06-30 15:34:40 -04003469 Short8::Short8(const Reference<Short8> &rhs)
3470 {
Nicolas Capensef8cd662016-06-30 15:34:40 -04003471 Value *value = rhs.loadValue();
3472 storeValue(value);
3473 }
3474
Nicolas Capens62abb552016-01-05 12:03:47 -05003475 Short8::Short8(RValue<Short4> lo, RValue<Short4> hi)
3476 {
3477 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
3478 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
3479
Nicolas Capens22008782016-10-20 01:11:47 -04003480 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Nicolas Capens62abb552016-01-05 12:03:47 -05003481 long2 = Nucleus::createInsertElement(long2, loLong, 0);
3482 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
3483 Value *short8 = Nucleus::createBitCast(long2, Short8::getType());
3484
3485 storeValue(short8);
3486 }
3487
John Bauman19bac1e2014-05-06 15:23:49 -04003488 RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003489 {
3490 return RValue<Short8>(Nucleus::createAdd(lhs.value, rhs.value));
3491 }
3492
John Bauman19bac1e2014-05-06 15:23:49 -04003493 RValue<Short8> operator&(RValue<Short8> lhs, RValue<Short8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003494 {
3495 return RValue<Short8>(Nucleus::createAnd(lhs.value, rhs.value));
3496 }
3497
John Bauman19bac1e2014-05-06 15:23:49 -04003498 RValue<Short8> operator<<(RValue<Short8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003499 {
3500 return x86::psllw(lhs, rhs); // FIXME: Fallback required
3501 }
3502
John Bauman19bac1e2014-05-06 15:23:49 -04003503 RValue<Short8> operator>>(RValue<Short8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003504 {
3505 return x86::psraw(lhs, rhs); // FIXME: Fallback required
3506 }
3507
John Bauman19bac1e2014-05-06 15:23:49 -04003508 RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04003509 {
3510 return x86::pmaddwd(x, y); // FIXME: Fallback required
3511 }
3512
Alexis Hetu0f448072016-03-18 10:56:08 -04003513 RValue<Int4> Abs(RValue<Int4> x)
3514 {
3515 if(CPUID::supportsSSSE3())
3516 {
3517 return x86::pabsd(x);
3518 }
3519 else
3520 {
3521 Int4 mask = (x >> 31);
3522 return (mask ^ x) - mask;
3523 }
3524 }
3525
John Bauman19bac1e2014-05-06 15:23:49 -04003526 RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04003527 {
3528 return x86::pmulhw(x, y); // FIXME: Fallback required
3529 }
3530
John Bauman19bac1e2014-05-06 15:23:49 -04003531 Type *Short8::getType()
John Bauman89401822014-05-06 15:04:28 -04003532 {
Nicolas Capensac230122016-09-20 14:30:06 -04003533 return T(VectorType::get(Short::getType(), 8));
John Bauman89401822014-05-06 15:04:28 -04003534 }
3535
3536 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)
3537 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04003538 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
3539 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04003540 }
3541
John Bauman19bac1e2014-05-06 15:23:49 -04003542 UShort8::UShort8(RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003543 {
John Bauman66b8ab22014-05-06 15:57:45 -04003544 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003545 }
3546
Nicolas Capensef8cd662016-06-30 15:34:40 -04003547 UShort8::UShort8(const Reference<UShort8> &rhs)
3548 {
Nicolas Capensef8cd662016-06-30 15:34:40 -04003549 Value *value = rhs.loadValue();
3550 storeValue(value);
3551 }
3552
Nicolas Capens62abb552016-01-05 12:03:47 -05003553 UShort8::UShort8(RValue<UShort4> lo, RValue<UShort4> hi)
3554 {
3555 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
3556 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
3557
Nicolas Capens22008782016-10-20 01:11:47 -04003558 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Nicolas Capens62abb552016-01-05 12:03:47 -05003559 long2 = Nucleus::createInsertElement(long2, loLong, 0);
3560 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
3561 Value *short8 = Nucleus::createBitCast(long2, Short8::getType());
3562
3563 storeValue(short8);
3564 }
3565
John Bauman19bac1e2014-05-06 15:23:49 -04003566 RValue<UShort8> UShort8::operator=(RValue<UShort8> rhs) const
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 return rhs;
3571 }
3572
3573 RValue<UShort8> UShort8::operator=(const UShort8 &rhs) const
3574 {
John Bauman66b8ab22014-05-06 15:57:45 -04003575 Value *value = rhs.loadValue();
3576 storeValue(value);
3577
3578 return RValue<UShort8>(value);
3579 }
3580
3581 RValue<UShort8> UShort8::operator=(const Reference<UShort8> &rhs) const
3582 {
3583 Value *value = rhs.loadValue();
3584 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003585
3586 return RValue<UShort8>(value);
3587 }
3588
John Bauman19bac1e2014-05-06 15:23:49 -04003589 RValue<UShort8> operator&(RValue<UShort8> lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003590 {
3591 return RValue<UShort8>(Nucleus::createAnd(lhs.value, rhs.value));
3592 }
3593
John Bauman19bac1e2014-05-06 15:23:49 -04003594 RValue<UShort8> operator<<(RValue<UShort8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003595 {
3596 return As<UShort8>(x86::psllw(As<Short8>(lhs), rhs)); // FIXME: Fallback required
3597 }
3598
John Bauman19bac1e2014-05-06 15:23:49 -04003599 RValue<UShort8> operator>>(RValue<UShort8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003600 {
3601 return x86::psrlw(lhs, rhs); // FIXME: Fallback required
3602 }
3603
John Bauman19bac1e2014-05-06 15:23:49 -04003604 RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003605 {
3606 return RValue<UShort8>(Nucleus::createAdd(lhs.value, rhs.value));
3607 }
3608
John Bauman19bac1e2014-05-06 15:23:49 -04003609 RValue<UShort8> operator*(RValue<UShort8> lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003610 {
3611 return RValue<UShort8>(Nucleus::createMul(lhs.value, rhs.value));
3612 }
3613
John Bauman19bac1e2014-05-06 15:23:49 -04003614 RValue<UShort8> operator+=(const UShort8 &lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003615 {
3616 return lhs = lhs + rhs;
3617 }
3618
John Bauman19bac1e2014-05-06 15:23:49 -04003619 RValue<UShort8> operator~(RValue<UShort8> val)
John Bauman89401822014-05-06 15:04:28 -04003620 {
3621 return RValue<UShort8>(Nucleus::createNot(val.value));
3622 }
3623
John Bauman19bac1e2014-05-06 15:23:49 -04003624 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 -04003625 {
Nicolas Capense89cd582016-09-30 14:23:47 -04003626 int pshufb[16] =
3627 {
3628 select0 + 0,
3629 select0 + 1,
3630 select1 + 0,
3631 select1 + 1,
3632 select2 + 0,
3633 select2 + 1,
3634 select3 + 0,
3635 select3 + 1,
3636 select4 + 0,
3637 select4 + 1,
3638 select5 + 0,
3639 select5 + 1,
3640 select6 + 0,
3641 select6 + 1,
3642 select7 + 0,
3643 select7 + 1,
3644 };
John Bauman89401822014-05-06 15:04:28 -04003645
3646 Value *byte16 = Nucleus::createBitCast(x.value, Byte16::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04003647 Value *shuffle = Nucleus::createShuffleVector(byte16, byte16, pshufb);
John Bauman89401822014-05-06 15:04:28 -04003648 Value *short8 = Nucleus::createBitCast(shuffle, UShort8::getType());
3649
3650 return RValue<UShort8>(short8);
3651 }
3652
John Bauman19bac1e2014-05-06 15:23:49 -04003653 RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y)
John Bauman89401822014-05-06 15:04:28 -04003654 {
3655 return x86::pmulhuw(x, y); // FIXME: Fallback required
3656 }
3657
John Bauman19bac1e2014-05-06 15:23:49 -04003658 Type *UShort8::getType()
John Bauman89401822014-05-06 15:04:28 -04003659 {
Nicolas Capensac230122016-09-20 14:30:06 -04003660 return T(VectorType::get(UShort::getType(), 8));
John Bauman89401822014-05-06 15:04:28 -04003661 }
3662
Nicolas Capens81f18302016-01-14 09:32:35 -05003663 Int::Int(Argument<Int> argument)
John Bauman89401822014-05-06 15:04:28 -04003664 {
Nicolas Capens81f18302016-01-14 09:32:35 -05003665 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04003666 }
3667
John Bauman19bac1e2014-05-06 15:23:49 -04003668 Int::Int(RValue<Byte> cast)
John Bauman89401822014-05-06 15:04:28 -04003669 {
John Bauman89401822014-05-06 15:04:28 -04003670 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3671
John Bauman66b8ab22014-05-06 15:57:45 -04003672 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003673 }
3674
John Bauman19bac1e2014-05-06 15:23:49 -04003675 Int::Int(RValue<SByte> cast)
John Bauman89401822014-05-06 15:04:28 -04003676 {
John Bauman89401822014-05-06 15:04:28 -04003677 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3678
John Bauman66b8ab22014-05-06 15:57:45 -04003679 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003680 }
3681
John Bauman19bac1e2014-05-06 15:23:49 -04003682 Int::Int(RValue<Short> cast)
John Bauman89401822014-05-06 15:04:28 -04003683 {
John Bauman89401822014-05-06 15:04:28 -04003684 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3685
John Bauman66b8ab22014-05-06 15:57:45 -04003686 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003687 }
3688
John Bauman19bac1e2014-05-06 15:23:49 -04003689 Int::Int(RValue<UShort> cast)
John Bauman89401822014-05-06 15:04:28 -04003690 {
John Bauman89401822014-05-06 15:04:28 -04003691 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3692
John Bauman66b8ab22014-05-06 15:57:45 -04003693 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003694 }
3695
John Bauman19bac1e2014-05-06 15:23:49 -04003696 Int::Int(RValue<Int2> cast)
John Bauman89401822014-05-06 15:04:28 -04003697 {
John Bauman89401822014-05-06 15:04:28 -04003698 *this = Extract(cast, 0);
3699 }
3700
John Bauman19bac1e2014-05-06 15:23:49 -04003701 Int::Int(RValue<Long> cast)
John Bauman89401822014-05-06 15:04:28 -04003702 {
John Bauman89401822014-05-06 15:04:28 -04003703 Value *integer = Nucleus::createTrunc(cast.value, Int::getType());
3704
John Bauman66b8ab22014-05-06 15:57:45 -04003705 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003706 }
3707
John Bauman19bac1e2014-05-06 15:23:49 -04003708 Int::Int(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04003709 {
John Bauman89401822014-05-06 15:04:28 -04003710 Value *integer = Nucleus::createFPToSI(cast.value, Int::getType());
3711
John Bauman66b8ab22014-05-06 15:57:45 -04003712 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003713 }
3714
3715 Int::Int()
3716 {
John Bauman89401822014-05-06 15:04:28 -04003717 }
3718
3719 Int::Int(int x)
3720 {
John Bauman66b8ab22014-05-06 15:57:45 -04003721 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04003722 }
3723
John Bauman19bac1e2014-05-06 15:23:49 -04003724 Int::Int(RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003725 {
John Bauman66b8ab22014-05-06 15:57:45 -04003726 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003727 }
3728
John Bauman19bac1e2014-05-06 15:23:49 -04003729 Int::Int(RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04003730 {
John Bauman66b8ab22014-05-06 15:57:45 -04003731 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003732 }
3733
3734 Int::Int(const Int &rhs)
3735 {
John Bauman66b8ab22014-05-06 15:57:45 -04003736 Value *value = rhs.loadValue();
3737 storeValue(value);
3738 }
John Bauman89401822014-05-06 15:04:28 -04003739
John Bauman66b8ab22014-05-06 15:57:45 -04003740 Int::Int(const Reference<Int> &rhs)
3741 {
3742 Value *value = rhs.loadValue();
3743 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003744 }
3745
3746 Int::Int(const UInt &rhs)
3747 {
John Bauman66b8ab22014-05-06 15:57:45 -04003748 Value *value = rhs.loadValue();
3749 storeValue(value);
3750 }
John Bauman89401822014-05-06 15:04:28 -04003751
John Bauman66b8ab22014-05-06 15:57:45 -04003752 Int::Int(const Reference<UInt> &rhs)
3753 {
3754 Value *value = rhs.loadValue();
3755 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003756 }
3757
3758 RValue<Int> Int::operator=(int rhs) const
3759 {
John Bauman66b8ab22014-05-06 15:57:45 -04003760 return RValue<Int>(storeValue(Nucleus::createConstantInt(rhs)));
John Bauman89401822014-05-06 15:04:28 -04003761 }
3762
John Bauman19bac1e2014-05-06 15:23:49 -04003763 RValue<Int> Int::operator=(RValue<Int> rhs) const
John Bauman89401822014-05-06 15:04:28 -04003764 {
John Bauman66b8ab22014-05-06 15:57:45 -04003765 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003766
3767 return rhs;
3768 }
3769
John Bauman19bac1e2014-05-06 15:23:49 -04003770 RValue<Int> Int::operator=(RValue<UInt> rhs) const
John Bauman89401822014-05-06 15:04:28 -04003771 {
John Bauman66b8ab22014-05-06 15:57:45 -04003772 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003773
John Bauman66b8ab22014-05-06 15:57:45 -04003774 return RValue<Int>(rhs);
John Bauman89401822014-05-06 15:04:28 -04003775 }
3776
3777 RValue<Int> Int::operator=(const Int &rhs) const
3778 {
John Bauman66b8ab22014-05-06 15:57:45 -04003779 Value *value = rhs.loadValue();
3780 storeValue(value);
3781
3782 return RValue<Int>(value);
3783 }
3784
3785 RValue<Int> Int::operator=(const Reference<Int> &rhs) const
3786 {
3787 Value *value = rhs.loadValue();
3788 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003789
3790 return RValue<Int>(value);
3791 }
3792
3793 RValue<Int> Int::operator=(const UInt &rhs) const
3794 {
John Bauman66b8ab22014-05-06 15:57:45 -04003795 Value *value = rhs.loadValue();
3796 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003797
3798 return RValue<Int>(value);
3799 }
3800
John Bauman66b8ab22014-05-06 15:57:45 -04003801 RValue<Int> Int::operator=(const Reference<UInt> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04003802 {
John Bauman66b8ab22014-05-06 15:57:45 -04003803 Value *value = rhs.loadValue();
3804 storeValue(value);
3805
3806 return RValue<Int>(value);
John Bauman89401822014-05-06 15:04:28 -04003807 }
3808
John Bauman19bac1e2014-05-06 15:23:49 -04003809 RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003810 {
3811 return RValue<Int>(Nucleus::createAdd(lhs.value, rhs.value));
3812 }
3813
John Bauman19bac1e2014-05-06 15:23:49 -04003814 RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003815 {
3816 return RValue<Int>(Nucleus::createSub(lhs.value, rhs.value));
3817 }
3818
John Bauman19bac1e2014-05-06 15:23:49 -04003819 RValue<Int> operator*(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003820 {
3821 return RValue<Int>(Nucleus::createMul(lhs.value, rhs.value));
3822 }
3823
John Bauman19bac1e2014-05-06 15:23:49 -04003824 RValue<Int> operator/(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003825 {
3826 return RValue<Int>(Nucleus::createSDiv(lhs.value, rhs.value));
3827 }
3828
John Bauman19bac1e2014-05-06 15:23:49 -04003829 RValue<Int> operator%(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003830 {
3831 return RValue<Int>(Nucleus::createSRem(lhs.value, rhs.value));
3832 }
3833
John Bauman19bac1e2014-05-06 15:23:49 -04003834 RValue<Int> operator&(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003835 {
3836 return RValue<Int>(Nucleus::createAnd(lhs.value, rhs.value));
3837 }
3838
John Bauman19bac1e2014-05-06 15:23:49 -04003839 RValue<Int> operator|(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003840 {
3841 return RValue<Int>(Nucleus::createOr(lhs.value, rhs.value));
3842 }
3843
John Bauman19bac1e2014-05-06 15:23:49 -04003844 RValue<Int> operator^(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003845 {
3846 return RValue<Int>(Nucleus::createXor(lhs.value, rhs.value));
3847 }
3848
John Bauman19bac1e2014-05-06 15:23:49 -04003849 RValue<Int> operator<<(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003850 {
3851 return RValue<Int>(Nucleus::createShl(lhs.value, rhs.value));
3852 }
3853
John Bauman19bac1e2014-05-06 15:23:49 -04003854 RValue<Int> operator>>(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003855 {
3856 return RValue<Int>(Nucleus::createAShr(lhs.value, rhs.value));
3857 }
3858
John Bauman19bac1e2014-05-06 15:23:49 -04003859 RValue<Int> operator+=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003860 {
3861 return lhs = lhs + rhs;
3862 }
3863
John Bauman19bac1e2014-05-06 15:23:49 -04003864 RValue<Int> operator-=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003865 {
3866 return lhs = lhs - rhs;
3867 }
3868
John Bauman19bac1e2014-05-06 15:23:49 -04003869 RValue<Int> operator*=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003870 {
3871 return lhs = lhs * rhs;
3872 }
3873
John Bauman19bac1e2014-05-06 15:23:49 -04003874 RValue<Int> operator/=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003875 {
3876 return lhs = lhs / rhs;
3877 }
3878
John Bauman19bac1e2014-05-06 15:23:49 -04003879 RValue<Int> operator%=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003880 {
3881 return lhs = lhs % rhs;
3882 }
3883
John Bauman19bac1e2014-05-06 15:23:49 -04003884 RValue<Int> operator&=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003885 {
3886 return lhs = lhs & rhs;
3887 }
3888
John Bauman19bac1e2014-05-06 15:23:49 -04003889 RValue<Int> operator|=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003890 {
3891 return lhs = lhs | rhs;
3892 }
3893
John Bauman19bac1e2014-05-06 15:23:49 -04003894 RValue<Int> operator^=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003895 {
3896 return lhs = lhs ^ rhs;
3897 }
3898
John Bauman19bac1e2014-05-06 15:23:49 -04003899 RValue<Int> operator<<=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003900 {
3901 return lhs = lhs << rhs;
3902 }
3903
John Bauman19bac1e2014-05-06 15:23:49 -04003904 RValue<Int> operator>>=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003905 {
3906 return lhs = lhs >> rhs;
3907 }
3908
John Bauman19bac1e2014-05-06 15:23:49 -04003909 RValue<Int> operator+(RValue<Int> val)
John Bauman89401822014-05-06 15:04:28 -04003910 {
3911 return val;
3912 }
3913
John Bauman19bac1e2014-05-06 15:23:49 -04003914 RValue<Int> operator-(RValue<Int> val)
John Bauman89401822014-05-06 15:04:28 -04003915 {
3916 return RValue<Int>(Nucleus::createNeg(val.value));
3917 }
3918
John Bauman19bac1e2014-05-06 15:23:49 -04003919 RValue<Int> operator~(RValue<Int> val)
John Bauman89401822014-05-06 15:04:28 -04003920 {
3921 return RValue<Int>(Nucleus::createNot(val.value));
3922 }
3923
3924 RValue<Int> operator++(const Int &val, int) // Post-increment
3925 {
3926 RValue<Int> res = val;
3927
Nicolas Capens19336542016-09-26 10:32:29 -04003928 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04003929 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04003930
3931 return res;
3932 }
3933
3934 const Int &operator++(const Int &val) // Pre-increment
3935 {
Nicolas Capens19336542016-09-26 10:32:29 -04003936 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04003937 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04003938
3939 return val;
3940 }
3941
3942 RValue<Int> operator--(const Int &val, int) // Post-decrement
3943 {
3944 RValue<Int> res = val;
3945
Nicolas Capens19336542016-09-26 10:32:29 -04003946 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04003947 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04003948
3949 return res;
3950 }
3951
3952 const Int &operator--(const Int &val) // Pre-decrement
3953 {
Nicolas Capens19336542016-09-26 10:32:29 -04003954 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04003955 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04003956
3957 return val;
3958 }
3959
John Bauman19bac1e2014-05-06 15:23:49 -04003960 RValue<Bool> operator<(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003961 {
3962 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
3963 }
3964
John Bauman19bac1e2014-05-06 15:23:49 -04003965 RValue<Bool> operator<=(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003966 {
3967 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
3968 }
3969
John Bauman19bac1e2014-05-06 15:23:49 -04003970 RValue<Bool> operator>(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003971 {
3972 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
3973 }
3974
John Bauman19bac1e2014-05-06 15:23:49 -04003975 RValue<Bool> operator>=(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003976 {
3977 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
3978 }
3979
John Bauman19bac1e2014-05-06 15:23:49 -04003980 RValue<Bool> operator!=(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003981 {
3982 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
3983 }
3984
John Bauman19bac1e2014-05-06 15:23:49 -04003985 RValue<Bool> operator==(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003986 {
3987 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
3988 }
3989
John Bauman19bac1e2014-05-06 15:23:49 -04003990 RValue<Int> Max(RValue<Int> x, RValue<Int> y)
3991 {
3992 return IfThenElse(x > y, x, y);
3993 }
3994
3995 RValue<Int> Min(RValue<Int> x, RValue<Int> y)
3996 {
3997 return IfThenElse(x < y, x, y);
3998 }
3999
4000 RValue<Int> Clamp(RValue<Int> x, RValue<Int> min, RValue<Int> max)
4001 {
4002 return Min(Max(x, min), max);
4003 }
4004
4005 RValue<Int> RoundInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04004006 {
4007 return x86::cvtss2si(cast);
4008
John Bauman66b8ab22014-05-06 15:57:45 -04004009 // return IfThenElse(val > 0.0f, Int(val + 0.5f), Int(val - 0.5f));
John Bauman89401822014-05-06 15:04:28 -04004010 }
4011
John Bauman19bac1e2014-05-06 15:23:49 -04004012 Type *Int::getType()
John Bauman89401822014-05-06 15:04:28 -04004013 {
Nicolas Capensac230122016-09-20 14:30:06 -04004014 return T(llvm::Type::getInt32Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04004015 }
4016
John Bauman19bac1e2014-05-06 15:23:49 -04004017 Long::Long(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04004018 {
John Bauman89401822014-05-06 15:04:28 -04004019 Value *integer = Nucleus::createSExt(cast.value, Long::getType());
4020
John Bauman66b8ab22014-05-06 15:57:45 -04004021 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04004022 }
4023
John Bauman19bac1e2014-05-06 15:23:49 -04004024 Long::Long(RValue<UInt> cast)
John Bauman89401822014-05-06 15:04:28 -04004025 {
John Bauman89401822014-05-06 15:04:28 -04004026 Value *integer = Nucleus::createZExt(cast.value, Long::getType());
4027
John Bauman66b8ab22014-05-06 15:57:45 -04004028 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04004029 }
4030
4031 Long::Long()
4032 {
John Bauman89401822014-05-06 15:04:28 -04004033 }
4034
John Bauman19bac1e2014-05-06 15:23:49 -04004035 Long::Long(RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04004036 {
John Bauman66b8ab22014-05-06 15:57:45 -04004037 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004038 }
4039
4040 RValue<Long> Long::operator=(int64_t rhs) const
4041 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04004042 return RValue<Long>(storeValue(Nucleus::createConstantLong(rhs)));
John Bauman89401822014-05-06 15:04:28 -04004043 }
4044
John Bauman19bac1e2014-05-06 15:23:49 -04004045 RValue<Long> Long::operator=(RValue<Long> rhs) const
John Bauman89401822014-05-06 15:04:28 -04004046 {
John Bauman66b8ab22014-05-06 15:57:45 -04004047 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004048
4049 return rhs;
4050 }
4051
4052 RValue<Long> Long::operator=(const Long &rhs) const
4053 {
John Bauman66b8ab22014-05-06 15:57:45 -04004054 Value *value = rhs.loadValue();
4055 storeValue(value);
4056
4057 return RValue<Long>(value);
4058 }
4059
4060 RValue<Long> Long::operator=(const Reference<Long> &rhs) const
4061 {
4062 Value *value = rhs.loadValue();
4063 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004064
4065 return RValue<Long>(value);
4066 }
4067
John Bauman19bac1e2014-05-06 15:23:49 -04004068 RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04004069 {
4070 return RValue<Long>(Nucleus::createAdd(lhs.value, rhs.value));
4071 }
4072
John Bauman19bac1e2014-05-06 15:23:49 -04004073 RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04004074 {
4075 return RValue<Long>(Nucleus::createSub(lhs.value, rhs.value));
4076 }
4077
John Bauman19bac1e2014-05-06 15:23:49 -04004078 RValue<Long> operator+=(const Long &lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04004079 {
4080 return lhs = lhs + rhs;
4081 }
4082
John Bauman19bac1e2014-05-06 15:23:49 -04004083 RValue<Long> operator-=(const Long &lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04004084 {
4085 return lhs = lhs - rhs;
4086 }
4087
John Bauman66b8ab22014-05-06 15:57:45 -04004088 RValue<Long> AddAtomic(RValue<Pointer<Long> > x, RValue<Long> y)
John Bauman89401822014-05-06 15:04:28 -04004089 {
John Bauman19bac1e2014-05-06 15:23:49 -04004090 return RValue<Long>(Nucleus::createAtomicAdd(x.value, y.value));
John Bauman89401822014-05-06 15:04:28 -04004091 }
4092
John Bauman19bac1e2014-05-06 15:23:49 -04004093 Type *Long::getType()
John Bauman89401822014-05-06 15:04:28 -04004094 {
Nicolas Capensac230122016-09-20 14:30:06 -04004095 return T(llvm::Type::getInt64Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04004096 }
4097
Nicolas Capens50c96362016-01-04 23:03:59 -05004098 Long1::Long1(const RValue<UInt> cast)
John Bauman89401822014-05-06 15:04:28 -04004099 {
Nicolas Capens19336542016-09-26 10:32:29 -04004100 Value *undefCast = Nucleus::createInsertElement(V(UndefValue::get(VectorType::get(Int::getType(), 2))), cast.value, 0);
4101 Value *zeroCast = Nucleus::createInsertElement(undefCast, V(Nucleus::createConstantInt(0)), 1);
John Bauman66b8ab22014-05-06 15:57:45 -04004102
Nicolas Capens50c96362016-01-04 23:03:59 -05004103 storeValue(Nucleus::createBitCast(zeroCast, Long1::getType()));
John Bauman89401822014-05-06 15:04:28 -04004104 }
4105
John Bauman19bac1e2014-05-06 15:23:49 -04004106 Long1::Long1(RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004107 {
John Bauman66b8ab22014-05-06 15:57:45 -04004108 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004109 }
4110
John Bauman19bac1e2014-05-06 15:23:49 -04004111 Type *Long1::getType()
John Bauman89401822014-05-06 15:04:28 -04004112 {
John Bauman19bac1e2014-05-06 15:23:49 -04004113 if(CPUID::supportsMMX2())
4114 {
4115 return MMX::getType();
4116 }
4117 else
4118 {
Nicolas Capensac230122016-09-20 14:30:06 -04004119 return T(VectorType::get(Long::getType(), 1));
John Bauman19bac1e2014-05-06 15:23:49 -04004120 }
John Bauman89401822014-05-06 15:04:28 -04004121 }
4122
Nicolas Capens81f18302016-01-14 09:32:35 -05004123 UInt::UInt(Argument<UInt> argument)
John Bauman89401822014-05-06 15:04:28 -04004124 {
Nicolas Capens81f18302016-01-14 09:32:35 -05004125 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04004126 }
4127
John Bauman19bac1e2014-05-06 15:23:49 -04004128 UInt::UInt(RValue<UShort> cast)
John Bauman89401822014-05-06 15:04:28 -04004129 {
John Bauman89401822014-05-06 15:04:28 -04004130 Value *integer = Nucleus::createZExt(cast.value, UInt::getType());
4131
John Bauman66b8ab22014-05-06 15:57:45 -04004132 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04004133 }
4134
John Bauman19bac1e2014-05-06 15:23:49 -04004135 UInt::UInt(RValue<Long> cast)
John Bauman89401822014-05-06 15:04:28 -04004136 {
John Bauman89401822014-05-06 15:04:28 -04004137 Value *integer = Nucleus::createTrunc(cast.value, UInt::getType());
4138
John Bauman66b8ab22014-05-06 15:57:45 -04004139 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04004140 }
4141
John Bauman19bac1e2014-05-06 15:23:49 -04004142 UInt::UInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04004143 {
Alexis Hetu764d1422016-09-28 08:44:22 -04004144 // Note: createFPToUI is broken, must perform conversion using createFPtoSI
4145 // Value *integer = Nucleus::createFPToUI(cast.value, UInt::getType());
John Bauman89401822014-05-06 15:04:28 -04004146
Alexis Hetu764d1422016-09-28 08:44:22 -04004147 // Smallest positive value representable in UInt, but not in Int
4148 const unsigned int ustart = 0x80000000u;
4149 const float ustartf = float(ustart);
4150
4151 // If the value is negative, store 0, otherwise store the result of the conversion
4152 storeValue((~(As<Int>(cast) >> 31) &
4153 // Check if the value can be represented as an Int
4154 IfThenElse(cast >= ustartf,
4155 // If the value is too large, subtract ustart and re-add it after conversion.
4156 As<Int>(As<UInt>(Int(cast - Float(ustartf))) + UInt(ustart)),
4157 // Otherwise, just convert normally
4158 Int(cast))).value);
John Bauman89401822014-05-06 15:04:28 -04004159 }
4160
4161 UInt::UInt()
4162 {
John Bauman89401822014-05-06 15:04:28 -04004163 }
4164
4165 UInt::UInt(int x)
4166 {
John Bauman66b8ab22014-05-06 15:57:45 -04004167 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04004168 }
4169
4170 UInt::UInt(unsigned int x)
4171 {
John Bauman66b8ab22014-05-06 15:57:45 -04004172 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04004173 }
4174
John Bauman19bac1e2014-05-06 15:23:49 -04004175 UInt::UInt(RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004176 {
John Bauman66b8ab22014-05-06 15:57:45 -04004177 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004178 }
4179
John Bauman19bac1e2014-05-06 15:23:49 -04004180 UInt::UInt(RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004181 {
John Bauman66b8ab22014-05-06 15:57:45 -04004182 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004183 }
4184
4185 UInt::UInt(const UInt &rhs)
4186 {
John Bauman66b8ab22014-05-06 15:57:45 -04004187 Value *value = rhs.loadValue();
4188 storeValue(value);
4189 }
John Bauman89401822014-05-06 15:04:28 -04004190
John Bauman66b8ab22014-05-06 15:57:45 -04004191 UInt::UInt(const Reference<UInt> &rhs)
4192 {
4193 Value *value = rhs.loadValue();
4194 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004195 }
4196
4197 UInt::UInt(const Int &rhs)
4198 {
John Bauman66b8ab22014-05-06 15:57:45 -04004199 Value *value = rhs.loadValue();
4200 storeValue(value);
4201 }
John Bauman89401822014-05-06 15:04:28 -04004202
John Bauman66b8ab22014-05-06 15:57:45 -04004203 UInt::UInt(const Reference<Int> &rhs)
4204 {
4205 Value *value = rhs.loadValue();
4206 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004207 }
4208
4209 RValue<UInt> UInt::operator=(unsigned int rhs) const
4210 {
John Bauman66b8ab22014-05-06 15:57:45 -04004211 return RValue<UInt>(storeValue(Nucleus::createConstantInt(rhs)));
John Bauman89401822014-05-06 15:04:28 -04004212 }
4213
John Bauman19bac1e2014-05-06 15:23:49 -04004214 RValue<UInt> UInt::operator=(RValue<UInt> rhs) const
John Bauman89401822014-05-06 15:04:28 -04004215 {
John Bauman66b8ab22014-05-06 15:57:45 -04004216 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004217
4218 return rhs;
4219 }
4220
John Bauman19bac1e2014-05-06 15:23:49 -04004221 RValue<UInt> UInt::operator=(RValue<Int> rhs) const
John Bauman89401822014-05-06 15:04:28 -04004222 {
John Bauman66b8ab22014-05-06 15:57:45 -04004223 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004224
John Bauman66b8ab22014-05-06 15:57:45 -04004225 return RValue<UInt>(rhs);
John Bauman89401822014-05-06 15:04:28 -04004226 }
4227
4228 RValue<UInt> UInt::operator=(const UInt &rhs) const
4229 {
John Bauman66b8ab22014-05-06 15:57:45 -04004230 Value *value = rhs.loadValue();
4231 storeValue(value);
4232
4233 return RValue<UInt>(value);
4234 }
4235
4236 RValue<UInt> UInt::operator=(const Reference<UInt> &rhs) const
4237 {
4238 Value *value = rhs.loadValue();
4239 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004240
4241 return RValue<UInt>(value);
4242 }
4243
4244 RValue<UInt> UInt::operator=(const Int &rhs) const
4245 {
John Bauman66b8ab22014-05-06 15:57:45 -04004246 Value *value = rhs.loadValue();
4247 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004248
4249 return RValue<UInt>(value);
4250 }
4251
John Bauman66b8ab22014-05-06 15:57:45 -04004252 RValue<UInt> UInt::operator=(const Reference<Int> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04004253 {
John Bauman66b8ab22014-05-06 15:57:45 -04004254 Value *value = rhs.loadValue();
4255 storeValue(value);
4256
4257 return RValue<UInt>(value);
John Bauman89401822014-05-06 15:04:28 -04004258 }
4259
John Bauman19bac1e2014-05-06 15:23:49 -04004260 RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004261 {
4262 return RValue<UInt>(Nucleus::createAdd(lhs.value, rhs.value));
4263 }
4264
John Bauman19bac1e2014-05-06 15:23:49 -04004265 RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004266 {
4267 return RValue<UInt>(Nucleus::createSub(lhs.value, rhs.value));
4268 }
4269
John Bauman19bac1e2014-05-06 15:23:49 -04004270 RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004271 {
4272 return RValue<UInt>(Nucleus::createMul(lhs.value, rhs.value));
4273 }
4274
John Bauman19bac1e2014-05-06 15:23:49 -04004275 RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004276 {
4277 return RValue<UInt>(Nucleus::createUDiv(lhs.value, rhs.value));
4278 }
4279
John Bauman19bac1e2014-05-06 15:23:49 -04004280 RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004281 {
4282 return RValue<UInt>(Nucleus::createURem(lhs.value, rhs.value));
4283 }
4284
John Bauman19bac1e2014-05-06 15:23:49 -04004285 RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004286 {
4287 return RValue<UInt>(Nucleus::createAnd(lhs.value, rhs.value));
4288 }
4289
John Bauman19bac1e2014-05-06 15:23:49 -04004290 RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004291 {
4292 return RValue<UInt>(Nucleus::createOr(lhs.value, rhs.value));
4293 }
4294
John Bauman19bac1e2014-05-06 15:23:49 -04004295 RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004296 {
4297 return RValue<UInt>(Nucleus::createXor(lhs.value, rhs.value));
4298 }
4299
John Bauman19bac1e2014-05-06 15:23:49 -04004300 RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004301 {
4302 return RValue<UInt>(Nucleus::createShl(lhs.value, rhs.value));
4303 }
4304
John Bauman19bac1e2014-05-06 15:23:49 -04004305 RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004306 {
4307 return RValue<UInt>(Nucleus::createLShr(lhs.value, rhs.value));
4308 }
4309
John Bauman19bac1e2014-05-06 15:23:49 -04004310 RValue<UInt> operator+=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004311 {
4312 return lhs = lhs + rhs;
4313 }
4314
John Bauman19bac1e2014-05-06 15:23:49 -04004315 RValue<UInt> operator-=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004316 {
4317 return lhs = lhs - rhs;
4318 }
4319
John Bauman19bac1e2014-05-06 15:23:49 -04004320 RValue<UInt> operator*=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004321 {
4322 return lhs = lhs * rhs;
4323 }
4324
John Bauman19bac1e2014-05-06 15:23:49 -04004325 RValue<UInt> operator/=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004326 {
4327 return lhs = lhs / rhs;
4328 }
4329
John Bauman19bac1e2014-05-06 15:23:49 -04004330 RValue<UInt> operator%=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004331 {
4332 return lhs = lhs % rhs;
4333 }
4334
John Bauman19bac1e2014-05-06 15:23:49 -04004335 RValue<UInt> operator&=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004336 {
4337 return lhs = lhs & rhs;
4338 }
4339
John Bauman19bac1e2014-05-06 15:23:49 -04004340 RValue<UInt> operator|=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004341 {
4342 return lhs = lhs | rhs;
4343 }
4344
John Bauman19bac1e2014-05-06 15:23:49 -04004345 RValue<UInt> operator^=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004346 {
4347 return lhs = lhs ^ rhs;
4348 }
4349
John Bauman19bac1e2014-05-06 15:23:49 -04004350 RValue<UInt> operator<<=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004351 {
4352 return lhs = lhs << rhs;
4353 }
4354
John Bauman19bac1e2014-05-06 15:23:49 -04004355 RValue<UInt> operator>>=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004356 {
4357 return lhs = lhs >> rhs;
4358 }
4359
John Bauman19bac1e2014-05-06 15:23:49 -04004360 RValue<UInt> operator+(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004361 {
4362 return val;
4363 }
4364
John Bauman19bac1e2014-05-06 15:23:49 -04004365 RValue<UInt> operator-(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004366 {
4367 return RValue<UInt>(Nucleus::createNeg(val.value));
4368 }
4369
John Bauman19bac1e2014-05-06 15:23:49 -04004370 RValue<UInt> operator~(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004371 {
4372 return RValue<UInt>(Nucleus::createNot(val.value));
4373 }
4374
4375 RValue<UInt> operator++(const UInt &val, int) // Post-increment
4376 {
4377 RValue<UInt> res = val;
4378
Nicolas Capens19336542016-09-26 10:32:29 -04004379 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04004380 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004381
4382 return res;
4383 }
4384
4385 const UInt &operator++(const UInt &val) // Pre-increment
4386 {
Nicolas Capens19336542016-09-26 10:32:29 -04004387 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04004388 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004389
4390 return val;
4391 }
4392
4393 RValue<UInt> operator--(const UInt &val, int) // Post-decrement
4394 {
4395 RValue<UInt> res = val;
4396
Nicolas Capens19336542016-09-26 10:32:29 -04004397 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04004398 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004399
4400 return res;
4401 }
4402
4403 const UInt &operator--(const UInt &val) // Pre-decrement
4404 {
Nicolas Capens19336542016-09-26 10:32:29 -04004405 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04004406 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004407
4408 return val;
4409 }
4410
John Bauman19bac1e2014-05-06 15:23:49 -04004411 RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y)
4412 {
4413 return IfThenElse(x > y, x, y);
4414 }
4415
4416 RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y)
4417 {
4418 return IfThenElse(x < y, x, y);
4419 }
4420
4421 RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max)
4422 {
4423 return Min(Max(x, min), max);
4424 }
4425
4426 RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004427 {
4428 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
4429 }
4430
John Bauman19bac1e2014-05-06 15:23:49 -04004431 RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004432 {
4433 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
4434 }
4435
John Bauman19bac1e2014-05-06 15:23:49 -04004436 RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004437 {
4438 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
4439 }
4440
John Bauman19bac1e2014-05-06 15:23:49 -04004441 RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004442 {
4443 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
4444 }
4445
John Bauman19bac1e2014-05-06 15:23:49 -04004446 RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004447 {
4448 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
4449 }
4450
John Bauman19bac1e2014-05-06 15:23:49 -04004451 RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004452 {
4453 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
4454 }
4455
John Bauman19bac1e2014-05-06 15:23:49 -04004456// RValue<UInt> RoundUInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04004457// {
4458// return x86::cvtss2si(val); // FIXME: Unsigned
4459//
John Bauman66b8ab22014-05-06 15:57:45 -04004460// // return IfThenElse(val > 0.0f, Int(val + 0.5f), Int(val - 0.5f));
John Bauman89401822014-05-06 15:04:28 -04004461// }
4462
John Bauman19bac1e2014-05-06 15:23:49 -04004463 Type *UInt::getType()
John Bauman89401822014-05-06 15:04:28 -04004464 {
Nicolas Capensac230122016-09-20 14:30:06 -04004465 return T(llvm::Type::getInt32Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04004466 }
4467
John Bauman19bac1e2014-05-06 15:23:49 -04004468// Int2::Int2(RValue<Int> cast)
4469// {
John Bauman19bac1e2014-05-06 15:23:49 -04004470// Value *extend = Nucleus::createZExt(cast.value, Long::getType());
4471// Value *vector = Nucleus::createBitCast(extend, Int2::getType());
John Bauman66b8ab22014-05-06 15:57:45 -04004472//
Nicolas Capense89cd582016-09-30 14:23:47 -04004473// int shuffle[2] = {0, 0};
4474// Value *replicate = Nucleus::createShuffleVector(vector, vector, shuffle);
John Bauman19bac1e2014-05-06 15:23:49 -04004475//
John Bauman66b8ab22014-05-06 15:57:45 -04004476// storeValue(replicate);
John Bauman19bac1e2014-05-06 15:23:49 -04004477// }
John Bauman89401822014-05-06 15:04:28 -04004478
John Bauman19bac1e2014-05-06 15:23:49 -04004479 Int2::Int2(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04004480 {
Nicolas Capens22008782016-10-20 01:11:47 -04004481 Value *long2 = Nucleus::createBitCast(cast.value, T(VectorType::get(Long::getType(), 2)));
Nicolas Capense95d5342016-09-30 11:37:28 -04004482 Value *element = Nucleus::createExtractElement(long2, Long::getType(), 0);
John Bauman89401822014-05-06 15:04:28 -04004483 Value *int2 = Nucleus::createBitCast(element, Int2::getType());
4484
John Bauman66b8ab22014-05-06 15:57:45 -04004485 storeValue(int2);
John Bauman89401822014-05-06 15:04:28 -04004486 }
4487
4488 Int2::Int2()
4489 {
4490 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004491 }
4492
4493 Int2::Int2(int x, int y)
4494 {
4495 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004496
Nicolas Capens13ac2322016-10-13 14:52:12 -04004497 int64_t constantVector[2] = {x, y};
4498 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(Int::getType(), 2))));
John Bauman89401822014-05-06 15:04:28 -04004499
John Bauman66b8ab22014-05-06 15:57:45 -04004500 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04004501 }
4502
John Bauman19bac1e2014-05-06 15:23:49 -04004503 Int2::Int2(RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004504 {
4505 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004506
John Bauman66b8ab22014-05-06 15:57:45 -04004507 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004508 }
4509
4510 Int2::Int2(const Int2 &rhs)
4511 {
4512 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004513
John Bauman66b8ab22014-05-06 15:57:45 -04004514 Value *value = rhs.loadValue();
4515 storeValue(value);
4516 }
4517
4518 Int2::Int2(const Reference<Int2> &rhs)
4519 {
4520 // xy.parent = this;
4521
4522 Value *value = rhs.loadValue();
4523 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004524 }
4525
Nicolas Capens62abb552016-01-05 12:03:47 -05004526 Int2::Int2(RValue<Int> lo, RValue<Int> hi)
4527 {
Nicolas Capensb40a2562016-01-05 00:08:45 -05004528 if(CPUID::supportsMMX2())
4529 {
4530 // movd mm0, lo
4531 // movd mm1, hi
4532 // punpckldq mm0, mm1
4533 storeValue(As<Int2>(UnpackLow(As<Int2>(Long1(RValue<UInt>(lo))), As<Int2>(Long1(RValue<UInt>(hi))))).value);
4534 }
4535 else
4536 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004537 int shuffle[2] = {0, 1};
4538 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 -05004539
Nicolas Capensb40a2562016-01-05 00:08:45 -05004540 storeValue(Nucleus::createBitCast(packed, Int2::getType()));
4541 }
Nicolas Capens62abb552016-01-05 12:03:47 -05004542 }
4543
John Bauman19bac1e2014-05-06 15:23:49 -04004544 RValue<Int2> Int2::operator=(RValue<Int2> rhs) const
John Bauman89401822014-05-06 15:04:28 -04004545 {
John Bauman66b8ab22014-05-06 15:57:45 -04004546 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004547
4548 return rhs;
4549 }
4550
4551 RValue<Int2> Int2::operator=(const Int2 &rhs) const
4552 {
John Bauman66b8ab22014-05-06 15:57:45 -04004553 Value *value = rhs.loadValue();
4554 storeValue(value);
4555
4556 return RValue<Int2>(value);
4557 }
4558
4559 RValue<Int2> Int2::operator=(const Reference<Int2> &rhs) const
4560 {
4561 Value *value = rhs.loadValue();
4562 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004563
4564 return RValue<Int2>(value);
4565 }
4566
John Bauman19bac1e2014-05-06 15:23:49 -04004567 RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004568 {
John Bauman19bac1e2014-05-06 15:23:49 -04004569 if(CPUID::supportsMMX2())
4570 {
4571 return x86::paddd(lhs, rhs);
4572 }
4573 else
4574 {
4575 return RValue<Int2>(Nucleus::createAdd(lhs.value, rhs.value));
4576 }
John Bauman89401822014-05-06 15:04:28 -04004577 }
4578
John Bauman19bac1e2014-05-06 15:23:49 -04004579 RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004580 {
John Bauman19bac1e2014-05-06 15:23:49 -04004581 if(CPUID::supportsMMX2())
4582 {
4583 return x86::psubd(lhs, rhs);
4584 }
4585 else
4586 {
4587 return RValue<Int2>(Nucleus::createSub(lhs.value, rhs.value));
4588 }
John Bauman89401822014-05-06 15:04:28 -04004589 }
4590
John Bauman19bac1e2014-05-06 15:23:49 -04004591// RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs)
4592// {
4593// return RValue<Int2>(Nucleus::createMul(lhs.value, rhs.value));
4594// }
4595
4596// RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs)
4597// {
4598// return RValue<Int2>(Nucleus::createSDiv(lhs.value, rhs.value));
4599// }
4600
4601// RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs)
4602// {
4603// return RValue<Int2>(Nucleus::createSRem(lhs.value, rhs.value));
4604// }
4605
4606 RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004607 {
John Bauman19bac1e2014-05-06 15:23:49 -04004608 if(CPUID::supportsMMX2())
4609 {
4610 return As<Int2>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
4611 }
4612 else
4613 {
4614 return RValue<Int2>(Nucleus::createAnd(lhs.value, rhs.value));
4615 }
John Bauman89401822014-05-06 15:04:28 -04004616 }
4617
John Bauman19bac1e2014-05-06 15:23:49 -04004618 RValue<Int2> operator|(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004619 {
John Bauman19bac1e2014-05-06 15:23:49 -04004620 if(CPUID::supportsMMX2())
4621 {
4622 return As<Int2>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
4623 }
4624 else
4625 {
4626 return RValue<Int2>(Nucleus::createOr(lhs.value, rhs.value));
4627 }
John Bauman89401822014-05-06 15:04:28 -04004628 }
4629
John Bauman19bac1e2014-05-06 15:23:49 -04004630 RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004631 {
John Bauman19bac1e2014-05-06 15:23:49 -04004632 if(CPUID::supportsMMX2())
4633 {
4634 return As<Int2>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
4635 }
4636 else
4637 {
4638 return RValue<Int2>(Nucleus::createXor(lhs.value, rhs.value));
4639 }
John Bauman89401822014-05-06 15:04:28 -04004640 }
4641
John Bauman19bac1e2014-05-06 15:23:49 -04004642 RValue<Int2> operator<<(RValue<Int2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004643 {
4644 // return RValue<Int2>(Nucleus::createShl(lhs.value, rhs.value));
4645
4646 return x86::pslld(lhs, rhs);
4647 }
4648
John Bauman19bac1e2014-05-06 15:23:49 -04004649 RValue<Int2> operator>>(RValue<Int2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004650 {
4651 // return RValue<Int2>(Nucleus::createAShr(lhs.value, rhs.value));
4652
4653 return x86::psrad(lhs, rhs);
4654 }
4655
John Bauman19bac1e2014-05-06 15:23:49 -04004656 RValue<Int2> operator<<(RValue<Int2> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004657 {
4658 // return RValue<Int2>(Nucleus::createShl(lhs.value, rhs.value));
4659
4660 return x86::pslld(lhs, rhs);
4661 }
4662
John Bauman19bac1e2014-05-06 15:23:49 -04004663 RValue<Int2> operator>>(RValue<Int2> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004664 {
4665 // return RValue<Int2>(Nucleus::createAShr(lhs.value, rhs.value));
4666
4667 return x86::psrad(lhs, rhs);
4668 }
4669
John Bauman19bac1e2014-05-06 15:23:49 -04004670 RValue<Int2> operator+=(const Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004671 {
4672 return lhs = lhs + rhs;
4673 }
4674
John Bauman19bac1e2014-05-06 15:23:49 -04004675 RValue<Int2> operator-=(const Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004676 {
4677 return lhs = lhs - rhs;
4678 }
4679
John Bauman19bac1e2014-05-06 15:23:49 -04004680// RValue<Int2> operator*=(const Int2 &lhs, RValue<Int2> rhs)
4681// {
4682// return lhs = lhs * rhs;
4683// }
John Bauman89401822014-05-06 15:04:28 -04004684
John Bauman19bac1e2014-05-06 15:23:49 -04004685// RValue<Int2> operator/=(const Int2 &lhs, RValue<Int2> rhs)
4686// {
4687// return lhs = lhs / rhs;
4688// }
John Bauman89401822014-05-06 15:04:28 -04004689
John Bauman19bac1e2014-05-06 15:23:49 -04004690// RValue<Int2> operator%=(const Int2 &lhs, RValue<Int2> rhs)
4691// {
4692// return lhs = lhs % rhs;
4693// }
John Bauman89401822014-05-06 15:04:28 -04004694
John Bauman19bac1e2014-05-06 15:23:49 -04004695 RValue<Int2> operator&=(const Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004696 {
4697 return lhs = lhs & rhs;
4698 }
4699
John Bauman19bac1e2014-05-06 15:23:49 -04004700 RValue<Int2> operator|=(const Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004701 {
4702 return lhs = lhs | rhs;
4703 }
4704
John Bauman19bac1e2014-05-06 15:23:49 -04004705 RValue<Int2> operator^=(const Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004706 {
4707 return lhs = lhs ^ rhs;
4708 }
4709
4710 RValue<Int2> operator<<=(const Int2 &lhs, unsigned char rhs)
4711 {
4712 return lhs = lhs << rhs;
4713 }
4714
4715 RValue<Int2> operator>>=(const Int2 &lhs, unsigned char rhs)
4716 {
4717 return lhs = lhs >> rhs;
4718 }
4719
John Bauman19bac1e2014-05-06 15:23:49 -04004720 RValue<Int2> operator<<=(const Int2 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004721 {
4722 return lhs = lhs << rhs;
4723 }
4724
John Bauman19bac1e2014-05-06 15:23:49 -04004725 RValue<Int2> operator>>=(const Int2 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004726 {
4727 return lhs = lhs >> rhs;
4728 }
4729
John Bauman19bac1e2014-05-06 15:23:49 -04004730// RValue<Int2> operator+(RValue<Int2> val)
4731// {
4732// return val;
4733// }
4734
4735// RValue<Int2> operator-(RValue<Int2> val)
4736// {
4737// return RValue<Int2>(Nucleus::createNeg(val.value));
4738// }
4739
4740 RValue<Int2> operator~(RValue<Int2> val)
John Bauman89401822014-05-06 15:04:28 -04004741 {
John Bauman19bac1e2014-05-06 15:23:49 -04004742 if(CPUID::supportsMMX2())
4743 {
4744 return val ^ Int2(0xFFFFFFFF, 0xFFFFFFFF);
4745 }
4746 else
4747 {
4748 return RValue<Int2>(Nucleus::createNot(val.value));
4749 }
John Bauman89401822014-05-06 15:04:28 -04004750 }
4751
John Bauman19bac1e2014-05-06 15:23:49 -04004752 RValue<Long1> UnpackLow(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04004753 {
John Bauman19bac1e2014-05-06 15:23:49 -04004754 if(CPUID::supportsMMX2())
4755 {
4756 return x86::punpckldq(x, y);
4757 }
4758 else
4759 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004760 int shuffle[2] = {0, 2};
4761 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04004762
John Bauman19bac1e2014-05-06 15:23:49 -04004763 return RValue<Long1>(Nucleus::createBitCast(packed, Long1::getType()));
4764 }
John Bauman89401822014-05-06 15:04:28 -04004765 }
John Bauman66b8ab22014-05-06 15:57:45 -04004766
John Bauman19bac1e2014-05-06 15:23:49 -04004767 RValue<Long1> UnpackHigh(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04004768 {
John Bauman19bac1e2014-05-06 15:23:49 -04004769 if(CPUID::supportsMMX2())
4770 {
4771 return x86::punpckhdq(x, y);
4772 }
4773 else
4774 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004775 int shuffle[2] = {1, 3};
4776 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04004777
John Bauman19bac1e2014-05-06 15:23:49 -04004778 return RValue<Long1>(Nucleus::createBitCast(packed, Long1::getType()));
4779 }
John Bauman89401822014-05-06 15:04:28 -04004780 }
4781
John Bauman19bac1e2014-05-06 15:23:49 -04004782 RValue<Int> Extract(RValue<Int2> val, int i)
John Bauman89401822014-05-06 15:04:28 -04004783 {
4784 if(false) // FIXME: LLVM does not generate optimal code
4785 {
Nicolas Capense95d5342016-09-30 11:37:28 -04004786 return RValue<Int>(Nucleus::createExtractElement(val.value, Int::getType(), i));
John Bauman89401822014-05-06 15:04:28 -04004787 }
4788 else
4789 {
4790 if(i == 0)
4791 {
Nicolas Capense95d5342016-09-30 11:37:28 -04004792 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 -04004793 }
4794 else
4795 {
4796 Int2 val2 = As<Int2>(UnpackHigh(val, val));
4797
4798 return Extract(val2, 0);
4799 }
4800 }
4801 }
4802
Nicolas Capensfff3c9b2015-05-13 23:40:44 -04004803 RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i)
4804 {
Nicolas Capensac230122016-09-20 14:30:06 -04004805 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 -04004806 }
John Bauman89401822014-05-06 15:04:28 -04004807
John Bauman19bac1e2014-05-06 15:23:49 -04004808 Type *Int2::getType()
John Bauman89401822014-05-06 15:04:28 -04004809 {
John Bauman19bac1e2014-05-06 15:23:49 -04004810 if(CPUID::supportsMMX2())
4811 {
4812 return MMX::getType();
4813 }
4814 else
4815 {
Nicolas Capensac230122016-09-20 14:30:06 -04004816 return T(VectorType::get(Int::getType(), 2));
John Bauman19bac1e2014-05-06 15:23:49 -04004817 }
John Bauman89401822014-05-06 15:04:28 -04004818 }
4819
4820 UInt2::UInt2()
4821 {
4822 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004823 }
4824
4825 UInt2::UInt2(unsigned int x, unsigned int y)
4826 {
4827 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004828
Nicolas Capens13ac2322016-10-13 14:52:12 -04004829 int64_t constantVector[2] = {x, y};
4830 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(UInt::getType(), 2))));
John Bauman89401822014-05-06 15:04:28 -04004831
John Bauman66b8ab22014-05-06 15:57:45 -04004832 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04004833 }
4834
John Bauman19bac1e2014-05-06 15:23:49 -04004835 UInt2::UInt2(RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004836 {
4837 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004838
John Bauman66b8ab22014-05-06 15:57:45 -04004839 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004840 }
4841
4842 UInt2::UInt2(const UInt2 &rhs)
4843 {
4844 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004845
John Bauman66b8ab22014-05-06 15:57:45 -04004846 Value *value = rhs.loadValue();
4847 storeValue(value);
4848 }
4849
4850 UInt2::UInt2(const Reference<UInt2> &rhs)
4851 {
4852 // xy.parent = this;
4853
4854 Value *value = rhs.loadValue();
4855 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004856 }
4857
John Bauman19bac1e2014-05-06 15:23:49 -04004858 RValue<UInt2> UInt2::operator=(RValue<UInt2> rhs) const
John Bauman89401822014-05-06 15:04:28 -04004859 {
John Bauman66b8ab22014-05-06 15:57:45 -04004860 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004861
4862 return rhs;
4863 }
4864
4865 RValue<UInt2> UInt2::operator=(const UInt2 &rhs) const
4866 {
John Bauman66b8ab22014-05-06 15:57:45 -04004867 Value *value = rhs.loadValue();
4868 storeValue(value);
4869
4870 return RValue<UInt2>(value);
4871 }
4872
4873 RValue<UInt2> UInt2::operator=(const Reference<UInt2> &rhs) const
4874 {
4875 Value *value = rhs.loadValue();
4876 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004877
4878 return RValue<UInt2>(value);
4879 }
4880
John Bauman19bac1e2014-05-06 15:23:49 -04004881 RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004882 {
John Bauman19bac1e2014-05-06 15:23:49 -04004883 if(CPUID::supportsMMX2())
4884 {
4885 return As<UInt2>(x86::paddd(As<Int2>(lhs), As<Int2>(rhs)));
4886 }
4887 else
4888 {
4889 return RValue<UInt2>(Nucleus::createAdd(lhs.value, rhs.value));
4890 }
John Bauman89401822014-05-06 15:04:28 -04004891 }
4892
John Bauman19bac1e2014-05-06 15:23:49 -04004893 RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004894 {
John Bauman19bac1e2014-05-06 15:23:49 -04004895 if(CPUID::supportsMMX2())
4896 {
4897 return As<UInt2>(x86::psubd(As<Int2>(lhs), As<Int2>(rhs)));
4898 }
4899 else
4900 {
4901 return RValue<UInt2>(Nucleus::createSub(lhs.value, rhs.value));
4902 }
John Bauman89401822014-05-06 15:04:28 -04004903 }
4904
John Bauman19bac1e2014-05-06 15:23:49 -04004905// RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs)
4906// {
4907// return RValue<UInt2>(Nucleus::createMul(lhs.value, rhs.value));
4908// }
4909
4910// RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs)
4911// {
4912// return RValue<UInt2>(Nucleus::createUDiv(lhs.value, rhs.value));
4913// }
4914
4915// RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs)
4916// {
4917// return RValue<UInt2>(Nucleus::createURem(lhs.value, rhs.value));
4918// }
4919
4920 RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004921 {
John Bauman19bac1e2014-05-06 15:23:49 -04004922 if(CPUID::supportsMMX2())
4923 {
4924 return As<UInt2>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
4925 }
4926 else
4927 {
4928 return RValue<UInt2>(Nucleus::createAnd(lhs.value, rhs.value));
4929 }
John Bauman89401822014-05-06 15:04:28 -04004930 }
4931
John Bauman19bac1e2014-05-06 15:23:49 -04004932 RValue<UInt2> operator|(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004933 {
John Bauman19bac1e2014-05-06 15:23:49 -04004934 if(CPUID::supportsMMX2())
4935 {
4936 return As<UInt2>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
4937 }
4938 else
4939 {
4940 return RValue<UInt2>(Nucleus::createOr(lhs.value, rhs.value));
4941 }
John Bauman89401822014-05-06 15:04:28 -04004942 }
4943
John Bauman19bac1e2014-05-06 15:23:49 -04004944 RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004945 {
John Bauman19bac1e2014-05-06 15:23:49 -04004946 if(CPUID::supportsMMX2())
4947 {
4948 return As<UInt2>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
4949 }
4950 else
4951 {
4952 return RValue<UInt2>(Nucleus::createXor(lhs.value, rhs.value));
4953 }
John Bauman89401822014-05-06 15:04:28 -04004954 }
4955
John Bauman19bac1e2014-05-06 15:23:49 -04004956 RValue<UInt2> operator<<(RValue<UInt2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004957 {
4958 // return RValue<UInt2>(Nucleus::createShl(lhs.value, rhs.value));
4959
4960 return As<UInt2>(x86::pslld(As<Int2>(lhs), rhs));
4961 }
4962
John Bauman19bac1e2014-05-06 15:23:49 -04004963 RValue<UInt2> operator>>(RValue<UInt2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004964 {
4965 // return RValue<UInt2>(Nucleus::createLShr(lhs.value, rhs.value));
4966
4967 return x86::psrld(lhs, rhs);
4968 }
4969
John Bauman19bac1e2014-05-06 15:23:49 -04004970 RValue<UInt2> operator<<(RValue<UInt2> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004971 {
4972 // return RValue<UInt2>(Nucleus::createShl(lhs.value, rhs.value));
4973
4974 return As<UInt2>(x86::pslld(As<Int2>(lhs), rhs));
4975 }
4976
John Bauman19bac1e2014-05-06 15:23:49 -04004977 RValue<UInt2> operator>>(RValue<UInt2> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004978 {
4979 // return RValue<UInt2>(Nucleus::createLShr(lhs.value, rhs.value));
4980
4981 return x86::psrld(lhs, rhs);
4982 }
4983
John Bauman19bac1e2014-05-06 15:23:49 -04004984 RValue<UInt2> operator+=(const UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004985 {
4986 return lhs = lhs + rhs;
4987 }
4988
John Bauman19bac1e2014-05-06 15:23:49 -04004989 RValue<UInt2> operator-=(const UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004990 {
4991 return lhs = lhs - rhs;
4992 }
4993
John Bauman19bac1e2014-05-06 15:23:49 -04004994// RValue<UInt2> operator*=(const UInt2 &lhs, RValue<UInt2> rhs)
4995// {
4996// return lhs = lhs * rhs;
4997// }
John Bauman89401822014-05-06 15:04:28 -04004998
John Bauman19bac1e2014-05-06 15:23:49 -04004999// RValue<UInt2> operator/=(const UInt2 &lhs, RValue<UInt2> rhs)
5000// {
5001// return lhs = lhs / rhs;
5002// }
John Bauman89401822014-05-06 15:04:28 -04005003
John Bauman19bac1e2014-05-06 15:23:49 -04005004// RValue<UInt2> operator%=(const UInt2 &lhs, RValue<UInt2> rhs)
5005// {
5006// return lhs = lhs % rhs;
5007// }
John Bauman89401822014-05-06 15:04:28 -04005008
John Bauman19bac1e2014-05-06 15:23:49 -04005009 RValue<UInt2> operator&=(const UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005010 {
5011 return lhs = lhs & rhs;
5012 }
5013
John Bauman19bac1e2014-05-06 15:23:49 -04005014 RValue<UInt2> operator|=(const UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005015 {
5016 return lhs = lhs | rhs;
5017 }
5018
John Bauman19bac1e2014-05-06 15:23:49 -04005019 RValue<UInt2> operator^=(const UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005020 {
5021 return lhs = lhs ^ rhs;
5022 }
5023
5024 RValue<UInt2> operator<<=(const UInt2 &lhs, unsigned char rhs)
5025 {
5026 return lhs = lhs << rhs;
5027 }
5028
5029 RValue<UInt2> operator>>=(const UInt2 &lhs, unsigned char rhs)
5030 {
5031 return lhs = lhs >> rhs;
5032 }
5033
John Bauman19bac1e2014-05-06 15:23:49 -04005034 RValue<UInt2> operator<<=(const UInt2 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04005035 {
5036 return lhs = lhs << rhs;
5037 }
5038
John Bauman19bac1e2014-05-06 15:23:49 -04005039 RValue<UInt2> operator>>=(const UInt2 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04005040 {
5041 return lhs = lhs >> rhs;
5042 }
5043
John Bauman19bac1e2014-05-06 15:23:49 -04005044// RValue<UInt2> operator+(RValue<UInt2> val)
5045// {
5046// return val;
5047// }
5048
5049// RValue<UInt2> operator-(RValue<UInt2> val)
5050// {
5051// return RValue<UInt2>(Nucleus::createNeg(val.value));
5052// }
5053
5054 RValue<UInt2> operator~(RValue<UInt2> val)
John Bauman89401822014-05-06 15:04:28 -04005055 {
John Bauman19bac1e2014-05-06 15:23:49 -04005056 if(CPUID::supportsMMX2())
5057 {
5058 return val ^ UInt2(0xFFFFFFFF, 0xFFFFFFFF);
5059 }
5060 else
5061 {
5062 return RValue<UInt2>(Nucleus::createNot(val.value));
5063 }
John Bauman89401822014-05-06 15:04:28 -04005064 }
5065
John Bauman19bac1e2014-05-06 15:23:49 -04005066 Type *UInt2::getType()
John Bauman89401822014-05-06 15:04:28 -04005067 {
John Bauman19bac1e2014-05-06 15:23:49 -04005068 if(CPUID::supportsMMX2())
5069 {
5070 return MMX::getType();
5071 }
5072 else
5073 {
Nicolas Capensac230122016-09-20 14:30:06 -04005074 return T(VectorType::get(UInt::getType(), 2));
John Bauman19bac1e2014-05-06 15:23:49 -04005075 }
John Bauman89401822014-05-06 15:04:28 -04005076 }
5077
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005078 Int4::Int4(RValue<Byte4> cast)
5079 {
5080 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
Nicolas Capens19336542016-09-26 10:32:29 -04005081 Value *a = Nucleus::createInsertElement(V(UndefValue::get(Int4::getType())), x, 0);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005082
5083 Value *e;
5084
5085 if (CPUID::supportsSSE4_1())
5086 {
5087 e = x86::pmovzxbd(RValue<Int4>(a)).value;
5088 }
5089 else
5090 {
Nicolas Capense89cd582016-09-30 14:23:47 -04005091 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 -04005092 Value *b = Nucleus::createBitCast(a, Byte16::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04005093 Value *c = Nucleus::createShuffleVector(b, V(Nucleus::createNullValue(Byte16::getType())), swizzle);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005094
Nicolas Capense89cd582016-09-30 14:23:47 -04005095 int swizzle2[8] = {0, 8, 1, 9, 2, 10, 3, 11};
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005096 Value *d = Nucleus::createBitCast(c, Short8::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04005097 e = Nucleus::createShuffleVector(d, V(Nucleus::createNullValue(Short8::getType())), swizzle2);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005098 }
5099
5100 Value *f = Nucleus::createBitCast(e, Int4::getType());
5101 storeValue(f);
5102 }
5103
5104 Int4::Int4(RValue<SByte4> cast)
5105 {
5106 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
Nicolas Capens19336542016-09-26 10:32:29 -04005107 Value *a = Nucleus::createInsertElement(V(UndefValue::get(Int4::getType())), x, 0);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005108
5109 Value *g;
5110
5111 if (CPUID::supportsSSE4_1())
5112 {
5113 g = x86::pmovsxbd(RValue<Int4>(a)).value;
5114 }
5115 else
5116 {
Nicolas Capense89cd582016-09-30 14:23:47 -04005117 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 -04005118 Value *b = Nucleus::createBitCast(a, Byte16::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04005119 Value *c = Nucleus::createShuffleVector(b, b, swizzle);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005120
Nicolas Capense89cd582016-09-30 14:23:47 -04005121 int swizzle2[8] = {0, 0, 1, 1, 2, 2, 3, 3};
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005122 Value *d = Nucleus::createBitCast(c, Short8::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04005123 Value *e = Nucleus::createShuffleVector(d, d, swizzle2);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005124
5125 Value *f = Nucleus::createBitCast(e, Int4::getType());
5126 // g = Nucleus::createAShr(f, Nucleus::createConstantInt(24));
5127 g = x86::psrad(RValue<Int4>(f), 24).value;
5128 }
5129
5130 storeValue(g);
5131 }
5132
John Bauman19bac1e2014-05-06 15:23:49 -04005133 Int4::Int4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005134 {
5135 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005136
5137 Value *xyzw = Nucleus::createFPToSI(cast.value, Int4::getType());
John Bauman89401822014-05-06 15:04:28 -04005138
John Bauman66b8ab22014-05-06 15:57:45 -04005139 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04005140 }
5141
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005142 Int4::Int4(RValue<Short4> cast)
5143 {
Nicolas Capens22008782016-10-20 01:11:47 -04005144 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005145 Value *element = Nucleus::createBitCast(cast.value, Long::getType());
5146 long2 = Nucleus::createInsertElement(long2, element, 0);
5147 RValue<Int4> vector = RValue<Int4>(Nucleus::createBitCast(long2, Int4::getType()));
Nicolas Capens05b3d662016-02-25 23:58:33 -05005148
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005149 if(CPUID::supportsSSE4_1())
5150 {
5151 storeValue(x86::pmovsxwd(vector).value);
5152 }
5153 else
5154 {
5155 Value *b = Nucleus::createBitCast(vector.value, Short8::getType());
5156
Nicolas Capense89cd582016-09-30 14:23:47 -04005157 int swizzle[8] = {0, 0, 1, 1, 2, 2, 3, 3};
5158 Value *c = Nucleus::createShuffleVector(b, b, swizzle);
Nicolas Capens6ce5c332015-10-28 01:58:18 -04005159 Value *d = Nucleus::createBitCast(c, Int4::getType());
5160 storeValue(d);
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005161
5162 // Each Short is packed into each Int in the (Short | Short) format.
5163 // Shifting by 16 will retrieve the original Short value.
5164 // Shitfing an Int will propagate the sign bit, which will work
5165 // for both positive and negative values of a Short.
5166 *this >>= 16;
5167 }
5168 }
5169
5170 Int4::Int4(RValue<UShort4> cast)
5171 {
Nicolas Capens22008782016-10-20 01:11:47 -04005172 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005173 Value *element = Nucleus::createBitCast(cast.value, Long::getType());
5174 long2 = Nucleus::createInsertElement(long2, element, 0);
5175 RValue<Int4> vector = RValue<Int4>(Nucleus::createBitCast(long2, Int4::getType()));
5176
5177 if(CPUID::supportsSSE4_1())
5178 {
5179 storeValue(x86::pmovzxwd(RValue<Int4>(vector)).value);
5180 }
5181 else
5182 {
5183 Value *b = Nucleus::createBitCast(vector.value, Short8::getType());
5184
Nicolas Capense89cd582016-09-30 14:23:47 -04005185 int swizzle[8] = {0, 8, 1, 9, 2, 10, 3, 11};
5186 Value *c = Nucleus::createShuffleVector(b, V(Nucleus::createNullValue(Short8::getType())), swizzle);
Nicolas Capens6ce5c332015-10-28 01:58:18 -04005187 Value *d = Nucleus::createBitCast(c, Int4::getType());
5188 storeValue(d);
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005189 }
5190 }
5191
John Bauman89401822014-05-06 15:04:28 -04005192 Int4::Int4()
5193 {
5194 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005195 }
5196
5197 Int4::Int4(int xyzw)
5198 {
5199 constant(xyzw, xyzw, xyzw, xyzw);
5200 }
5201
5202 Int4::Int4(int x, int yzw)
5203 {
5204 constant(x, yzw, yzw, yzw);
5205 }
5206
5207 Int4::Int4(int x, int y, int zw)
5208 {
5209 constant(x, y, zw, zw);
5210 }
5211
5212 Int4::Int4(int x, int y, int z, int w)
5213 {
5214 constant(x, y, z, w);
5215 }
5216
5217 void Int4::constant(int x, int y, int z, int w)
5218 {
5219 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005220
Nicolas Capens13ac2322016-10-13 14:52:12 -04005221 int64_t constantVector[4] = {x, y, z, w};
5222 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04005223 }
5224
John Bauman19bac1e2014-05-06 15:23:49 -04005225 Int4::Int4(RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005226 {
5227 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005228
John Bauman66b8ab22014-05-06 15:57:45 -04005229 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005230 }
5231
5232 Int4::Int4(const Int4 &rhs)
5233 {
5234 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005235
John Bauman66b8ab22014-05-06 15:57:45 -04005236 Value *value = rhs.loadValue();
5237 storeValue(value);
5238 }
5239
5240 Int4::Int4(const Reference<Int4> &rhs)
5241 {
5242 // xyzw.parent = this;
5243
5244 Value *value = rhs.loadValue();
5245 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005246 }
5247
John Bauman19bac1e2014-05-06 15:23:49 -04005248 Int4::Int4(RValue<UInt4> rhs)
5249 {
5250 // xyzw.parent = this;
John Bauman19bac1e2014-05-06 15:23:49 -04005251
John Bauman66b8ab22014-05-06 15:57:45 -04005252 storeValue(rhs.value);
John Bauman19bac1e2014-05-06 15:23:49 -04005253 }
5254
5255 Int4::Int4(const UInt4 &rhs)
5256 {
5257 // xyzw.parent = this;
John Bauman19bac1e2014-05-06 15:23:49 -04005258
John Bauman66b8ab22014-05-06 15:57:45 -04005259 Value *value = rhs.loadValue();
5260 storeValue(value);
5261 }
5262
5263 Int4::Int4(const Reference<UInt4> &rhs)
5264 {
5265 // xyzw.parent = this;
5266
5267 Value *value = rhs.loadValue();
5268 storeValue(value);
John Bauman19bac1e2014-05-06 15:23:49 -04005269 }
5270
Nicolas Capens62abb552016-01-05 12:03:47 -05005271 Int4::Int4(RValue<Int2> lo, RValue<Int2> hi)
5272 {
Nicolas Capens24c8cf02016-08-15 15:33:14 -04005273 // xyzw.parent = this;
5274
Nicolas Capens62abb552016-01-05 12:03:47 -05005275 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
5276 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
5277
Nicolas Capens22008782016-10-20 01:11:47 -04005278 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Nicolas Capens62abb552016-01-05 12:03:47 -05005279 long2 = Nucleus::createInsertElement(long2, loLong, 0);
5280 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
5281 Value *int4 = Nucleus::createBitCast(long2, Int4::getType());
5282
5283 storeValue(int4);
5284 }
5285
Nicolas Capens24c8cf02016-08-15 15:33:14 -04005286 Int4::Int4(RValue<Int> rhs)
5287 {
5288 // xyzw.parent = this;
5289
5290 Value *vector = loadValue();
5291 Value *insert = Nucleus::createInsertElement(vector, rhs.value, 0);
5292
Nicolas Capense89cd582016-09-30 14:23:47 -04005293 int swizzle[4] = {0, 0, 0, 0};
5294 Value *replicate = Nucleus::createShuffleVector(insert, insert, swizzle);
Nicolas Capens24c8cf02016-08-15 15:33:14 -04005295
5296 storeValue(replicate);
5297 }
5298
5299 Int4::Int4(const Int &rhs)
5300 {
5301 // xyzw.parent = this;
5302
5303 *this = RValue<Int>(rhs.loadValue());
5304 }
5305
5306 Int4::Int4(const Reference<Int> &rhs)
5307 {
5308 // xyzw.parent = this;
5309
5310 *this = RValue<Int>(rhs.loadValue());
5311 }
5312
John Bauman19bac1e2014-05-06 15:23:49 -04005313 RValue<Int4> Int4::operator=(RValue<Int4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04005314 {
John Bauman66b8ab22014-05-06 15:57:45 -04005315 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005316
5317 return rhs;
5318 }
5319
5320 RValue<Int4> Int4::operator=(const Int4 &rhs) const
5321 {
John Bauman66b8ab22014-05-06 15:57:45 -04005322 Value *value = rhs.loadValue();
5323 storeValue(value);
5324
5325 return RValue<Int4>(value);
5326 }
5327
5328 RValue<Int4> Int4::operator=(const Reference<Int4> &rhs) const
5329 {
5330 Value *value = rhs.loadValue();
5331 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005332
5333 return RValue<Int4>(value);
5334 }
5335
John Bauman19bac1e2014-05-06 15:23:49 -04005336 RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005337 {
5338 return RValue<Int4>(Nucleus::createAdd(lhs.value, rhs.value));
5339 }
5340
John Bauman19bac1e2014-05-06 15:23:49 -04005341 RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005342 {
5343 return RValue<Int4>(Nucleus::createSub(lhs.value, rhs.value));
5344 }
5345
John Bauman19bac1e2014-05-06 15:23:49 -04005346 RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005347 {
5348 return RValue<Int4>(Nucleus::createMul(lhs.value, rhs.value));
5349 }
5350
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005351 RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs)
5352 {
5353 return RValue<Int4>(Nucleus::createSDiv(lhs.value, rhs.value));
5354 }
John Bauman89401822014-05-06 15:04:28 -04005355
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005356 RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs)
5357 {
5358 return RValue<Int4>(Nucleus::createSRem(lhs.value, rhs.value));
5359 }
John Bauman89401822014-05-06 15:04:28 -04005360
John Bauman19bac1e2014-05-06 15:23:49 -04005361 RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005362 {
5363 return RValue<Int4>(Nucleus::createAnd(lhs.value, rhs.value));
5364 }
5365
John Bauman19bac1e2014-05-06 15:23:49 -04005366 RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005367 {
5368 return RValue<Int4>(Nucleus::createOr(lhs.value, rhs.value));
5369 }
5370
John Bauman19bac1e2014-05-06 15:23:49 -04005371 RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005372 {
5373 return RValue<Int4>(Nucleus::createXor(lhs.value, rhs.value));
5374 }
5375
John Bauman19bac1e2014-05-06 15:23:49 -04005376 RValue<Int4> operator<<(RValue<Int4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005377 {
John Bauman89401822014-05-06 15:04:28 -04005378 return x86::pslld(lhs, rhs);
5379 }
5380
John Bauman19bac1e2014-05-06 15:23:49 -04005381 RValue<Int4> operator>>(RValue<Int4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005382 {
John Bauman89401822014-05-06 15:04:28 -04005383 return x86::psrad(lhs, rhs);
5384 }
5385
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005386 RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs)
5387 {
5388 return RValue<Int4>(Nucleus::createShl(lhs.value, rhs.value));
5389 }
5390
5391 RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs)
5392 {
5393 return RValue<Int4>(Nucleus::createAShr(lhs.value, rhs.value));
5394 }
5395
John Bauman19bac1e2014-05-06 15:23:49 -04005396 RValue<Int4> operator+=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005397 {
5398 return lhs = lhs + rhs;
5399 }
5400
John Bauman19bac1e2014-05-06 15:23:49 -04005401 RValue<Int4> operator-=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005402 {
5403 return lhs = lhs - rhs;
5404 }
5405
John Bauman19bac1e2014-05-06 15:23:49 -04005406 RValue<Int4> operator*=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005407 {
5408 return lhs = lhs * rhs;
5409 }
5410
John Bauman19bac1e2014-05-06 15:23:49 -04005411// RValue<Int4> operator/=(const Int4 &lhs, RValue<Int4> rhs)
5412// {
5413// return lhs = lhs / rhs;
5414// }
John Bauman89401822014-05-06 15:04:28 -04005415
John Bauman19bac1e2014-05-06 15:23:49 -04005416// RValue<Int4> operator%=(const Int4 &lhs, RValue<Int4> rhs)
5417// {
5418// return lhs = lhs % rhs;
5419// }
John Bauman89401822014-05-06 15:04:28 -04005420
John Bauman19bac1e2014-05-06 15:23:49 -04005421 RValue<Int4> operator&=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005422 {
5423 return lhs = lhs & rhs;
5424 }
5425
John Bauman19bac1e2014-05-06 15:23:49 -04005426 RValue<Int4> operator|=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005427 {
5428 return lhs = lhs | rhs;
5429 }
5430
John Bauman19bac1e2014-05-06 15:23:49 -04005431 RValue<Int4> operator^=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005432 {
5433 return lhs = lhs ^ rhs;
5434 }
5435
5436 RValue<Int4> operator<<=(const Int4 &lhs, unsigned char rhs)
5437 {
5438 return lhs = lhs << rhs;
5439 }
5440
5441 RValue<Int4> operator>>=(const Int4 &lhs, unsigned char rhs)
5442 {
5443 return lhs = lhs >> rhs;
5444 }
5445
John Bauman19bac1e2014-05-06 15:23:49 -04005446 RValue<Int4> operator+(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005447 {
5448 return val;
5449 }
5450
John Bauman19bac1e2014-05-06 15:23:49 -04005451 RValue<Int4> operator-(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005452 {
5453 return RValue<Int4>(Nucleus::createNeg(val.value));
5454 }
5455
John Bauman19bac1e2014-05-06 15:23:49 -04005456 RValue<Int4> operator~(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005457 {
5458 return RValue<Int4>(Nucleus::createNot(val.value));
5459 }
5460
John Bauman19bac1e2014-05-06 15:23:49 -04005461 RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y)
5462 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005463 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
Alexis Hetufb603992016-04-26 11:50:40 -04005464 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5465 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
5466 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005467 }
5468
5469 RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y)
5470 {
5471 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLT(x.value, y.value), Int4::getType()));
5472 }
5473
5474 RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y)
5475 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005476 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5477 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5478 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLE(x.value, y.value), Int4::getType()));
5479 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGT(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005480 }
5481
5482 RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y)
5483 {
5484 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
5485 }
5486
5487 RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y)
5488 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005489 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5490 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5491 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGE(x.value, y.value), Int4::getType()));
5492 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLT(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005493 }
5494
5495 RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y)
5496 {
5497 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGT(x.value, y.value), Int4::getType()));
5498 }
5499
5500 RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y)
5501 {
5502 if(CPUID::supportsSSE4_1())
5503 {
5504 return x86::pmaxsd(x, y);
5505 }
5506 else
5507 {
5508 RValue<Int4> greater = CmpNLE(x, y);
5509 return x & greater | y & ~greater;
5510 }
5511 }
5512
5513 RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y)
5514 {
5515 if(CPUID::supportsSSE4_1())
5516 {
5517 return x86::pminsd(x, y);
5518 }
5519 else
5520 {
5521 RValue<Int4> less = CmpLT(x, y);
5522 return x & less | y & ~less;
5523 }
5524 }
5525
5526 RValue<Int4> RoundInt(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005527 {
5528 return x86::cvtps2dq(cast);
5529 }
5530
John Bauman19bac1e2014-05-06 15:23:49 -04005531 RValue<Short8> Pack(RValue<Int4> x, RValue<Int4> y)
John Bauman89401822014-05-06 15:04:28 -04005532 {
5533 return x86::packssdw(x, y);
5534 }
5535
John Bauman19bac1e2014-05-06 15:23:49 -04005536 RValue<Int> Extract(RValue<Int4> x, int i)
John Bauman89401822014-05-06 15:04:28 -04005537 {
Nicolas Capense95d5342016-09-30 11:37:28 -04005538 return RValue<Int>(Nucleus::createExtractElement(x.value, Int::getType(), i));
John Bauman89401822014-05-06 15:04:28 -04005539 }
5540
John Bauman19bac1e2014-05-06 15:23:49 -04005541 RValue<Int4> Insert(RValue<Int4> x, RValue<Int> element, int i)
John Bauman89401822014-05-06 15:04:28 -04005542 {
5543 return RValue<Int4>(Nucleus::createInsertElement(x.value, element.value, i));
5544 }
5545
John Bauman19bac1e2014-05-06 15:23:49 -04005546 RValue<Int> SignMask(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04005547 {
5548 return x86::movmskps(As<Float4>(x));
5549 }
5550
John Bauman19bac1e2014-05-06 15:23:49 -04005551 RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04005552 {
Nicolas Capense95d5342016-09-30 11:37:28 -04005553 return RValue<Int4>(createSwizzle4(x.value, select));
John Bauman89401822014-05-06 15:04:28 -04005554 }
5555
John Bauman19bac1e2014-05-06 15:23:49 -04005556 Type *Int4::getType()
John Bauman89401822014-05-06 15:04:28 -04005557 {
Nicolas Capensac230122016-09-20 14:30:06 -04005558 return T(VectorType::get(Int::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04005559 }
5560
John Bauman19bac1e2014-05-06 15:23:49 -04005561 UInt4::UInt4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005562 {
5563 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005564
Alexis Hetu764d1422016-09-28 08:44:22 -04005565 // Note: createFPToUI is broken, must perform conversion using createFPtoSI
5566 // Value *xyzw = Nucleus::createFPToUI(cast.value, UInt4::getType());
John Bauman89401822014-05-06 15:04:28 -04005567
Alexis Hetu764d1422016-09-28 08:44:22 -04005568 // Smallest positive value representable in UInt, but not in Int
5569 const unsigned int ustart = 0x80000000u;
5570 const float ustartf = float(ustart);
5571
5572 // Check if the value can be represented as an Int
5573 Int4 uiValue = CmpNLT(cast, Float4(ustartf));
5574 // If the value is too large, subtract ustart and re-add it after conversion.
5575 uiValue = (uiValue & As<Int4>(As<UInt4>(Int4(cast - Float4(ustartf))) + UInt4(ustart))) |
5576 // Otherwise, just convert normally
5577 (~uiValue & Int4(cast));
5578 // If the value is negative, store 0, otherwise store the result of the conversion
5579 storeValue((~(As<Int4>(cast) >> 31) & uiValue).value);
John Bauman89401822014-05-06 15:04:28 -04005580 }
5581
5582 UInt4::UInt4()
5583 {
5584 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005585 }
5586
John Bauman19bac1e2014-05-06 15:23:49 -04005587 UInt4::UInt4(int xyzw)
5588 {
5589 constant(xyzw, xyzw, xyzw, xyzw);
5590 }
5591
5592 UInt4::UInt4(int x, int yzw)
5593 {
5594 constant(x, yzw, yzw, yzw);
5595 }
5596
5597 UInt4::UInt4(int x, int y, int zw)
5598 {
5599 constant(x, y, zw, zw);
5600 }
5601
5602 UInt4::UInt4(int x, int y, int z, int w)
5603 {
5604 constant(x, y, z, w);
5605 }
5606
5607 void UInt4::constant(int x, int y, int z, int w)
John Bauman89401822014-05-06 15:04:28 -04005608 {
5609 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005610
Nicolas Capens13ac2322016-10-13 14:52:12 -04005611 int64_t constantVector[4] = {x, y, z, w};
5612 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04005613 }
5614
John Bauman19bac1e2014-05-06 15:23:49 -04005615 UInt4::UInt4(RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005616 {
5617 // xyzw.parent = this;
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
5622 UInt4::UInt4(const UInt4 &rhs)
5623 {
5624 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005625
John Bauman66b8ab22014-05-06 15:57:45 -04005626 Value *value = rhs.loadValue();
5627 storeValue(value);
5628 }
5629
5630 UInt4::UInt4(const Reference<UInt4> &rhs)
5631 {
5632 // xyzw.parent = this;
5633
5634 Value *value = rhs.loadValue();
5635 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005636 }
5637
John Bauman19bac1e2014-05-06 15:23:49 -04005638 UInt4::UInt4(RValue<Int4> rhs)
5639 {
5640 // xyzw.parent = this;
John Bauman19bac1e2014-05-06 15:23:49 -04005641
John Bauman66b8ab22014-05-06 15:57:45 -04005642 storeValue(rhs.value);
John Bauman19bac1e2014-05-06 15:23:49 -04005643 }
5644
5645 UInt4::UInt4(const Int4 &rhs)
5646 {
5647 // xyzw.parent = this;
John Bauman19bac1e2014-05-06 15:23:49 -04005648
John Bauman66b8ab22014-05-06 15:57:45 -04005649 Value *value = rhs.loadValue();
5650 storeValue(value);
5651 }
5652
5653 UInt4::UInt4(const Reference<Int4> &rhs)
5654 {
5655 // xyzw.parent = this;
5656
5657 Value *value = rhs.loadValue();
5658 storeValue(value);
John Bauman19bac1e2014-05-06 15:23:49 -04005659 }
5660
Nicolas Capens62abb552016-01-05 12:03:47 -05005661 UInt4::UInt4(RValue<UInt2> lo, RValue<UInt2> hi)
5662 {
5663 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
5664 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
5665
Nicolas Capens22008782016-10-20 01:11:47 -04005666 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Nicolas Capens62abb552016-01-05 12:03:47 -05005667 long2 = Nucleus::createInsertElement(long2, loLong, 0);
5668 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
5669 Value *uint4 = Nucleus::createBitCast(long2, Int4::getType());
5670
5671 storeValue(uint4);
5672 }
5673
John Bauman19bac1e2014-05-06 15:23:49 -04005674 RValue<UInt4> UInt4::operator=(RValue<UInt4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04005675 {
John Bauman66b8ab22014-05-06 15:57:45 -04005676 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005677
5678 return rhs;
5679 }
5680
5681 RValue<UInt4> UInt4::operator=(const UInt4 &rhs) const
5682 {
John Bauman66b8ab22014-05-06 15:57:45 -04005683 Value *value = rhs.loadValue();
5684 storeValue(value);
5685
5686 return RValue<UInt4>(value);
5687 }
5688
5689 RValue<UInt4> UInt4::operator=(const Reference<UInt4> &rhs) const
5690 {
5691 Value *value = rhs.loadValue();
5692 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005693
5694 return RValue<UInt4>(value);
5695 }
5696
John Bauman19bac1e2014-05-06 15:23:49 -04005697 RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005698 {
5699 return RValue<UInt4>(Nucleus::createAdd(lhs.value, rhs.value));
5700 }
5701
John Bauman19bac1e2014-05-06 15:23:49 -04005702 RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005703 {
5704 return RValue<UInt4>(Nucleus::createSub(lhs.value, rhs.value));
5705 }
5706
John Bauman19bac1e2014-05-06 15:23:49 -04005707 RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005708 {
5709 return RValue<UInt4>(Nucleus::createMul(lhs.value, rhs.value));
5710 }
5711
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005712 RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs)
5713 {
5714 return RValue<UInt4>(Nucleus::createUDiv(lhs.value, rhs.value));
5715 }
John Bauman89401822014-05-06 15:04:28 -04005716
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005717 RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs)
5718 {
5719 return RValue<UInt4>(Nucleus::createURem(lhs.value, rhs.value));
5720 }
John Bauman89401822014-05-06 15:04:28 -04005721
John Bauman19bac1e2014-05-06 15:23:49 -04005722 RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005723 {
5724 return RValue<UInt4>(Nucleus::createAnd(lhs.value, rhs.value));
5725 }
5726
John Bauman19bac1e2014-05-06 15:23:49 -04005727 RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005728 {
5729 return RValue<UInt4>(Nucleus::createOr(lhs.value, rhs.value));
5730 }
5731
John Bauman19bac1e2014-05-06 15:23:49 -04005732 RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005733 {
5734 return RValue<UInt4>(Nucleus::createXor(lhs.value, rhs.value));
5735 }
5736
John Bauman19bac1e2014-05-06 15:23:49 -04005737 RValue<UInt4> operator<<(RValue<UInt4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005738 {
John Bauman89401822014-05-06 15:04:28 -04005739 return As<UInt4>(x86::pslld(As<Int4>(lhs), rhs));
5740 }
5741
John Bauman19bac1e2014-05-06 15:23:49 -04005742 RValue<UInt4> operator>>(RValue<UInt4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005743 {
John Bauman89401822014-05-06 15:04:28 -04005744 return x86::psrld(lhs, rhs);
5745 }
5746
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005747 RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs)
5748 {
5749 return RValue<UInt4>(Nucleus::createShl(lhs.value, rhs.value));
5750 }
5751
5752 RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs)
5753 {
5754 return RValue<UInt4>(Nucleus::createLShr(lhs.value, rhs.value));
5755 }
5756
John Bauman19bac1e2014-05-06 15:23:49 -04005757 RValue<UInt4> operator+=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005758 {
5759 return lhs = lhs + rhs;
5760 }
5761
John Bauman19bac1e2014-05-06 15:23:49 -04005762 RValue<UInt4> operator-=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005763 {
5764 return lhs = lhs - rhs;
5765 }
5766
John Bauman19bac1e2014-05-06 15:23:49 -04005767 RValue<UInt4> operator*=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005768 {
5769 return lhs = lhs * rhs;
5770 }
5771
John Bauman19bac1e2014-05-06 15:23:49 -04005772// RValue<UInt4> operator/=(const UInt4 &lhs, RValue<UInt4> rhs)
5773// {
5774// return lhs = lhs / rhs;
5775// }
John Bauman89401822014-05-06 15:04:28 -04005776
John Bauman19bac1e2014-05-06 15:23:49 -04005777// RValue<UInt4> operator%=(const UInt4 &lhs, RValue<UInt4> rhs)
5778// {
5779// return lhs = lhs % rhs;
5780// }
John Bauman89401822014-05-06 15:04:28 -04005781
John Bauman19bac1e2014-05-06 15:23:49 -04005782 RValue<UInt4> operator&=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005783 {
5784 return lhs = lhs & rhs;
5785 }
5786
John Bauman19bac1e2014-05-06 15:23:49 -04005787 RValue<UInt4> operator|=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005788 {
5789 return lhs = lhs | rhs;
5790 }
5791
John Bauman19bac1e2014-05-06 15:23:49 -04005792 RValue<UInt4> operator^=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005793 {
5794 return lhs = lhs ^ rhs;
5795 }
5796
5797 RValue<UInt4> operator<<=(const UInt4 &lhs, unsigned char rhs)
5798 {
5799 return lhs = lhs << rhs;
5800 }
5801
5802 RValue<UInt4> operator>>=(const UInt4 &lhs, unsigned char rhs)
5803 {
5804 return lhs = lhs >> rhs;
5805 }
5806
John Bauman19bac1e2014-05-06 15:23:49 -04005807 RValue<UInt4> operator+(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04005808 {
5809 return val;
5810 }
5811
John Bauman19bac1e2014-05-06 15:23:49 -04005812 RValue<UInt4> operator-(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04005813 {
5814 return RValue<UInt4>(Nucleus::createNeg(val.value));
5815 }
5816
John Bauman19bac1e2014-05-06 15:23:49 -04005817 RValue<UInt4> operator~(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04005818 {
5819 return RValue<UInt4>(Nucleus::createNot(val.value));
5820 }
5821
John Bauman19bac1e2014-05-06 15:23:49 -04005822 RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y)
5823 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005824 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
Alexis Hetufb603992016-04-26 11:50:40 -04005825 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5826 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
5827 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005828 }
5829
5830 RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y)
5831 {
5832 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULT(x.value, y.value), Int4::getType()));
5833 }
5834
5835 RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y)
5836 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005837 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5838 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5839 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULE(x.value, y.value), Int4::getType()));
5840 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGT(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005841 }
5842
5843 RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y)
5844 {
5845 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
5846 }
5847
5848 RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y)
5849 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005850 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5851 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5852 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGE(x.value, y.value), Int4::getType()));
5853 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULT(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005854 }
5855
5856 RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y)
5857 {
5858 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGT(x.value, y.value), Int4::getType()));
5859 }
5860
5861 RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y)
5862 {
5863 if(CPUID::supportsSSE4_1())
5864 {
5865 return x86::pmaxud(x, y);
5866 }
5867 else
5868 {
5869 RValue<UInt4> greater = CmpNLE(x, y);
5870 return x & greater | y & ~greater;
5871 }
5872 }
5873
5874 RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y)
5875 {
5876 if(CPUID::supportsSSE4_1())
5877 {
5878 return x86::pminud(x, y);
5879 }
5880 else
5881 {
5882 RValue<UInt4> less = CmpLT(x, y);
5883 return x & less | y & ~less;
5884 }
5885 }
5886
5887 RValue<UShort8> Pack(RValue<UInt4> x, RValue<UInt4> y)
John Bauman89401822014-05-06 15:04:28 -04005888 {
5889 return x86::packusdw(x, y); // FIXME: Fallback required
5890 }
5891
John Bauman19bac1e2014-05-06 15:23:49 -04005892 Type *UInt4::getType()
John Bauman89401822014-05-06 15:04:28 -04005893 {
Nicolas Capensac230122016-09-20 14:30:06 -04005894 return T(VectorType::get(UInt::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04005895 }
5896
John Bauman19bac1e2014-05-06 15:23:49 -04005897 Float::Float(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04005898 {
John Bauman89401822014-05-06 15:04:28 -04005899 Value *integer = Nucleus::createSIToFP(cast.value, Float::getType());
5900
John Bauman66b8ab22014-05-06 15:57:45 -04005901 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04005902 }
5903
5904 Float::Float()
5905 {
John Bauman66b8ab22014-05-06 15:57:45 -04005906
John Bauman89401822014-05-06 15:04:28 -04005907 }
5908
5909 Float::Float(float x)
5910 {
John Bauman66b8ab22014-05-06 15:57:45 -04005911 storeValue(Nucleus::createConstantFloat(x));
John Bauman89401822014-05-06 15:04:28 -04005912 }
5913
John Bauman19bac1e2014-05-06 15:23:49 -04005914 Float::Float(RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005915 {
John Bauman66b8ab22014-05-06 15:57:45 -04005916 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005917 }
5918
5919 Float::Float(const Float &rhs)
5920 {
John Bauman66b8ab22014-05-06 15:57:45 -04005921 Value *value = rhs.loadValue();
5922 storeValue(value);
5923 }
John Bauman89401822014-05-06 15:04:28 -04005924
John Bauman66b8ab22014-05-06 15:57:45 -04005925 Float::Float(const Reference<Float> &rhs)
5926 {
5927 Value *value = rhs.loadValue();
5928 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005929 }
5930
John Bauman19bac1e2014-05-06 15:23:49 -04005931 RValue<Float> Float::operator=(RValue<Float> rhs) const
John Bauman89401822014-05-06 15:04:28 -04005932 {
John Bauman66b8ab22014-05-06 15:57:45 -04005933 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005934
5935 return rhs;
5936 }
5937
5938 RValue<Float> Float::operator=(const Float &rhs) const
5939 {
John Bauman66b8ab22014-05-06 15:57:45 -04005940 Value *value = rhs.loadValue();
5941 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005942
5943 return RValue<Float>(value);
5944 }
5945
John Bauman66b8ab22014-05-06 15:57:45 -04005946 RValue<Float> Float::operator=(const Reference<Float> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04005947 {
John Bauman66b8ab22014-05-06 15:57:45 -04005948 Value *value = rhs.loadValue();
5949 storeValue(value);
5950
5951 return RValue<Float>(value);
John Bauman89401822014-05-06 15:04:28 -04005952 }
5953
John Bauman19bac1e2014-05-06 15:23:49 -04005954 RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005955 {
5956 return RValue<Float>(Nucleus::createFAdd(lhs.value, rhs.value));
5957 }
5958
John Bauman19bac1e2014-05-06 15:23:49 -04005959 RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005960 {
5961 return RValue<Float>(Nucleus::createFSub(lhs.value, rhs.value));
5962 }
5963
John Bauman19bac1e2014-05-06 15:23:49 -04005964 RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005965 {
5966 return RValue<Float>(Nucleus::createFMul(lhs.value, rhs.value));
5967 }
5968
John Bauman19bac1e2014-05-06 15:23:49 -04005969 RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005970 {
5971 return RValue<Float>(Nucleus::createFDiv(lhs.value, rhs.value));
5972 }
5973
John Bauman19bac1e2014-05-06 15:23:49 -04005974 RValue<Float> operator+=(const Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005975 {
5976 return lhs = lhs + rhs;
5977 }
5978
John Bauman19bac1e2014-05-06 15:23:49 -04005979 RValue<Float> operator-=(const Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005980 {
5981 return lhs = lhs - rhs;
5982 }
5983
John Bauman19bac1e2014-05-06 15:23:49 -04005984 RValue<Float> operator*=(const Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005985 {
5986 return lhs = lhs * rhs;
5987 }
5988
John Bauman19bac1e2014-05-06 15:23:49 -04005989 RValue<Float> operator/=(const Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005990 {
5991 return lhs = lhs / rhs;
5992 }
5993
John Bauman19bac1e2014-05-06 15:23:49 -04005994 RValue<Float> operator+(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04005995 {
5996 return val;
5997 }
5998
John Bauman19bac1e2014-05-06 15:23:49 -04005999 RValue<Float> operator-(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006000 {
6001 return RValue<Float>(Nucleus::createFNeg(val.value));
6002 }
6003
John Bauman19bac1e2014-05-06 15:23:49 -04006004 RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006005 {
6006 return RValue<Bool>(Nucleus::createFCmpOLT(lhs.value, rhs.value));
6007 }
6008
John Bauman19bac1e2014-05-06 15:23:49 -04006009 RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006010 {
6011 return RValue<Bool>(Nucleus::createFCmpOLE(lhs.value, rhs.value));
6012 }
6013
John Bauman19bac1e2014-05-06 15:23:49 -04006014 RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006015 {
6016 return RValue<Bool>(Nucleus::createFCmpOGT(lhs.value, rhs.value));
6017 }
6018
John Bauman19bac1e2014-05-06 15:23:49 -04006019 RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006020 {
6021 return RValue<Bool>(Nucleus::createFCmpOGE(lhs.value, rhs.value));
6022 }
6023
John Bauman19bac1e2014-05-06 15:23:49 -04006024 RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006025 {
6026 return RValue<Bool>(Nucleus::createFCmpONE(lhs.value, rhs.value));
6027 }
6028
John Bauman19bac1e2014-05-06 15:23:49 -04006029 RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006030 {
6031 return RValue<Bool>(Nucleus::createFCmpOEQ(lhs.value, rhs.value));
6032 }
6033
John Bauman19bac1e2014-05-06 15:23:49 -04006034 RValue<Float> Abs(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006035 {
John Bauman66b8ab22014-05-06 15:57:45 -04006036 return IfThenElse(x > 0.0f, x, -x);
John Bauman89401822014-05-06 15:04:28 -04006037 }
6038
John Bauman19bac1e2014-05-06 15:23:49 -04006039 RValue<Float> Max(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006040 {
6041 return IfThenElse(x > y, x, y);
6042 }
6043
John Bauman19bac1e2014-05-06 15:23:49 -04006044 RValue<Float> Min(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006045 {
6046 return IfThenElse(x < y, x, y);
6047 }
6048
Nicolas Capens05b3d662016-02-25 23:58:33 -05006049 RValue<Float> Rcp_pp(RValue<Float> x, bool exactAtPow2)
John Bauman89401822014-05-06 15:04:28 -04006050 {
Nicolas Capens05b3d662016-02-25 23:58:33 -05006051 if(exactAtPow2)
6052 {
6053 // rcpss uses a piecewise-linear approximation which minimizes the relative error
6054 // but is not exact at power-of-two values. Rectify by multiplying by the inverse.
6055 return x86::rcpss(x) * Float(1.0f / _mm_cvtss_f32(_mm_rcp_ss(_mm_set_ps1(1.0f))));
6056 }
6057 else
6058 {
6059 return x86::rcpss(x);
6060 }
John Bauman89401822014-05-06 15:04:28 -04006061 }
John Bauman66b8ab22014-05-06 15:57:45 -04006062
John Bauman19bac1e2014-05-06 15:23:49 -04006063 RValue<Float> RcpSqrt_pp(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006064 {
6065 return x86::rsqrtss(x);
6066 }
6067
John Bauman19bac1e2014-05-06 15:23:49 -04006068 RValue<Float> Sqrt(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006069 {
6070 return x86::sqrtss(x);
6071 }
6072
John Bauman19bac1e2014-05-06 15:23:49 -04006073 RValue<Float> Round(RValue<Float> x)
6074 {
6075 if(CPUID::supportsSSE4_1())
6076 {
6077 return x86::roundss(x, 0);
6078 }
6079 else
6080 {
6081 return Float4(Round(Float4(x))).x;
6082 }
6083 }
6084
6085 RValue<Float> Trunc(RValue<Float> x)
6086 {
6087 if(CPUID::supportsSSE4_1())
6088 {
6089 return x86::roundss(x, 3);
6090 }
6091 else
6092 {
6093 return Float(Int(x)); // Rounded toward zero
6094 }
6095 }
6096
6097 RValue<Float> Frac(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006098 {
6099 if(CPUID::supportsSSE4_1())
6100 {
6101 return x - x86::floorss(x);
6102 }
6103 else
6104 {
John Bauman19bac1e2014-05-06 15:23:49 -04006105 return Float4(Frac(Float4(x))).x;
John Bauman89401822014-05-06 15:04:28 -04006106 }
6107 }
6108
John Bauman19bac1e2014-05-06 15:23:49 -04006109 RValue<Float> Floor(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006110 {
6111 if(CPUID::supportsSSE4_1())
6112 {
6113 return x86::floorss(x);
6114 }
6115 else
6116 {
6117 return Float4(Floor(Float4(x))).x;
6118 }
6119 }
6120
John Bauman19bac1e2014-05-06 15:23:49 -04006121 RValue<Float> Ceil(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006122 {
John Bauman19bac1e2014-05-06 15:23:49 -04006123 if(CPUID::supportsSSE4_1())
6124 {
6125 return x86::ceilss(x);
6126 }
6127 else
6128 {
6129 return Float4(Ceil(Float4(x))).x;
6130 }
John Bauman89401822014-05-06 15:04:28 -04006131 }
6132
John Bauman19bac1e2014-05-06 15:23:49 -04006133 Type *Float::getType()
John Bauman89401822014-05-06 15:04:28 -04006134 {
Nicolas Capensac230122016-09-20 14:30:06 -04006135 return T(llvm::Type::getFloatTy(*::context));
John Bauman89401822014-05-06 15:04:28 -04006136 }
6137
John Bauman19bac1e2014-05-06 15:23:49 -04006138 Float2::Float2(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04006139 {
6140 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006141
Nicolas Capens22008782016-10-20 01:11:47 -04006142 Value *int64x2 = Nucleus::createBitCast(cast.value, T(VectorType::get(Long::getType(), 2)));
Nicolas Capense95d5342016-09-30 11:37:28 -04006143 Value *int64 = Nucleus::createExtractElement(int64x2, Long::getType(), 0);
John Bauman89401822014-05-06 15:04:28 -04006144 Value *float2 = Nucleus::createBitCast(int64, Float2::getType());
6145
John Bauman66b8ab22014-05-06 15:57:45 -04006146 storeValue(float2);
John Bauman89401822014-05-06 15:04:28 -04006147 }
6148
John Bauman19bac1e2014-05-06 15:23:49 -04006149 Type *Float2::getType()
John Bauman89401822014-05-06 15:04:28 -04006150 {
Nicolas Capensac230122016-09-20 14:30:06 -04006151 return T(VectorType::get(Float::getType(), 2));
John Bauman89401822014-05-06 15:04:28 -04006152 }
6153
John Bauman19bac1e2014-05-06 15:23:49 -04006154 Float4::Float4(RValue<Byte4> cast)
John Bauman89401822014-05-06 15:04:28 -04006155 {
6156 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006157
6158 #if 0
6159 Value *xyzw = Nucleus::createUIToFP(cast.value, Float4::getType()); // FIXME: Crashes
6160 #elif 0
John Bauman66b8ab22014-05-06 15:57:45 -04006161 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04006162
6163 Value *i8x = Nucleus::createExtractElement(cast.value, 0);
6164 Value *f32x = Nucleus::createUIToFP(i8x, Float::getType());
6165 Value *x = Nucleus::createInsertElement(vector, f32x, 0);
6166
Nicolas Capens19336542016-09-26 10:32:29 -04006167 Value *i8y = Nucleus::createExtractElement(cast.value, V(Nucleus::createConstantInt(1)));
John Bauman89401822014-05-06 15:04:28 -04006168 Value *f32y = Nucleus::createUIToFP(i8y, Float::getType());
Nicolas Capens19336542016-09-26 10:32:29 -04006169 Value *xy = Nucleus::createInsertElement(x, f32y, V(Nucleus::createConstantInt(1)));
John Bauman89401822014-05-06 15:04:28 -04006170
6171 Value *i8z = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(2));
6172 Value *f32z = Nucleus::createUIToFP(i8z, Float::getType());
6173 Value *xyz = Nucleus::createInsertElement(xy, f32z, Nucleus::createConstantInt(2));
6174
6175 Value *i8w = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(3));
6176 Value *f32w = Nucleus::createUIToFP(i8w, Float::getType());
6177 Value *xyzw = Nucleus::createInsertElement(xyz, f32w, Nucleus::createConstantInt(3));
6178 #else
Meng-Lin Wu601d0052016-06-10 14:18:41 -04006179 Value *a = Int4(cast).loadValue();
6180 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04006181 #endif
John Bauman66b8ab22014-05-06 15:57:45 -04006182
6183 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04006184 }
6185
John Bauman19bac1e2014-05-06 15:23:49 -04006186 Float4::Float4(RValue<SByte4> cast)
John Bauman89401822014-05-06 15:04:28 -04006187 {
6188 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006189
6190 #if 0
6191 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType()); // FIXME: Crashes
6192 #elif 0
John Bauman66b8ab22014-05-06 15:57:45 -04006193 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04006194
6195 Value *i8x = Nucleus::createExtractElement(cast.value, 0);
6196 Value *f32x = Nucleus::createSIToFP(i8x, Float::getType());
6197 Value *x = Nucleus::createInsertElement(vector, f32x, 0);
6198
Nicolas Capens19336542016-09-26 10:32:29 -04006199 Value *i8y = Nucleus::createExtractElement(cast.value, V(Nucleus::createConstantInt(1)));
John Bauman89401822014-05-06 15:04:28 -04006200 Value *f32y = Nucleus::createSIToFP(i8y, Float::getType());
Nicolas Capens19336542016-09-26 10:32:29 -04006201 Value *xy = Nucleus::createInsertElement(x, f32y, V(Nucleus::createConstantInt(1)));
John Bauman89401822014-05-06 15:04:28 -04006202
6203 Value *i8z = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(2));
6204 Value *f32z = Nucleus::createSIToFP(i8z, Float::getType());
6205 Value *xyz = Nucleus::createInsertElement(xy, f32z, Nucleus::createConstantInt(2));
6206
6207 Value *i8w = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(3));
6208 Value *f32w = Nucleus::createSIToFP(i8w, Float::getType());
6209 Value *xyzw = Nucleus::createInsertElement(xyz, f32w, Nucleus::createConstantInt(3));
6210 #else
Meng-Lin Wu601d0052016-06-10 14:18:41 -04006211 Value *a = Int4(cast).loadValue();
6212 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04006213 #endif
John Bauman66b8ab22014-05-06 15:57:45 -04006214
6215 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04006216 }
6217
John Bauman19bac1e2014-05-06 15:23:49 -04006218 Float4::Float4(RValue<Short4> cast)
John Bauman89401822014-05-06 15:04:28 -04006219 {
6220 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006221
Alexis Hetu2aa852f2015-10-14 16:32:39 -04006222 Int4 c(cast);
6223 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
John Bauman89401822014-05-06 15:04:28 -04006224 }
6225
John Bauman19bac1e2014-05-06 15:23:49 -04006226 Float4::Float4(RValue<UShort4> cast)
John Bauman89401822014-05-06 15:04:28 -04006227 {
6228 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006229
Alexis Hetu2aa852f2015-10-14 16:32:39 -04006230 Int4 c(cast);
6231 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
John Bauman89401822014-05-06 15:04:28 -04006232 }
6233
John Bauman19bac1e2014-05-06 15:23:49 -04006234 Float4::Float4(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04006235 {
6236 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006237
6238 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04006239
John Bauman66b8ab22014-05-06 15:57:45 -04006240 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04006241 }
6242
John Bauman19bac1e2014-05-06 15:23:49 -04006243 Float4::Float4(RValue<UInt4> cast)
John Bauman89401822014-05-06 15:04:28 -04006244 {
6245 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006246
6247 Value *xyzw = Nucleus::createUIToFP(cast.value, Float4::getType());
6248
John Bauman66b8ab22014-05-06 15:57:45 -04006249 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04006250 }
6251
6252 Float4::Float4()
6253 {
6254 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006255 }
John Bauman66b8ab22014-05-06 15:57:45 -04006256
John Bauman89401822014-05-06 15:04:28 -04006257 Float4::Float4(float xyzw)
6258 {
6259 constant(xyzw, xyzw, xyzw, xyzw);
6260 }
6261
6262 Float4::Float4(float x, float yzw)
6263 {
6264 constant(x, yzw, yzw, yzw);
6265 }
6266
6267 Float4::Float4(float x, float y, float zw)
6268 {
6269 constant(x, y, zw, zw);
6270 }
6271
6272 Float4::Float4(float x, float y, float z, float w)
6273 {
6274 constant(x, y, z, w);
6275 }
6276
6277 void Float4::constant(float x, float y, float z, float w)
6278 {
6279 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006280
Nicolas Capens13ac2322016-10-13 14:52:12 -04006281 double constantVector[4] = {x, y, z, w};
6282 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04006283 }
6284
John Bauman19bac1e2014-05-06 15:23:49 -04006285 Float4::Float4(RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006286 {
6287 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006288
John Bauman66b8ab22014-05-06 15:57:45 -04006289 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04006290 }
6291
6292 Float4::Float4(const Float4 &rhs)
6293 {
6294 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006295
John Bauman66b8ab22014-05-06 15:57:45 -04006296 Value *value = rhs.loadValue();
6297 storeValue(value);
6298 }
6299
6300 Float4::Float4(const Reference<Float4> &rhs)
6301 {
6302 xyzw.parent = this;
6303
6304 Value *value = rhs.loadValue();
6305 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04006306 }
6307
John Bauman19bac1e2014-05-06 15:23:49 -04006308 Float4::Float4(RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006309 {
6310 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006311
John Bauman66b8ab22014-05-06 15:57:45 -04006312 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04006313 Value *insert = Nucleus::createInsertElement(vector, rhs.value, 0);
6314
Nicolas Capense89cd582016-09-30 14:23:47 -04006315 int swizzle[4] = {0, 0, 0, 0};
6316 Value *replicate = Nucleus::createShuffleVector(insert, insert, swizzle);
John Bauman89401822014-05-06 15:04:28 -04006317
John Bauman66b8ab22014-05-06 15:57:45 -04006318 storeValue(replicate);
John Bauman89401822014-05-06 15:04:28 -04006319 }
6320
6321 Float4::Float4(const Float &rhs)
6322 {
6323 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006324
John Bauman66b8ab22014-05-06 15:57:45 -04006325 *this = RValue<Float>(rhs.loadValue());
6326 }
John Bauman89401822014-05-06 15:04:28 -04006327
John Bauman66b8ab22014-05-06 15:57:45 -04006328 Float4::Float4(const Reference<Float> &rhs)
6329 {
6330 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006331
John Bauman66b8ab22014-05-06 15:57:45 -04006332 *this = RValue<Float>(rhs.loadValue());
John Bauman89401822014-05-06 15:04:28 -04006333 }
6334
6335 RValue<Float4> Float4::operator=(float x) const
6336 {
6337 return *this = Float4(x, x, x, x);
6338 }
6339
John Bauman19bac1e2014-05-06 15:23:49 -04006340 RValue<Float4> Float4::operator=(RValue<Float4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04006341 {
John Bauman66b8ab22014-05-06 15:57:45 -04006342 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04006343
6344 return rhs;
6345 }
6346
6347 RValue<Float4> Float4::operator=(const Float4 &rhs) const
6348 {
John Bauman66b8ab22014-05-06 15:57:45 -04006349 Value *value = rhs.loadValue();
6350 storeValue(value);
6351
6352 return RValue<Float4>(value);
6353 }
6354
6355 RValue<Float4> Float4::operator=(const Reference<Float4> &rhs) const
6356 {
6357 Value *value = rhs.loadValue();
6358 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04006359
6360 return RValue<Float4>(value);
6361 }
6362
John Bauman19bac1e2014-05-06 15:23:49 -04006363 RValue<Float4> Float4::operator=(RValue<Float> rhs) const
John Bauman89401822014-05-06 15:04:28 -04006364 {
6365 return *this = Float4(rhs);
6366 }
6367
6368 RValue<Float4> Float4::operator=(const Float &rhs) const
6369 {
6370 return *this = Float4(rhs);
6371 }
6372
John Bauman66b8ab22014-05-06 15:57:45 -04006373 RValue<Float4> Float4::operator=(const Reference<Float> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04006374 {
John Bauman66b8ab22014-05-06 15:57:45 -04006375 return *this = Float4(rhs);
John Bauman89401822014-05-06 15:04:28 -04006376 }
6377
John Bauman19bac1e2014-05-06 15:23:49 -04006378 RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006379 {
6380 return RValue<Float4>(Nucleus::createFAdd(lhs.value, rhs.value));
6381 }
6382
John Bauman19bac1e2014-05-06 15:23:49 -04006383 RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006384 {
6385 return RValue<Float4>(Nucleus::createFSub(lhs.value, rhs.value));
6386 }
6387
John Bauman19bac1e2014-05-06 15:23:49 -04006388 RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006389 {
6390 return RValue<Float4>(Nucleus::createFMul(lhs.value, rhs.value));
6391 }
6392
John Bauman19bac1e2014-05-06 15:23:49 -04006393 RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006394 {
6395 return RValue<Float4>(Nucleus::createFDiv(lhs.value, rhs.value));
6396 }
6397
John Bauman19bac1e2014-05-06 15:23:49 -04006398 RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006399 {
6400 return RValue<Float4>(Nucleus::createFRem(lhs.value, rhs.value));
6401 }
6402
John Bauman19bac1e2014-05-06 15:23:49 -04006403 RValue<Float4> operator+=(const Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006404 {
6405 return lhs = lhs + rhs;
6406 }
6407
John Bauman19bac1e2014-05-06 15:23:49 -04006408 RValue<Float4> operator-=(const Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006409 {
6410 return lhs = lhs - rhs;
6411 }
6412
John Bauman19bac1e2014-05-06 15:23:49 -04006413 RValue<Float4> operator*=(const Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006414 {
6415 return lhs = lhs * rhs;
6416 }
6417
John Bauman19bac1e2014-05-06 15:23:49 -04006418 RValue<Float4> operator/=(const Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006419 {
6420 return lhs = lhs / rhs;
6421 }
6422
John Bauman19bac1e2014-05-06 15:23:49 -04006423 RValue<Float4> operator%=(const Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006424 {
6425 return lhs = lhs % rhs;
6426 }
6427
John Bauman19bac1e2014-05-06 15:23:49 -04006428 RValue<Float4> operator+(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006429 {
6430 return val;
6431 }
6432
John Bauman19bac1e2014-05-06 15:23:49 -04006433 RValue<Float4> operator-(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006434 {
6435 return RValue<Float4>(Nucleus::createFNeg(val.value));
6436 }
6437
John Bauman19bac1e2014-05-06 15:23:49 -04006438 RValue<Float4> Abs(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006439 {
6440 Value *vector = Nucleus::createBitCast(x.value, Int4::getType());
Nicolas Capens13ac2322016-10-13 14:52:12 -04006441 int64_t constantVector[4] = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF};
6442 Value *result = Nucleus::createAnd(vector, V(Nucleus::createConstantVector(constantVector, Int4::getType())));
John Bauman89401822014-05-06 15:04:28 -04006443
6444 return RValue<Float4>(Nucleus::createBitCast(result, Float4::getType()));
6445 }
6446
John Bauman19bac1e2014-05-06 15:23:49 -04006447 RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006448 {
6449 return x86::maxps(x, y);
6450 }
6451
John Bauman19bac1e2014-05-06 15:23:49 -04006452 RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006453 {
6454 return x86::minps(x, y);
6455 }
6456
Nicolas Capens05b3d662016-02-25 23:58:33 -05006457 RValue<Float4> Rcp_pp(RValue<Float4> x, bool exactAtPow2)
John Bauman89401822014-05-06 15:04:28 -04006458 {
Nicolas Capens05b3d662016-02-25 23:58:33 -05006459 if(exactAtPow2)
6460 {
6461 // rcpps uses a piecewise-linear approximation which minimizes the relative error
6462 // but is not exact at power-of-two values. Rectify by multiplying by the inverse.
6463 return x86::rcpps(x) * Float4(1.0f / _mm_cvtss_f32(_mm_rcp_ss(_mm_set_ps1(1.0f))));
6464 }
6465 else
6466 {
6467 return x86::rcpps(x);
6468 }
John Bauman89401822014-05-06 15:04:28 -04006469 }
John Bauman66b8ab22014-05-06 15:57:45 -04006470
John Bauman19bac1e2014-05-06 15:23:49 -04006471 RValue<Float4> RcpSqrt_pp(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006472 {
6473 return x86::rsqrtps(x);
6474 }
6475
John Bauman19bac1e2014-05-06 15:23:49 -04006476 RValue<Float4> Sqrt(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006477 {
6478 return x86::sqrtps(x);
6479 }
6480
John Bauman19bac1e2014-05-06 15:23:49 -04006481 RValue<Float4> Insert(const Float4 &val, RValue<Float> element, int i)
John Bauman89401822014-05-06 15:04:28 -04006482 {
Nicolas Capens19336542016-09-26 10:32:29 -04006483 Value *value = val.loadValue();
6484 Value *insert = Nucleus::createInsertElement(value, element.value, i);
John Bauman89401822014-05-06 15:04:28 -04006485
6486 val = RValue<Float4>(insert);
6487
6488 return val;
6489 }
6490
John Bauman19bac1e2014-05-06 15:23:49 -04006491 RValue<Float> Extract(RValue<Float4> x, int i)
John Bauman89401822014-05-06 15:04:28 -04006492 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006493 return RValue<Float>(Nucleus::createExtractElement(x.value, Float::getType(), i));
John Bauman89401822014-05-06 15:04:28 -04006494 }
6495
John Bauman19bac1e2014-05-06 15:23:49 -04006496 RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04006497 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006498 return RValue<Float4>(createSwizzle4(x.value, select));
John Bauman89401822014-05-06 15:04:28 -04006499 }
6500
John Bauman19bac1e2014-05-06 15:23:49 -04006501 RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006502 {
Nicolas Capense89cd582016-09-30 14:23:47 -04006503 int shuffle[4] =
6504 {
6505 ((imm >> 0) & 0x03) + 0,
6506 ((imm >> 2) & 0x03) + 0,
6507 ((imm >> 4) & 0x03) + 4,
6508 ((imm >> 6) & 0x03) + 4,
6509 };
John Bauman89401822014-05-06 15:04:28 -04006510
Nicolas Capense89cd582016-09-30 14:23:47 -04006511 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
John Bauman89401822014-05-06 15:04:28 -04006512 }
6513
John Bauman19bac1e2014-05-06 15:23:49 -04006514 RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006515 {
Nicolas Capense89cd582016-09-30 14:23:47 -04006516 int shuffle[4] = {0, 4, 1, 5};
6517 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
John Bauman89401822014-05-06 15:04:28 -04006518 }
6519
John Bauman19bac1e2014-05-06 15:23:49 -04006520 RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006521 {
Nicolas Capense89cd582016-09-30 14:23:47 -04006522 int shuffle[4] = {2, 6, 3, 7};
6523 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
John Bauman89401822014-05-06 15:04:28 -04006524 }
John Bauman66b8ab22014-05-06 15:57:45 -04006525
John Bauman19bac1e2014-05-06 15:23:49 -04006526 RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04006527 {
John Bauman66b8ab22014-05-06 15:57:45 -04006528 Value *vector = lhs.loadValue();
Nicolas Capense95d5342016-09-30 11:37:28 -04006529 Value *shuffle = createMask4(vector, rhs.value, select);
John Bauman66b8ab22014-05-06 15:57:45 -04006530 lhs.storeValue(shuffle);
John Bauman89401822014-05-06 15:04:28 -04006531
6532 return RValue<Float4>(shuffle);
6533 }
6534
John Bauman19bac1e2014-05-06 15:23:49 -04006535 RValue<Int> SignMask(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006536 {
6537 return x86::movmskps(x);
6538 }
6539
John Bauman19bac1e2014-05-06 15:23:49 -04006540 RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006541 {
6542 // return As<Int4>(x86::cmpeqps(x, y));
6543 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOEQ(x.value, y.value), Int4::getType()));
6544 }
6545
John Bauman19bac1e2014-05-06 15:23:49 -04006546 RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006547 {
6548 // return As<Int4>(x86::cmpltps(x, y));
6549 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOLT(x.value, y.value), Int4::getType()));
6550 }
6551
John Bauman19bac1e2014-05-06 15:23:49 -04006552 RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006553 {
6554 // return As<Int4>(x86::cmpleps(x, y));
6555 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOLE(x.value, y.value), Int4::getType()));
6556 }
6557
John Bauman19bac1e2014-05-06 15:23:49 -04006558 RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006559 {
6560 // return As<Int4>(x86::cmpneqps(x, y));
6561 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpONE(x.value, y.value), Int4::getType()));
6562 }
6563
John Bauman19bac1e2014-05-06 15:23:49 -04006564 RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006565 {
6566 // return As<Int4>(x86::cmpnltps(x, y));
6567 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOGE(x.value, y.value), Int4::getType()));
6568 }
6569
John Bauman19bac1e2014-05-06 15:23:49 -04006570 RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006571 {
6572 // return As<Int4>(x86::cmpnleps(x, y));
6573 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOGT(x.value, y.value), Int4::getType()));
6574 }
6575
John Bauman19bac1e2014-05-06 15:23:49 -04006576 RValue<Float4> Round(RValue<Float4> x)
6577 {
6578 if(CPUID::supportsSSE4_1())
6579 {
6580 return x86::roundps(x, 0);
6581 }
6582 else
6583 {
6584 return Float4(RoundInt(x));
6585 }
6586 }
6587
6588 RValue<Float4> Trunc(RValue<Float4> x)
6589 {
6590 if(CPUID::supportsSSE4_1())
6591 {
6592 return x86::roundps(x, 3);
6593 }
6594 else
6595 {
6596 return Float4(Int4(x)); // Rounded toward zero
6597 }
6598 }
6599
6600 RValue<Float4> Frac(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006601 {
6602 if(CPUID::supportsSSE4_1())
6603 {
6604 return x - x86::floorps(x);
6605 }
6606 else
6607 {
John Bauman19bac1e2014-05-06 15:23:49 -04006608 Float4 frc = x - Float4(Int4(x)); // Signed fractional part
John Bauman89401822014-05-06 15:04:28 -04006609
John Bauman19bac1e2014-05-06 15:23:49 -04006610 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 -04006611 }
6612 }
6613
John Bauman19bac1e2014-05-06 15:23:49 -04006614 RValue<Float4> Floor(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006615 {
6616 if(CPUID::supportsSSE4_1())
6617 {
6618 return x86::floorps(x);
6619 }
6620 else
6621 {
John Bauman19bac1e2014-05-06 15:23:49 -04006622 return x - Frac(x);
John Bauman89401822014-05-06 15:04:28 -04006623 }
6624 }
6625
John Bauman19bac1e2014-05-06 15:23:49 -04006626 RValue<Float4> Ceil(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006627 {
John Bauman19bac1e2014-05-06 15:23:49 -04006628 if(CPUID::supportsSSE4_1())
6629 {
6630 return x86::ceilps(x);
6631 }
6632 else
6633 {
6634 return -Floor(-x);
6635 }
John Bauman89401822014-05-06 15:04:28 -04006636 }
6637
John Bauman19bac1e2014-05-06 15:23:49 -04006638 Type *Float4::getType()
John Bauman89401822014-05-06 15:04:28 -04006639 {
Nicolas Capensac230122016-09-20 14:30:06 -04006640 return T(VectorType::get(Float::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04006641 }
6642
Nicolas Capens81f18302016-01-14 09:32:35 -05006643 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006644 {
Nicolas Capens6d738712016-09-30 04:15:22 -04006645 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), V(Nucleus::createConstantInt(offset))));
John Bauman89401822014-05-06 15:04:28 -04006646 }
6647
Nicolas Capens81f18302016-01-14 09:32:35 -05006648 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006649 {
Nicolas Capens6d738712016-09-30 04:15:22 -04006650 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value));
John Bauman89401822014-05-06 15:04:28 -04006651 }
6652
Nicolas Capens81f18302016-01-14 09:32:35 -05006653 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006654 {
Nicolas Capens6d738712016-09-30 04:15:22 -04006655 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value));
John Bauman89401822014-05-06 15:04:28 -04006656 }
6657
Nicolas Capens81f18302016-01-14 09:32:35 -05006658 RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006659 {
6660 return lhs = lhs + offset;
6661 }
6662
Nicolas Capens81f18302016-01-14 09:32:35 -05006663 RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006664 {
6665 return lhs = lhs + offset;
6666 }
6667
Nicolas Capens81f18302016-01-14 09:32:35 -05006668 RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006669 {
6670 return lhs = lhs + offset;
6671 }
6672
Nicolas Capens81f18302016-01-14 09:32:35 -05006673 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006674 {
6675 return lhs + -offset;
6676 }
6677
Nicolas Capens81f18302016-01-14 09:32:35 -05006678 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006679 {
6680 return lhs + -offset;
6681 }
6682
Nicolas Capens81f18302016-01-14 09:32:35 -05006683 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006684 {
6685 return lhs + -offset;
6686 }
6687
Nicolas Capens81f18302016-01-14 09:32:35 -05006688 RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006689 {
6690 return lhs = lhs - offset;
6691 }
6692
Nicolas Capens81f18302016-01-14 09:32:35 -05006693 RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006694 {
6695 return lhs = lhs - offset;
6696 }
6697
Nicolas Capens81f18302016-01-14 09:32:35 -05006698 RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006699 {
6700 return lhs = lhs - offset;
6701 }
6702
6703 void Return()
6704 {
John Bauman89401822014-05-06 15:04:28 -04006705 Nucleus::createRetVoid();
6706 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
John Bauman19bac1e2014-05-06 15:23:49 -04006707 Nucleus::createUnreachable();
6708 }
6709
6710 void Return(bool ret)
6711 {
Nicolas Capens19336542016-09-26 10:32:29 -04006712 Nucleus::createRet(V(Nucleus::createConstantBool(ret)));
John Bauman19bac1e2014-05-06 15:23:49 -04006713 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
6714 Nucleus::createUnreachable();
John Bauman89401822014-05-06 15:04:28 -04006715 }
6716
6717 void Return(const Int &ret)
6718 {
John Bauman66b8ab22014-05-06 15:57:45 -04006719 Nucleus::createRet(ret.loadValue());
John Bauman89401822014-05-06 15:04:28 -04006720 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
John Bauman19bac1e2014-05-06 15:23:49 -04006721 Nucleus::createUnreachable();
John Bauman89401822014-05-06 15:04:28 -04006722 }
6723
6724 BasicBlock *beginLoop()
6725 {
6726 BasicBlock *loopBB = Nucleus::createBasicBlock();
6727
6728 Nucleus::createBr(loopBB);
John Bauman66b8ab22014-05-06 15:57:45 -04006729 Nucleus::setInsertBlock(loopBB);
John Bauman89401822014-05-06 15:04:28 -04006730
6731 return loopBB;
6732 }
6733
John Bauman19bac1e2014-05-06 15:23:49 -04006734 bool branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB)
John Bauman89401822014-05-06 15:04:28 -04006735 {
6736 Nucleus::createCondBr(cmp.value, bodyBB, endBB);
John Bauman66b8ab22014-05-06 15:57:45 -04006737 Nucleus::setInsertBlock(bodyBB);
6738
John Bauman89401822014-05-06 15:04:28 -04006739 return true;
6740 }
6741
6742 bool elseBlock(BasicBlock *falseBB)
6743 {
6744 falseBB->back().eraseFromParent();
John Bauman66b8ab22014-05-06 15:57:45 -04006745 Nucleus::setInsertBlock(falseBB);
John Bauman89401822014-05-06 15:04:28 -04006746
6747 return true;
6748 }
6749
6750 RValue<Long> Ticks()
6751 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006752 llvm::Function *rdtsc = Intrinsic::getDeclaration(::module, Intrinsic::readcyclecounter);
John Bauman89401822014-05-06 15:04:28 -04006753
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006754 return RValue<Long>(V(::builder->CreateCall(rdtsc)));
John Bauman89401822014-05-06 15:04:28 -04006755 }
John Bauman89401822014-05-06 15:04:28 -04006756}
6757
6758namespace sw
6759{
6760 namespace x86
6761 {
John Bauman19bac1e2014-05-06 15:23:49 -04006762 RValue<Int> cvtss2si(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006763 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006764 llvm::Function *cvtss2si = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cvtss2si);
John Bauman66b8ab22014-05-06 15:57:45 -04006765
John Bauman89401822014-05-06 15:04:28 -04006766 Float4 vector;
6767 vector.x = val;
6768
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006769 return RValue<Int>(V(::builder->CreateCall(cvtss2si, RValue<Float4>(vector).value)));
John Bauman89401822014-05-06 15:04:28 -04006770 }
6771
John Bauman19bac1e2014-05-06 15:23:49 -04006772 RValue<Int2> cvtps2pi(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006773 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006774 llvm::Function *cvtps2pi = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cvtps2pi);
John Bauman89401822014-05-06 15:04:28 -04006775
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006776 return RValue<Int2>(V(::builder->CreateCall(cvtps2pi, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006777 }
6778
John Bauman19bac1e2014-05-06 15:23:49 -04006779 RValue<Int2> cvttps2pi(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006780 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006781 llvm::Function *cvttps2pi = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cvttps2pi);
John Bauman89401822014-05-06 15:04:28 -04006782
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006783 return RValue<Int2>(V(::builder->CreateCall(cvttps2pi, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006784 }
6785
John Bauman19bac1e2014-05-06 15:23:49 -04006786 RValue<Int4> cvtps2dq(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006787 {
6788 if(CPUID::supportsSSE2())
6789 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006790 llvm::Function *cvtps2dq = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_cvtps2dq);
John Bauman89401822014-05-06 15:04:28 -04006791
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006792 return RValue<Int4>(V(::builder->CreateCall(cvtps2dq, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006793 }
6794 else
6795 {
6796 Int2 lo = x86::cvtps2pi(val);
6797 Int2 hi = x86::cvtps2pi(Swizzle(val, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04006798
Nicolas Capens62abb552016-01-05 12:03:47 -05006799 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04006800 }
6801 }
6802
John Bauman19bac1e2014-05-06 15:23:49 -04006803 RValue<Float> rcpss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006804 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006805 llvm::Function *rcpss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rcp_ss);
John Bauman89401822014-05-06 15:04:28 -04006806
Nicolas Capens19336542016-09-26 10:32:29 -04006807 Value *vector = Nucleus::createInsertElement(V(UndefValue::get(Float4::getType())), val.value, 0);
John Bauman66b8ab22014-05-06 15:57:45 -04006808
Nicolas Capense95d5342016-09-30 11:37:28 -04006809 return RValue<Float>(Nucleus::createExtractElement(V(::builder->CreateCall(rcpss, vector)), Float::getType(), 0));
John Bauman89401822014-05-06 15:04:28 -04006810 }
6811
John Bauman19bac1e2014-05-06 15:23:49 -04006812 RValue<Float> sqrtss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006813 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006814 llvm::Function *sqrtss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_sqrt_ss);
John Bauman89401822014-05-06 15:04:28 -04006815
Nicolas Capens19336542016-09-26 10:32:29 -04006816 Value *vector = Nucleus::createInsertElement(V(UndefValue::get(Float4::getType())), val.value, 0);
John Bauman66b8ab22014-05-06 15:57:45 -04006817
Nicolas Capense95d5342016-09-30 11:37:28 -04006818 return RValue<Float>(Nucleus::createExtractElement(V(::builder->CreateCall(sqrtss, vector)), Float::getType(), 0));
John Bauman89401822014-05-06 15:04:28 -04006819 }
6820
John Bauman19bac1e2014-05-06 15:23:49 -04006821 RValue<Float> rsqrtss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006822 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006823 llvm::Function *rsqrtss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rsqrt_ss);
John Bauman66b8ab22014-05-06 15:57:45 -04006824
Nicolas Capens19336542016-09-26 10:32:29 -04006825 Value *vector = Nucleus::createInsertElement(V(UndefValue::get(Float4::getType())), val.value, 0);
John Bauman89401822014-05-06 15:04:28 -04006826
Nicolas Capense95d5342016-09-30 11:37:28 -04006827 return RValue<Float>(Nucleus::createExtractElement(V(::builder->CreateCall(rsqrtss, vector)), Float::getType(), 0));
John Bauman89401822014-05-06 15:04:28 -04006828 }
6829
John Bauman19bac1e2014-05-06 15:23:49 -04006830 RValue<Float4> rcpps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006831 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006832 llvm::Function *rcpps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rcp_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04006833
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006834 return RValue<Float4>(V(::builder->CreateCall(rcpps, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006835 }
6836
John Bauman19bac1e2014-05-06 15:23:49 -04006837 RValue<Float4> sqrtps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006838 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006839 llvm::Function *sqrtps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_sqrt_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04006840
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006841 return RValue<Float4>(V(::builder->CreateCall(sqrtps, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006842 }
6843
John Bauman19bac1e2014-05-06 15:23:49 -04006844 RValue<Float4> rsqrtps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006845 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006846 llvm::Function *rsqrtps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rsqrt_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04006847
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006848 return RValue<Float4>(V(::builder->CreateCall(rsqrtps, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006849 }
6850
John Bauman19bac1e2014-05-06 15:23:49 -04006851 RValue<Float4> maxps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006852 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006853 llvm::Function *maxps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_max_ps);
John Bauman89401822014-05-06 15:04:28 -04006854
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006855 return RValue<Float4>(V(::builder->CreateCall2(maxps, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04006856 }
6857
John Bauman19bac1e2014-05-06 15:23:49 -04006858 RValue<Float4> minps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006859 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006860 llvm::Function *minps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_min_ps);
John Bauman89401822014-05-06 15:04:28 -04006861
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006862 return RValue<Float4>(V(::builder->CreateCall2(minps, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04006863 }
6864
John Bauman19bac1e2014-05-06 15:23:49 -04006865 RValue<Float> roundss(RValue<Float> val, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006866 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006867 llvm::Function *roundss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_round_ss);
John Bauman89401822014-05-06 15:04:28 -04006868
Nicolas Capens19336542016-09-26 10:32:29 -04006869 Value *undef = V(UndefValue::get(Float4::getType()));
John Bauman89401822014-05-06 15:04:28 -04006870 Value *vector = Nucleus::createInsertElement(undef, val.value, 0);
6871
Nicolas Capense95d5342016-09-30 11:37:28 -04006872 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 -04006873 }
6874
John Bauman19bac1e2014-05-06 15:23:49 -04006875 RValue<Float> floorss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006876 {
6877 return roundss(val, 1);
6878 }
6879
John Bauman19bac1e2014-05-06 15:23:49 -04006880 RValue<Float> ceilss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006881 {
6882 return roundss(val, 2);
6883 }
6884
John Bauman19bac1e2014-05-06 15:23:49 -04006885 RValue<Float4> roundps(RValue<Float4> val, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006886 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006887 llvm::Function *roundps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_round_ps);
John Bauman89401822014-05-06 15:04:28 -04006888
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006889 return RValue<Float4>(V(::builder->CreateCall2(roundps, val.value, V(Nucleus::createConstantInt(imm)))));
John Bauman89401822014-05-06 15:04:28 -04006890 }
6891
John Bauman19bac1e2014-05-06 15:23:49 -04006892 RValue<Float4> floorps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006893 {
6894 return roundps(val, 1);
6895 }
6896
John Bauman19bac1e2014-05-06 15:23:49 -04006897 RValue<Float4> ceilps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006898 {
6899 return roundps(val, 2);
6900 }
6901
John Bauman19bac1e2014-05-06 15:23:49 -04006902 RValue<Float4> cmpps(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006903 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006904 llvm::Function *cmpps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cmp_ps);
John Bauman89401822014-05-06 15:04:28 -04006905
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006906 return RValue<Float4>(V(::builder->CreateCall3(cmpps, x.value, y.value, V(Nucleus::createConstantByte(imm)))));
John Bauman89401822014-05-06 15:04:28 -04006907 }
6908
John Bauman19bac1e2014-05-06 15:23:49 -04006909 RValue<Float4> cmpeqps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006910 {
6911 return cmpps(x, y, 0);
6912 }
6913
John Bauman19bac1e2014-05-06 15:23:49 -04006914 RValue<Float4> cmpltps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006915 {
6916 return cmpps(x, y, 1);
6917 }
6918
John Bauman19bac1e2014-05-06 15:23:49 -04006919 RValue<Float4> cmpleps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006920 {
6921 return cmpps(x, y, 2);
6922 }
6923
John Bauman19bac1e2014-05-06 15:23:49 -04006924 RValue<Float4> cmpunordps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006925 {
6926 return cmpps(x, y, 3);
6927 }
6928
John Bauman19bac1e2014-05-06 15:23:49 -04006929 RValue<Float4> cmpneqps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006930 {
6931 return cmpps(x, y, 4);
6932 }
6933
John Bauman19bac1e2014-05-06 15:23:49 -04006934 RValue<Float4> cmpnltps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006935 {
6936 return cmpps(x, y, 5);
6937 }
6938
John Bauman19bac1e2014-05-06 15:23:49 -04006939 RValue<Float4> cmpnleps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006940 {
6941 return cmpps(x, y, 6);
6942 }
6943
John Bauman19bac1e2014-05-06 15:23:49 -04006944 RValue<Float4> cmpordps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006945 {
6946 return cmpps(x, y, 7);
6947 }
6948
John Bauman19bac1e2014-05-06 15:23:49 -04006949 RValue<Float> cmpss(RValue<Float> x, RValue<Float> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006950 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006951 llvm::Function *cmpss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cmp_ss);
John Bauman89401822014-05-06 15:04:28 -04006952
Nicolas Capens19336542016-09-26 10:32:29 -04006953 Value *vector1 = Nucleus::createInsertElement(V(UndefValue::get(Float4::getType())), x.value, 0);
6954 Value *vector2 = Nucleus::createInsertElement(V(UndefValue::get(Float4::getType())), y.value, 0);
John Bauman89401822014-05-06 15:04:28 -04006955
Nicolas Capense95d5342016-09-30 11:37:28 -04006956 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 -04006957 }
6958
John Bauman19bac1e2014-05-06 15:23:49 -04006959 RValue<Float> cmpeqss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006960 {
6961 return cmpss(x, y, 0);
6962 }
6963
John Bauman19bac1e2014-05-06 15:23:49 -04006964 RValue<Float> cmpltss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006965 {
6966 return cmpss(x, y, 1);
6967 }
6968
John Bauman19bac1e2014-05-06 15:23:49 -04006969 RValue<Float> cmpless(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006970 {
6971 return cmpss(x, y, 2);
6972 }
6973
John Bauman19bac1e2014-05-06 15:23:49 -04006974 RValue<Float> cmpunordss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006975 {
6976 return cmpss(x, y, 3);
6977 }
6978
John Bauman19bac1e2014-05-06 15:23:49 -04006979 RValue<Float> cmpneqss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006980 {
6981 return cmpss(x, y, 4);
6982 }
6983
John Bauman19bac1e2014-05-06 15:23:49 -04006984 RValue<Float> cmpnltss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006985 {
6986 return cmpss(x, y, 5);
6987 }
6988
John Bauman19bac1e2014-05-06 15:23:49 -04006989 RValue<Float> cmpnless(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006990 {
6991 return cmpss(x, y, 6);
6992 }
6993
John Bauman19bac1e2014-05-06 15:23:49 -04006994 RValue<Float> cmpordss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006995 {
6996 return cmpss(x, y, 7);
6997 }
6998
Alexis Hetu0f448072016-03-18 10:56:08 -04006999 RValue<Int4> pabsd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007000 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007001 llvm::Function *pabsd = Intrinsic::getDeclaration(::module, Intrinsic::x86_ssse3_pabs_d_128);
John Bauman89401822014-05-06 15:04:28 -04007002
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007003 return RValue<Int4>(V(::builder->CreateCall(pabsd, x.value)));
John Bauman89401822014-05-06 15:04:28 -04007004 }
7005
John Bauman19bac1e2014-05-06 15:23:49 -04007006 RValue<Short4> paddsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007007 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007008 llvm::Function *paddsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padds_w);
John Bauman89401822014-05-06 15:04:28 -04007009
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007010 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(paddsw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007011 }
John Bauman66b8ab22014-05-06 15:57:45 -04007012
John Bauman19bac1e2014-05-06 15:23:49 -04007013 RValue<Short4> psubsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007014 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007015 llvm::Function *psubsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubs_w);
John Bauman89401822014-05-06 15:04:28 -04007016
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007017 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(psubsw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007018 }
7019
John Bauman19bac1e2014-05-06 15:23:49 -04007020 RValue<UShort4> paddusw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007021 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007022 llvm::Function *paddusw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_paddus_w);
John Bauman89401822014-05-06 15:04:28 -04007023
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007024 return As<UShort4>(RValue<MMX>(V(::builder->CreateCall2(paddusw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007025 }
John Bauman66b8ab22014-05-06 15:57:45 -04007026
John Bauman19bac1e2014-05-06 15:23:49 -04007027 RValue<UShort4> psubusw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007028 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007029 llvm::Function *psubusw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubus_w);
John Bauman89401822014-05-06 15:04:28 -04007030
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007031 return As<UShort4>(RValue<MMX>(V(::builder->CreateCall2(psubusw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007032 }
7033
John Bauman19bac1e2014-05-06 15:23:49 -04007034 RValue<SByte8> paddsb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04007035 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007036 llvm::Function *paddsb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padds_b);
John Bauman89401822014-05-06 15:04:28 -04007037
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007038 return As<SByte8>(RValue<MMX>(V(::builder->CreateCall2(paddsb, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007039 }
John Bauman66b8ab22014-05-06 15:57:45 -04007040
John Bauman19bac1e2014-05-06 15:23:49 -04007041 RValue<SByte8> psubsb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04007042 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007043 llvm::Function *psubsb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubs_b);
John Bauman89401822014-05-06 15:04:28 -04007044
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007045 return As<SByte8>(RValue<MMX>(V(::builder->CreateCall2(psubsb, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007046 }
John Bauman66b8ab22014-05-06 15:57:45 -04007047
John Bauman19bac1e2014-05-06 15:23:49 -04007048 RValue<Byte8> paddusb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04007049 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007050 llvm::Function *paddusb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_paddus_b);
John Bauman89401822014-05-06 15:04:28 -04007051
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007052 return As<Byte8>(RValue<MMX>(V(::builder->CreateCall2(paddusb, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007053 }
John Bauman66b8ab22014-05-06 15:57:45 -04007054
John Bauman19bac1e2014-05-06 15:23:49 -04007055 RValue<Byte8> psubusb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04007056 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007057 llvm::Function *psubusb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubus_b);
John Bauman89401822014-05-06 15:04:28 -04007058
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007059 return As<Byte8>(RValue<MMX>(V(::builder->CreateCall2(psubusb, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007060 }
7061
John Bauman19bac1e2014-05-06 15:23:49 -04007062 RValue<Short4> paddw(RValue<Short4> x, RValue<Short4> y)
7063 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007064 llvm::Function *paddw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padd_w);
John Bauman19bac1e2014-05-06 15:23:49 -04007065
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007066 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(paddw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007067 }
7068
7069 RValue<Short4> psubw(RValue<Short4> x, RValue<Short4> y)
7070 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007071 llvm::Function *psubw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psub_w);
John Bauman19bac1e2014-05-06 15:23:49 -04007072
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007073 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(psubw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007074 }
7075
7076 RValue<Short4> pmullw(RValue<Short4> x, RValue<Short4> y)
7077 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007078 llvm::Function *pmullw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmull_w);
John Bauman19bac1e2014-05-06 15:23:49 -04007079
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007080 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(pmullw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007081 }
7082
7083 RValue<Short4> pand(RValue<Short4> x, RValue<Short4> y)
7084 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007085 llvm::Function *pand = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pand);
John Bauman19bac1e2014-05-06 15:23:49 -04007086
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007087 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(pand, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007088 }
7089
7090 RValue<Short4> por(RValue<Short4> x, RValue<Short4> y)
7091 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007092 llvm::Function *por = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_por);
John Bauman19bac1e2014-05-06 15:23:49 -04007093
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007094 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(por, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007095 }
7096
7097 RValue<Short4> pxor(RValue<Short4> x, RValue<Short4> y)
7098 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007099 llvm::Function *pxor = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pxor);
John Bauman19bac1e2014-05-06 15:23:49 -04007100
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007101 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(pxor, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007102 }
7103
7104 RValue<Short4> pshufw(RValue<Short4> x, unsigned char y)
7105 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007106 llvm::Function *pshufw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_pshuf_w);
John Bauman19bac1e2014-05-06 15:23:49 -04007107
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007108 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(pshufw, As<MMX>(x).value, V(Nucleus::createConstantByte(y))))));
John Bauman19bac1e2014-05-06 15:23:49 -04007109 }
7110
7111 RValue<Int2> punpcklwd(RValue<Short4> x, RValue<Short4> y)
7112 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007113 llvm::Function *punpcklwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpcklwd);
John Bauman19bac1e2014-05-06 15:23:49 -04007114
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007115 return As<Int2>(RValue<MMX>(V(::builder->CreateCall2(punpcklwd, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007116 }
7117
7118 RValue<Int2> punpckhwd(RValue<Short4> x, RValue<Short4> y)
7119 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007120 llvm::Function *punpckhwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckhwd);
John Bauman19bac1e2014-05-06 15:23:49 -04007121
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007122 return As<Int2>(RValue<MMX>(V(::builder->CreateCall2(punpckhwd, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007123 }
7124
7125 RValue<Short4> pinsrw(RValue<Short4> x, RValue<Int> y, unsigned int i)
7126 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007127 llvm::Function *pinsrw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pinsr_w);
John Bauman19bac1e2014-05-06 15:23:49 -04007128
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007129 return As<Short4>(RValue<MMX>(V(::builder->CreateCall3(pinsrw, As<MMX>(x).value, y.value, V(Nucleus::createConstantInt(i))))));
John Bauman19bac1e2014-05-06 15:23:49 -04007130 }
7131
7132 RValue<Int> pextrw(RValue<Short4> x, unsigned int i)
7133 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007134 llvm::Function *pextrw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pextr_w);
John Bauman19bac1e2014-05-06 15:23:49 -04007135
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007136 return RValue<Int>(V(::builder->CreateCall2(pextrw, As<MMX>(x).value, V(Nucleus::createConstantInt(i)))));
John Bauman19bac1e2014-05-06 15:23:49 -04007137 }
7138
7139 RValue<Long1> punpckldq(RValue<Int2> x, RValue<Int2> y)
7140 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007141 llvm::Function *punpckldq = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckldq);
John Bauman19bac1e2014-05-06 15:23:49 -04007142
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007143 return As<Long1>(RValue<MMX>(V(::builder->CreateCall2(punpckldq, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007144 }
7145
7146 RValue<Long1> punpckhdq(RValue<Int2> x, RValue<Int2> y)
7147 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007148 llvm::Function *punpckhdq = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckhdq);
John Bauman19bac1e2014-05-06 15:23:49 -04007149
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007150 return As<Long1>(RValue<MMX>(V(::builder->CreateCall2(punpckhdq, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007151 }
7152
7153 RValue<Short4> punpcklbw(RValue<Byte8> x, RValue<Byte8> y)
7154 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007155 llvm::Function *punpcklbw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpcklbw);
John Bauman19bac1e2014-05-06 15:23:49 -04007156
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007157 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(punpcklbw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007158 }
7159
7160 RValue<Short4> punpckhbw(RValue<Byte8> x, RValue<Byte8> y)
7161 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007162 llvm::Function *punpckhbw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckhbw);
John Bauman19bac1e2014-05-06 15:23:49 -04007163
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007164 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(punpckhbw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007165 }
7166
7167 RValue<Byte8> paddb(RValue<Byte8> x, RValue<Byte8> y)
7168 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007169 llvm::Function *paddb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padd_b);
John Bauman19bac1e2014-05-06 15:23:49 -04007170
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007171 return As<Byte8>(RValue<MMX>(V(::builder->CreateCall2(paddb, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007172 }
7173
7174 RValue<Byte8> psubb(RValue<Byte8> x, RValue<Byte8> y)
7175 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007176 llvm::Function *psubb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psub_b);
John Bauman19bac1e2014-05-06 15:23:49 -04007177
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007178 return As<Byte8>(RValue<MMX>(V(::builder->CreateCall2(psubb, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007179 }
7180
7181 RValue<Int2> paddd(RValue<Int2> x, RValue<Int2> y)
7182 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007183 llvm::Function *paddd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padd_d);
John Bauman19bac1e2014-05-06 15:23:49 -04007184
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007185 return As<Int2>(RValue<MMX>(V(::builder->CreateCall2(paddd, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007186 }
7187
7188 RValue<Int2> psubd(RValue<Int2> x, RValue<Int2> y)
7189 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007190 llvm::Function *psubd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psub_d);
John Bauman19bac1e2014-05-06 15:23:49 -04007191
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007192 return As<Int2>(RValue<MMX>(V(::builder->CreateCall2(psubd, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007193 }
7194
7195 RValue<UShort4> pavgw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007196 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007197 llvm::Function *pavgw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pavg_w);
John Bauman89401822014-05-06 15:04:28 -04007198
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007199 return As<UShort4>(RValue<MMX>(V(::builder->CreateCall2(pavgw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007200 }
7201
John Bauman19bac1e2014-05-06 15:23:49 -04007202 RValue<Short4> pmaxsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007203 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007204 llvm::Function *pmaxsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmaxs_w);
John Bauman89401822014-05-06 15:04:28 -04007205
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007206 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(pmaxsw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007207 }
7208
John Bauman19bac1e2014-05-06 15:23:49 -04007209 RValue<Short4> pminsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007210 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007211 llvm::Function *pminsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmins_w);
John Bauman89401822014-05-06 15:04:28 -04007212
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007213 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(pminsw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007214 }
7215
John Bauman19bac1e2014-05-06 15:23:49 -04007216 RValue<Short4> pcmpgtw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007217 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007218 llvm::Function *pcmpgtw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpgt_w);
John Bauman89401822014-05-06 15:04:28 -04007219
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007220 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(pcmpgtw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007221 }
7222
John Bauman19bac1e2014-05-06 15:23:49 -04007223 RValue<Short4> pcmpeqw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007224 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007225 llvm::Function *pcmpeqw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpeq_w);
John Bauman89401822014-05-06 15:04:28 -04007226
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007227 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(pcmpeqw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007228 }
7229
John Bauman19bac1e2014-05-06 15:23:49 -04007230 RValue<Byte8> pcmpgtb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04007231 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007232 llvm::Function *pcmpgtb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpgt_b);
John Bauman89401822014-05-06 15:04:28 -04007233
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007234 return As<Byte8>(RValue<MMX>(V(::builder->CreateCall2(pcmpgtb, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007235 }
7236
John Bauman19bac1e2014-05-06 15:23:49 -04007237 RValue<Byte8> pcmpeqb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04007238 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007239 llvm::Function *pcmpeqb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpeq_b);
John Bauman89401822014-05-06 15:04:28 -04007240
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007241 return As<Byte8>(RValue<MMX>(V(::builder->CreateCall2(pcmpeqb, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007242 }
7243
John Bauman19bac1e2014-05-06 15:23:49 -04007244 RValue<Short4> packssdw(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04007245 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007246 llvm::Function *packssdw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_packssdw);
John Bauman89401822014-05-06 15:04:28 -04007247
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007248 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(packssdw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007249 }
7250
John Bauman19bac1e2014-05-06 15:23:49 -04007251 RValue<Short8> packssdw(RValue<Int4> x, RValue<Int4> y)
John Bauman89401822014-05-06 15:04:28 -04007252 {
7253 if(CPUID::supportsSSE2())
7254 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007255 llvm::Function *packssdw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_packssdw_128);
John Bauman89401822014-05-06 15:04:28 -04007256
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007257 return RValue<Short8>(V(::builder->CreateCall2(packssdw, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04007258 }
7259 else
7260 {
7261 Int2 loX = Int2(x);
7262 Int2 hiX = Int2(Swizzle(x, 0xEE));
7263
7264 Int2 loY = Int2(y);
7265 Int2 hiY = Int2(Swizzle(y, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04007266
John Bauman89401822014-05-06 15:04:28 -04007267 Short4 lo = x86::packssdw(loX, hiX);
7268 Short4 hi = x86::packssdw(loY, hiY);
John Bauman66b8ab22014-05-06 15:57:45 -04007269
Nicolas Capens62abb552016-01-05 12:03:47 -05007270 return Short8(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007271 }
7272 }
7273
John Bauman19bac1e2014-05-06 15:23:49 -04007274 RValue<SByte8> packsswb(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007275 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007276 llvm::Function *packsswb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_packsswb);
John Bauman89401822014-05-06 15:04:28 -04007277
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007278 return As<SByte8>(RValue<MMX>(V(::builder->CreateCall2(packsswb, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007279 }
7280
John Bauman19bac1e2014-05-06 15:23:49 -04007281 RValue<Byte8> packuswb(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007282 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007283 llvm::Function *packuswb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_packuswb);
John Bauman89401822014-05-06 15:04:28 -04007284
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007285 return As<Byte8>(RValue<MMX>(V(::builder->CreateCall2(packuswb, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007286 }
7287
John Bauman19bac1e2014-05-06 15:23:49 -04007288 RValue<UShort8> packusdw(RValue<UInt4> x, RValue<UInt4> y)
John Bauman89401822014-05-06 15:04:28 -04007289 {
7290 if(CPUID::supportsSSE4_1())
7291 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007292 llvm::Function *packusdw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_packusdw);
John Bauman66b8ab22014-05-06 15:57:45 -04007293
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007294 return RValue<UShort8>(V(::builder->CreateCall2(packusdw, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04007295 }
7296 else
7297 {
7298 // FIXME: Not an exact replacement!
John Bauman19bac1e2014-05-06 15:23:49 -04007299 return As<UShort8>(packssdw(As<Int4>(x - UInt4(0x00008000, 0x00008000, 0x00008000, 0x00008000)), As<Int4>(y - UInt4(0x00008000, 0x00008000, 0x00008000, 0x00008000))) + Short8(0x8000u, 0x8000u, 0x8000u, 0x8000u, 0x8000u, 0x8000u, 0x8000u, 0x8000u));
John Bauman89401822014-05-06 15:04:28 -04007300 }
7301 }
7302
John Bauman19bac1e2014-05-06 15:23:49 -04007303 RValue<UShort4> psrlw(RValue<UShort4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007304 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007305 llvm::Function *psrlw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrli_w);
John Bauman89401822014-05-06 15:04:28 -04007306
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007307 return As<UShort4>(RValue<MMX>(V(::builder->CreateCall2(psrlw, As<MMX>(x).value, V(Nucleus::createConstantInt(y))))));
John Bauman89401822014-05-06 15:04:28 -04007308 }
7309
John Bauman19bac1e2014-05-06 15:23:49 -04007310 RValue<UShort8> psrlw(RValue<UShort8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007311 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007312 llvm::Function *psrlw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrli_w);
John Bauman89401822014-05-06 15:04:28 -04007313
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007314 return RValue<UShort8>(V(::builder->CreateCall2(psrlw, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007315 }
7316
John Bauman19bac1e2014-05-06 15:23:49 -04007317 RValue<Short4> psraw(RValue<Short4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007318 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007319 llvm::Function *psraw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrai_w);
John Bauman89401822014-05-06 15:04:28 -04007320
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007321 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(psraw, As<MMX>(x).value, V(Nucleus::createConstantInt(y))))));
John Bauman89401822014-05-06 15:04:28 -04007322 }
7323
John Bauman19bac1e2014-05-06 15:23:49 -04007324 RValue<Short8> psraw(RValue<Short8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007325 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007326 llvm::Function *psraw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrai_w);
John Bauman89401822014-05-06 15:04:28 -04007327
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007328 return RValue<Short8>(V(::builder->CreateCall2(psraw, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007329 }
7330
John Bauman19bac1e2014-05-06 15:23:49 -04007331 RValue<Short4> psllw(RValue<Short4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007332 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007333 llvm::Function *psllw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pslli_w);
John Bauman89401822014-05-06 15:04:28 -04007334
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007335 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(psllw, As<MMX>(x).value, V(Nucleus::createConstantInt(y))))));
John Bauman89401822014-05-06 15:04:28 -04007336 }
7337
John Bauman19bac1e2014-05-06 15:23:49 -04007338 RValue<Short8> psllw(RValue<Short8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007339 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007340 llvm::Function *psllw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pslli_w);
John Bauman89401822014-05-06 15:04:28 -04007341
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007342 return RValue<Short8>(V(::builder->CreateCall2(psllw, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007343 }
7344
John Bauman19bac1e2014-05-06 15:23:49 -04007345 RValue<Int2> pslld(RValue<Int2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007346 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007347 llvm::Function *pslld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pslli_d);
John Bauman89401822014-05-06 15:04:28 -04007348
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007349 return As<Int2>(RValue<MMX>(V(::builder->CreateCall2(pslld, As<MMX>(x).value, V(Nucleus::createConstantInt(y))))));
John Bauman89401822014-05-06 15:04:28 -04007350 }
7351
John Bauman19bac1e2014-05-06 15:23:49 -04007352 RValue<Int4> pslld(RValue<Int4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007353 {
7354 if(CPUID::supportsSSE2())
7355 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007356 llvm::Function *pslld = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pslli_d);
John Bauman89401822014-05-06 15:04:28 -04007357
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007358 return RValue<Int4>(V(::builder->CreateCall2(pslld, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007359 }
7360 else
7361 {
7362 Int2 lo = Int2(x);
7363 Int2 hi = Int2(Swizzle(x, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04007364
John Bauman89401822014-05-06 15:04:28 -04007365 lo = x86::pslld(lo, y);
7366 hi = x86::pslld(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04007367
Nicolas Capens62abb552016-01-05 12:03:47 -05007368 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007369 }
7370 }
7371
John Bauman19bac1e2014-05-06 15:23:49 -04007372 RValue<Int2> psrad(RValue<Int2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007373 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007374 llvm::Function *psrad = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrai_d);
John Bauman89401822014-05-06 15:04:28 -04007375
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007376 return As<Int2>(RValue<MMX>(V(::builder->CreateCall2(psrad, As<MMX>(x).value, V(Nucleus::createConstantInt(y))))));
John Bauman89401822014-05-06 15:04:28 -04007377 }
7378
John Bauman19bac1e2014-05-06 15:23:49 -04007379 RValue<Int4> psrad(RValue<Int4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007380 {
7381 if(CPUID::supportsSSE2())
7382 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007383 llvm::Function *psrad = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrai_d);
John Bauman89401822014-05-06 15:04:28 -04007384
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007385 return RValue<Int4>(V(::builder->CreateCall2(psrad, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007386 }
7387 else
7388 {
7389 Int2 lo = Int2(x);
7390 Int2 hi = Int2(Swizzle(x, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04007391
John Bauman89401822014-05-06 15:04:28 -04007392 lo = x86::psrad(lo, y);
7393 hi = x86::psrad(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04007394
Nicolas Capens62abb552016-01-05 12:03:47 -05007395 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007396 }
7397 }
7398
John Bauman19bac1e2014-05-06 15:23:49 -04007399 RValue<UInt2> psrld(RValue<UInt2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007400 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007401 llvm::Function *psrld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrli_d);
John Bauman89401822014-05-06 15:04:28 -04007402
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007403 return As<UInt2>(RValue<MMX>(V(::builder->CreateCall2(psrld, As<MMX>(x).value, V(Nucleus::createConstantInt(y))))));
John Bauman89401822014-05-06 15:04:28 -04007404 }
7405
John Bauman19bac1e2014-05-06 15:23:49 -04007406 RValue<UInt4> psrld(RValue<UInt4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007407 {
7408 if(CPUID::supportsSSE2())
7409 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007410 llvm::Function *psrld = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrli_d);
John Bauman89401822014-05-06 15:04:28 -04007411
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007412 return RValue<UInt4>(V(::builder->CreateCall2(psrld, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007413 }
7414 else
7415 {
7416 UInt2 lo = As<UInt2>(Int2(As<Int4>(x)));
7417 UInt2 hi = As<UInt2>(Int2(Swizzle(As<Int4>(x), 0xEE)));
John Bauman66b8ab22014-05-06 15:57:45 -04007418
John Bauman89401822014-05-06 15:04:28 -04007419 lo = x86::psrld(lo, y);
7420 hi = x86::psrld(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04007421
Nicolas Capens62abb552016-01-05 12:03:47 -05007422 return UInt4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007423 }
7424 }
7425
John Bauman19bac1e2014-05-06 15:23:49 -04007426 RValue<UShort4> psrlw(RValue<UShort4> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007427 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007428 llvm::Function *psrlw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrl_w);
John Bauman89401822014-05-06 15:04:28 -04007429
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007430 return As<UShort4>(RValue<MMX>(V(::builder->CreateCall2(psrlw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007431 }
7432
John Bauman19bac1e2014-05-06 15:23:49 -04007433 RValue<Short4> psraw(RValue<Short4> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007434 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007435 llvm::Function *psraw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psra_w);
John Bauman89401822014-05-06 15:04:28 -04007436
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007437 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(psraw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007438 }
7439
John Bauman19bac1e2014-05-06 15:23:49 -04007440 RValue<Short4> psllw(RValue<Short4> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007441 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007442 llvm::Function *psllw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psll_w);
John Bauman89401822014-05-06 15:04:28 -04007443
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007444 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(psllw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007445 }
7446
John Bauman19bac1e2014-05-06 15:23:49 -04007447 RValue<Int2> pslld(RValue<Int2> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007448 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007449 llvm::Function *pslld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psll_d);
John Bauman89401822014-05-06 15:04:28 -04007450
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007451 return As<Int2>(RValue<MMX>(V(::builder->CreateCall2(pslld, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007452 }
7453
John Bauman19bac1e2014-05-06 15:23:49 -04007454 RValue<UInt2> psrld(RValue<UInt2> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007455 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007456 llvm::Function *psrld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrl_d);
John Bauman89401822014-05-06 15:04:28 -04007457
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007458 return As<UInt2>(RValue<MMX>(V(::builder->CreateCall2(psrld, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007459 }
7460
John Bauman19bac1e2014-05-06 15:23:49 -04007461 RValue<Int2> psrad(RValue<Int2> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007462 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007463 llvm::Function *psrld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psra_d);
John Bauman89401822014-05-06 15:04:28 -04007464
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007465 return As<Int2>(RValue<MMX>(V(::builder->CreateCall2(psrld, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007466 }
7467
John Bauman19bac1e2014-05-06 15:23:49 -04007468 RValue<Int4> pmaxsd(RValue<Int4> x, RValue<Int4> y)
7469 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007470 llvm::Function *pmaxsd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmaxsd);
John Bauman19bac1e2014-05-06 15:23:49 -04007471
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007472 return RValue<Int4>(V(::builder->CreateCall2(pmaxsd, x.value, y.value)));
John Bauman19bac1e2014-05-06 15:23:49 -04007473 }
7474
7475 RValue<Int4> pminsd(RValue<Int4> x, RValue<Int4> y)
7476 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007477 llvm::Function *pminsd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pminsd);
John Bauman19bac1e2014-05-06 15:23:49 -04007478
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007479 return RValue<Int4>(V(::builder->CreateCall2(pminsd, x.value, y.value)));
John Bauman19bac1e2014-05-06 15:23:49 -04007480 }
7481
7482 RValue<UInt4> pmaxud(RValue<UInt4> x, RValue<UInt4> y)
7483 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007484 llvm::Function *pmaxud = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmaxud);
John Bauman19bac1e2014-05-06 15:23:49 -04007485
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007486 return RValue<UInt4>(V(::builder->CreateCall2(pmaxud, x.value, y.value)));
John Bauman19bac1e2014-05-06 15:23:49 -04007487 }
7488
7489 RValue<UInt4> pminud(RValue<UInt4> x, RValue<UInt4> y)
7490 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007491 llvm::Function *pminud = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pminud);
John Bauman19bac1e2014-05-06 15:23:49 -04007492
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007493 return RValue<UInt4>(V(::builder->CreateCall2(pminud, x.value, y.value)));
John Bauman19bac1e2014-05-06 15:23:49 -04007494 }
7495
7496 RValue<Short4> pmulhw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007497 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007498 llvm::Function *pmulhw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmulh_w);
John Bauman89401822014-05-06 15:04:28 -04007499
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007500 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(pmulhw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007501 }
7502
John Bauman19bac1e2014-05-06 15:23:49 -04007503 RValue<UShort4> pmulhuw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007504 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007505 llvm::Function *pmulhuw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmulhu_w);
John Bauman89401822014-05-06 15:04:28 -04007506
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007507 return As<UShort4>(RValue<MMX>(V(::builder->CreateCall2(pmulhuw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007508 }
7509
John Bauman19bac1e2014-05-06 15:23:49 -04007510 RValue<Int2> pmaddwd(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007511 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007512 llvm::Function *pmaddwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmadd_wd);
John Bauman89401822014-05-06 15:04:28 -04007513
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007514 return As<Int2>(RValue<MMX>(V(::builder->CreateCall2(pmaddwd, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007515 }
7516
John Bauman19bac1e2014-05-06 15:23:49 -04007517 RValue<Short8> pmulhw(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04007518 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007519 llvm::Function *pmulhw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pmulh_w);
John Bauman89401822014-05-06 15:04:28 -04007520
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007521 return RValue<Short8>(V(::builder->CreateCall2(pmulhw, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04007522 }
7523
John Bauman19bac1e2014-05-06 15:23:49 -04007524 RValue<UShort8> pmulhuw(RValue<UShort8> x, RValue<UShort8> y)
John Bauman89401822014-05-06 15:04:28 -04007525 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007526 llvm::Function *pmulhuw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pmulhu_w);
John Bauman89401822014-05-06 15:04:28 -04007527
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007528 return RValue<UShort8>(V(::builder->CreateCall2(pmulhuw, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04007529 }
7530
John Bauman19bac1e2014-05-06 15:23:49 -04007531 RValue<Int4> pmaddwd(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04007532 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007533 llvm::Function *pmaddwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pmadd_wd);
John Bauman89401822014-05-06 15:04:28 -04007534
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007535 return RValue<Int4>(V(::builder->CreateCall2(pmaddwd, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04007536 }
7537
John Bauman19bac1e2014-05-06 15:23:49 -04007538 RValue<Int> movmskps(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04007539 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007540 llvm::Function *movmskps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_movmsk_ps);
John Bauman89401822014-05-06 15:04:28 -04007541
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007542 return RValue<Int>(V(::builder->CreateCall(movmskps, x.value)));
John Bauman89401822014-05-06 15:04:28 -04007543 }
7544
John Bauman19bac1e2014-05-06 15:23:49 -04007545 RValue<Int> pmovmskb(RValue<Byte8> x)
John Bauman89401822014-05-06 15:04:28 -04007546 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007547 llvm::Function *pmovmskb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmovmskb);
John Bauman89401822014-05-06 15:04:28 -04007548
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007549 return RValue<Int>(V(::builder->CreateCall(pmovmskb, As<MMX>(x).value)));
John Bauman89401822014-05-06 15:04:28 -04007550 }
7551
Nicolas Capens81f18302016-01-14 09:32:35 -05007552 //RValue<Int2> movd(RValue<Pointer<Int>> x)
John Bauman89401822014-05-06 15:04:28 -04007553 //{
7554 // Value *element = Nucleus::createLoad(x.value);
7555
7556 //// Value *int2 = UndefValue::get(Int2::getType());
7557 //// int2 = Nucleus::createInsertElement(int2, element, ConstantInt::get(Int::getType(), 0));
7558
7559 // Value *int2 = Nucleus::createBitCast(Nucleus::createZExt(element, Long::getType()), Int2::getType());
7560
7561 // return RValue<Int2>(int2);
7562 //}
7563
John Bauman19bac1e2014-05-06 15:23:49 -04007564 //RValue<Int2> movdq2q(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007565 //{
Nicolas Capens22008782016-10-20 01:11:47 -04007566 // Value *long2 = Nucleus::createBitCast(x.value, T(VectorType::get(Long::getType(), 2)));
John Bauman89401822014-05-06 15:04:28 -04007567 // Value *element = Nucleus::createExtractElement(long2, ConstantInt::get(Int::getType(), 0));
7568
7569 // return RValue<Int2>(Nucleus::createBitCast(element, Int2::getType()));
7570 //}
7571
John Bauman19bac1e2014-05-06 15:23:49 -04007572 RValue<Int4> pmovzxbd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007573 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007574 llvm::Function *pmovzxbd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovzxbd);
John Bauman66b8ab22014-05-06 15:57:45 -04007575
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007576 return RValue<Int4>(V(::builder->CreateCall(pmovzxbd, Nucleus::createBitCast(x.value, Byte16::getType()))));
John Bauman89401822014-05-06 15:04:28 -04007577 }
7578
John Bauman19bac1e2014-05-06 15:23:49 -04007579 RValue<Int4> pmovsxbd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007580 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007581 llvm::Function *pmovsxbd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovsxbd);
John Bauman66b8ab22014-05-06 15:57:45 -04007582
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007583 return RValue<Int4>(V(::builder->CreateCall(pmovsxbd, Nucleus::createBitCast(x.value, SByte16::getType()))));
John Bauman89401822014-05-06 15:04:28 -04007584 }
7585
John Bauman19bac1e2014-05-06 15:23:49 -04007586 RValue<Int4> pmovzxwd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007587 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007588 llvm::Function *pmovzxwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovzxwd);
John Bauman66b8ab22014-05-06 15:57:45 -04007589
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007590 return RValue<Int4>(V(::builder->CreateCall(pmovzxwd, Nucleus::createBitCast(x.value, UShort8::getType()))));
John Bauman89401822014-05-06 15:04:28 -04007591 }
7592
John Bauman19bac1e2014-05-06 15:23:49 -04007593 RValue<Int4> pmovsxwd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007594 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007595 llvm::Function *pmovsxwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovsxwd);
John Bauman66b8ab22014-05-06 15:57:45 -04007596
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007597 return RValue<Int4>(V(::builder->CreateCall(pmovsxwd, Nucleus::createBitCast(x.value, Short8::getType()))));
John Bauman89401822014-05-06 15:04:28 -04007598 }
7599
7600 void emms()
7601 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007602 llvm::Function *emms = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_emms);
John Bauman89401822014-05-06 15:04:28 -04007603
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007604 V(::builder->CreateCall(emms));
John Bauman89401822014-05-06 15:04:28 -04007605 }
7606 }
7607}