blob: 8204697929ea08e187d94ee9b4b8455b017f6f99 [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 Capens9ed1a182016-10-24 09:52:23 -040072
73 sw::BasicBlock *falseBB = nullptr;
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -040074}
75
John Bauman89401822014-05-06 15:04:28 -040076namespace sw
77{
John Bauman89401822014-05-06 15:04:28 -040078 using namespace llvm;
John Bauman89401822014-05-06 15:04:28 -040079
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -040080 Optimization optimization[10] = {InstructionCombining, Disabled};
John Bauman89401822014-05-06 15:04:28 -040081
Nicolas Capensc8b67a42016-09-25 15:02:52 -040082 class Type : public llvm::Type {};
Nicolas Capens19336542016-09-26 10:32:29 -040083 class Value : public llvm::Value {};
Nicolas Capensc8b67a42016-09-25 15:02:52 -040084 class BasicBlock : public llvm::BasicBlock {};
Nicolas Capensac230122016-09-20 14:30:06 -040085
86 inline Type *T(llvm::Type *t)
87 {
88 return reinterpret_cast<Type*>(t);
89 }
90
Nicolas Capens19336542016-09-26 10:32:29 -040091 inline Value *V(llvm::Value *t)
92 {
93 return reinterpret_cast<Value*>(t);
94 }
95
Nicolas Capensac230122016-09-20 14:30:06 -040096 inline std::vector<llvm::Type*> &T(std::vector<Type*> &t)
97 {
98 return reinterpret_cast<std::vector<llvm::Type*>&>(t);
99 }
100
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400101 inline BasicBlock *B(llvm::BasicBlock *t)
102 {
103 return reinterpret_cast<BasicBlock*>(t);
104 }
105
John Bauman89401822014-05-06 15:04:28 -0400106 Nucleus::Nucleus()
107 {
Nicolas Capens3bbc5e12016-09-27 10:49:52 -0400108 ::codegenMutex.lock(); // Reactor and LLVM are currently not thread safe
Nicolas Capensb7ea9842015-04-01 10:54:59 -0400109
John Bauman19bac1e2014-05-06 15:23:49 -0400110 InitializeNativeTarget();
John Bauman89401822014-05-06 15:04:28 -0400111 JITEmitDebugInfo = false;
112
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400113 if(!::context)
John Bauman89401822014-05-06 15:04:28 -0400114 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400115 ::context = new LLVMContext();
John Bauman89401822014-05-06 15:04:28 -0400116 }
117
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400118 ::module = new Module("", *::context);
Nicolas Capensdaa5d912016-09-28 16:56:36 -0400119 ::routineManager = new LLVMRoutineManager();
John Bauman66b8ab22014-05-06 15:57:45 -0400120
John Bauman89401822014-05-06 15:04:28 -0400121 #if defined(__x86_64__)
122 const char *architecture = "x86-64";
123 #else
124 const char *architecture = "x86";
125 #endif
126
127 SmallVector<std::string, 1> MAttrs;
128 MAttrs.push_back(CPUID::supportsMMX() ? "+mmx" : "-mmx");
129 MAttrs.push_back(CPUID::supportsCMOV() ? "+cmov" : "-cmov");
130 MAttrs.push_back(CPUID::supportsSSE() ? "+sse" : "-sse");
131 MAttrs.push_back(CPUID::supportsSSE2() ? "+sse2" : "-sse2");
132 MAttrs.push_back(CPUID::supportsSSE3() ? "+sse3" : "-sse3");
133 MAttrs.push_back(CPUID::supportsSSSE3() ? "+ssse3" : "-ssse3");
134 MAttrs.push_back(CPUID::supportsSSE4_1() ? "+sse41" : "-sse41");
135
John Bauman19bac1e2014-05-06 15:23:49 -0400136 std::string error;
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400137 TargetMachine *targetMachine = EngineBuilder::selectTarget(::module, architecture, "", MAttrs, Reloc::Default, CodeModel::JITDefault, &error);
138 ::executionEngine = JIT::createJIT(::module, 0, ::routineManager, CodeGenOpt::Aggressive, true, targetMachine);
John Bauman89401822014-05-06 15:04:28 -0400139
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400140 if(!::builder)
John Bauman89401822014-05-06 15:04:28 -0400141 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400142 ::builder = new IRBuilder<>(*::context);
John Bauman89401822014-05-06 15:04:28 -0400143
John Bauman66b8ab22014-05-06 15:57:45 -0400144 #if defined(_WIN32)
145 HMODULE CodeAnalyst = LoadLibrary("CAJitNtfyLib.dll");
146 if(CodeAnalyst)
147 {
148 CodeAnalystInitialize = (bool(*)())GetProcAddress(CodeAnalyst, "CAJIT_Initialize");
149 CodeAnalystCompleteJITLog = (void(*)())GetProcAddress(CodeAnalyst, "CAJIT_CompleteJITLog");
150 CodeAnalystLogJITCode = (bool(*)(const void*, unsigned int, const wchar_t*))GetProcAddress(CodeAnalyst, "CAJIT_LogJITCode");
151
152 CodeAnalystInitialize();
153 }
154 #endif
John Bauman89401822014-05-06 15:04:28 -0400155 }
156 }
157
158 Nucleus::~Nucleus()
159 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400160 delete ::executionEngine;
161 ::executionEngine = nullptr;
John Bauman89401822014-05-06 15:04:28 -0400162
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400163 ::routineManager = nullptr;
164 ::function = nullptr;
165 ::module = nullptr;
Nicolas Capensb7ea9842015-04-01 10:54:59 -0400166
Nicolas Capens3bbc5e12016-09-27 10:49:52 -0400167 ::codegenMutex.unlock();
John Bauman89401822014-05-06 15:04:28 -0400168 }
169
170 Routine *Nucleus::acquireRoutine(const wchar_t *name, bool runOptimizations)
171 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400172 if(::builder->GetInsertBlock()->empty() || !::builder->GetInsertBlock()->back().isTerminator())
John Bauman19bac1e2014-05-06 15:23:49 -0400173 {
Nicolas Capensac230122016-09-20 14:30:06 -0400174 llvm::Type *type = ::function->getReturnType();
John Bauman19bac1e2014-05-06 15:23:49 -0400175
176 if(type->isVoidTy())
177 {
178 createRetVoid();
179 }
180 else
181 {
Nicolas Capens19336542016-09-26 10:32:29 -0400182 createRet(V(UndefValue::get(type)));
John Bauman19bac1e2014-05-06 15:23:49 -0400183 }
184 }
John Bauman89401822014-05-06 15:04:28 -0400185
186 if(false)
187 {
John Bauman66b8ab22014-05-06 15:57:45 -0400188 std::string error;
189 raw_fd_ostream file("llvm-dump-unopt.txt", error);
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400190 ::module->print(file, 0);
John Bauman89401822014-05-06 15:04:28 -0400191 }
192
193 if(runOptimizations)
194 {
195 optimize();
196 }
197
198 if(false)
199 {
John Bauman66b8ab22014-05-06 15:57:45 -0400200 std::string error;
201 raw_fd_ostream file("llvm-dump-opt.txt", error);
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400202 ::module->print(file, 0);
John Bauman89401822014-05-06 15:04:28 -0400203 }
204
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400205 void *entry = ::executionEngine->getPointerToFunction(::function);
Nicolas Capensdaa5d912016-09-28 16:56:36 -0400206 LLVMRoutine *routine = ::routineManager->acquireRoutine(entry);
John Bauman89401822014-05-06 15:04:28 -0400207
208 if(CodeAnalystLogJITCode)
209 {
Nicolas Capensd946e0a2014-06-26 11:31:08 -0400210 CodeAnalystLogJITCode(routine->getEntry(), routine->getCodeSize(), name);
John Bauman89401822014-05-06 15:04:28 -0400211 }
212
213 return routine;
214 }
215
216 void Nucleus::optimize()
217 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400218 static PassManager *passManager = nullptr;
John Bauman66b8ab22014-05-06 15:57:45 -0400219
John Bauman89401822014-05-06 15:04:28 -0400220 if(!passManager)
221 {
222 passManager = new PassManager();
223
224 UnsafeFPMath = true;
225 // NoInfsFPMath = true;
226 // NoNaNsFPMath = true;
227
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400228 passManager->add(new TargetData(*::executionEngine->getTargetData()));
John Bauman89401822014-05-06 15:04:28 -0400229 passManager->add(createScalarReplAggregatesPass());
230
231 for(int pass = 0; pass < 10 && optimization[pass] != Disabled; pass++)
232 {
233 switch(optimization[pass])
234 {
235 case Disabled: break;
236 case CFGSimplification: passManager->add(createCFGSimplificationPass()); break;
237 case LICM: passManager->add(createLICMPass()); break;
238 case AggressiveDCE: passManager->add(createAggressiveDCEPass()); break;
239 case GVN: passManager->add(createGVNPass()); break;
240 case InstructionCombining: passManager->add(createInstructionCombiningPass()); break;
241 case Reassociate: passManager->add(createReassociatePass()); break;
242 case DeadStoreElimination: passManager->add(createDeadStoreEliminationPass()); break;
243 case SCCP: passManager->add(createSCCPPass()); break;
John Bauman19bac1e2014-05-06 15:23:49 -0400244 case ScalarReplAggregates: passManager->add(createScalarReplAggregatesPass()); break;
John Bauman89401822014-05-06 15:04:28 -0400245 default:
246 assert(false);
247 }
248 }
249 }
250
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400251 passManager->run(*::module);
John Bauman89401822014-05-06 15:04:28 -0400252 }
253
John Bauman19bac1e2014-05-06 15:23:49 -0400254 Value *Nucleus::allocateStackVariable(Type *type, int arraySize)
John Bauman89401822014-05-06 15:04:28 -0400255 {
256 // Need to allocate it in the entry block for mem2reg to work
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400257 llvm::BasicBlock &entryBlock = ::function->getEntryBlock();
John Bauman89401822014-05-06 15:04:28 -0400258
259 Instruction *declaration;
260
261 if(arraySize)
262 {
263 declaration = new AllocaInst(type, Nucleus::createConstantInt(arraySize));
264 }
265 else
266 {
267 declaration = new AllocaInst(type, (Value*)0);
268 }
269
270 entryBlock.getInstList().push_front(declaration);
271
Nicolas Capens19336542016-09-26 10:32:29 -0400272 return V(declaration);
John Bauman89401822014-05-06 15:04:28 -0400273 }
274
275 BasicBlock *Nucleus::createBasicBlock()
276 {
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400277 return B(BasicBlock::Create(*::context, "", ::function));
John Bauman89401822014-05-06 15:04:28 -0400278 }
279
280 BasicBlock *Nucleus::getInsertBlock()
281 {
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400282 return B(::builder->GetInsertBlock());
John Bauman89401822014-05-06 15:04:28 -0400283 }
284
285 void Nucleus::setInsertBlock(BasicBlock *basicBlock)
286 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400287 // assert(::builder->GetInsertBlock()->back().isTerminator());
288 return ::builder->SetInsertPoint(basicBlock);
John Bauman89401822014-05-06 15:04:28 -0400289 }
290
Nicolas Capensac230122016-09-20 14:30:06 -0400291 void Nucleus::createFunction(Type *ReturnType, std::vector<Type*> &Params)
John Bauman89401822014-05-06 15:04:28 -0400292 {
Nicolas Capensac230122016-09-20 14:30:06 -0400293 llvm::FunctionType *functionType = llvm::FunctionType::get(ReturnType, T(Params), false);
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400294 ::function = llvm::Function::Create(functionType, llvm::GlobalValue::InternalLinkage, "", ::module);
295 ::function->setCallingConv(llvm::CallingConv::C);
John Bauman89401822014-05-06 15:04:28 -0400296
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400297 ::builder->SetInsertPoint(BasicBlock::Create(*::context, "", ::function));
John Bauman89401822014-05-06 15:04:28 -0400298 }
299
Nicolas Capens19336542016-09-26 10:32:29 -0400300 Value *Nucleus::getArgument(unsigned int index)
John Bauman89401822014-05-06 15:04:28 -0400301 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400302 llvm::Function::arg_iterator args = ::function->arg_begin();
John Bauman89401822014-05-06 15:04:28 -0400303
304 while(index)
305 {
306 args++;
307 index--;
308 }
309
Nicolas Capens19336542016-09-26 10:32:29 -0400310 return V(&*args);
John Bauman89401822014-05-06 15:04:28 -0400311 }
312
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400313 void Nucleus::createRetVoid()
John Bauman89401822014-05-06 15:04:28 -0400314 {
John Bauman66b8ab22014-05-06 15:57:45 -0400315 x86::emms();
316
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400317 ::builder->CreateRetVoid();
John Bauman89401822014-05-06 15:04:28 -0400318 }
319
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400320 void Nucleus::createRet(Value *v)
John Bauman89401822014-05-06 15:04:28 -0400321 {
John Bauman66b8ab22014-05-06 15:57:45 -0400322 x86::emms();
323
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400324 ::builder->CreateRet(v);
John Bauman89401822014-05-06 15:04:28 -0400325 }
326
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400327 void Nucleus::createBr(BasicBlock *dest)
John Bauman89401822014-05-06 15:04:28 -0400328 {
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400329 ::builder->CreateBr(dest);
John Bauman89401822014-05-06 15:04:28 -0400330 }
331
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400332 void Nucleus::createCondBr(Value *cond, BasicBlock *ifTrue, BasicBlock *ifFalse)
John Bauman89401822014-05-06 15:04:28 -0400333 {
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400334 ::builder->CreateCondBr(cond, ifTrue, ifFalse);
John Bauman89401822014-05-06 15:04:28 -0400335 }
336
337 Value *Nucleus::createAdd(Value *lhs, Value *rhs)
338 {
Nicolas Capens19336542016-09-26 10:32:29 -0400339 return V(::builder->CreateAdd(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400340 }
341
342 Value *Nucleus::createSub(Value *lhs, Value *rhs)
343 {
Nicolas Capens19336542016-09-26 10:32:29 -0400344 return V(::builder->CreateSub(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400345 }
346
347 Value *Nucleus::createMul(Value *lhs, Value *rhs)
348 {
Nicolas Capens19336542016-09-26 10:32:29 -0400349 return V(::builder->CreateMul(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400350 }
351
352 Value *Nucleus::createUDiv(Value *lhs, Value *rhs)
353 {
Nicolas Capens19336542016-09-26 10:32:29 -0400354 return V(::builder->CreateUDiv(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400355 }
356
357 Value *Nucleus::createSDiv(Value *lhs, Value *rhs)
358 {
Nicolas Capens19336542016-09-26 10:32:29 -0400359 return V(::builder->CreateSDiv(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400360 }
361
362 Value *Nucleus::createFAdd(Value *lhs, Value *rhs)
363 {
Nicolas Capens19336542016-09-26 10:32:29 -0400364 return V(::builder->CreateFAdd(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400365 }
366
367 Value *Nucleus::createFSub(Value *lhs, Value *rhs)
368 {
Nicolas Capens19336542016-09-26 10:32:29 -0400369 return V(::builder->CreateFSub(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400370 }
371
372 Value *Nucleus::createFMul(Value *lhs, Value *rhs)
373 {
Nicolas Capens19336542016-09-26 10:32:29 -0400374 return V(::builder->CreateFMul(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400375 }
376
377 Value *Nucleus::createFDiv(Value *lhs, Value *rhs)
378 {
Nicolas Capens19336542016-09-26 10:32:29 -0400379 return V(::builder->CreateFDiv(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400380 }
381
382 Value *Nucleus::createURem(Value *lhs, Value *rhs)
383 {
Nicolas Capens19336542016-09-26 10:32:29 -0400384 return V(::builder->CreateURem(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400385 }
386
387 Value *Nucleus::createSRem(Value *lhs, Value *rhs)
388 {
Nicolas Capens19336542016-09-26 10:32:29 -0400389 return V(::builder->CreateSRem(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400390 }
391
392 Value *Nucleus::createFRem(Value *lhs, Value *rhs)
393 {
Nicolas Capens19336542016-09-26 10:32:29 -0400394 return V(::builder->CreateFRem(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400395 }
396
397 Value *Nucleus::createShl(Value *lhs, Value *rhs)
398 {
Nicolas Capens19336542016-09-26 10:32:29 -0400399 return V(::builder->CreateShl(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400400 }
401
402 Value *Nucleus::createLShr(Value *lhs, Value *rhs)
403 {
Nicolas Capens19336542016-09-26 10:32:29 -0400404 return V(::builder->CreateLShr(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400405 }
406
407 Value *Nucleus::createAShr(Value *lhs, Value *rhs)
408 {
Nicolas Capens19336542016-09-26 10:32:29 -0400409 return V(::builder->CreateAShr(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400410 }
411
412 Value *Nucleus::createAnd(Value *lhs, Value *rhs)
413 {
Nicolas Capens19336542016-09-26 10:32:29 -0400414 return V(::builder->CreateAnd(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400415 }
416
417 Value *Nucleus::createOr(Value *lhs, Value *rhs)
418 {
Nicolas Capens19336542016-09-26 10:32:29 -0400419 return V(::builder->CreateOr(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400420 }
421
422 Value *Nucleus::createXor(Value *lhs, Value *rhs)
423 {
Nicolas Capens19336542016-09-26 10:32:29 -0400424 return V(::builder->CreateXor(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400425 }
426
Nicolas Capens19336542016-09-26 10:32:29 -0400427 Value *Nucleus::createNeg(Value *v)
John Bauman89401822014-05-06 15:04:28 -0400428 {
Nicolas Capens19336542016-09-26 10:32:29 -0400429 return V(::builder->CreateNeg(v));
John Bauman89401822014-05-06 15:04:28 -0400430 }
431
Nicolas Capens19336542016-09-26 10:32:29 -0400432 Value *Nucleus::createFNeg(Value *v)
John Bauman89401822014-05-06 15:04:28 -0400433 {
Nicolas Capens19336542016-09-26 10:32:29 -0400434 return V(::builder->CreateFNeg(v));
John Bauman89401822014-05-06 15:04:28 -0400435 }
436
Nicolas Capens19336542016-09-26 10:32:29 -0400437 Value *Nucleus::createNot(Value *v)
John Bauman89401822014-05-06 15:04:28 -0400438 {
Nicolas Capens19336542016-09-26 10:32:29 -0400439 return V(::builder->CreateNot(v));
John Bauman89401822014-05-06 15:04:28 -0400440 }
441
Nicolas Capense12780d2016-09-27 14:18:07 -0400442 Value *Nucleus::createLoad(Value *ptr, Type *type, bool isVolatile, unsigned int align)
John Bauman89401822014-05-06 15:04:28 -0400443 {
Nicolas Capense12780d2016-09-27 14:18:07 -0400444 assert(ptr->getType()->getContainedType(0) == type);
Nicolas Capens19336542016-09-26 10:32:29 -0400445 return V(::builder->Insert(new LoadInst(ptr, "", isVolatile, align)));
John Bauman89401822014-05-06 15:04:28 -0400446 }
447
Nicolas Capens6d738712016-09-30 04:15:22 -0400448 Value *Nucleus::createStore(Value *value, Value *ptr, Type *type, bool isVolatile, unsigned int align)
John Bauman89401822014-05-06 15:04:28 -0400449 {
Nicolas Capens6d738712016-09-30 04:15:22 -0400450 assert(ptr->getType()->getContainedType(0) == type);
Nicolas Capensb955d5b2016-09-28 22:36:28 -0400451 ::builder->Insert(new StoreInst(value, ptr, isVolatile, align));
452 return value;
John Bauman89401822014-05-06 15:04:28 -0400453 }
454
Nicolas Capens6d738712016-09-30 04:15:22 -0400455 Value *Nucleus::createGEP(Value *ptr, Type *type, Value *index)
John Bauman89401822014-05-06 15:04:28 -0400456 {
Nicolas Capens6d738712016-09-30 04:15:22 -0400457 assert(ptr->getType()->getContainedType(0) == type);
Nicolas Capens19336542016-09-26 10:32:29 -0400458 return V(::builder->CreateGEP(ptr, index));
John Bauman89401822014-05-06 15:04:28 -0400459 }
460
John Bauman19bac1e2014-05-06 15:23:49 -0400461 Value *Nucleus::createAtomicAdd(Value *ptr, Value *value)
462 {
Nicolas Capens19336542016-09-26 10:32:29 -0400463 return V(::builder->CreateAtomicRMW(AtomicRMWInst::Add, ptr, value, SequentiallyConsistent));
John Bauman19bac1e2014-05-06 15:23:49 -0400464 }
465
Nicolas Capens19336542016-09-26 10:32:29 -0400466 Value *Nucleus::createTrunc(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400467 {
Nicolas Capens19336542016-09-26 10:32:29 -0400468 return V(::builder->CreateTrunc(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400469 }
470
Nicolas Capens19336542016-09-26 10:32:29 -0400471 Value *Nucleus::createZExt(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400472 {
Nicolas Capens19336542016-09-26 10:32:29 -0400473 return V(::builder->CreateZExt(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400474 }
475
Nicolas Capens19336542016-09-26 10:32:29 -0400476 Value *Nucleus::createSExt(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400477 {
Nicolas Capens19336542016-09-26 10:32:29 -0400478 return V(::builder->CreateSExt(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400479 }
480
Nicolas Capens19336542016-09-26 10:32:29 -0400481 Value *Nucleus::createFPToSI(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400482 {
Nicolas Capens19336542016-09-26 10:32:29 -0400483 return V(::builder->CreateFPToSI(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400484 }
485
Nicolas Capens19336542016-09-26 10:32:29 -0400486 Value *Nucleus::createUIToFP(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400487 {
Nicolas Capens19336542016-09-26 10:32:29 -0400488 return V(::builder->CreateUIToFP(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400489 }
490
Nicolas Capens19336542016-09-26 10:32:29 -0400491 Value *Nucleus::createSIToFP(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400492 {
Nicolas Capens19336542016-09-26 10:32:29 -0400493 return V(::builder->CreateSIToFP(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400494 }
495
Nicolas Capens19336542016-09-26 10:32:29 -0400496 Value *Nucleus::createFPTrunc(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400497 {
Nicolas Capens19336542016-09-26 10:32:29 -0400498 return V(::builder->CreateFPTrunc(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400499 }
500
Nicolas Capens19336542016-09-26 10:32:29 -0400501 Value *Nucleus::createFPExt(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400502 {
Nicolas Capens19336542016-09-26 10:32:29 -0400503 return V(::builder->CreateFPExt(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400504 }
505
Nicolas Capens19336542016-09-26 10:32:29 -0400506 Value *Nucleus::createBitCast(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400507 {
Nicolas Capens19336542016-09-26 10:32:29 -0400508 return V(::builder->CreateBitCast(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400509 }
510
Nicolas Capens19336542016-09-26 10:32:29 -0400511 Value *Nucleus::createIntCast(Value *v, Type *destType, bool isSigned)
John Bauman89401822014-05-06 15:04:28 -0400512 {
Nicolas Capens19336542016-09-26 10:32:29 -0400513 return V(::builder->CreateIntCast(v, destType, isSigned));
John Bauman89401822014-05-06 15:04:28 -0400514 }
515
516 Value *Nucleus::createICmpEQ(Value *lhs, Value *rhs)
517 {
Nicolas Capens19336542016-09-26 10:32:29 -0400518 return V(::builder->CreateICmpEQ(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400519 }
520
521 Value *Nucleus::createICmpNE(Value *lhs, Value *rhs)
522 {
Nicolas Capens19336542016-09-26 10:32:29 -0400523 return V(::builder->CreateICmpNE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400524 }
525
526 Value *Nucleus::createICmpUGT(Value *lhs, Value *rhs)
527 {
Nicolas Capens19336542016-09-26 10:32:29 -0400528 return V(::builder->CreateICmpUGT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400529 }
530
531 Value *Nucleus::createICmpUGE(Value *lhs, Value *rhs)
532 {
Nicolas Capens19336542016-09-26 10:32:29 -0400533 return V(::builder->CreateICmpUGE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400534 }
535
536 Value *Nucleus::createICmpULT(Value *lhs, Value *rhs)
537 {
Nicolas Capens19336542016-09-26 10:32:29 -0400538 return V(::builder->CreateICmpULT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400539 }
540
541 Value *Nucleus::createICmpULE(Value *lhs, Value *rhs)
542 {
Nicolas Capens19336542016-09-26 10:32:29 -0400543 return V(::builder->CreateICmpULE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400544 }
545
546 Value *Nucleus::createICmpSGT(Value *lhs, Value *rhs)
547 {
Nicolas Capens19336542016-09-26 10:32:29 -0400548 return V(::builder->CreateICmpSGT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400549 }
550
551 Value *Nucleus::createICmpSGE(Value *lhs, Value *rhs)
552 {
Nicolas Capens19336542016-09-26 10:32:29 -0400553 return V(::builder->CreateICmpSGE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400554 }
555
556 Value *Nucleus::createICmpSLT(Value *lhs, Value *rhs)
557 {
Nicolas Capens19336542016-09-26 10:32:29 -0400558 return V(::builder->CreateICmpSLT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400559 }
560
561 Value *Nucleus::createICmpSLE(Value *lhs, Value *rhs)
562 {
Nicolas Capens19336542016-09-26 10:32:29 -0400563 return V(::builder->CreateICmpSLE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400564 }
565
566 Value *Nucleus::createFCmpOEQ(Value *lhs, Value *rhs)
567 {
Nicolas Capens19336542016-09-26 10:32:29 -0400568 return V(::builder->CreateFCmpOEQ(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400569 }
570
571 Value *Nucleus::createFCmpOGT(Value *lhs, Value *rhs)
572 {
Nicolas Capens19336542016-09-26 10:32:29 -0400573 return V(::builder->CreateFCmpOGT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400574 }
575
576 Value *Nucleus::createFCmpOGE(Value *lhs, Value *rhs)
577 {
Nicolas Capens19336542016-09-26 10:32:29 -0400578 return V(::builder->CreateFCmpOGE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400579 }
580
581 Value *Nucleus::createFCmpOLT(Value *lhs, Value *rhs)
582 {
Nicolas Capens19336542016-09-26 10:32:29 -0400583 return V(::builder->CreateFCmpOLT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400584 }
585
586 Value *Nucleus::createFCmpOLE(Value *lhs, Value *rhs)
587 {
Nicolas Capens19336542016-09-26 10:32:29 -0400588 return V(::builder->CreateFCmpOLE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400589 }
590
591 Value *Nucleus::createFCmpONE(Value *lhs, Value *rhs)
592 {
Nicolas Capens19336542016-09-26 10:32:29 -0400593 return V(::builder->CreateFCmpONE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400594 }
595
596 Value *Nucleus::createFCmpORD(Value *lhs, Value *rhs)
597 {
Nicolas Capens19336542016-09-26 10:32:29 -0400598 return V(::builder->CreateFCmpORD(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400599 }
600
601 Value *Nucleus::createFCmpUNO(Value *lhs, Value *rhs)
602 {
Nicolas Capens19336542016-09-26 10:32:29 -0400603 return V(::builder->CreateFCmpUNO(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400604 }
605
606 Value *Nucleus::createFCmpUEQ(Value *lhs, Value *rhs)
607 {
Nicolas Capens19336542016-09-26 10:32:29 -0400608 return V(::builder->CreateFCmpUEQ(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400609 }
610
611 Value *Nucleus::createFCmpUGT(Value *lhs, Value *rhs)
612 {
Nicolas Capens19336542016-09-26 10:32:29 -0400613 return V(::builder->CreateFCmpUGT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400614 }
615
616 Value *Nucleus::createFCmpUGE(Value *lhs, Value *rhs)
617 {
Nicolas Capens19336542016-09-26 10:32:29 -0400618 return V(::builder->CreateFCmpUGE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400619 }
620
621 Value *Nucleus::createFCmpULT(Value *lhs, Value *rhs)
622 {
Nicolas Capens19336542016-09-26 10:32:29 -0400623 return V(::builder->CreateFCmpULT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400624 }
625
626 Value *Nucleus::createFCmpULE(Value *lhs, Value *rhs)
627 {
Nicolas Capens19336542016-09-26 10:32:29 -0400628 return V(::builder->CreateFCmpULE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400629 }
630
631 Value *Nucleus::createFCmpUNE(Value *lhs, Value *rhs)
632 {
Nicolas Capens19336542016-09-26 10:32:29 -0400633 return V(::builder->CreateFCmpULE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400634 }
635
Nicolas Capense95d5342016-09-30 11:37:28 -0400636 Value *Nucleus::createExtractElement(Value *vector, Type *type, int index)
John Bauman89401822014-05-06 15:04:28 -0400637 {
Nicolas Capense95d5342016-09-30 11:37:28 -0400638 assert(vector->getType()->getContainedType(0) == type);
Nicolas Capens19336542016-09-26 10:32:29 -0400639 return V(::builder->CreateExtractElement(vector, createConstantInt(index)));
John Bauman89401822014-05-06 15:04:28 -0400640 }
641
642 Value *Nucleus::createInsertElement(Value *vector, Value *element, int index)
643 {
Nicolas Capens19336542016-09-26 10:32:29 -0400644 return V(::builder->CreateInsertElement(vector, element, createConstantInt(index)));
John Bauman89401822014-05-06 15:04:28 -0400645 }
646
Nicolas Capense89cd582016-09-30 14:23:47 -0400647 Value *Nucleus::createShuffleVector(Value *V1, Value *V2, const int *select)
John Bauman89401822014-05-06 15:04:28 -0400648 {
Nicolas Capense89cd582016-09-30 14:23:47 -0400649 int size = llvm::cast<llvm::VectorType>(V1->getType())->getNumElements();
650 const int maxSize = 16;
651 llvm::Constant *swizzle[maxSize];
652 assert(size <= maxSize);
653
654 for(int i = 0; i < size; i++)
655 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400656 swizzle[i] = llvm::ConstantInt::get(Type::getInt32Ty(*::context), select[i]);
Nicolas Capense89cd582016-09-30 14:23:47 -0400657 }
658
659 llvm::Value *shuffle = llvm::ConstantVector::get(llvm::ArrayRef<llvm::Constant*>(swizzle, size));
660
661 return V(::builder->CreateShuffleVector(V1, V2, shuffle));
John Bauman89401822014-05-06 15:04:28 -0400662 }
663
664 Value *Nucleus::createSelect(Value *C, Value *ifTrue, Value *ifFalse)
665 {
Nicolas Capens19336542016-09-26 10:32:29 -0400666 return V(::builder->CreateSelect(C, ifTrue, ifFalse));
John Bauman89401822014-05-06 15:04:28 -0400667 }
668
Nicolas Capens19336542016-09-26 10:32:29 -0400669 Value *Nucleus::createSwitch(Value *v, BasicBlock *Dest, unsigned NumCases)
John Bauman89401822014-05-06 15:04:28 -0400670 {
Nicolas Capens19336542016-09-26 10:32:29 -0400671 return V(::builder->CreateSwitch(v, Dest, NumCases));
John Bauman89401822014-05-06 15:04:28 -0400672 }
673
Nicolas Capens19336542016-09-26 10:32:29 -0400674 void Nucleus::addSwitchCase(Value *Switch, int Case, BasicBlock *Branch)
John Bauman89401822014-05-06 15:04:28 -0400675 {
Nicolas Capens19336542016-09-26 10:32:29 -0400676 reinterpret_cast<SwitchInst*>(Switch)->addCase(llvm::ConstantInt::get(Type::getInt32Ty(*::context), Case, true), Branch);
John Bauman89401822014-05-06 15:04:28 -0400677 }
678
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400679 void Nucleus::createUnreachable()
John Bauman89401822014-05-06 15:04:28 -0400680 {
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400681 ::builder->CreateUnreachable();
John Bauman89401822014-05-06 15:04:28 -0400682 }
683
Nicolas Capense95d5342016-09-30 11:37:28 -0400684 static Value *createSwizzle4(Value *val, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -0400685 {
Nicolas Capense89cd582016-09-30 14:23:47 -0400686 int swizzle[4] =
687 {
688 (select >> 0) & 0x03,
689 (select >> 2) & 0x03,
690 (select >> 4) & 0x03,
691 (select >> 6) & 0x03,
692 };
John Bauman89401822014-05-06 15:04:28 -0400693
Nicolas Capense89cd582016-09-30 14:23:47 -0400694 return Nucleus::createShuffleVector(val, val, swizzle);
John Bauman89401822014-05-06 15:04:28 -0400695 }
696
Nicolas Capense95d5342016-09-30 11:37:28 -0400697 static Value *createMask4(Value *lhs, Value *rhs, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -0400698 {
699 bool mask[4] = {false, false, false, false};
700
701 mask[(select >> 0) & 0x03] = true;
702 mask[(select >> 2) & 0x03] = true;
703 mask[(select >> 4) & 0x03] = true;
704 mask[(select >> 6) & 0x03] = true;
705
Nicolas Capense89cd582016-09-30 14:23:47 -0400706 int swizzle[4] =
707 {
708 mask[0] ? 4 : 0,
709 mask[1] ? 5 : 1,
710 mask[2] ? 6 : 2,
711 mask[3] ? 7 : 3,
712 };
John Bauman89401822014-05-06 15:04:28 -0400713
Nicolas Capense89cd582016-09-30 14:23:47 -0400714 Value *shuffle = Nucleus::createShuffleVector(lhs, rhs, swizzle);
John Bauman89401822014-05-06 15:04:28 -0400715
716 return shuffle;
717 }
718
Nicolas Capens73dd7a22016-10-20 13:20:34 -0400719 Value *Nucleus::createConstantPointer(const void *address, Type *Ty, unsigned int align)
John Bauman89401822014-05-06 15:04:28 -0400720 {
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400721 const GlobalValue *existingGlobal = ::executionEngine->getGlobalValueAtAddress(const_cast<void*>(address)); // FIXME: Const
John Bauman89401822014-05-06 15:04:28 -0400722
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400723 if(existingGlobal)
724 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400725 return (Value*)existingGlobal;
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400726 }
John Bauman89401822014-05-06 15:04:28 -0400727
Nicolas Capens73dd7a22016-10-20 13:20:34 -0400728 llvm::GlobalValue *global = new llvm::GlobalVariable(*::module, Ty, true, llvm::GlobalValue::ExternalLinkage, 0, "");
729 global->setAlignment(align);
John Bauman89401822014-05-06 15:04:28 -0400730
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400731 ::executionEngine->addGlobalMapping(global, const_cast<void*>(address));
732
Nicolas Capens13ac2322016-10-13 14:52:12 -0400733 return V(global);
John Bauman89401822014-05-06 15:04:28 -0400734 }
735
Nicolas Capensac230122016-09-20 14:30:06 -0400736 Type *Nucleus::getPointerType(Type *ElementType)
John Bauman89401822014-05-06 15:04:28 -0400737 {
Nicolas Capensac230122016-09-20 14:30:06 -0400738 return T(llvm::PointerType::get(ElementType, 0));
John Bauman89401822014-05-06 15:04:28 -0400739 }
740
Nicolas Capens13ac2322016-10-13 14:52:12 -0400741 Value *Nucleus::createNullValue(Type *Ty)
John Bauman89401822014-05-06 15:04:28 -0400742 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400743 return V(llvm::Constant::getNullValue(Ty));
John Bauman89401822014-05-06 15:04:28 -0400744 }
745
Nicolas Capens13ac2322016-10-13 14:52:12 -0400746 Value *Nucleus::createConstantLong(int64_t i)
John Bauman89401822014-05-06 15:04:28 -0400747 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400748 return V(llvm::ConstantInt::get(Type::getInt64Ty(*::context), i, true));
John Bauman89401822014-05-06 15:04:28 -0400749 }
750
Nicolas Capens13ac2322016-10-13 14:52:12 -0400751 Value *Nucleus::createConstantInt(int i)
John Bauman89401822014-05-06 15:04:28 -0400752 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400753 return V(llvm::ConstantInt::get(Type::getInt32Ty(*::context), i, true));
John Bauman89401822014-05-06 15:04:28 -0400754 }
755
Nicolas Capens13ac2322016-10-13 14:52:12 -0400756 Value *Nucleus::createConstantInt(unsigned int i)
John Bauman89401822014-05-06 15:04:28 -0400757 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400758 return V(llvm::ConstantInt::get(Type::getInt32Ty(*::context), i, false));
John Bauman89401822014-05-06 15:04:28 -0400759 }
760
Nicolas Capens13ac2322016-10-13 14:52:12 -0400761 Value *Nucleus::createConstantBool(bool b)
John Bauman89401822014-05-06 15:04:28 -0400762 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400763 return V(llvm::ConstantInt::get(Type::getInt1Ty(*::context), b));
John Bauman89401822014-05-06 15:04:28 -0400764 }
765
Nicolas Capens13ac2322016-10-13 14:52:12 -0400766 Value *Nucleus::createConstantByte(signed char i)
John Bauman89401822014-05-06 15:04:28 -0400767 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400768 return V(llvm::ConstantInt::get(Type::getInt8Ty(*::context), i, true));
John Bauman89401822014-05-06 15:04:28 -0400769 }
770
Nicolas Capens13ac2322016-10-13 14:52:12 -0400771 Value *Nucleus::createConstantByte(unsigned char i)
John Bauman89401822014-05-06 15:04:28 -0400772 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400773 return V(llvm::ConstantInt::get(Type::getInt8Ty(*::context), i, false));
John Bauman89401822014-05-06 15:04:28 -0400774 }
775
Nicolas Capens13ac2322016-10-13 14:52:12 -0400776 Value *Nucleus::createConstantShort(short i)
John Bauman89401822014-05-06 15:04:28 -0400777 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400778 return V(llvm::ConstantInt::get(Type::getInt16Ty(*::context), i, true));
John Bauman89401822014-05-06 15:04:28 -0400779 }
780
Nicolas Capens13ac2322016-10-13 14:52:12 -0400781 Value *Nucleus::createConstantShort(unsigned short i)
John Bauman89401822014-05-06 15:04:28 -0400782 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400783 return V(llvm::ConstantInt::get(Type::getInt16Ty(*::context), i, false));
John Bauman89401822014-05-06 15:04:28 -0400784 }
785
Nicolas Capens13ac2322016-10-13 14:52:12 -0400786 Value *Nucleus::createConstantFloat(float x)
John Bauman89401822014-05-06 15:04:28 -0400787 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400788 return V(llvm::ConstantFP::get(Float::getType(), x));
John Bauman89401822014-05-06 15:04:28 -0400789 }
790
Nicolas Capens13ac2322016-10-13 14:52:12 -0400791 Value *Nucleus::createNullPointer(Type *Ty)
John Bauman89401822014-05-06 15:04:28 -0400792 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400793 return V(llvm::ConstantPointerNull::get(llvm::PointerType::get(Ty, 0)));
John Bauman89401822014-05-06 15:04:28 -0400794 }
795
Nicolas Capens13ac2322016-10-13 14:52:12 -0400796 Value *Nucleus::createConstantVector(const int64_t *constants, Type *type)
John Bauman89401822014-05-06 15:04:28 -0400797 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400798 assert(llvm::isa<VectorType>(type));
799 const int numConstants = llvm::cast<VectorType>(type)->getNumElements();
800 assert(numConstants <= 16);
801 llvm::Constant *constantVector[16];
802
803 for(int i = 0; i < numConstants; i++)
804 {
805 constantVector[i] = llvm::ConstantInt::get(type->getContainedType(0), constants[i]);
806 }
807
808 return V(llvm::ConstantVector::get(llvm::ArrayRef<llvm::Constant*>(constantVector, numConstants)));
809 }
810
811 Value *Nucleus::createConstantVector(const double *constants, Type *type)
812 {
813 assert(llvm::isa<VectorType>(type));
814 const int numConstants = llvm::cast<VectorType>(type)->getNumElements();
815 assert(numConstants <= 8);
816 llvm::Constant *constantVector[8];
817
818 for(int i = 0; i < numConstants; i++)
819 {
820 constantVector[i] = llvm::ConstantFP::get(type->getContainedType(0), constants[i]);
821 }
822
823 return V(llvm::ConstantVector::get(llvm::ArrayRef<llvm::Constant*>(constantVector, numConstants)));
John Bauman89401822014-05-06 15:04:28 -0400824 }
825
John Bauman19bac1e2014-05-06 15:23:49 -0400826 Type *Void::getType()
John Bauman89401822014-05-06 15:04:28 -0400827 {
Nicolas Capensac230122016-09-20 14:30:06 -0400828 return T(llvm::Type::getVoidTy(*::context));
John Bauman89401822014-05-06 15:04:28 -0400829 }
830
Nicolas Capens4f738a12016-09-20 15:46:16 -0400831 class MMX : public Variable<MMX>
832 {
833 public:
834 static Type *getType();
835 };
836
John Bauman19bac1e2014-05-06 15:23:49 -0400837 Type *MMX::getType()
838 {
Nicolas Capensac230122016-09-20 14:30:06 -0400839 return T(llvm::Type::getX86_MMXTy(*::context));
John Bauman19bac1e2014-05-06 15:23:49 -0400840 }
841
Nicolas Capens81f18302016-01-14 09:32:35 -0500842 Bool::Bool(Argument<Bool> argument)
John Bauman89401822014-05-06 15:04:28 -0400843 {
Nicolas Capens81f18302016-01-14 09:32:35 -0500844 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -0400845 }
846
847 Bool::Bool()
848 {
John Bauman89401822014-05-06 15:04:28 -0400849 }
850
851 Bool::Bool(bool x)
852 {
John Bauman66b8ab22014-05-06 15:57:45 -0400853 storeValue(Nucleus::createConstantBool(x));
John Bauman89401822014-05-06 15:04:28 -0400854 }
855
John Bauman19bac1e2014-05-06 15:23:49 -0400856 Bool::Bool(RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400857 {
John Bauman66b8ab22014-05-06 15:57:45 -0400858 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400859 }
860
861 Bool::Bool(const Bool &rhs)
862 {
John Bauman66b8ab22014-05-06 15:57:45 -0400863 Value *value = rhs.loadValue();
864 storeValue(value);
865 }
John Bauman89401822014-05-06 15:04:28 -0400866
John Bauman66b8ab22014-05-06 15:57:45 -0400867 Bool::Bool(const Reference<Bool> &rhs)
868 {
869 Value *value = rhs.loadValue();
870 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400871 }
872
John Bauman19bac1e2014-05-06 15:23:49 -0400873 RValue<Bool> Bool::operator=(RValue<Bool> rhs) const
John Bauman89401822014-05-06 15:04:28 -0400874 {
John Bauman66b8ab22014-05-06 15:57:45 -0400875 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400876
877 return rhs;
878 }
879
880 RValue<Bool> Bool::operator=(const Bool &rhs) const
881 {
John Bauman66b8ab22014-05-06 15:57:45 -0400882 Value *value = rhs.loadValue();
883 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400884
885 return RValue<Bool>(value);
886 }
887
John Bauman66b8ab22014-05-06 15:57:45 -0400888 RValue<Bool> Bool::operator=(const Reference<Bool> &rhs) const
John Bauman89401822014-05-06 15:04:28 -0400889 {
John Bauman66b8ab22014-05-06 15:57:45 -0400890 Value *value = rhs.loadValue();
891 storeValue(value);
892
893 return RValue<Bool>(value);
John Bauman89401822014-05-06 15:04:28 -0400894 }
895
John Bauman19bac1e2014-05-06 15:23:49 -0400896 RValue<Bool> operator!(RValue<Bool> val)
John Bauman89401822014-05-06 15:04:28 -0400897 {
898 return RValue<Bool>(Nucleus::createNot(val.value));
899 }
900
John Bauman19bac1e2014-05-06 15:23:49 -0400901 RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400902 {
903 return RValue<Bool>(Nucleus::createAnd(lhs.value, rhs.value));
904 }
905
John Bauman19bac1e2014-05-06 15:23:49 -0400906 RValue<Bool> operator||(RValue<Bool> lhs, RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400907 {
908 return RValue<Bool>(Nucleus::createOr(lhs.value, rhs.value));
909 }
910
John Bauman19bac1e2014-05-06 15:23:49 -0400911 Type *Bool::getType()
John Bauman89401822014-05-06 15:04:28 -0400912 {
Nicolas Capensac230122016-09-20 14:30:06 -0400913 return T(llvm::Type::getInt1Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -0400914 }
915
Nicolas Capens81f18302016-01-14 09:32:35 -0500916 Byte::Byte(Argument<Byte> argument)
John Bauman89401822014-05-06 15:04:28 -0400917 {
Nicolas Capens81f18302016-01-14 09:32:35 -0500918 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -0400919 }
920
John Bauman19bac1e2014-05-06 15:23:49 -0400921 Byte::Byte(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -0400922 {
John Bauman89401822014-05-06 15:04:28 -0400923 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
924
John Bauman66b8ab22014-05-06 15:57:45 -0400925 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -0400926 }
927
Alexis Hetu77dfab42015-11-23 13:31:22 -0500928 Byte::Byte(RValue<UInt> cast)
929 {
930 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
931
932 storeValue(integer);
933 }
934
935 Byte::Byte(RValue<UShort> cast)
936 {
937 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
938
939 storeValue(integer);
940 }
941
John Bauman89401822014-05-06 15:04:28 -0400942 Byte::Byte()
943 {
John Bauman89401822014-05-06 15:04:28 -0400944 }
945
946 Byte::Byte(int x)
947 {
John Bauman66b8ab22014-05-06 15:57:45 -0400948 storeValue(Nucleus::createConstantByte((unsigned char)x));
John Bauman89401822014-05-06 15:04:28 -0400949 }
950
951 Byte::Byte(unsigned char x)
952 {
John Bauman66b8ab22014-05-06 15:57:45 -0400953 storeValue(Nucleus::createConstantByte(x));
John Bauman89401822014-05-06 15:04:28 -0400954 }
955
John Bauman19bac1e2014-05-06 15:23:49 -0400956 Byte::Byte(RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400957 {
John Bauman66b8ab22014-05-06 15:57:45 -0400958 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400959 }
960
961 Byte::Byte(const Byte &rhs)
962 {
John Bauman66b8ab22014-05-06 15:57:45 -0400963 Value *value = rhs.loadValue();
964 storeValue(value);
965 }
John Bauman89401822014-05-06 15:04:28 -0400966
John Bauman66b8ab22014-05-06 15:57:45 -0400967 Byte::Byte(const Reference<Byte> &rhs)
968 {
969 Value *value = rhs.loadValue();
970 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400971 }
972
John Bauman19bac1e2014-05-06 15:23:49 -0400973 RValue<Byte> Byte::operator=(RValue<Byte> rhs) const
John Bauman89401822014-05-06 15:04:28 -0400974 {
John Bauman66b8ab22014-05-06 15:57:45 -0400975 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400976
977 return rhs;
978 }
979
980 RValue<Byte> Byte::operator=(const Byte &rhs) const
981 {
John Bauman66b8ab22014-05-06 15:57:45 -0400982 Value *value = rhs.loadValue();
983 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400984
985 return RValue<Byte>(value);
986 }
987
John Bauman66b8ab22014-05-06 15:57:45 -0400988 RValue<Byte> Byte::operator=(const Reference<Byte> &rhs) const
John Bauman89401822014-05-06 15:04:28 -0400989 {
John Bauman66b8ab22014-05-06 15:57:45 -0400990 Value *value = rhs.loadValue();
991 storeValue(value);
992
993 return RValue<Byte>(value);
John Bauman89401822014-05-06 15:04:28 -0400994 }
995
John Bauman19bac1e2014-05-06 15:23:49 -0400996 RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400997 {
998 return RValue<Byte>(Nucleus::createAdd(lhs.value, rhs.value));
999 }
1000
John Bauman19bac1e2014-05-06 15:23:49 -04001001 RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001002 {
1003 return RValue<Byte>(Nucleus::createSub(lhs.value, rhs.value));
1004 }
1005
John Bauman19bac1e2014-05-06 15:23:49 -04001006 RValue<Byte> operator*(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001007 {
1008 return RValue<Byte>(Nucleus::createMul(lhs.value, rhs.value));
1009 }
1010
John Bauman19bac1e2014-05-06 15:23:49 -04001011 RValue<Byte> operator/(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001012 {
1013 return RValue<Byte>(Nucleus::createUDiv(lhs.value, rhs.value));
1014 }
1015
John Bauman19bac1e2014-05-06 15:23:49 -04001016 RValue<Byte> operator%(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001017 {
1018 return RValue<Byte>(Nucleus::createURem(lhs.value, rhs.value));
1019 }
1020
John Bauman19bac1e2014-05-06 15:23:49 -04001021 RValue<Byte> operator&(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001022 {
1023 return RValue<Byte>(Nucleus::createAnd(lhs.value, rhs.value));
1024 }
1025
John Bauman19bac1e2014-05-06 15:23:49 -04001026 RValue<Byte> operator|(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001027 {
1028 return RValue<Byte>(Nucleus::createOr(lhs.value, rhs.value));
1029 }
1030
John Bauman19bac1e2014-05-06 15:23:49 -04001031 RValue<Byte> operator^(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001032 {
1033 return RValue<Byte>(Nucleus::createXor(lhs.value, rhs.value));
1034 }
1035
John Bauman19bac1e2014-05-06 15:23:49 -04001036 RValue<Byte> operator<<(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001037 {
1038 return RValue<Byte>(Nucleus::createShl(lhs.value, rhs.value));
1039 }
1040
John Bauman19bac1e2014-05-06 15:23:49 -04001041 RValue<Byte> operator>>(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001042 {
1043 return RValue<Byte>(Nucleus::createLShr(lhs.value, rhs.value));
1044 }
1045
John Bauman19bac1e2014-05-06 15:23:49 -04001046 RValue<Byte> operator+=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001047 {
1048 return lhs = lhs + rhs;
1049 }
1050
John Bauman19bac1e2014-05-06 15:23:49 -04001051 RValue<Byte> operator-=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001052 {
1053 return lhs = lhs - rhs;
1054 }
1055
John Bauman19bac1e2014-05-06 15:23:49 -04001056 RValue<Byte> operator*=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001057 {
1058 return lhs = lhs * rhs;
1059 }
1060
John Bauman19bac1e2014-05-06 15:23:49 -04001061 RValue<Byte> operator/=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001062 {
1063 return lhs = lhs / rhs;
1064 }
1065
John Bauman19bac1e2014-05-06 15:23:49 -04001066 RValue<Byte> operator%=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001067 {
1068 return lhs = lhs % rhs;
1069 }
1070
John Bauman19bac1e2014-05-06 15:23:49 -04001071 RValue<Byte> operator&=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001072 {
1073 return lhs = lhs & rhs;
1074 }
1075
John Bauman19bac1e2014-05-06 15:23:49 -04001076 RValue<Byte> operator|=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001077 {
1078 return lhs = lhs | rhs;
1079 }
1080
John Bauman19bac1e2014-05-06 15:23:49 -04001081 RValue<Byte> operator^=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001082 {
1083 return lhs = lhs ^ rhs;
1084 }
1085
John Bauman19bac1e2014-05-06 15:23:49 -04001086 RValue<Byte> operator<<=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001087 {
1088 return lhs = lhs << rhs;
1089 }
1090
John Bauman19bac1e2014-05-06 15:23:49 -04001091 RValue<Byte> operator>>=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001092 {
1093 return lhs = lhs >> rhs;
1094 }
1095
John Bauman19bac1e2014-05-06 15:23:49 -04001096 RValue<Byte> operator+(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001097 {
1098 return val;
1099 }
1100
John Bauman19bac1e2014-05-06 15:23:49 -04001101 RValue<Byte> operator-(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001102 {
1103 return RValue<Byte>(Nucleus::createNeg(val.value));
1104 }
1105
John Bauman19bac1e2014-05-06 15:23:49 -04001106 RValue<Byte> operator~(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001107 {
1108 return RValue<Byte>(Nucleus::createNot(val.value));
1109 }
1110
1111 RValue<Byte> operator++(const Byte &val, int) // Post-increment
1112 {
1113 RValue<Byte> res = val;
1114
Nicolas Capens19336542016-09-26 10:32:29 -04001115 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantByte((unsigned char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001116 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001117
1118 return res;
1119 }
1120
1121 const Byte &operator++(const Byte &val) // Pre-increment
1122 {
Nicolas Capens19336542016-09-26 10:32:29 -04001123 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantByte((unsigned char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001124 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001125
1126 return val;
1127 }
1128
1129 RValue<Byte> operator--(const Byte &val, int) // Post-decrement
1130 {
1131 RValue<Byte> res = val;
1132
Nicolas Capens19336542016-09-26 10:32:29 -04001133 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantByte((unsigned char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001134 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001135
1136 return res;
1137 }
1138
1139 const Byte &operator--(const Byte &val) // Pre-decrement
1140 {
Nicolas Capens19336542016-09-26 10:32:29 -04001141 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantByte((unsigned char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001142 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001143
1144 return val;
1145 }
1146
John Bauman19bac1e2014-05-06 15:23:49 -04001147 RValue<Bool> operator<(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001148 {
1149 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1150 }
1151
John Bauman19bac1e2014-05-06 15:23:49 -04001152 RValue<Bool> operator<=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001153 {
1154 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1155 }
1156
John Bauman19bac1e2014-05-06 15:23:49 -04001157 RValue<Bool> operator>(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001158 {
1159 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1160 }
1161
John Bauman19bac1e2014-05-06 15:23:49 -04001162 RValue<Bool> operator>=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001163 {
1164 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1165 }
1166
John Bauman19bac1e2014-05-06 15:23:49 -04001167 RValue<Bool> operator!=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001168 {
1169 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1170 }
1171
John Bauman19bac1e2014-05-06 15:23:49 -04001172 RValue<Bool> operator==(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001173 {
1174 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1175 }
1176
John Bauman19bac1e2014-05-06 15:23:49 -04001177 Type *Byte::getType()
John Bauman89401822014-05-06 15:04:28 -04001178 {
Nicolas Capensac230122016-09-20 14:30:06 -04001179 return T(llvm::Type::getInt8Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001180 }
1181
Nicolas Capens81f18302016-01-14 09:32:35 -05001182 SByte::SByte(Argument<SByte> argument)
John Bauman89401822014-05-06 15:04:28 -04001183 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001184 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001185 }
1186
Alexis Hetu77dfab42015-11-23 13:31:22 -05001187 SByte::SByte(RValue<Int> cast)
1188 {
1189 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1190
1191 storeValue(integer);
1192 }
1193
1194 SByte::SByte(RValue<Short> cast)
1195 {
1196 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1197
1198 storeValue(integer);
1199 }
1200
John Bauman89401822014-05-06 15:04:28 -04001201 SByte::SByte()
1202 {
John Bauman89401822014-05-06 15:04:28 -04001203 }
1204
1205 SByte::SByte(signed char x)
1206 {
John Bauman66b8ab22014-05-06 15:57:45 -04001207 storeValue(Nucleus::createConstantByte(x));
John Bauman89401822014-05-06 15:04:28 -04001208 }
1209
John Bauman19bac1e2014-05-06 15:23:49 -04001210 SByte::SByte(RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001211 {
John Bauman66b8ab22014-05-06 15:57:45 -04001212 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001213 }
1214
1215 SByte::SByte(const SByte &rhs)
1216 {
John Bauman66b8ab22014-05-06 15:57:45 -04001217 Value *value = rhs.loadValue();
1218 storeValue(value);
1219 }
John Bauman89401822014-05-06 15:04:28 -04001220
John Bauman66b8ab22014-05-06 15:57:45 -04001221 SByte::SByte(const Reference<SByte> &rhs)
1222 {
1223 Value *value = rhs.loadValue();
1224 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001225 }
1226
John Bauman19bac1e2014-05-06 15:23:49 -04001227 RValue<SByte> SByte::operator=(RValue<SByte> rhs) const
John Bauman89401822014-05-06 15:04:28 -04001228 {
John Bauman66b8ab22014-05-06 15:57:45 -04001229 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001230
1231 return rhs;
1232 }
1233
1234 RValue<SByte> SByte::operator=(const SByte &rhs) const
1235 {
John Bauman66b8ab22014-05-06 15:57:45 -04001236 Value *value = rhs.loadValue();
1237 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001238
1239 return RValue<SByte>(value);
1240 }
1241
John Bauman66b8ab22014-05-06 15:57:45 -04001242 RValue<SByte> SByte::operator=(const Reference<SByte> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04001243 {
John Bauman66b8ab22014-05-06 15:57:45 -04001244 Value *value = rhs.loadValue();
1245 storeValue(value);
1246
1247 return RValue<SByte>(value);
John Bauman89401822014-05-06 15:04:28 -04001248 }
1249
John Bauman19bac1e2014-05-06 15:23:49 -04001250 RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001251 {
1252 return RValue<SByte>(Nucleus::createAdd(lhs.value, rhs.value));
1253 }
1254
John Bauman19bac1e2014-05-06 15:23:49 -04001255 RValue<SByte> operator-(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001256 {
1257 return RValue<SByte>(Nucleus::createSub(lhs.value, rhs.value));
1258 }
1259
John Bauman19bac1e2014-05-06 15:23:49 -04001260 RValue<SByte> operator*(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001261 {
1262 return RValue<SByte>(Nucleus::createMul(lhs.value, rhs.value));
1263 }
1264
John Bauman19bac1e2014-05-06 15:23:49 -04001265 RValue<SByte> operator/(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001266 {
1267 return RValue<SByte>(Nucleus::createSDiv(lhs.value, rhs.value));
1268 }
1269
John Bauman19bac1e2014-05-06 15:23:49 -04001270 RValue<SByte> operator%(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001271 {
1272 return RValue<SByte>(Nucleus::createSRem(lhs.value, rhs.value));
1273 }
1274
John Bauman19bac1e2014-05-06 15:23:49 -04001275 RValue<SByte> operator&(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001276 {
1277 return RValue<SByte>(Nucleus::createAnd(lhs.value, rhs.value));
1278 }
1279
John Bauman19bac1e2014-05-06 15:23:49 -04001280 RValue<SByte> operator|(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001281 {
1282 return RValue<SByte>(Nucleus::createOr(lhs.value, rhs.value));
1283 }
1284
John Bauman19bac1e2014-05-06 15:23:49 -04001285 RValue<SByte> operator^(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001286 {
1287 return RValue<SByte>(Nucleus::createXor(lhs.value, rhs.value));
1288 }
1289
John Bauman19bac1e2014-05-06 15:23:49 -04001290 RValue<SByte> operator<<(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001291 {
1292 return RValue<SByte>(Nucleus::createShl(lhs.value, rhs.value));
1293 }
1294
John Bauman19bac1e2014-05-06 15:23:49 -04001295 RValue<SByte> operator>>(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001296 {
1297 return RValue<SByte>(Nucleus::createAShr(lhs.value, rhs.value));
1298 }
1299
John Bauman19bac1e2014-05-06 15:23:49 -04001300 RValue<SByte> operator+=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001301 {
1302 return lhs = lhs + rhs;
1303 }
1304
John Bauman19bac1e2014-05-06 15:23:49 -04001305 RValue<SByte> operator-=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001306 {
1307 return lhs = lhs - rhs;
1308 }
1309
John Bauman19bac1e2014-05-06 15:23:49 -04001310 RValue<SByte> operator*=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001311 {
1312 return lhs = lhs * rhs;
1313 }
1314
John Bauman19bac1e2014-05-06 15:23:49 -04001315 RValue<SByte> operator/=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001316 {
1317 return lhs = lhs / rhs;
1318 }
1319
John Bauman19bac1e2014-05-06 15:23:49 -04001320 RValue<SByte> operator%=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001321 {
1322 return lhs = lhs % rhs;
1323 }
1324
John Bauman19bac1e2014-05-06 15:23:49 -04001325 RValue<SByte> operator&=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001326 {
1327 return lhs = lhs & rhs;
1328 }
1329
John Bauman19bac1e2014-05-06 15:23:49 -04001330 RValue<SByte> operator|=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001331 {
1332 return lhs = lhs | rhs;
1333 }
1334
John Bauman19bac1e2014-05-06 15:23:49 -04001335 RValue<SByte> operator^=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001336 {
1337 return lhs = lhs ^ rhs;
1338 }
1339
John Bauman19bac1e2014-05-06 15:23:49 -04001340 RValue<SByte> operator<<=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001341 {
1342 return lhs = lhs << rhs;
1343 }
1344
John Bauman19bac1e2014-05-06 15:23:49 -04001345 RValue<SByte> operator>>=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001346 {
1347 return lhs = lhs >> rhs;
1348 }
1349
John Bauman19bac1e2014-05-06 15:23:49 -04001350 RValue<SByte> operator+(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001351 {
1352 return val;
1353 }
1354
John Bauman19bac1e2014-05-06 15:23:49 -04001355 RValue<SByte> operator-(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001356 {
1357 return RValue<SByte>(Nucleus::createNeg(val.value));
1358 }
1359
John Bauman19bac1e2014-05-06 15:23:49 -04001360 RValue<SByte> operator~(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001361 {
1362 return RValue<SByte>(Nucleus::createNot(val.value));
1363 }
1364
1365 RValue<SByte> operator++(const SByte &val, int) // Post-increment
1366 {
1367 RValue<SByte> res = val;
1368
Nicolas Capens19336542016-09-26 10:32:29 -04001369 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantByte((signed char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001370 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001371
1372 return res;
1373 }
1374
1375 const SByte &operator++(const SByte &val) // Pre-increment
1376 {
Nicolas Capens19336542016-09-26 10:32:29 -04001377 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantByte((signed char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001378 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001379
1380 return val;
1381 }
1382
1383 RValue<SByte> operator--(const SByte &val, int) // Post-decrement
1384 {
1385 RValue<SByte> res = val;
1386
Nicolas Capens19336542016-09-26 10:32:29 -04001387 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantByte((signed char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001388 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001389
1390 return res;
1391 }
1392
1393 const SByte &operator--(const SByte &val) // Pre-decrement
1394 {
Nicolas Capens19336542016-09-26 10:32:29 -04001395 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantByte((signed char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001396 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001397
1398 return val;
1399 }
1400
John Bauman19bac1e2014-05-06 15:23:49 -04001401 RValue<Bool> operator<(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001402 {
1403 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
1404 }
1405
John Bauman19bac1e2014-05-06 15:23:49 -04001406 RValue<Bool> operator<=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001407 {
1408 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
1409 }
1410
John Bauman19bac1e2014-05-06 15:23:49 -04001411 RValue<Bool> operator>(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001412 {
1413 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
1414 }
1415
John Bauman19bac1e2014-05-06 15:23:49 -04001416 RValue<Bool> operator>=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001417 {
1418 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
1419 }
1420
John Bauman19bac1e2014-05-06 15:23:49 -04001421 RValue<Bool> operator!=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001422 {
1423 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1424 }
1425
John Bauman19bac1e2014-05-06 15:23:49 -04001426 RValue<Bool> operator==(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001427 {
1428 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1429 }
1430
John Bauman19bac1e2014-05-06 15:23:49 -04001431 Type *SByte::getType()
John Bauman89401822014-05-06 15:04:28 -04001432 {
Nicolas Capensac230122016-09-20 14:30:06 -04001433 return T(llvm::Type::getInt8Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001434 }
1435
Nicolas Capens81f18302016-01-14 09:32:35 -05001436 Short::Short(Argument<Short> argument)
John Bauman89401822014-05-06 15:04:28 -04001437 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001438 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001439 }
1440
John Bauman19bac1e2014-05-06 15:23:49 -04001441 Short::Short(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04001442 {
John Bauman89401822014-05-06 15:04:28 -04001443 Value *integer = Nucleus::createTrunc(cast.value, Short::getType());
1444
John Bauman66b8ab22014-05-06 15:57:45 -04001445 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04001446 }
1447
1448 Short::Short()
1449 {
John Bauman89401822014-05-06 15:04:28 -04001450 }
1451
1452 Short::Short(short x)
1453 {
John Bauman66b8ab22014-05-06 15:57:45 -04001454 storeValue(Nucleus::createConstantShort(x));
John Bauman89401822014-05-06 15:04:28 -04001455 }
1456
John Bauman19bac1e2014-05-06 15:23:49 -04001457 Short::Short(RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001458 {
John Bauman66b8ab22014-05-06 15:57:45 -04001459 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001460 }
1461
1462 Short::Short(const Short &rhs)
1463 {
John Bauman66b8ab22014-05-06 15:57:45 -04001464 Value *value = rhs.loadValue();
1465 storeValue(value);
1466 }
John Bauman89401822014-05-06 15:04:28 -04001467
John Bauman66b8ab22014-05-06 15:57:45 -04001468 Short::Short(const Reference<Short> &rhs)
1469 {
1470 Value *value = rhs.loadValue();
1471 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001472 }
1473
John Bauman19bac1e2014-05-06 15:23:49 -04001474 RValue<Short> Short::operator=(RValue<Short> rhs) const
John Bauman89401822014-05-06 15:04:28 -04001475 {
John Bauman66b8ab22014-05-06 15:57:45 -04001476 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001477
1478 return rhs;
1479 }
1480
1481 RValue<Short> Short::operator=(const Short &rhs) const
1482 {
John Bauman66b8ab22014-05-06 15:57:45 -04001483 Value *value = rhs.loadValue();
1484 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001485
1486 return RValue<Short>(value);
1487 }
1488
John Bauman66b8ab22014-05-06 15:57:45 -04001489 RValue<Short> Short::operator=(const Reference<Short> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04001490 {
John Bauman66b8ab22014-05-06 15:57:45 -04001491 Value *value = rhs.loadValue();
1492 storeValue(value);
1493
1494 return RValue<Short>(value);
John Bauman89401822014-05-06 15:04:28 -04001495 }
1496
John Bauman19bac1e2014-05-06 15:23:49 -04001497 RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001498 {
1499 return RValue<Short>(Nucleus::createAdd(lhs.value, rhs.value));
1500 }
1501
John Bauman19bac1e2014-05-06 15:23:49 -04001502 RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001503 {
1504 return RValue<Short>(Nucleus::createSub(lhs.value, rhs.value));
1505 }
1506
John Bauman19bac1e2014-05-06 15:23:49 -04001507 RValue<Short> operator*(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001508 {
1509 return RValue<Short>(Nucleus::createMul(lhs.value, rhs.value));
1510 }
1511
John Bauman19bac1e2014-05-06 15:23:49 -04001512 RValue<Short> operator/(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001513 {
1514 return RValue<Short>(Nucleus::createSDiv(lhs.value, rhs.value));
1515 }
1516
John Bauman19bac1e2014-05-06 15:23:49 -04001517 RValue<Short> operator%(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001518 {
1519 return RValue<Short>(Nucleus::createSRem(lhs.value, rhs.value));
1520 }
1521
John Bauman19bac1e2014-05-06 15:23:49 -04001522 RValue<Short> operator&(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001523 {
1524 return RValue<Short>(Nucleus::createAnd(lhs.value, rhs.value));
1525 }
1526
John Bauman19bac1e2014-05-06 15:23:49 -04001527 RValue<Short> operator|(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001528 {
1529 return RValue<Short>(Nucleus::createOr(lhs.value, rhs.value));
1530 }
1531
John Bauman19bac1e2014-05-06 15:23:49 -04001532 RValue<Short> operator^(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001533 {
1534 return RValue<Short>(Nucleus::createXor(lhs.value, rhs.value));
1535 }
1536
John Bauman19bac1e2014-05-06 15:23:49 -04001537 RValue<Short> operator<<(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001538 {
1539 return RValue<Short>(Nucleus::createShl(lhs.value, rhs.value));
1540 }
1541
John Bauman19bac1e2014-05-06 15:23:49 -04001542 RValue<Short> operator>>(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001543 {
1544 return RValue<Short>(Nucleus::createAShr(lhs.value, rhs.value));
1545 }
1546
John Bauman19bac1e2014-05-06 15:23:49 -04001547 RValue<Short> operator+=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001548 {
1549 return lhs = lhs + rhs;
1550 }
1551
John Bauman19bac1e2014-05-06 15:23:49 -04001552 RValue<Short> operator-=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001553 {
1554 return lhs = lhs - rhs;
1555 }
1556
John Bauman19bac1e2014-05-06 15:23:49 -04001557 RValue<Short> operator*=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001558 {
1559 return lhs = lhs * rhs;
1560 }
1561
John Bauman19bac1e2014-05-06 15:23:49 -04001562 RValue<Short> operator/=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001563 {
1564 return lhs = lhs / rhs;
1565 }
1566
John Bauman19bac1e2014-05-06 15:23:49 -04001567 RValue<Short> operator%=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001568 {
1569 return lhs = lhs % rhs;
1570 }
1571
John Bauman19bac1e2014-05-06 15:23:49 -04001572 RValue<Short> operator&=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001573 {
1574 return lhs = lhs & rhs;
1575 }
1576
John Bauman19bac1e2014-05-06 15:23:49 -04001577 RValue<Short> operator|=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001578 {
1579 return lhs = lhs | rhs;
1580 }
1581
John Bauman19bac1e2014-05-06 15:23:49 -04001582 RValue<Short> operator^=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001583 {
1584 return lhs = lhs ^ rhs;
1585 }
1586
John Bauman19bac1e2014-05-06 15:23:49 -04001587 RValue<Short> operator<<=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001588 {
1589 return lhs = lhs << rhs;
1590 }
1591
John Bauman19bac1e2014-05-06 15:23:49 -04001592 RValue<Short> operator>>=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001593 {
1594 return lhs = lhs >> rhs;
1595 }
1596
John Bauman19bac1e2014-05-06 15:23:49 -04001597 RValue<Short> operator+(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001598 {
1599 return val;
1600 }
1601
John Bauman19bac1e2014-05-06 15:23:49 -04001602 RValue<Short> operator-(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001603 {
1604 return RValue<Short>(Nucleus::createNeg(val.value));
1605 }
1606
John Bauman19bac1e2014-05-06 15:23:49 -04001607 RValue<Short> operator~(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001608 {
1609 return RValue<Short>(Nucleus::createNot(val.value));
1610 }
1611
1612 RValue<Short> operator++(const Short &val, int) // Post-increment
1613 {
1614 RValue<Short> res = val;
1615
Nicolas Capens19336542016-09-26 10:32:29 -04001616 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantShort((short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001617 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001618
1619 return res;
1620 }
1621
1622 const Short &operator++(const Short &val) // Pre-increment
1623 {
Nicolas Capens19336542016-09-26 10:32:29 -04001624 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantShort((short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001625 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001626
1627 return val;
1628 }
1629
1630 RValue<Short> operator--(const Short &val, int) // Post-decrement
1631 {
1632 RValue<Short> res = val;
1633
Nicolas Capens19336542016-09-26 10:32:29 -04001634 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantShort((short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001635 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001636
1637 return res;
1638 }
1639
1640 const Short &operator--(const Short &val) // Pre-decrement
1641 {
Nicolas Capens19336542016-09-26 10:32:29 -04001642 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantShort((short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001643 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001644
1645 return val;
1646 }
1647
John Bauman19bac1e2014-05-06 15:23:49 -04001648 RValue<Bool> operator<(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001649 {
1650 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
1651 }
1652
John Bauman19bac1e2014-05-06 15:23:49 -04001653 RValue<Bool> operator<=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001654 {
1655 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
1656 }
1657
John Bauman19bac1e2014-05-06 15:23:49 -04001658 RValue<Bool> operator>(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001659 {
1660 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
1661 }
1662
John Bauman19bac1e2014-05-06 15:23:49 -04001663 RValue<Bool> operator>=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001664 {
1665 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
1666 }
1667
John Bauman19bac1e2014-05-06 15:23:49 -04001668 RValue<Bool> operator!=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001669 {
1670 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1671 }
1672
John Bauman19bac1e2014-05-06 15:23:49 -04001673 RValue<Bool> operator==(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001674 {
1675 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1676 }
1677
John Bauman19bac1e2014-05-06 15:23:49 -04001678 Type *Short::getType()
John Bauman89401822014-05-06 15:04:28 -04001679 {
Nicolas Capensac230122016-09-20 14:30:06 -04001680 return T(llvm::Type::getInt16Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001681 }
1682
Nicolas Capens81f18302016-01-14 09:32:35 -05001683 UShort::UShort(Argument<UShort> argument)
John Bauman89401822014-05-06 15:04:28 -04001684 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001685 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001686 }
1687
Alexis Hetu77dfab42015-11-23 13:31:22 -05001688 UShort::UShort(RValue<UInt> cast)
1689 {
1690 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
1691
1692 storeValue(integer);
1693 }
1694
Alexis Hetu75b650f2015-11-19 17:40:15 -05001695 UShort::UShort(RValue<Int> cast)
1696 {
1697 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
1698
1699 storeValue(integer);
1700 }
1701
John Bauman89401822014-05-06 15:04:28 -04001702 UShort::UShort()
1703 {
John Bauman89401822014-05-06 15:04:28 -04001704 }
1705
1706 UShort::UShort(unsigned short x)
1707 {
John Bauman66b8ab22014-05-06 15:57:45 -04001708 storeValue(Nucleus::createConstantShort(x));
John Bauman89401822014-05-06 15:04:28 -04001709 }
1710
John Bauman19bac1e2014-05-06 15:23:49 -04001711 UShort::UShort(RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001712 {
John Bauman66b8ab22014-05-06 15:57:45 -04001713 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001714 }
1715
1716 UShort::UShort(const UShort &rhs)
1717 {
John Bauman66b8ab22014-05-06 15:57:45 -04001718 Value *value = rhs.loadValue();
1719 storeValue(value);
1720 }
John Bauman89401822014-05-06 15:04:28 -04001721
John Bauman66b8ab22014-05-06 15:57:45 -04001722 UShort::UShort(const Reference<UShort> &rhs)
1723 {
1724 Value *value = rhs.loadValue();
1725 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001726 }
1727
John Bauman19bac1e2014-05-06 15:23:49 -04001728 RValue<UShort> UShort::operator=(RValue<UShort> rhs) const
John Bauman89401822014-05-06 15:04:28 -04001729 {
John Bauman66b8ab22014-05-06 15:57:45 -04001730 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001731
1732 return rhs;
1733 }
1734
1735 RValue<UShort> UShort::operator=(const UShort &rhs) const
1736 {
John Bauman66b8ab22014-05-06 15:57:45 -04001737 Value *value = rhs.loadValue();
1738 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001739
1740 return RValue<UShort>(value);
1741 }
1742
John Bauman66b8ab22014-05-06 15:57:45 -04001743 RValue<UShort> UShort::operator=(const Reference<UShort> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04001744 {
John Bauman66b8ab22014-05-06 15:57:45 -04001745 Value *value = rhs.loadValue();
1746 storeValue(value);
1747
1748 return RValue<UShort>(value);
John Bauman89401822014-05-06 15:04:28 -04001749 }
1750
John Bauman19bac1e2014-05-06 15:23:49 -04001751 RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001752 {
1753 return RValue<UShort>(Nucleus::createAdd(lhs.value, rhs.value));
1754 }
1755
John Bauman19bac1e2014-05-06 15:23:49 -04001756 RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001757 {
1758 return RValue<UShort>(Nucleus::createSub(lhs.value, rhs.value));
1759 }
1760
John Bauman19bac1e2014-05-06 15:23:49 -04001761 RValue<UShort> operator*(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001762 {
1763 return RValue<UShort>(Nucleus::createMul(lhs.value, rhs.value));
1764 }
1765
John Bauman19bac1e2014-05-06 15:23:49 -04001766 RValue<UShort> operator/(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001767 {
1768 return RValue<UShort>(Nucleus::createUDiv(lhs.value, rhs.value));
1769 }
1770
John Bauman19bac1e2014-05-06 15:23:49 -04001771 RValue<UShort> operator%(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001772 {
1773 return RValue<UShort>(Nucleus::createURem(lhs.value, rhs.value));
1774 }
1775
John Bauman19bac1e2014-05-06 15:23:49 -04001776 RValue<UShort> operator&(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001777 {
1778 return RValue<UShort>(Nucleus::createAnd(lhs.value, rhs.value));
1779 }
1780
John Bauman19bac1e2014-05-06 15:23:49 -04001781 RValue<UShort> operator|(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001782 {
1783 return RValue<UShort>(Nucleus::createOr(lhs.value, rhs.value));
1784 }
1785
John Bauman19bac1e2014-05-06 15:23:49 -04001786 RValue<UShort> operator^(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001787 {
1788 return RValue<UShort>(Nucleus::createXor(lhs.value, rhs.value));
1789 }
1790
John Bauman19bac1e2014-05-06 15:23:49 -04001791 RValue<UShort> operator<<(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001792 {
1793 return RValue<UShort>(Nucleus::createShl(lhs.value, rhs.value));
1794 }
1795
John Bauman19bac1e2014-05-06 15:23:49 -04001796 RValue<UShort> operator>>(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001797 {
1798 return RValue<UShort>(Nucleus::createLShr(lhs.value, rhs.value));
1799 }
1800
John Bauman19bac1e2014-05-06 15:23:49 -04001801 RValue<UShort> operator+=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001802 {
1803 return lhs = lhs + rhs;
1804 }
1805
John Bauman19bac1e2014-05-06 15:23:49 -04001806 RValue<UShort> operator-=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001807 {
1808 return lhs = lhs - rhs;
1809 }
1810
John Bauman19bac1e2014-05-06 15:23:49 -04001811 RValue<UShort> operator*=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001812 {
1813 return lhs = lhs * rhs;
1814 }
1815
John Bauman19bac1e2014-05-06 15:23:49 -04001816 RValue<UShort> operator/=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001817 {
1818 return lhs = lhs / rhs;
1819 }
1820
John Bauman19bac1e2014-05-06 15:23:49 -04001821 RValue<UShort> operator%=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001822 {
1823 return lhs = lhs % rhs;
1824 }
1825
John Bauman19bac1e2014-05-06 15:23:49 -04001826 RValue<UShort> operator&=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001827 {
1828 return lhs = lhs & rhs;
1829 }
1830
John Bauman19bac1e2014-05-06 15:23:49 -04001831 RValue<UShort> operator|=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001832 {
1833 return lhs = lhs | rhs;
1834 }
1835
John Bauman19bac1e2014-05-06 15:23:49 -04001836 RValue<UShort> operator^=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001837 {
1838 return lhs = lhs ^ rhs;
1839 }
1840
John Bauman19bac1e2014-05-06 15:23:49 -04001841 RValue<UShort> operator<<=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001842 {
1843 return lhs = lhs << rhs;
1844 }
1845
John Bauman19bac1e2014-05-06 15:23:49 -04001846 RValue<UShort> operator>>=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001847 {
1848 return lhs = lhs >> rhs;
1849 }
1850
John Bauman19bac1e2014-05-06 15:23:49 -04001851 RValue<UShort> operator+(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001852 {
1853 return val;
1854 }
1855
John Bauman19bac1e2014-05-06 15:23:49 -04001856 RValue<UShort> operator-(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001857 {
1858 return RValue<UShort>(Nucleus::createNeg(val.value));
1859 }
1860
John Bauman19bac1e2014-05-06 15:23:49 -04001861 RValue<UShort> operator~(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001862 {
1863 return RValue<UShort>(Nucleus::createNot(val.value));
1864 }
1865
1866 RValue<UShort> operator++(const UShort &val, int) // Post-increment
1867 {
1868 RValue<UShort> res = val;
1869
Nicolas Capens19336542016-09-26 10:32:29 -04001870 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantShort((unsigned short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001871 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001872
1873 return res;
1874 }
1875
1876 const UShort &operator++(const UShort &val) // Pre-increment
1877 {
Nicolas Capens19336542016-09-26 10:32:29 -04001878 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantShort((unsigned short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001879 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001880
1881 return val;
1882 }
1883
1884 RValue<UShort> operator--(const UShort &val, int) // Post-decrement
1885 {
1886 RValue<UShort> res = val;
1887
Nicolas Capens19336542016-09-26 10:32:29 -04001888 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantShort((unsigned short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001889 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001890
1891 return res;
1892 }
1893
1894 const UShort &operator--(const UShort &val) // Pre-decrement
1895 {
Nicolas Capens19336542016-09-26 10:32:29 -04001896 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantShort((unsigned short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001897 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001898
1899 return val;
1900 }
1901
John Bauman19bac1e2014-05-06 15:23:49 -04001902 RValue<Bool> operator<(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001903 {
1904 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1905 }
1906
John Bauman19bac1e2014-05-06 15:23:49 -04001907 RValue<Bool> operator<=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001908 {
1909 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1910 }
1911
John Bauman19bac1e2014-05-06 15:23:49 -04001912 RValue<Bool> operator>(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001913 {
1914 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1915 }
1916
John Bauman19bac1e2014-05-06 15:23:49 -04001917 RValue<Bool> operator>=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001918 {
1919 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1920 }
1921
John Bauman19bac1e2014-05-06 15:23:49 -04001922 RValue<Bool> operator!=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001923 {
1924 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1925 }
1926
John Bauman19bac1e2014-05-06 15:23:49 -04001927 RValue<Bool> operator==(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001928 {
1929 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1930 }
1931
John Bauman19bac1e2014-05-06 15:23:49 -04001932 Type *UShort::getType()
John Bauman89401822014-05-06 15:04:28 -04001933 {
Nicolas Capensac230122016-09-20 14:30:06 -04001934 return T(llvm::Type::getInt16Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001935 }
1936
Nicolas Capens16b5f152016-10-13 13:39:01 -04001937 Byte4::Byte4(RValue<Byte8> cast)
1938 {
1939 // xyzw.parent = this;
1940
1941 storeValue(Nucleus::createTrunc(Nucleus::createBitCast(cast.value, Long::getType()), Int::getType()));
1942 }
1943
1944 Byte4::Byte4(const Reference<Byte4> &rhs)
1945 {
1946 // xyzw.parent = this;
1947
1948 Value *value = rhs.loadValue();
1949 storeValue(value);
1950 }
1951
John Bauman19bac1e2014-05-06 15:23:49 -04001952 Type *Byte4::getType()
John Bauman89401822014-05-06 15:04:28 -04001953 {
1954 #if 0
Nicolas Capensac230122016-09-20 14:30:06 -04001955 return T(VectorType::get(Byte::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04001956 #else
1957 return UInt::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
1958 #endif
1959 }
1960
John Bauman19bac1e2014-05-06 15:23:49 -04001961 Type *SByte4::getType()
John Bauman89401822014-05-06 15:04:28 -04001962 {
1963 #if 0
Nicolas Capensac230122016-09-20 14:30:06 -04001964 return T(VectorType::get(SByte::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04001965 #else
1966 return Int::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
1967 #endif
1968 }
1969
1970 Byte8::Byte8()
1971 {
1972 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04001973 }
1974
Nicolas Capens3bbc5e12016-09-27 10:49:52 -04001975 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 -04001976 {
1977 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04001978
Nicolas Capens13ac2322016-10-13 14:52:12 -04001979 int64_t constantVector[8] = {x0, x1, x2, x3, x4, x5, x6, x7};
1980 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(Byte::getType(), 8))));
John Bauman89401822014-05-06 15:04:28 -04001981
John Bauman66b8ab22014-05-06 15:57:45 -04001982 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04001983 }
1984
John Bauman19bac1e2014-05-06 15:23:49 -04001985 Byte8::Byte8(RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04001986 {
1987 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04001988
John Bauman66b8ab22014-05-06 15:57:45 -04001989 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001990 }
1991
1992 Byte8::Byte8(const Byte8 &rhs)
1993 {
1994 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04001995
John Bauman66b8ab22014-05-06 15:57:45 -04001996 Value *value = rhs.loadValue();
1997 storeValue(value);
1998 }
1999
2000 Byte8::Byte8(const Reference<Byte8> &rhs)
2001 {
2002 // xyzw.parent = this;
2003
2004 Value *value = rhs.loadValue();
2005 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002006 }
2007
John Bauman19bac1e2014-05-06 15:23:49 -04002008 RValue<Byte8> Byte8::operator=(RValue<Byte8> rhs) const
John Bauman89401822014-05-06 15:04:28 -04002009 {
John Bauman66b8ab22014-05-06 15:57:45 -04002010 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002011
2012 return rhs;
2013 }
2014
2015 RValue<Byte8> Byte8::operator=(const Byte8 &rhs) const
2016 {
John Bauman66b8ab22014-05-06 15:57:45 -04002017 Value *value = rhs.loadValue();
2018 storeValue(value);
2019
2020 return RValue<Byte8>(value);
2021 }
2022
2023 RValue<Byte8> Byte8::operator=(const Reference<Byte8> &rhs) const
2024 {
2025 Value *value = rhs.loadValue();
2026 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002027
2028 return RValue<Byte8>(value);
2029 }
2030
John Bauman19bac1e2014-05-06 15:23:49 -04002031 RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002032 {
John Bauman19bac1e2014-05-06 15:23:49 -04002033 if(CPUID::supportsMMX2())
2034 {
2035 return x86::paddb(lhs, rhs);
2036 }
2037 else
2038 {
2039 return RValue<Byte8>(Nucleus::createAdd(lhs.value, rhs.value));
2040 }
John Bauman89401822014-05-06 15:04:28 -04002041 }
2042
John Bauman19bac1e2014-05-06 15:23:49 -04002043 RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002044 {
John Bauman19bac1e2014-05-06 15:23:49 -04002045 if(CPUID::supportsMMX2())
2046 {
2047 return x86::psubb(lhs, rhs);
2048 }
2049 else
2050 {
2051 return RValue<Byte8>(Nucleus::createSub(lhs.value, rhs.value));
2052 }
John Bauman89401822014-05-06 15:04:28 -04002053 }
2054
John Bauman19bac1e2014-05-06 15:23:49 -04002055// RValue<Byte8> operator*(RValue<Byte8> lhs, RValue<Byte8> rhs)
2056// {
2057// return RValue<Byte8>(Nucleus::createMul(lhs.value, rhs.value));
2058// }
2059
2060// RValue<Byte8> operator/(RValue<Byte8> lhs, RValue<Byte8> rhs)
2061// {
2062// return RValue<Byte8>(Nucleus::createUDiv(lhs.value, rhs.value));
2063// }
2064
2065// RValue<Byte8> operator%(RValue<Byte8> lhs, RValue<Byte8> rhs)
2066// {
2067// return RValue<Byte8>(Nucleus::createURem(lhs.value, rhs.value));
2068// }
2069
2070 RValue<Byte8> operator&(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002071 {
John Bauman19bac1e2014-05-06 15:23:49 -04002072 if(CPUID::supportsMMX2())
2073 {
2074 return As<Byte8>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
2075 }
2076 else
2077 {
2078 return RValue<Byte8>(Nucleus::createAnd(lhs.value, rhs.value));
2079 }
John Bauman89401822014-05-06 15:04:28 -04002080 }
2081
John Bauman19bac1e2014-05-06 15:23:49 -04002082 RValue<Byte8> operator|(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002083 {
John Bauman19bac1e2014-05-06 15:23:49 -04002084 if(CPUID::supportsMMX2())
2085 {
2086 return As<Byte8>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
2087 }
2088 else
2089 {
2090 return RValue<Byte8>(Nucleus::createOr(lhs.value, rhs.value));
2091 }
John Bauman89401822014-05-06 15:04:28 -04002092 }
2093
John Bauman19bac1e2014-05-06 15:23:49 -04002094 RValue<Byte8> operator^(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002095 {
John Bauman19bac1e2014-05-06 15:23:49 -04002096 if(CPUID::supportsMMX2())
2097 {
2098 return As<Byte8>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
2099 }
2100 else
John Bauman66b8ab22014-05-06 15:57:45 -04002101 {
John Bauman19bac1e2014-05-06 15:23:49 -04002102 return RValue<Byte8>(Nucleus::createXor(lhs.value, rhs.value));
2103 }
John Bauman89401822014-05-06 15:04:28 -04002104 }
2105
John Bauman19bac1e2014-05-06 15:23:49 -04002106// RValue<Byte8> operator<<(RValue<Byte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002107// {
2108// return RValue<Byte8>(Nucleus::createShl(lhs.value, rhs.value));
2109// }
2110
John Bauman19bac1e2014-05-06 15:23:49 -04002111// RValue<Byte8> operator>>(RValue<Byte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002112// {
2113// return RValue<Byte8>(Nucleus::createLShr(lhs.value, rhs.value));
2114// }
2115
John Bauman19bac1e2014-05-06 15:23:49 -04002116 RValue<Byte8> operator+=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002117 {
2118 return lhs = lhs + rhs;
2119 }
2120
John Bauman19bac1e2014-05-06 15:23:49 -04002121 RValue<Byte8> operator-=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002122 {
2123 return lhs = lhs - rhs;
2124 }
2125
John Bauman19bac1e2014-05-06 15:23:49 -04002126// RValue<Byte8> operator*=(const Byte8 &lhs, RValue<Byte8> rhs)
2127// {
2128// return lhs = lhs * rhs;
2129// }
John Bauman89401822014-05-06 15:04:28 -04002130
John Bauman19bac1e2014-05-06 15:23:49 -04002131// RValue<Byte8> operator/=(const Byte8 &lhs, RValue<Byte8> rhs)
2132// {
2133// return lhs = lhs / rhs;
2134// }
John Bauman89401822014-05-06 15:04:28 -04002135
John Bauman19bac1e2014-05-06 15:23:49 -04002136// RValue<Byte8> operator%=(const Byte8 &lhs, RValue<Byte8> rhs)
2137// {
2138// return lhs = lhs % rhs;
2139// }
John Bauman89401822014-05-06 15:04:28 -04002140
John Bauman19bac1e2014-05-06 15:23:49 -04002141 RValue<Byte8> operator&=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002142 {
2143 return lhs = lhs & rhs;
2144 }
2145
John Bauman19bac1e2014-05-06 15:23:49 -04002146 RValue<Byte8> operator|=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002147 {
2148 return lhs = lhs | rhs;
2149 }
2150
John Bauman19bac1e2014-05-06 15:23:49 -04002151 RValue<Byte8> operator^=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002152 {
2153 return lhs = lhs ^ rhs;
2154 }
2155
John Bauman19bac1e2014-05-06 15:23:49 -04002156// RValue<Byte8> operator<<=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002157// {
2158// return lhs = lhs << rhs;
2159// }
2160
John Bauman19bac1e2014-05-06 15:23:49 -04002161// RValue<Byte8> operator>>=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002162// {
2163// return lhs = lhs >> rhs;
2164// }
2165
John Bauman19bac1e2014-05-06 15:23:49 -04002166// RValue<Byte8> operator+(RValue<Byte8> val)
2167// {
2168// return val;
2169// }
2170
2171// RValue<Byte8> operator-(RValue<Byte8> val)
2172// {
2173// return RValue<Byte8>(Nucleus::createNeg(val.value));
2174// }
2175
2176 RValue<Byte8> operator~(RValue<Byte8> val)
John Bauman89401822014-05-06 15:04:28 -04002177 {
John Bauman19bac1e2014-05-06 15:23:49 -04002178 if(CPUID::supportsMMX2())
2179 {
Nicolas Capens16b5f152016-10-13 13:39:01 -04002180 return val ^ Byte8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
John Bauman19bac1e2014-05-06 15:23:49 -04002181 }
2182 else
2183 {
2184 return RValue<Byte8>(Nucleus::createNot(val.value));
2185 }
John Bauman89401822014-05-06 15:04:28 -04002186 }
2187
John Bauman19bac1e2014-05-06 15:23:49 -04002188 RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002189 {
2190 return x86::paddusb(x, y);
2191 }
John Bauman66b8ab22014-05-06 15:57:45 -04002192
John Bauman19bac1e2014-05-06 15:23:49 -04002193 RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002194 {
2195 return x86::psubusb(x, y);
2196 }
2197
John Bauman19bac1e2014-05-06 15:23:49 -04002198 RValue<Short4> Unpack(RValue<Byte4> x)
John Bauman89401822014-05-06 15:04:28 -04002199 {
Nicolas Capens19336542016-09-26 10:32:29 -04002200 Value *int2 = Nucleus::createInsertElement(V(UndefValue::get(VectorType::get(Int::getType(), 2))), x.value, 0);
John Bauman19bac1e2014-05-06 15:23:49 -04002201 Value *byte8 = Nucleus::createBitCast(int2, Byte8::getType());
John Bauman89401822014-05-06 15:04:28 -04002202
John Bauman19bac1e2014-05-06 15:23:49 -04002203 return UnpackLow(RValue<Byte8>(byte8), RValue<Byte8>(byte8));
2204 }
John Bauman89401822014-05-06 15:04:28 -04002205
John Bauman19bac1e2014-05-06 15:23:49 -04002206 RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y)
2207 {
2208 if(CPUID::supportsMMX2())
2209 {
2210 return x86::punpcklbw(x, y);
2211 }
2212 else
2213 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002214 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11};
2215 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman19bac1e2014-05-06 15:23:49 -04002216
2217 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2218 }
John Bauman89401822014-05-06 15:04:28 -04002219 }
John Bauman66b8ab22014-05-06 15:57:45 -04002220
John Bauman19bac1e2014-05-06 15:23:49 -04002221 RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002222 {
John Bauman19bac1e2014-05-06 15:23:49 -04002223 if(CPUID::supportsMMX2())
2224 {
2225 return x86::punpckhbw(x, y);
2226 }
2227 else
2228 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002229 int shuffle[8] = {4, 12, 5, 13, 6, 14, 7, 15};
2230 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002231
John Bauman19bac1e2014-05-06 15:23:49 -04002232 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2233 }
John Bauman89401822014-05-06 15:04:28 -04002234 }
2235
John Bauman19bac1e2014-05-06 15:23:49 -04002236 RValue<Int> SignMask(RValue<Byte8> x)
John Bauman89401822014-05-06 15:04:28 -04002237 {
2238 return x86::pmovmskb(x);
2239 }
2240
John Bauman19bac1e2014-05-06 15:23:49 -04002241// RValue<Byte8> CmpGT(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002242// {
2243// return x86::pcmpgtb(x, y); // FIXME: Signedness
2244// }
John Bauman66b8ab22014-05-06 15:57:45 -04002245
John Bauman19bac1e2014-05-06 15:23:49 -04002246 RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002247 {
2248 return x86::pcmpeqb(x, y);
2249 }
2250
John Bauman19bac1e2014-05-06 15:23:49 -04002251 Type *Byte8::getType()
John Bauman89401822014-05-06 15:04:28 -04002252 {
John Bauman19bac1e2014-05-06 15:23:49 -04002253 if(CPUID::supportsMMX2())
2254 {
2255 return MMX::getType();
2256 }
2257 else
2258 {
Nicolas Capensac230122016-09-20 14:30:06 -04002259 return T(VectorType::get(Byte::getType(), 8));
John Bauman19bac1e2014-05-06 15:23:49 -04002260 }
John Bauman89401822014-05-06 15:04:28 -04002261 }
2262
2263 SByte8::SByte8()
2264 {
2265 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002266 }
2267
Nicolas Capens3bbc5e12016-09-27 10:49:52 -04002268 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 -04002269 {
2270 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002271
Nicolas Capens13ac2322016-10-13 14:52:12 -04002272 int64_t constantVector[8] = {x0, x1, x2, x3, x4, x5, x6, x7};
2273 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(SByte::getType(), 8))));
John Bauman89401822014-05-06 15:04:28 -04002274
John Bauman66b8ab22014-05-06 15:57:45 -04002275 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04002276 }
2277
John Bauman19bac1e2014-05-06 15:23:49 -04002278 SByte8::SByte8(RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002279 {
2280 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002281
John Bauman66b8ab22014-05-06 15:57:45 -04002282 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002283 }
2284
2285 SByte8::SByte8(const SByte8 &rhs)
2286 {
2287 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002288
John Bauman66b8ab22014-05-06 15:57:45 -04002289 Value *value = rhs.loadValue();
2290 storeValue(value);
2291 }
2292
2293 SByte8::SByte8(const Reference<SByte8> &rhs)
2294 {
2295 // xyzw.parent = this;
2296
2297 Value *value = rhs.loadValue();
2298 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002299 }
2300
John Bauman19bac1e2014-05-06 15:23:49 -04002301 RValue<SByte8> SByte8::operator=(RValue<SByte8> rhs) const
John Bauman89401822014-05-06 15:04:28 -04002302 {
John Bauman66b8ab22014-05-06 15:57:45 -04002303 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002304
2305 return rhs;
2306 }
2307
2308 RValue<SByte8> SByte8::operator=(const SByte8 &rhs) const
2309 {
John Bauman66b8ab22014-05-06 15:57:45 -04002310 Value *value = rhs.loadValue();
2311 storeValue(value);
2312
2313 return RValue<SByte8>(value);
2314 }
2315
2316 RValue<SByte8> SByte8::operator=(const Reference<SByte8> &rhs) const
2317 {
2318 Value *value = rhs.loadValue();
2319 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002320
2321 return RValue<SByte8>(value);
2322 }
2323
John Bauman19bac1e2014-05-06 15:23:49 -04002324 RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002325 {
John Bauman19bac1e2014-05-06 15:23:49 -04002326 if(CPUID::supportsMMX2())
2327 {
2328 return As<SByte8>(x86::paddb(As<Byte8>(lhs), As<Byte8>(rhs)));
2329 }
2330 else
2331 {
2332 return RValue<SByte8>(Nucleus::createAdd(lhs.value, rhs.value));
2333 }
John Bauman89401822014-05-06 15:04:28 -04002334 }
2335
John Bauman19bac1e2014-05-06 15:23:49 -04002336 RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002337 {
John Bauman19bac1e2014-05-06 15:23:49 -04002338 if(CPUID::supportsMMX2())
2339 {
2340 return As<SByte8>(x86::psubb(As<Byte8>(lhs), As<Byte8>(rhs)));
2341 }
2342 else
2343 {
2344 return RValue<SByte8>(Nucleus::createSub(lhs.value, rhs.value));
2345 }
John Bauman89401822014-05-06 15:04:28 -04002346 }
2347
John Bauman19bac1e2014-05-06 15:23:49 -04002348// RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs)
2349// {
2350// return RValue<SByte8>(Nucleus::createMul(lhs.value, rhs.value));
2351// }
John Bauman89401822014-05-06 15:04:28 -04002352
John Bauman19bac1e2014-05-06 15:23:49 -04002353// RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs)
2354// {
2355// return RValue<SByte8>(Nucleus::createSDiv(lhs.value, rhs.value));
2356// }
John Bauman89401822014-05-06 15:04:28 -04002357
John Bauman19bac1e2014-05-06 15:23:49 -04002358// RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs)
2359// {
2360// return RValue<SByte8>(Nucleus::createSRem(lhs.value, rhs.value));
2361// }
John Bauman89401822014-05-06 15:04:28 -04002362
John Bauman19bac1e2014-05-06 15:23:49 -04002363 RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002364 {
2365 return RValue<SByte8>(Nucleus::createAnd(lhs.value, rhs.value));
2366 }
2367
John Bauman19bac1e2014-05-06 15:23:49 -04002368 RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002369 {
2370 return RValue<SByte8>(Nucleus::createOr(lhs.value, rhs.value));
2371 }
2372
John Bauman19bac1e2014-05-06 15:23:49 -04002373 RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002374 {
2375 return RValue<SByte8>(Nucleus::createXor(lhs.value, rhs.value));
2376 }
2377
John Bauman19bac1e2014-05-06 15:23:49 -04002378// RValue<SByte8> operator<<(RValue<SByte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002379// {
2380// return RValue<SByte8>(Nucleus::createShl(lhs.value, rhs.value));
2381// }
2382
John Bauman19bac1e2014-05-06 15:23:49 -04002383// RValue<SByte8> operator>>(RValue<SByte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002384// {
2385// return RValue<SByte8>(Nucleus::createAShr(lhs.value, rhs.value));
2386// }
2387
John Bauman19bac1e2014-05-06 15:23:49 -04002388 RValue<SByte8> operator+=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002389 {
2390 return lhs = lhs + rhs;
2391 }
2392
John Bauman19bac1e2014-05-06 15:23:49 -04002393 RValue<SByte8> operator-=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002394 {
2395 return lhs = lhs - rhs;
2396 }
2397
John Bauman19bac1e2014-05-06 15:23:49 -04002398// RValue<SByte8> operator*=(const SByte8 &lhs, RValue<SByte8> rhs)
2399// {
2400// return lhs = lhs * rhs;
2401// }
John Bauman89401822014-05-06 15:04:28 -04002402
John Bauman19bac1e2014-05-06 15:23:49 -04002403// RValue<SByte8> operator/=(const SByte8 &lhs, RValue<SByte8> rhs)
2404// {
2405// return lhs = lhs / rhs;
2406// }
John Bauman89401822014-05-06 15:04:28 -04002407
John Bauman19bac1e2014-05-06 15:23:49 -04002408// RValue<SByte8> operator%=(const SByte8 &lhs, RValue<SByte8> rhs)
2409// {
2410// return lhs = lhs % rhs;
2411// }
John Bauman89401822014-05-06 15:04:28 -04002412
John Bauman19bac1e2014-05-06 15:23:49 -04002413 RValue<SByte8> operator&=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002414 {
2415 return lhs = lhs & rhs;
2416 }
2417
John Bauman19bac1e2014-05-06 15:23:49 -04002418 RValue<SByte8> operator|=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002419 {
2420 return lhs = lhs | rhs;
2421 }
2422
John Bauman19bac1e2014-05-06 15:23:49 -04002423 RValue<SByte8> operator^=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002424 {
2425 return lhs = lhs ^ rhs;
2426 }
2427
John Bauman19bac1e2014-05-06 15:23:49 -04002428// RValue<SByte8> operator<<=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002429// {
2430// return lhs = lhs << rhs;
2431// }
2432
John Bauman19bac1e2014-05-06 15:23:49 -04002433// RValue<SByte8> operator>>=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002434// {
2435// return lhs = lhs >> rhs;
2436// }
2437
John Bauman19bac1e2014-05-06 15:23:49 -04002438// RValue<SByte8> operator+(RValue<SByte8> val)
2439// {
2440// return val;
2441// }
2442
2443// RValue<SByte8> operator-(RValue<SByte8> val)
2444// {
2445// return RValue<SByte8>(Nucleus::createNeg(val.value));
2446// }
2447
2448 RValue<SByte8> operator~(RValue<SByte8> val)
John Bauman89401822014-05-06 15:04:28 -04002449 {
John Bauman19bac1e2014-05-06 15:23:49 -04002450 if(CPUID::supportsMMX2())
2451 {
Nicolas Capens16b5f152016-10-13 13:39:01 -04002452 return val ^ SByte8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
John Bauman19bac1e2014-05-06 15:23:49 -04002453 }
2454 else
2455 {
2456 return RValue<SByte8>(Nucleus::createNot(val.value));
2457 }
John Bauman89401822014-05-06 15:04:28 -04002458 }
2459
John Bauman19bac1e2014-05-06 15:23:49 -04002460 RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002461 {
2462 return x86::paddsb(x, y);
2463 }
John Bauman66b8ab22014-05-06 15:57:45 -04002464
John Bauman19bac1e2014-05-06 15:23:49 -04002465 RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002466 {
2467 return x86::psubsb(x, y);
2468 }
2469
John Bauman19bac1e2014-05-06 15:23:49 -04002470 RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002471 {
John Bauman19bac1e2014-05-06 15:23:49 -04002472 if(CPUID::supportsMMX2())
2473 {
2474 return As<Short4>(x86::punpcklbw(As<Byte8>(x), As<Byte8>(y)));
2475 }
2476 else
2477 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002478 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11};
2479 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002480
John Bauman19bac1e2014-05-06 15:23:49 -04002481 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2482 }
John Bauman89401822014-05-06 15:04:28 -04002483 }
John Bauman66b8ab22014-05-06 15:57:45 -04002484
John Bauman19bac1e2014-05-06 15:23:49 -04002485 RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002486 {
John Bauman19bac1e2014-05-06 15:23:49 -04002487 if(CPUID::supportsMMX2())
2488 {
2489 return As<Short4>(x86::punpckhbw(As<Byte8>(x), As<Byte8>(y)));
2490 }
2491 else
2492 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002493 int shuffle[8] = {4, 12, 5, 13, 6, 14, 7, 15};
2494 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002495
John Bauman19bac1e2014-05-06 15:23:49 -04002496 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2497 }
John Bauman89401822014-05-06 15:04:28 -04002498 }
2499
John Bauman19bac1e2014-05-06 15:23:49 -04002500 RValue<Int> SignMask(RValue<SByte8> x)
John Bauman89401822014-05-06 15:04:28 -04002501 {
2502 return x86::pmovmskb(As<Byte8>(x));
2503 }
2504
John Bauman19bac1e2014-05-06 15:23:49 -04002505 RValue<Byte8> CmpGT(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002506 {
2507 return x86::pcmpgtb(x, y);
2508 }
John Bauman66b8ab22014-05-06 15:57:45 -04002509
John Bauman19bac1e2014-05-06 15:23:49 -04002510 RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002511 {
2512 return x86::pcmpeqb(As<Byte8>(x), As<Byte8>(y));
2513 }
2514
John Bauman19bac1e2014-05-06 15:23:49 -04002515 Type *SByte8::getType()
John Bauman89401822014-05-06 15:04:28 -04002516 {
John Bauman19bac1e2014-05-06 15:23:49 -04002517 if(CPUID::supportsMMX2())
2518 {
2519 return MMX::getType();
2520 }
2521 else
2522 {
Nicolas Capensac230122016-09-20 14:30:06 -04002523 return T(VectorType::get(SByte::getType(), 8));
John Bauman19bac1e2014-05-06 15:23:49 -04002524 }
John Bauman89401822014-05-06 15:04:28 -04002525 }
2526
John Bauman19bac1e2014-05-06 15:23:49 -04002527 Byte16::Byte16(RValue<Byte16> rhs)
John Bauman89401822014-05-06 15:04:28 -04002528 {
2529 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002530
John Bauman66b8ab22014-05-06 15:57:45 -04002531 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002532 }
2533
2534 Byte16::Byte16(const Byte16 &rhs)
2535 {
2536 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002537
John Bauman66b8ab22014-05-06 15:57:45 -04002538 Value *value = rhs.loadValue();
2539 storeValue(value);
2540 }
2541
2542 Byte16::Byte16(const Reference<Byte16> &rhs)
2543 {
2544 // xyzw.parent = this;
2545
2546 Value *value = rhs.loadValue();
2547 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002548 }
2549
John Bauman19bac1e2014-05-06 15:23:49 -04002550 RValue<Byte16> Byte16::operator=(RValue<Byte16> rhs) const
John Bauman89401822014-05-06 15:04:28 -04002551 {
John Bauman66b8ab22014-05-06 15:57:45 -04002552 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002553
2554 return rhs;
2555 }
2556
2557 RValue<Byte16> Byte16::operator=(const Byte16 &rhs) const
2558 {
John Bauman66b8ab22014-05-06 15:57:45 -04002559 Value *value = rhs.loadValue();
2560 storeValue(value);
2561
2562 return RValue<Byte16>(value);
2563 }
2564
2565 RValue<Byte16> Byte16::operator=(const Reference<Byte16> &rhs) const
2566 {
2567 Value *value = rhs.loadValue();
2568 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002569
2570 return RValue<Byte16>(value);
2571 }
2572
John Bauman19bac1e2014-05-06 15:23:49 -04002573 Type *Byte16::getType()
John Bauman89401822014-05-06 15:04:28 -04002574 {
Nicolas Capensac230122016-09-20 14:30:06 -04002575 return T(VectorType::get(Byte::getType(), 16));
John Bauman89401822014-05-06 15:04:28 -04002576 }
2577
John Bauman19bac1e2014-05-06 15:23:49 -04002578 Type *SByte16::getType()
John Bauman89401822014-05-06 15:04:28 -04002579 {
Nicolas Capensac230122016-09-20 14:30:06 -04002580 return T( VectorType::get(SByte::getType(), 16));
John Bauman89401822014-05-06 15:04:28 -04002581 }
2582
Nicolas Capens16b5f152016-10-13 13:39:01 -04002583 Short2::Short2(RValue<Short4> cast)
2584 {
2585 storeValue(Nucleus::createTrunc(Nucleus::createBitCast(cast.value, Long::getType()), UInt::getType()));
2586 }
2587
2588 Type *Short2::getType()
2589 {
2590 #if 0
2591 return T(VectorType::get(Short::getType(), 2));
2592 #else
2593 return UInt::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
2594 #endif
2595 }
2596
2597 UShort2::UShort2(RValue<UShort4> cast)
2598 {
2599 storeValue(Nucleus::createTrunc(Nucleus::createBitCast(cast.value, Long::getType()), UInt::getType()));
2600 }
2601
2602 Type *UShort2::getType()
2603 {
2604 #if 0
2605 return T(VectorType::get(UShort::getType(), 2));
2606 #else
2607 return UInt::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
2608 #endif
2609 }
2610
John Bauman19bac1e2014-05-06 15:23:49 -04002611 Short4::Short4(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04002612 {
John Bauman89401822014-05-06 15:04:28 -04002613 Value *extend = Nucleus::createZExt(cast.value, Long::getType());
John Bauman19bac1e2014-05-06 15:23:49 -04002614 Value *swizzle = Swizzle(RValue<Short4>(extend), 0x00).value;
John Bauman66b8ab22014-05-06 15:57:45 -04002615
2616 storeValue(swizzle);
John Bauman89401822014-05-06 15:04:28 -04002617 }
2618
John Bauman19bac1e2014-05-06 15:23:49 -04002619 Short4::Short4(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04002620 {
John Bauman89401822014-05-06 15:04:28 -04002621 Value *short8 = Nucleus::createBitCast(cast.value, Short8::getType());
2622
2623 #if 0 // FIXME: Check codegen (pshuflw phshufhw pshufd)
2624 Constant *pack[8];
2625 pack[0] = Nucleus::createConstantInt(0);
2626 pack[1] = Nucleus::createConstantInt(2);
2627 pack[2] = Nucleus::createConstantInt(4);
2628 pack[3] = Nucleus::createConstantInt(6);
2629
2630 Value *short4 = Nucleus::createShuffleVector(short8, short8, Nucleus::createConstantVector(pack, 4));
2631 #else
2632 Value *packed;
2633
2634 // FIXME: Use Swizzle<Short8>
2635 if(!CPUID::supportsSSSE3())
2636 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002637 int pshuflw[8] = {0, 2, 0, 2, 4, 5, 6, 7};
2638 int pshufhw[8] = {0, 1, 2, 3, 4, 6, 4, 6};
John Bauman89401822014-05-06 15:04:28 -04002639
Nicolas Capense89cd582016-09-30 14:23:47 -04002640 Value *shuffle1 = Nucleus::createShuffleVector(short8, short8, pshuflw);
2641 Value *shuffle2 = Nucleus::createShuffleVector(shuffle1, shuffle1, pshufhw);
John Bauman89401822014-05-06 15:04:28 -04002642 Value *int4 = Nucleus::createBitCast(shuffle2, Int4::getType());
Nicolas Capense95d5342016-09-30 11:37:28 -04002643 packed = createSwizzle4(int4, 0x88);
John Bauman89401822014-05-06 15:04:28 -04002644 }
2645 else
2646 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002647 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 -04002648 Value *byte16 = Nucleus::createBitCast(cast.value, Byte16::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04002649 packed = Nucleus::createShuffleVector(byte16, byte16, pshufb);
John Bauman89401822014-05-06 15:04:28 -04002650 }
2651
2652 #if 0 // FIXME: No optimal instruction selection
Nicolas Capens22008782016-10-20 01:11:47 -04002653 Value *qword2 = Nucleus::createBitCast(packed, T(VectorType::get(Long::getType(), 2)));
John Bauman89401822014-05-06 15:04:28 -04002654 Value *element = Nucleus::createExtractElement(qword2, 0);
2655 Value *short4 = Nucleus::createBitCast(element, Short4::getType());
2656 #else // FIXME: Requires SSE
2657 Value *int2 = RValue<Int2>(Int2(RValue<Int4>(packed))).value;
2658 Value *short4 = Nucleus::createBitCast(int2, Short4::getType());
2659 #endif
2660 #endif
2661
John Bauman66b8ab22014-05-06 15:57:45 -04002662 storeValue(short4);
John Bauman89401822014-05-06 15:04:28 -04002663 }
2664
John Bauman19bac1e2014-05-06 15:23:49 -04002665// Short4::Short4(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04002666// {
2667// }
2668
John Bauman19bac1e2014-05-06 15:23:49 -04002669 Short4::Short4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04002670 {
John Bauman89401822014-05-06 15:04:28 -04002671 Int4 v4i32 = Int4(cast);
2672 v4i32 = As<Int4>(x86::packssdw(v4i32, v4i32));
John Bauman66b8ab22014-05-06 15:57:45 -04002673
2674 storeValue(As<Short4>(Int2(v4i32)).value);
John Bauman89401822014-05-06 15:04:28 -04002675 }
2676
2677 Short4::Short4()
2678 {
2679 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002680 }
2681
John Bauman19bac1e2014-05-06 15:23:49 -04002682 Short4::Short4(short xyzw)
2683 {
2684 // xyzw.parent = this;
John Bauman19bac1e2014-05-06 15:23:49 -04002685
Nicolas Capens13ac2322016-10-13 14:52:12 -04002686 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
2687 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(Short::getType(), 4))));
John Bauman19bac1e2014-05-06 15:23:49 -04002688
John Bauman66b8ab22014-05-06 15:57:45 -04002689 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman19bac1e2014-05-06 15:23:49 -04002690 }
2691
John Bauman89401822014-05-06 15:04:28 -04002692 Short4::Short4(short x, short y, short z, short w)
2693 {
2694 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002695
Nicolas Capens13ac2322016-10-13 14:52:12 -04002696 int64_t constantVector[4] = {x, y, z, w};
2697 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(Short::getType(), 4))));
John Bauman19bac1e2014-05-06 15:23:49 -04002698
John Bauman66b8ab22014-05-06 15:57:45 -04002699 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04002700 }
2701
John Bauman19bac1e2014-05-06 15:23:49 -04002702 Short4::Short4(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002703 {
2704 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002705
John Bauman66b8ab22014-05-06 15:57:45 -04002706 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002707 }
2708
2709 Short4::Short4(const Short4 &rhs)
2710 {
2711 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002712
John Bauman66b8ab22014-05-06 15:57:45 -04002713 Value *value = rhs.loadValue();
2714 storeValue(value);
2715 }
2716
2717 Short4::Short4(const Reference<Short4> &rhs)
2718 {
2719 // xyzw.parent = this;
2720
2721 Value *value = rhs.loadValue();
2722 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002723 }
2724
John Bauman19bac1e2014-05-06 15:23:49 -04002725 Short4::Short4(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002726 {
2727 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002728
John Bauman66b8ab22014-05-06 15:57:45 -04002729 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002730 }
2731
2732 Short4::Short4(const UShort4 &rhs)
2733 {
2734 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002735
John Bauman66b8ab22014-05-06 15:57:45 -04002736 storeValue(rhs.loadValue());
2737 }
2738
2739 Short4::Short4(const Reference<UShort4> &rhs)
2740 {
2741 // xyzw.parent = this;
2742
2743 storeValue(rhs.loadValue());
John Bauman89401822014-05-06 15:04:28 -04002744 }
2745
John Bauman19bac1e2014-05-06 15:23:49 -04002746 RValue<Short4> Short4::operator=(RValue<Short4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04002747 {
John Bauman66b8ab22014-05-06 15:57:45 -04002748 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002749
2750 return rhs;
2751 }
2752
2753 RValue<Short4> Short4::operator=(const Short4 &rhs) const
2754 {
John Bauman66b8ab22014-05-06 15:57:45 -04002755 Value *value = rhs.loadValue();
2756 storeValue(value);
2757
2758 return RValue<Short4>(value);
2759 }
2760
2761 RValue<Short4> Short4::operator=(const Reference<Short4> &rhs) const
2762 {
2763 Value *value = rhs.loadValue();
2764 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002765
2766 return RValue<Short4>(value);
2767 }
2768
John Bauman19bac1e2014-05-06 15:23:49 -04002769 RValue<Short4> Short4::operator=(RValue<UShort4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04002770 {
John Bauman66b8ab22014-05-06 15:57:45 -04002771 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002772
John Bauman66b8ab22014-05-06 15:57:45 -04002773 return RValue<Short4>(rhs);
John Bauman89401822014-05-06 15:04:28 -04002774 }
2775
2776 RValue<Short4> Short4::operator=(const UShort4 &rhs) const
2777 {
John Bauman66b8ab22014-05-06 15:57:45 -04002778 Value *value = rhs.loadValue();
2779 storeValue(value);
2780
2781 return RValue<Short4>(value);
2782 }
2783
2784 RValue<Short4> Short4::operator=(const Reference<UShort4> &rhs) const
2785 {
2786 Value *value = rhs.loadValue();
2787 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002788
2789 return RValue<Short4>(value);
2790 }
2791
John Bauman19bac1e2014-05-06 15:23:49 -04002792 RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002793 {
John Bauman19bac1e2014-05-06 15:23:49 -04002794 if(CPUID::supportsMMX2())
2795 {
2796 return x86::paddw(lhs, rhs);
2797 }
2798 else
2799 {
2800 return RValue<Short4>(Nucleus::createAdd(lhs.value, rhs.value));
2801 }
John Bauman89401822014-05-06 15:04:28 -04002802 }
2803
John Bauman19bac1e2014-05-06 15:23:49 -04002804 RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002805 {
John Bauman19bac1e2014-05-06 15:23:49 -04002806 if(CPUID::supportsMMX2())
2807 {
2808 return x86::psubw(lhs, rhs);
2809 }
2810 else
2811 {
2812 return RValue<Short4>(Nucleus::createSub(lhs.value, rhs.value));
2813 }
John Bauman89401822014-05-06 15:04:28 -04002814 }
2815
John Bauman19bac1e2014-05-06 15:23:49 -04002816 RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002817 {
John Bauman19bac1e2014-05-06 15:23:49 -04002818 if(CPUID::supportsMMX2())
2819 {
2820 return x86::pmullw(lhs, rhs);
2821 }
2822 else
2823 {
2824 return RValue<Short4>(Nucleus::createMul(lhs.value, rhs.value));
2825 }
John Bauman89401822014-05-06 15:04:28 -04002826 }
2827
John Bauman19bac1e2014-05-06 15:23:49 -04002828// RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs)
2829// {
2830// return RValue<Short4>(Nucleus::createSDiv(lhs.value, rhs.value));
2831// }
2832
2833// RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs)
2834// {
2835// return RValue<Short4>(Nucleus::createSRem(lhs.value, rhs.value));
2836// }
2837
2838 RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002839 {
John Bauman19bac1e2014-05-06 15:23:49 -04002840 if(CPUID::supportsMMX2())
2841 {
2842 return x86::pand(lhs, rhs);
2843 }
2844 else
2845 {
2846 return RValue<Short4>(Nucleus::createAnd(lhs.value, rhs.value));
2847 }
John Bauman89401822014-05-06 15:04:28 -04002848 }
2849
John Bauman19bac1e2014-05-06 15:23:49 -04002850 RValue<Short4> operator|(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002851 {
John Bauman19bac1e2014-05-06 15:23:49 -04002852 if(CPUID::supportsMMX2())
2853 {
2854 return x86::por(lhs, rhs);
2855 }
2856 else
2857 {
2858 return RValue<Short4>(Nucleus::createOr(lhs.value, rhs.value));
2859 }
John Bauman89401822014-05-06 15:04:28 -04002860 }
2861
John Bauman19bac1e2014-05-06 15:23:49 -04002862 RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002863 {
John Bauman19bac1e2014-05-06 15:23:49 -04002864 if(CPUID::supportsMMX2())
2865 {
2866 return x86::pxor(lhs, rhs);
2867 }
2868 else
2869 {
2870 return RValue<Short4>(Nucleus::createXor(lhs.value, rhs.value));
2871 }
John Bauman89401822014-05-06 15:04:28 -04002872 }
2873
John Bauman19bac1e2014-05-06 15:23:49 -04002874 RValue<Short4> operator<<(RValue<Short4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002875 {
2876 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
2877
2878 return x86::psllw(lhs, rhs);
2879 }
2880
John Bauman19bac1e2014-05-06 15:23:49 -04002881 RValue<Short4> operator>>(RValue<Short4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002882 {
2883 // return RValue<Short4>(Nucleus::createAShr(lhs.value, rhs.value));
2884
2885 return x86::psraw(lhs, rhs);
2886 }
2887
John Bauman19bac1e2014-05-06 15:23:49 -04002888 RValue<Short4> operator<<(RValue<Short4> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04002889 {
2890 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
2891
2892 return x86::psllw(lhs, rhs);
2893 }
2894
John Bauman19bac1e2014-05-06 15:23:49 -04002895 RValue<Short4> operator>>(RValue<Short4> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04002896 {
2897 // return RValue<Short4>(Nucleus::createAShr(lhs.value, rhs.value));
2898
2899 return x86::psraw(lhs, rhs);
2900 }
2901
John Bauman19bac1e2014-05-06 15:23:49 -04002902 RValue<Short4> operator+=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002903 {
2904 return lhs = lhs + rhs;
2905 }
2906
John Bauman19bac1e2014-05-06 15:23:49 -04002907 RValue<Short4> operator-=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002908 {
2909 return lhs = lhs - rhs;
2910 }
2911
John Bauman19bac1e2014-05-06 15:23:49 -04002912 RValue<Short4> operator*=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002913 {
2914 return lhs = lhs * rhs;
2915 }
2916
John Bauman19bac1e2014-05-06 15:23:49 -04002917// RValue<Short4> operator/=(const Short4 &lhs, RValue<Short4> rhs)
2918// {
2919// return lhs = lhs / rhs;
2920// }
John Bauman89401822014-05-06 15:04:28 -04002921
John Bauman19bac1e2014-05-06 15:23:49 -04002922// RValue<Short4> operator%=(const Short4 &lhs, RValue<Short4> rhs)
2923// {
2924// return lhs = lhs % rhs;
2925// }
John Bauman89401822014-05-06 15:04:28 -04002926
John Bauman19bac1e2014-05-06 15:23:49 -04002927 RValue<Short4> operator&=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002928 {
2929 return lhs = lhs & rhs;
2930 }
2931
John Bauman19bac1e2014-05-06 15:23:49 -04002932 RValue<Short4> operator|=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002933 {
2934 return lhs = lhs | rhs;
2935 }
2936
John Bauman19bac1e2014-05-06 15:23:49 -04002937 RValue<Short4> operator^=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002938 {
2939 return lhs = lhs ^ rhs;
2940 }
2941
2942 RValue<Short4> operator<<=(const Short4 &lhs, unsigned char rhs)
2943 {
2944 return lhs = lhs << rhs;
2945 }
2946
2947 RValue<Short4> operator>>=(const Short4 &lhs, unsigned char rhs)
2948 {
2949 return lhs = lhs >> rhs;
2950 }
2951
John Bauman19bac1e2014-05-06 15:23:49 -04002952 RValue<Short4> operator<<=(const Short4 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04002953 {
2954 return lhs = lhs << rhs;
2955 }
2956
John Bauman19bac1e2014-05-06 15:23:49 -04002957 RValue<Short4> operator>>=(const Short4 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04002958 {
2959 return lhs = lhs >> rhs;
2960 }
2961
John Bauman19bac1e2014-05-06 15:23:49 -04002962// RValue<Short4> operator+(RValue<Short4> val)
2963// {
2964// return val;
2965// }
2966
2967 RValue<Short4> operator-(RValue<Short4> val)
John Bauman89401822014-05-06 15:04:28 -04002968 {
John Bauman19bac1e2014-05-06 15:23:49 -04002969 if(CPUID::supportsMMX2())
2970 {
2971 return Short4(0, 0, 0, 0) - val;
2972 }
2973 else
2974 {
2975 return RValue<Short4>(Nucleus::createNeg(val.value));
2976 }
John Bauman89401822014-05-06 15:04:28 -04002977 }
2978
John Bauman19bac1e2014-05-06 15:23:49 -04002979 RValue<Short4> operator~(RValue<Short4> val)
John Bauman89401822014-05-06 15:04:28 -04002980 {
John Bauman19bac1e2014-05-06 15:23:49 -04002981 if(CPUID::supportsMMX2())
2982 {
2983 return val ^ Short4(0xFFFFu, 0xFFFFu, 0xFFFFu, 0xFFFFu);
2984 }
2985 else
2986 {
2987 return RValue<Short4>(Nucleus::createNot(val.value));
2988 }
John Bauman89401822014-05-06 15:04:28 -04002989 }
2990
John Bauman19bac1e2014-05-06 15:23:49 -04002991 RValue<Short4> RoundShort4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04002992 {
2993 RValue<Int4> v4i32 = x86::cvtps2dq(cast);
Nicolas Capens698633a2015-02-04 00:16:13 -05002994 RValue<Short8> v8i16 = x86::packssdw(v4i32, v4i32);
John Bauman66b8ab22014-05-06 15:57:45 -04002995
Nicolas Capens698633a2015-02-04 00:16:13 -05002996 return As<Short4>(Int2(As<Int4>(v8i16)));
John Bauman89401822014-05-06 15:04:28 -04002997 }
2998
John Bauman19bac1e2014-05-06 15:23:49 -04002999 RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003000 {
3001 return x86::pmaxsw(x, y);
3002 }
3003
John Bauman19bac1e2014-05-06 15:23:49 -04003004 RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003005 {
3006 return x86::pminsw(x, y);
3007 }
3008
John Bauman19bac1e2014-05-06 15:23:49 -04003009 RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003010 {
3011 return x86::paddsw(x, y);
3012 }
3013
John Bauman19bac1e2014-05-06 15:23:49 -04003014 RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003015 {
3016 return x86::psubsw(x, y);
3017 }
3018
John Bauman19bac1e2014-05-06 15:23:49 -04003019 RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003020 {
3021 return x86::pmulhw(x, y);
3022 }
3023
John Bauman19bac1e2014-05-06 15:23:49 -04003024 RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003025 {
3026 return x86::pmaddwd(x, y);
3027 }
3028
John Bauman19bac1e2014-05-06 15:23:49 -04003029 RValue<SByte8> Pack(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003030 {
3031 return x86::packsswb(x, y);
3032 }
3033
John Bauman19bac1e2014-05-06 15:23:49 -04003034 RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003035 {
John Bauman19bac1e2014-05-06 15:23:49 -04003036 if(CPUID::supportsMMX2())
3037 {
3038 return x86::punpcklwd(x, y);
3039 }
3040 else
3041 {
Nicolas Capense89cd582016-09-30 14:23:47 -04003042 int shuffle[4] = {0, 4, 1, 5};
3043 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04003044
John Bauman19bac1e2014-05-06 15:23:49 -04003045 return RValue<Int2>(Nucleus::createBitCast(packed, Int2::getType()));
3046 }
John Bauman89401822014-05-06 15:04:28 -04003047 }
3048
John Bauman19bac1e2014-05-06 15:23:49 -04003049 RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003050 {
John Bauman19bac1e2014-05-06 15:23:49 -04003051 if(CPUID::supportsMMX2())
3052 {
3053 return x86::punpckhwd(x, y);
3054 }
3055 else
3056 {
Nicolas Capense89cd582016-09-30 14:23:47 -04003057 int shuffle[4] = {2, 6, 3, 7};
3058 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04003059
John Bauman19bac1e2014-05-06 15:23:49 -04003060 return RValue<Int2>(Nucleus::createBitCast(packed, Int2::getType()));
3061 }
John Bauman89401822014-05-06 15:04:28 -04003062 }
3063
John Bauman19bac1e2014-05-06 15:23:49 -04003064 RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04003065 {
John Bauman19bac1e2014-05-06 15:23:49 -04003066 if(CPUID::supportsMMX2())
3067 {
3068 return x86::pshufw(x, select);
3069 }
3070 else
3071 {
Nicolas Capense95d5342016-09-30 11:37:28 -04003072 return RValue<Short4>(createSwizzle4(x.value, select));
John Bauman19bac1e2014-05-06 15:23:49 -04003073 }
John Bauman89401822014-05-06 15:04:28 -04003074 }
3075
John Bauman19bac1e2014-05-06 15:23:49 -04003076 RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i)
John Bauman89401822014-05-06 15:04:28 -04003077 {
John Bauman19bac1e2014-05-06 15:23:49 -04003078 if(CPUID::supportsMMX2())
3079 {
3080 return x86::pinsrw(val, Int(element), i);
3081 }
3082 else
3083 {
3084 return RValue<Short4>(Nucleus::createInsertElement(val.value, element.value, i));
3085 }
John Bauman89401822014-05-06 15:04:28 -04003086 }
3087
John Bauman19bac1e2014-05-06 15:23:49 -04003088 RValue<Short> Extract(RValue<Short4> val, int i)
John Bauman89401822014-05-06 15:04:28 -04003089 {
John Bauman19bac1e2014-05-06 15:23:49 -04003090 if(CPUID::supportsMMX2())
3091 {
3092 return Short(x86::pextrw(val, i));
3093 }
3094 else
3095 {
Nicolas Capense95d5342016-09-30 11:37:28 -04003096 return RValue<Short>(Nucleus::createExtractElement(val.value, Short::getType(), i));
John Bauman19bac1e2014-05-06 15:23:49 -04003097 }
John Bauman89401822014-05-06 15:04:28 -04003098 }
3099
John Bauman19bac1e2014-05-06 15:23:49 -04003100 RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003101 {
3102 return x86::pcmpgtw(x, y);
3103 }
3104
John Bauman19bac1e2014-05-06 15:23:49 -04003105 RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003106 {
3107 return x86::pcmpeqw(x, y);
3108 }
3109
John Bauman19bac1e2014-05-06 15:23:49 -04003110 Type *Short4::getType()
John Bauman89401822014-05-06 15:04:28 -04003111 {
John Bauman19bac1e2014-05-06 15:23:49 -04003112 if(CPUID::supportsMMX2())
3113 {
3114 return MMX::getType();
3115 }
3116 else
3117 {
Nicolas Capensac230122016-09-20 14:30:06 -04003118 return T(VectorType::get(Short::getType(), 4));
John Bauman19bac1e2014-05-06 15:23:49 -04003119 }
John Bauman89401822014-05-06 15:04:28 -04003120 }
3121
John Bauman19bac1e2014-05-06 15:23:49 -04003122 UShort4::UShort4(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04003123 {
John Bauman89401822014-05-06 15:04:28 -04003124 *this = Short4(cast);
3125 }
3126
John Bauman19bac1e2014-05-06 15:23:49 -04003127 UShort4::UShort4(RValue<Float4> cast, bool saturate)
John Bauman89401822014-05-06 15:04:28 -04003128 {
John Bauman89401822014-05-06 15:04:28 -04003129 Float4 sat;
3130
3131 if(saturate)
3132 {
3133 if(CPUID::supportsSSE4_1())
3134 {
3135 sat = Min(cast, Float4(0xFFFF)); // packusdw takes care of 0x0000 saturation
3136 }
3137 else
3138 {
3139 sat = Max(Min(cast, Float4(0xFFFF)), Float4(0x0000));
3140 }
3141 }
3142 else
3143 {
3144 sat = cast;
3145 }
3146
3147 Int4 int4(sat);
3148
3149 if(!saturate || !CPUID::supportsSSE4_1())
3150 {
3151 *this = Short4(Int4(int4));
3152 }
3153 else
3154 {
3155 *this = As<Short4>(Int2(As<Int4>(x86::packusdw(As<UInt4>(int4), As<UInt4>(int4)))));
3156 }
3157 }
3158
3159 UShort4::UShort4()
3160 {
3161 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003162 }
3163
Alexis Hetu90c7ad62016-06-27 11:50:40 -04003164 UShort4::UShort4(unsigned short xyzw)
3165 {
3166 // xyzw.parent = this;
3167
Nicolas Capens13ac2322016-10-13 14:52:12 -04003168 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
3169 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(UShort::getType(), 4))));
Alexis Hetu90c7ad62016-06-27 11:50:40 -04003170
3171 storeValue(Nucleus::createBitCast(vector, getType()));
3172 }
3173
John Bauman89401822014-05-06 15:04:28 -04003174 UShort4::UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w)
3175 {
3176 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003177
Nicolas Capens13ac2322016-10-13 14:52:12 -04003178 int64_t constantVector[4] = {x, y, z, w};
3179 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(UShort::getType(), 4))));
John Bauman89401822014-05-06 15:04:28 -04003180
John Bauman66b8ab22014-05-06 15:57:45 -04003181 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04003182 }
3183
John Bauman19bac1e2014-05-06 15:23:49 -04003184 UShort4::UShort4(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003185 {
3186 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003187
John Bauman66b8ab22014-05-06 15:57:45 -04003188 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003189 }
3190
3191 UShort4::UShort4(const UShort4 &rhs)
3192 {
3193 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003194
John Bauman66b8ab22014-05-06 15:57:45 -04003195 Value *value = rhs.loadValue();
3196 storeValue(value);
3197 }
3198
3199 UShort4::UShort4(const Reference<UShort4> &rhs)
3200 {
3201 // xyzw.parent = this;
3202
3203 Value *value = rhs.loadValue();
3204 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003205 }
3206
John Bauman19bac1e2014-05-06 15:23:49 -04003207 UShort4::UShort4(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003208 {
3209 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003210
John Bauman66b8ab22014-05-06 15:57:45 -04003211 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003212 }
3213
3214 UShort4::UShort4(const Short4 &rhs)
3215 {
3216 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003217
John Bauman66b8ab22014-05-06 15:57:45 -04003218 Value *value = rhs.loadValue();
3219 storeValue(value);
3220 }
3221
3222 UShort4::UShort4(const Reference<Short4> &rhs)
3223 {
3224 // xyzw.parent = this;
3225
3226 Value *value = rhs.loadValue();
3227 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003228 }
3229
John Bauman19bac1e2014-05-06 15:23:49 -04003230 RValue<UShort4> UShort4::operator=(RValue<UShort4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04003231 {
John Bauman66b8ab22014-05-06 15:57:45 -04003232 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003233
3234 return rhs;
3235 }
3236
3237 RValue<UShort4> UShort4::operator=(const UShort4 &rhs) const
3238 {
John Bauman66b8ab22014-05-06 15:57:45 -04003239 Value *value = rhs.loadValue();
3240 storeValue(value);
3241
3242 return RValue<UShort4>(value);
3243 }
3244
3245 RValue<UShort4> UShort4::operator=(const Reference<UShort4> &rhs) const
3246 {
3247 Value *value = rhs.loadValue();
3248 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003249
3250 return RValue<UShort4>(value);
3251 }
3252
John Bauman19bac1e2014-05-06 15:23:49 -04003253 RValue<UShort4> UShort4::operator=(RValue<Short4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04003254 {
John Bauman66b8ab22014-05-06 15:57:45 -04003255 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003256
John Bauman66b8ab22014-05-06 15:57:45 -04003257 return RValue<UShort4>(rhs);
John Bauman89401822014-05-06 15:04:28 -04003258 }
3259
3260 RValue<UShort4> UShort4::operator=(const Short4 &rhs) const
3261 {
John Bauman66b8ab22014-05-06 15:57:45 -04003262 Value *value = rhs.loadValue();
3263 storeValue(value);
3264
3265 return RValue<UShort4>(value);
3266 }
3267
3268 RValue<UShort4> UShort4::operator=(const Reference<Short4> &rhs) const
3269 {
3270 Value *value = rhs.loadValue();
3271 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003272
3273 return RValue<UShort4>(value);
3274 }
3275
John Bauman19bac1e2014-05-06 15:23:49 -04003276 RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003277 {
John Bauman19bac1e2014-05-06 15:23:49 -04003278 if(CPUID::supportsMMX2())
3279 {
3280 return As<UShort4>(x86::paddw(As<Short4>(lhs), As<Short4>(rhs)));
3281 }
3282 else
3283 {
3284 return RValue<UShort4>(Nucleus::createAdd(lhs.value, rhs.value));
3285 }
John Bauman89401822014-05-06 15:04:28 -04003286 }
3287
John Bauman19bac1e2014-05-06 15:23:49 -04003288 RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003289 {
John Bauman19bac1e2014-05-06 15:23:49 -04003290 if(CPUID::supportsMMX2())
3291 {
3292 return As<UShort4>(x86::psubw(As<Short4>(lhs), As<Short4>(rhs)));
3293 }
3294 else
3295 {
3296 return RValue<UShort4>(Nucleus::createSub(lhs.value, rhs.value));
3297 }
John Bauman89401822014-05-06 15:04:28 -04003298 }
3299
John Bauman19bac1e2014-05-06 15:23:49 -04003300 RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003301 {
John Bauman19bac1e2014-05-06 15:23:49 -04003302 if(CPUID::supportsMMX2())
3303 {
3304 return As<UShort4>(x86::pmullw(As<Short4>(lhs), As<Short4>(rhs)));
3305 }
3306 else
3307 {
3308 return RValue<UShort4>(Nucleus::createMul(lhs.value, rhs.value));
3309 }
John Bauman89401822014-05-06 15:04:28 -04003310 }
3311
Nicolas Capens16b5f152016-10-13 13:39:01 -04003312 RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs)
3313 {
3314 if(CPUID::supportsMMX2())
3315 {
3316 return As<UShort4>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
3317 }
3318 else
3319 {
3320 return RValue<UShort4>(Nucleus::createAnd(lhs.value, rhs.value));
3321 }
3322 }
3323
3324 RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs)
3325 {
3326 if(CPUID::supportsMMX2())
3327 {
3328 return As<UShort4>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
3329 }
3330 else
3331 {
3332 return RValue<UShort4>(Nucleus::createOr(lhs.value, rhs.value));
3333 }
3334 }
3335
3336 RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs)
3337 {
3338 if(CPUID::supportsMMX2())
3339 {
3340 return As<UShort4>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
3341 }
3342 else
3343 {
3344 return RValue<UShort4>(Nucleus::createXor(lhs.value, rhs.value));
3345 }
3346 }
3347
John Bauman19bac1e2014-05-06 15:23:49 -04003348 RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003349 {
3350 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
3351
3352 return As<UShort4>(x86::psllw(As<Short4>(lhs), rhs));
3353 }
3354
John Bauman19bac1e2014-05-06 15:23:49 -04003355 RValue<UShort4> operator>>(RValue<UShort4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003356 {
3357 // return RValue<Short4>(Nucleus::createLShr(lhs.value, rhs.value));
3358
3359 return x86::psrlw(lhs, rhs);
3360 }
3361
John Bauman19bac1e2014-05-06 15:23:49 -04003362 RValue<UShort4> operator<<(RValue<UShort4> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04003363 {
3364 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
3365
3366 return As<UShort4>(x86::psllw(As<Short4>(lhs), rhs));
3367 }
3368
John Bauman19bac1e2014-05-06 15:23:49 -04003369 RValue<UShort4> operator>>(RValue<UShort4> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04003370 {
3371 // return RValue<Short4>(Nucleus::createLShr(lhs.value, rhs.value));
3372
3373 return x86::psrlw(lhs, rhs);
3374 }
3375
3376 RValue<UShort4> operator<<=(const UShort4 &lhs, unsigned char rhs)
3377 {
3378 return lhs = lhs << rhs;
3379 }
3380
3381 RValue<UShort4> operator>>=(const UShort4 &lhs, unsigned char rhs)
3382 {
3383 return lhs = lhs >> rhs;
3384 }
3385
John Bauman19bac1e2014-05-06 15:23:49 -04003386 RValue<UShort4> operator<<=(const UShort4 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04003387 {
3388 return lhs = lhs << rhs;
3389 }
3390
John Bauman19bac1e2014-05-06 15:23:49 -04003391 RValue<UShort4> operator>>=(const UShort4 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04003392 {
3393 return lhs = lhs >> rhs;
3394 }
3395
John Bauman19bac1e2014-05-06 15:23:49 -04003396 RValue<UShort4> operator~(RValue<UShort4> val)
John Bauman89401822014-05-06 15:04:28 -04003397 {
John Bauman19bac1e2014-05-06 15:23:49 -04003398 if(CPUID::supportsMMX2())
3399 {
3400 return As<UShort4>(As<Short4>(val) ^ Short4(0xFFFFu, 0xFFFFu, 0xFFFFu, 0xFFFFu));
3401 }
3402 else
3403 {
3404 return RValue<UShort4>(Nucleus::createNot(val.value));
3405 }
John Bauman89401822014-05-06 15:04:28 -04003406 }
3407
John Bauman19bac1e2014-05-06 15:23:49 -04003408 RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003409 {
John Bauman66b8ab22014-05-06 15:57:45 -04003410 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 -04003411 }
3412
John Bauman19bac1e2014-05-06 15:23:49 -04003413 RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003414 {
John Bauman66b8ab22014-05-06 15:57:45 -04003415 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 -04003416 }
3417
John Bauman19bac1e2014-05-06 15:23:49 -04003418 RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003419 {
3420 return x86::paddusw(x, y);
3421 }
3422
John Bauman19bac1e2014-05-06 15:23:49 -04003423 RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003424 {
3425 return x86::psubusw(x, y);
3426 }
3427
John Bauman19bac1e2014-05-06 15:23:49 -04003428 RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003429 {
3430 return x86::pmulhuw(x, y);
3431 }
3432
John Bauman19bac1e2014-05-06 15:23:49 -04003433 RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003434 {
3435 return x86::pavgw(x, y);
3436 }
3437
John Bauman19bac1e2014-05-06 15:23:49 -04003438 RValue<Byte8> Pack(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003439 {
3440 return x86::packuswb(x, y);
3441 }
3442
John Bauman19bac1e2014-05-06 15:23:49 -04003443 Type *UShort4::getType()
John Bauman89401822014-05-06 15:04:28 -04003444 {
John Bauman19bac1e2014-05-06 15:23:49 -04003445 if(CPUID::supportsMMX2())
3446 {
3447 return MMX::getType();
3448 }
3449 else
3450 {
Nicolas Capensac230122016-09-20 14:30:06 -04003451 return T(VectorType::get(UShort::getType(), 4));
John Bauman19bac1e2014-05-06 15:23:49 -04003452 }
John Bauman89401822014-05-06 15:04:28 -04003453 }
3454
3455 Short8::Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7)
3456 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04003457 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
3458 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04003459 }
3460
John Bauman19bac1e2014-05-06 15:23:49 -04003461 Short8::Short8(RValue<Short8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003462 {
John Bauman66b8ab22014-05-06 15:57:45 -04003463 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003464 }
3465
Nicolas Capensef8cd662016-06-30 15:34:40 -04003466 Short8::Short8(const Reference<Short8> &rhs)
3467 {
Nicolas Capensef8cd662016-06-30 15:34:40 -04003468 Value *value = rhs.loadValue();
3469 storeValue(value);
3470 }
3471
Nicolas Capens62abb552016-01-05 12:03:47 -05003472 Short8::Short8(RValue<Short4> lo, RValue<Short4> hi)
3473 {
3474 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
3475 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
3476
Nicolas Capens22008782016-10-20 01:11:47 -04003477 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Nicolas Capens62abb552016-01-05 12:03:47 -05003478 long2 = Nucleus::createInsertElement(long2, loLong, 0);
3479 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
3480 Value *short8 = Nucleus::createBitCast(long2, Short8::getType());
3481
3482 storeValue(short8);
3483 }
3484
John Bauman19bac1e2014-05-06 15:23:49 -04003485 RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003486 {
3487 return RValue<Short8>(Nucleus::createAdd(lhs.value, rhs.value));
3488 }
3489
John Bauman19bac1e2014-05-06 15:23:49 -04003490 RValue<Short8> operator&(RValue<Short8> lhs, RValue<Short8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003491 {
3492 return RValue<Short8>(Nucleus::createAnd(lhs.value, rhs.value));
3493 }
3494
John Bauman19bac1e2014-05-06 15:23:49 -04003495 RValue<Short8> operator<<(RValue<Short8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003496 {
3497 return x86::psllw(lhs, rhs); // FIXME: Fallback required
3498 }
3499
John Bauman19bac1e2014-05-06 15:23:49 -04003500 RValue<Short8> operator>>(RValue<Short8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003501 {
3502 return x86::psraw(lhs, rhs); // FIXME: Fallback required
3503 }
3504
John Bauman19bac1e2014-05-06 15:23:49 -04003505 RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04003506 {
3507 return x86::pmaddwd(x, y); // FIXME: Fallback required
3508 }
3509
Alexis Hetu0f448072016-03-18 10:56:08 -04003510 RValue<Int4> Abs(RValue<Int4> x)
3511 {
3512 if(CPUID::supportsSSSE3())
3513 {
3514 return x86::pabsd(x);
3515 }
3516 else
3517 {
3518 Int4 mask = (x >> 31);
3519 return (mask ^ x) - mask;
3520 }
3521 }
3522
John Bauman19bac1e2014-05-06 15:23:49 -04003523 RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04003524 {
3525 return x86::pmulhw(x, y); // FIXME: Fallback required
3526 }
3527
John Bauman19bac1e2014-05-06 15:23:49 -04003528 Type *Short8::getType()
John Bauman89401822014-05-06 15:04:28 -04003529 {
Nicolas Capensac230122016-09-20 14:30:06 -04003530 return T(VectorType::get(Short::getType(), 8));
John Bauman89401822014-05-06 15:04:28 -04003531 }
3532
3533 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)
3534 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04003535 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
3536 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04003537 }
3538
John Bauman19bac1e2014-05-06 15:23:49 -04003539 UShort8::UShort8(RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003540 {
John Bauman66b8ab22014-05-06 15:57:45 -04003541 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003542 }
3543
Nicolas Capensef8cd662016-06-30 15:34:40 -04003544 UShort8::UShort8(const Reference<UShort8> &rhs)
3545 {
Nicolas Capensef8cd662016-06-30 15:34:40 -04003546 Value *value = rhs.loadValue();
3547 storeValue(value);
3548 }
3549
Nicolas Capens62abb552016-01-05 12:03:47 -05003550 UShort8::UShort8(RValue<UShort4> lo, RValue<UShort4> hi)
3551 {
3552 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
3553 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
3554
Nicolas Capens22008782016-10-20 01:11:47 -04003555 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Nicolas Capens62abb552016-01-05 12:03:47 -05003556 long2 = Nucleus::createInsertElement(long2, loLong, 0);
3557 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
3558 Value *short8 = Nucleus::createBitCast(long2, Short8::getType());
3559
3560 storeValue(short8);
3561 }
3562
John Bauman19bac1e2014-05-06 15:23:49 -04003563 RValue<UShort8> UShort8::operator=(RValue<UShort8> rhs) const
John Bauman89401822014-05-06 15:04:28 -04003564 {
John Bauman66b8ab22014-05-06 15:57:45 -04003565 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003566
3567 return rhs;
3568 }
3569
3570 RValue<UShort8> UShort8::operator=(const UShort8 &rhs) const
3571 {
John Bauman66b8ab22014-05-06 15:57:45 -04003572 Value *value = rhs.loadValue();
3573 storeValue(value);
3574
3575 return RValue<UShort8>(value);
3576 }
3577
3578 RValue<UShort8> UShort8::operator=(const Reference<UShort8> &rhs) const
3579 {
3580 Value *value = rhs.loadValue();
3581 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003582
3583 return RValue<UShort8>(value);
3584 }
3585
John Bauman19bac1e2014-05-06 15:23:49 -04003586 RValue<UShort8> operator&(RValue<UShort8> lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003587 {
3588 return RValue<UShort8>(Nucleus::createAnd(lhs.value, rhs.value));
3589 }
3590
John Bauman19bac1e2014-05-06 15:23:49 -04003591 RValue<UShort8> operator<<(RValue<UShort8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003592 {
3593 return As<UShort8>(x86::psllw(As<Short8>(lhs), rhs)); // FIXME: Fallback required
3594 }
3595
John Bauman19bac1e2014-05-06 15:23:49 -04003596 RValue<UShort8> operator>>(RValue<UShort8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003597 {
3598 return x86::psrlw(lhs, rhs); // FIXME: Fallback required
3599 }
3600
John Bauman19bac1e2014-05-06 15:23:49 -04003601 RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003602 {
3603 return RValue<UShort8>(Nucleus::createAdd(lhs.value, rhs.value));
3604 }
3605
John Bauman19bac1e2014-05-06 15:23:49 -04003606 RValue<UShort8> operator*(RValue<UShort8> lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003607 {
3608 return RValue<UShort8>(Nucleus::createMul(lhs.value, rhs.value));
3609 }
3610
John Bauman19bac1e2014-05-06 15:23:49 -04003611 RValue<UShort8> operator+=(const UShort8 &lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003612 {
3613 return lhs = lhs + rhs;
3614 }
3615
John Bauman19bac1e2014-05-06 15:23:49 -04003616 RValue<UShort8> operator~(RValue<UShort8> val)
John Bauman89401822014-05-06 15:04:28 -04003617 {
3618 return RValue<UShort8>(Nucleus::createNot(val.value));
3619 }
3620
John Bauman19bac1e2014-05-06 15:23:49 -04003621 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 -04003622 {
Nicolas Capense89cd582016-09-30 14:23:47 -04003623 int pshufb[16] =
3624 {
3625 select0 + 0,
3626 select0 + 1,
3627 select1 + 0,
3628 select1 + 1,
3629 select2 + 0,
3630 select2 + 1,
3631 select3 + 0,
3632 select3 + 1,
3633 select4 + 0,
3634 select4 + 1,
3635 select5 + 0,
3636 select5 + 1,
3637 select6 + 0,
3638 select6 + 1,
3639 select7 + 0,
3640 select7 + 1,
3641 };
John Bauman89401822014-05-06 15:04:28 -04003642
3643 Value *byte16 = Nucleus::createBitCast(x.value, Byte16::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04003644 Value *shuffle = Nucleus::createShuffleVector(byte16, byte16, pshufb);
John Bauman89401822014-05-06 15:04:28 -04003645 Value *short8 = Nucleus::createBitCast(shuffle, UShort8::getType());
3646
3647 return RValue<UShort8>(short8);
3648 }
3649
John Bauman19bac1e2014-05-06 15:23:49 -04003650 RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y)
John Bauman89401822014-05-06 15:04:28 -04003651 {
3652 return x86::pmulhuw(x, y); // FIXME: Fallback required
3653 }
3654
John Bauman19bac1e2014-05-06 15:23:49 -04003655 Type *UShort8::getType()
John Bauman89401822014-05-06 15:04:28 -04003656 {
Nicolas Capensac230122016-09-20 14:30:06 -04003657 return T(VectorType::get(UShort::getType(), 8));
John Bauman89401822014-05-06 15:04:28 -04003658 }
3659
Nicolas Capens81f18302016-01-14 09:32:35 -05003660 Int::Int(Argument<Int> argument)
John Bauman89401822014-05-06 15:04:28 -04003661 {
Nicolas Capens81f18302016-01-14 09:32:35 -05003662 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04003663 }
3664
John Bauman19bac1e2014-05-06 15:23:49 -04003665 Int::Int(RValue<Byte> cast)
John Bauman89401822014-05-06 15:04:28 -04003666 {
John Bauman89401822014-05-06 15:04:28 -04003667 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3668
John Bauman66b8ab22014-05-06 15:57:45 -04003669 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003670 }
3671
John Bauman19bac1e2014-05-06 15:23:49 -04003672 Int::Int(RValue<SByte> cast)
John Bauman89401822014-05-06 15:04:28 -04003673 {
John Bauman89401822014-05-06 15:04:28 -04003674 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3675
John Bauman66b8ab22014-05-06 15:57:45 -04003676 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003677 }
3678
John Bauman19bac1e2014-05-06 15:23:49 -04003679 Int::Int(RValue<Short> cast)
John Bauman89401822014-05-06 15:04:28 -04003680 {
John Bauman89401822014-05-06 15:04:28 -04003681 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3682
John Bauman66b8ab22014-05-06 15:57:45 -04003683 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003684 }
3685
John Bauman19bac1e2014-05-06 15:23:49 -04003686 Int::Int(RValue<UShort> cast)
John Bauman89401822014-05-06 15:04:28 -04003687 {
John Bauman89401822014-05-06 15:04:28 -04003688 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3689
John Bauman66b8ab22014-05-06 15:57:45 -04003690 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003691 }
3692
John Bauman19bac1e2014-05-06 15:23:49 -04003693 Int::Int(RValue<Int2> cast)
John Bauman89401822014-05-06 15:04:28 -04003694 {
John Bauman89401822014-05-06 15:04:28 -04003695 *this = Extract(cast, 0);
3696 }
3697
John Bauman19bac1e2014-05-06 15:23:49 -04003698 Int::Int(RValue<Long> cast)
John Bauman89401822014-05-06 15:04:28 -04003699 {
John Bauman89401822014-05-06 15:04:28 -04003700 Value *integer = Nucleus::createTrunc(cast.value, Int::getType());
3701
John Bauman66b8ab22014-05-06 15:57:45 -04003702 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003703 }
3704
John Bauman19bac1e2014-05-06 15:23:49 -04003705 Int::Int(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04003706 {
John Bauman89401822014-05-06 15:04:28 -04003707 Value *integer = Nucleus::createFPToSI(cast.value, Int::getType());
3708
John Bauman66b8ab22014-05-06 15:57:45 -04003709 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003710 }
3711
3712 Int::Int()
3713 {
John Bauman89401822014-05-06 15:04:28 -04003714 }
3715
3716 Int::Int(int x)
3717 {
John Bauman66b8ab22014-05-06 15:57:45 -04003718 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04003719 }
3720
John Bauman19bac1e2014-05-06 15:23:49 -04003721 Int::Int(RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003722 {
John Bauman66b8ab22014-05-06 15:57:45 -04003723 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003724 }
3725
John Bauman19bac1e2014-05-06 15:23:49 -04003726 Int::Int(RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04003727 {
John Bauman66b8ab22014-05-06 15:57:45 -04003728 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003729 }
3730
3731 Int::Int(const Int &rhs)
3732 {
John Bauman66b8ab22014-05-06 15:57:45 -04003733 Value *value = rhs.loadValue();
3734 storeValue(value);
3735 }
John Bauman89401822014-05-06 15:04:28 -04003736
John Bauman66b8ab22014-05-06 15:57:45 -04003737 Int::Int(const Reference<Int> &rhs)
3738 {
3739 Value *value = rhs.loadValue();
3740 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003741 }
3742
3743 Int::Int(const UInt &rhs)
3744 {
John Bauman66b8ab22014-05-06 15:57:45 -04003745 Value *value = rhs.loadValue();
3746 storeValue(value);
3747 }
John Bauman89401822014-05-06 15:04:28 -04003748
John Bauman66b8ab22014-05-06 15:57:45 -04003749 Int::Int(const Reference<UInt> &rhs)
3750 {
3751 Value *value = rhs.loadValue();
3752 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003753 }
3754
3755 RValue<Int> Int::operator=(int rhs) const
3756 {
John Bauman66b8ab22014-05-06 15:57:45 -04003757 return RValue<Int>(storeValue(Nucleus::createConstantInt(rhs)));
John Bauman89401822014-05-06 15:04:28 -04003758 }
3759
John Bauman19bac1e2014-05-06 15:23:49 -04003760 RValue<Int> Int::operator=(RValue<Int> rhs) const
John Bauman89401822014-05-06 15:04:28 -04003761 {
John Bauman66b8ab22014-05-06 15:57:45 -04003762 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003763
3764 return rhs;
3765 }
3766
John Bauman19bac1e2014-05-06 15:23:49 -04003767 RValue<Int> Int::operator=(RValue<UInt> rhs) const
John Bauman89401822014-05-06 15:04:28 -04003768 {
John Bauman66b8ab22014-05-06 15:57:45 -04003769 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003770
John Bauman66b8ab22014-05-06 15:57:45 -04003771 return RValue<Int>(rhs);
John Bauman89401822014-05-06 15:04:28 -04003772 }
3773
3774 RValue<Int> Int::operator=(const Int &rhs) const
3775 {
John Bauman66b8ab22014-05-06 15:57:45 -04003776 Value *value = rhs.loadValue();
3777 storeValue(value);
3778
3779 return RValue<Int>(value);
3780 }
3781
3782 RValue<Int> Int::operator=(const Reference<Int> &rhs) const
3783 {
3784 Value *value = rhs.loadValue();
3785 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003786
3787 return RValue<Int>(value);
3788 }
3789
3790 RValue<Int> Int::operator=(const UInt &rhs) const
3791 {
John Bauman66b8ab22014-05-06 15:57:45 -04003792 Value *value = rhs.loadValue();
3793 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003794
3795 return RValue<Int>(value);
3796 }
3797
John Bauman66b8ab22014-05-06 15:57:45 -04003798 RValue<Int> Int::operator=(const Reference<UInt> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04003799 {
John Bauman66b8ab22014-05-06 15:57:45 -04003800 Value *value = rhs.loadValue();
3801 storeValue(value);
3802
3803 return RValue<Int>(value);
John Bauman89401822014-05-06 15:04:28 -04003804 }
3805
John Bauman19bac1e2014-05-06 15:23:49 -04003806 RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003807 {
3808 return RValue<Int>(Nucleus::createAdd(lhs.value, rhs.value));
3809 }
3810
John Bauman19bac1e2014-05-06 15:23:49 -04003811 RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003812 {
3813 return RValue<Int>(Nucleus::createSub(lhs.value, rhs.value));
3814 }
3815
John Bauman19bac1e2014-05-06 15:23:49 -04003816 RValue<Int> operator*(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003817 {
3818 return RValue<Int>(Nucleus::createMul(lhs.value, rhs.value));
3819 }
3820
John Bauman19bac1e2014-05-06 15:23:49 -04003821 RValue<Int> operator/(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003822 {
3823 return RValue<Int>(Nucleus::createSDiv(lhs.value, rhs.value));
3824 }
3825
John Bauman19bac1e2014-05-06 15:23:49 -04003826 RValue<Int> operator%(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003827 {
3828 return RValue<Int>(Nucleus::createSRem(lhs.value, rhs.value));
3829 }
3830
John Bauman19bac1e2014-05-06 15:23:49 -04003831 RValue<Int> operator&(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003832 {
3833 return RValue<Int>(Nucleus::createAnd(lhs.value, rhs.value));
3834 }
3835
John Bauman19bac1e2014-05-06 15:23:49 -04003836 RValue<Int> operator|(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003837 {
3838 return RValue<Int>(Nucleus::createOr(lhs.value, rhs.value));
3839 }
3840
John Bauman19bac1e2014-05-06 15:23:49 -04003841 RValue<Int> operator^(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003842 {
3843 return RValue<Int>(Nucleus::createXor(lhs.value, rhs.value));
3844 }
3845
John Bauman19bac1e2014-05-06 15:23:49 -04003846 RValue<Int> operator<<(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003847 {
3848 return RValue<Int>(Nucleus::createShl(lhs.value, rhs.value));
3849 }
3850
John Bauman19bac1e2014-05-06 15:23:49 -04003851 RValue<Int> operator>>(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003852 {
3853 return RValue<Int>(Nucleus::createAShr(lhs.value, rhs.value));
3854 }
3855
John Bauman19bac1e2014-05-06 15:23:49 -04003856 RValue<Int> operator+=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003857 {
3858 return lhs = lhs + rhs;
3859 }
3860
John Bauman19bac1e2014-05-06 15:23:49 -04003861 RValue<Int> operator-=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003862 {
3863 return lhs = lhs - rhs;
3864 }
3865
John Bauman19bac1e2014-05-06 15:23:49 -04003866 RValue<Int> operator*=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003867 {
3868 return lhs = lhs * rhs;
3869 }
3870
John Bauman19bac1e2014-05-06 15:23:49 -04003871 RValue<Int> operator/=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003872 {
3873 return lhs = lhs / rhs;
3874 }
3875
John Bauman19bac1e2014-05-06 15:23:49 -04003876 RValue<Int> operator%=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003877 {
3878 return lhs = lhs % rhs;
3879 }
3880
John Bauman19bac1e2014-05-06 15:23:49 -04003881 RValue<Int> operator&=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003882 {
3883 return lhs = lhs & rhs;
3884 }
3885
John Bauman19bac1e2014-05-06 15:23:49 -04003886 RValue<Int> operator|=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003887 {
3888 return lhs = lhs | rhs;
3889 }
3890
John Bauman19bac1e2014-05-06 15:23:49 -04003891 RValue<Int> operator^=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003892 {
3893 return lhs = lhs ^ rhs;
3894 }
3895
John Bauman19bac1e2014-05-06 15:23:49 -04003896 RValue<Int> operator<<=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003897 {
3898 return lhs = lhs << rhs;
3899 }
3900
John Bauman19bac1e2014-05-06 15:23:49 -04003901 RValue<Int> operator>>=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003902 {
3903 return lhs = lhs >> rhs;
3904 }
3905
John Bauman19bac1e2014-05-06 15:23:49 -04003906 RValue<Int> operator+(RValue<Int> val)
John Bauman89401822014-05-06 15:04:28 -04003907 {
3908 return val;
3909 }
3910
John Bauman19bac1e2014-05-06 15:23:49 -04003911 RValue<Int> operator-(RValue<Int> val)
John Bauman89401822014-05-06 15:04:28 -04003912 {
3913 return RValue<Int>(Nucleus::createNeg(val.value));
3914 }
3915
John Bauman19bac1e2014-05-06 15:23:49 -04003916 RValue<Int> operator~(RValue<Int> val)
John Bauman89401822014-05-06 15:04:28 -04003917 {
3918 return RValue<Int>(Nucleus::createNot(val.value));
3919 }
3920
3921 RValue<Int> operator++(const Int &val, int) // Post-increment
3922 {
3923 RValue<Int> res = val;
3924
Nicolas Capens19336542016-09-26 10:32:29 -04003925 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04003926 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04003927
3928 return res;
3929 }
3930
3931 const Int &operator++(const Int &val) // Pre-increment
3932 {
Nicolas Capens19336542016-09-26 10:32:29 -04003933 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04003934 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04003935
3936 return val;
3937 }
3938
3939 RValue<Int> operator--(const Int &val, int) // Post-decrement
3940 {
3941 RValue<Int> res = val;
3942
Nicolas Capens19336542016-09-26 10:32:29 -04003943 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04003944 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04003945
3946 return res;
3947 }
3948
3949 const Int &operator--(const Int &val) // Pre-decrement
3950 {
Nicolas Capens19336542016-09-26 10:32:29 -04003951 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04003952 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04003953
3954 return val;
3955 }
3956
John Bauman19bac1e2014-05-06 15:23:49 -04003957 RValue<Bool> operator<(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003958 {
3959 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
3960 }
3961
John Bauman19bac1e2014-05-06 15:23:49 -04003962 RValue<Bool> operator<=(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003963 {
3964 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
3965 }
3966
John Bauman19bac1e2014-05-06 15:23:49 -04003967 RValue<Bool> operator>(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003968 {
3969 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
3970 }
3971
John Bauman19bac1e2014-05-06 15:23:49 -04003972 RValue<Bool> operator>=(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003973 {
3974 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
3975 }
3976
John Bauman19bac1e2014-05-06 15:23:49 -04003977 RValue<Bool> operator!=(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003978 {
3979 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
3980 }
3981
John Bauman19bac1e2014-05-06 15:23:49 -04003982 RValue<Bool> operator==(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003983 {
3984 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
3985 }
3986
John Bauman19bac1e2014-05-06 15:23:49 -04003987 RValue<Int> Max(RValue<Int> x, RValue<Int> y)
3988 {
3989 return IfThenElse(x > y, x, y);
3990 }
3991
3992 RValue<Int> Min(RValue<Int> x, RValue<Int> y)
3993 {
3994 return IfThenElse(x < y, x, y);
3995 }
3996
3997 RValue<Int> Clamp(RValue<Int> x, RValue<Int> min, RValue<Int> max)
3998 {
3999 return Min(Max(x, min), max);
4000 }
4001
4002 RValue<Int> RoundInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04004003 {
4004 return x86::cvtss2si(cast);
4005
John Bauman66b8ab22014-05-06 15:57:45 -04004006 // return IfThenElse(val > 0.0f, Int(val + 0.5f), Int(val - 0.5f));
John Bauman89401822014-05-06 15:04:28 -04004007 }
4008
John Bauman19bac1e2014-05-06 15:23:49 -04004009 Type *Int::getType()
John Bauman89401822014-05-06 15:04:28 -04004010 {
Nicolas Capensac230122016-09-20 14:30:06 -04004011 return T(llvm::Type::getInt32Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04004012 }
4013
John Bauman19bac1e2014-05-06 15:23:49 -04004014 Long::Long(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04004015 {
John Bauman89401822014-05-06 15:04:28 -04004016 Value *integer = Nucleus::createSExt(cast.value, Long::getType());
4017
John Bauman66b8ab22014-05-06 15:57:45 -04004018 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04004019 }
4020
John Bauman19bac1e2014-05-06 15:23:49 -04004021 Long::Long(RValue<UInt> cast)
John Bauman89401822014-05-06 15:04:28 -04004022 {
John Bauman89401822014-05-06 15:04:28 -04004023 Value *integer = Nucleus::createZExt(cast.value, Long::getType());
4024
John Bauman66b8ab22014-05-06 15:57:45 -04004025 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04004026 }
4027
4028 Long::Long()
4029 {
John Bauman89401822014-05-06 15:04:28 -04004030 }
4031
John Bauman19bac1e2014-05-06 15:23:49 -04004032 Long::Long(RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04004033 {
John Bauman66b8ab22014-05-06 15:57:45 -04004034 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004035 }
4036
4037 RValue<Long> Long::operator=(int64_t rhs) const
4038 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04004039 return RValue<Long>(storeValue(Nucleus::createConstantLong(rhs)));
John Bauman89401822014-05-06 15:04:28 -04004040 }
4041
John Bauman19bac1e2014-05-06 15:23:49 -04004042 RValue<Long> Long::operator=(RValue<Long> rhs) const
John Bauman89401822014-05-06 15:04:28 -04004043 {
John Bauman66b8ab22014-05-06 15:57:45 -04004044 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004045
4046 return rhs;
4047 }
4048
4049 RValue<Long> Long::operator=(const Long &rhs) const
4050 {
John Bauman66b8ab22014-05-06 15:57:45 -04004051 Value *value = rhs.loadValue();
4052 storeValue(value);
4053
4054 return RValue<Long>(value);
4055 }
4056
4057 RValue<Long> Long::operator=(const Reference<Long> &rhs) const
4058 {
4059 Value *value = rhs.loadValue();
4060 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004061
4062 return RValue<Long>(value);
4063 }
4064
John Bauman19bac1e2014-05-06 15:23:49 -04004065 RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04004066 {
4067 return RValue<Long>(Nucleus::createAdd(lhs.value, rhs.value));
4068 }
4069
John Bauman19bac1e2014-05-06 15:23:49 -04004070 RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04004071 {
4072 return RValue<Long>(Nucleus::createSub(lhs.value, rhs.value));
4073 }
4074
John Bauman19bac1e2014-05-06 15:23:49 -04004075 RValue<Long> operator+=(const Long &lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04004076 {
4077 return lhs = lhs + rhs;
4078 }
4079
John Bauman19bac1e2014-05-06 15:23:49 -04004080 RValue<Long> operator-=(const Long &lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04004081 {
4082 return lhs = lhs - rhs;
4083 }
4084
John Bauman66b8ab22014-05-06 15:57:45 -04004085 RValue<Long> AddAtomic(RValue<Pointer<Long> > x, RValue<Long> y)
John Bauman89401822014-05-06 15:04:28 -04004086 {
John Bauman19bac1e2014-05-06 15:23:49 -04004087 return RValue<Long>(Nucleus::createAtomicAdd(x.value, y.value));
John Bauman89401822014-05-06 15:04:28 -04004088 }
4089
John Bauman19bac1e2014-05-06 15:23:49 -04004090 Type *Long::getType()
John Bauman89401822014-05-06 15:04:28 -04004091 {
Nicolas Capensac230122016-09-20 14:30:06 -04004092 return T(llvm::Type::getInt64Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04004093 }
4094
Nicolas Capens50c96362016-01-04 23:03:59 -05004095 Long1::Long1(const RValue<UInt> cast)
John Bauman89401822014-05-06 15:04:28 -04004096 {
Nicolas Capens19336542016-09-26 10:32:29 -04004097 Value *undefCast = Nucleus::createInsertElement(V(UndefValue::get(VectorType::get(Int::getType(), 2))), cast.value, 0);
4098 Value *zeroCast = Nucleus::createInsertElement(undefCast, V(Nucleus::createConstantInt(0)), 1);
John Bauman66b8ab22014-05-06 15:57:45 -04004099
Nicolas Capens50c96362016-01-04 23:03:59 -05004100 storeValue(Nucleus::createBitCast(zeroCast, Long1::getType()));
John Bauman89401822014-05-06 15:04:28 -04004101 }
4102
John Bauman19bac1e2014-05-06 15:23:49 -04004103 Long1::Long1(RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004104 {
John Bauman66b8ab22014-05-06 15:57:45 -04004105 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004106 }
4107
John Bauman19bac1e2014-05-06 15:23:49 -04004108 Type *Long1::getType()
John Bauman89401822014-05-06 15:04:28 -04004109 {
John Bauman19bac1e2014-05-06 15:23:49 -04004110 if(CPUID::supportsMMX2())
4111 {
4112 return MMX::getType();
4113 }
4114 else
4115 {
Nicolas Capensac230122016-09-20 14:30:06 -04004116 return T(VectorType::get(Long::getType(), 1));
John Bauman19bac1e2014-05-06 15:23:49 -04004117 }
John Bauman89401822014-05-06 15:04:28 -04004118 }
4119
Nicolas Capens81f18302016-01-14 09:32:35 -05004120 UInt::UInt(Argument<UInt> argument)
John Bauman89401822014-05-06 15:04:28 -04004121 {
Nicolas Capens81f18302016-01-14 09:32:35 -05004122 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04004123 }
4124
John Bauman19bac1e2014-05-06 15:23:49 -04004125 UInt::UInt(RValue<UShort> cast)
John Bauman89401822014-05-06 15:04:28 -04004126 {
John Bauman89401822014-05-06 15:04:28 -04004127 Value *integer = Nucleus::createZExt(cast.value, UInt::getType());
4128
John Bauman66b8ab22014-05-06 15:57:45 -04004129 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04004130 }
4131
John Bauman19bac1e2014-05-06 15:23:49 -04004132 UInt::UInt(RValue<Long> cast)
John Bauman89401822014-05-06 15:04:28 -04004133 {
John Bauman89401822014-05-06 15:04:28 -04004134 Value *integer = Nucleus::createTrunc(cast.value, UInt::getType());
4135
John Bauman66b8ab22014-05-06 15:57:45 -04004136 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04004137 }
4138
John Bauman19bac1e2014-05-06 15:23:49 -04004139 UInt::UInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04004140 {
Alexis Hetu764d1422016-09-28 08:44:22 -04004141 // Note: createFPToUI is broken, must perform conversion using createFPtoSI
4142 // Value *integer = Nucleus::createFPToUI(cast.value, UInt::getType());
John Bauman89401822014-05-06 15:04:28 -04004143
Alexis Hetu764d1422016-09-28 08:44:22 -04004144 // Smallest positive value representable in UInt, but not in Int
4145 const unsigned int ustart = 0x80000000u;
4146 const float ustartf = float(ustart);
4147
4148 // If the value is negative, store 0, otherwise store the result of the conversion
4149 storeValue((~(As<Int>(cast) >> 31) &
4150 // Check if the value can be represented as an Int
4151 IfThenElse(cast >= ustartf,
4152 // If the value is too large, subtract ustart and re-add it after conversion.
4153 As<Int>(As<UInt>(Int(cast - Float(ustartf))) + UInt(ustart)),
4154 // Otherwise, just convert normally
4155 Int(cast))).value);
John Bauman89401822014-05-06 15:04:28 -04004156 }
4157
4158 UInt::UInt()
4159 {
John Bauman89401822014-05-06 15:04:28 -04004160 }
4161
4162 UInt::UInt(int x)
4163 {
John Bauman66b8ab22014-05-06 15:57:45 -04004164 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04004165 }
4166
4167 UInt::UInt(unsigned int x)
4168 {
John Bauman66b8ab22014-05-06 15:57:45 -04004169 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04004170 }
4171
John Bauman19bac1e2014-05-06 15:23:49 -04004172 UInt::UInt(RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004173 {
John Bauman66b8ab22014-05-06 15:57:45 -04004174 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004175 }
4176
John Bauman19bac1e2014-05-06 15:23:49 -04004177 UInt::UInt(RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004178 {
John Bauman66b8ab22014-05-06 15:57:45 -04004179 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004180 }
4181
4182 UInt::UInt(const UInt &rhs)
4183 {
John Bauman66b8ab22014-05-06 15:57:45 -04004184 Value *value = rhs.loadValue();
4185 storeValue(value);
4186 }
John Bauman89401822014-05-06 15:04:28 -04004187
John Bauman66b8ab22014-05-06 15:57:45 -04004188 UInt::UInt(const Reference<UInt> &rhs)
4189 {
4190 Value *value = rhs.loadValue();
4191 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004192 }
4193
4194 UInt::UInt(const Int &rhs)
4195 {
John Bauman66b8ab22014-05-06 15:57:45 -04004196 Value *value = rhs.loadValue();
4197 storeValue(value);
4198 }
John Bauman89401822014-05-06 15:04:28 -04004199
John Bauman66b8ab22014-05-06 15:57:45 -04004200 UInt::UInt(const Reference<Int> &rhs)
4201 {
4202 Value *value = rhs.loadValue();
4203 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004204 }
4205
4206 RValue<UInt> UInt::operator=(unsigned int rhs) const
4207 {
John Bauman66b8ab22014-05-06 15:57:45 -04004208 return RValue<UInt>(storeValue(Nucleus::createConstantInt(rhs)));
John Bauman89401822014-05-06 15:04:28 -04004209 }
4210
John Bauman19bac1e2014-05-06 15:23:49 -04004211 RValue<UInt> UInt::operator=(RValue<UInt> rhs) const
John Bauman89401822014-05-06 15:04:28 -04004212 {
John Bauman66b8ab22014-05-06 15:57:45 -04004213 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004214
4215 return rhs;
4216 }
4217
John Bauman19bac1e2014-05-06 15:23:49 -04004218 RValue<UInt> UInt::operator=(RValue<Int> rhs) const
John Bauman89401822014-05-06 15:04:28 -04004219 {
John Bauman66b8ab22014-05-06 15:57:45 -04004220 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004221
John Bauman66b8ab22014-05-06 15:57:45 -04004222 return RValue<UInt>(rhs);
John Bauman89401822014-05-06 15:04:28 -04004223 }
4224
4225 RValue<UInt> UInt::operator=(const UInt &rhs) const
4226 {
John Bauman66b8ab22014-05-06 15:57:45 -04004227 Value *value = rhs.loadValue();
4228 storeValue(value);
4229
4230 return RValue<UInt>(value);
4231 }
4232
4233 RValue<UInt> UInt::operator=(const Reference<UInt> &rhs) const
4234 {
4235 Value *value = rhs.loadValue();
4236 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004237
4238 return RValue<UInt>(value);
4239 }
4240
4241 RValue<UInt> UInt::operator=(const Int &rhs) const
4242 {
John Bauman66b8ab22014-05-06 15:57:45 -04004243 Value *value = rhs.loadValue();
4244 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004245
4246 return RValue<UInt>(value);
4247 }
4248
John Bauman66b8ab22014-05-06 15:57:45 -04004249 RValue<UInt> UInt::operator=(const Reference<Int> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04004250 {
John Bauman66b8ab22014-05-06 15:57:45 -04004251 Value *value = rhs.loadValue();
4252 storeValue(value);
4253
4254 return RValue<UInt>(value);
John Bauman89401822014-05-06 15:04:28 -04004255 }
4256
John Bauman19bac1e2014-05-06 15:23:49 -04004257 RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004258 {
4259 return RValue<UInt>(Nucleus::createAdd(lhs.value, rhs.value));
4260 }
4261
John Bauman19bac1e2014-05-06 15:23:49 -04004262 RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004263 {
4264 return RValue<UInt>(Nucleus::createSub(lhs.value, rhs.value));
4265 }
4266
John Bauman19bac1e2014-05-06 15:23:49 -04004267 RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004268 {
4269 return RValue<UInt>(Nucleus::createMul(lhs.value, rhs.value));
4270 }
4271
John Bauman19bac1e2014-05-06 15:23:49 -04004272 RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004273 {
4274 return RValue<UInt>(Nucleus::createUDiv(lhs.value, rhs.value));
4275 }
4276
John Bauman19bac1e2014-05-06 15:23:49 -04004277 RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004278 {
4279 return RValue<UInt>(Nucleus::createURem(lhs.value, rhs.value));
4280 }
4281
John Bauman19bac1e2014-05-06 15:23:49 -04004282 RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004283 {
4284 return RValue<UInt>(Nucleus::createAnd(lhs.value, rhs.value));
4285 }
4286
John Bauman19bac1e2014-05-06 15:23:49 -04004287 RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004288 {
4289 return RValue<UInt>(Nucleus::createOr(lhs.value, rhs.value));
4290 }
4291
John Bauman19bac1e2014-05-06 15:23:49 -04004292 RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004293 {
4294 return RValue<UInt>(Nucleus::createXor(lhs.value, rhs.value));
4295 }
4296
John Bauman19bac1e2014-05-06 15:23:49 -04004297 RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004298 {
4299 return RValue<UInt>(Nucleus::createShl(lhs.value, rhs.value));
4300 }
4301
John Bauman19bac1e2014-05-06 15:23:49 -04004302 RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004303 {
4304 return RValue<UInt>(Nucleus::createLShr(lhs.value, rhs.value));
4305 }
4306
John Bauman19bac1e2014-05-06 15:23:49 -04004307 RValue<UInt> operator+=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004308 {
4309 return lhs = lhs + rhs;
4310 }
4311
John Bauman19bac1e2014-05-06 15:23:49 -04004312 RValue<UInt> operator-=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004313 {
4314 return lhs = lhs - rhs;
4315 }
4316
John Bauman19bac1e2014-05-06 15:23:49 -04004317 RValue<UInt> operator*=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004318 {
4319 return lhs = lhs * rhs;
4320 }
4321
John Bauman19bac1e2014-05-06 15:23:49 -04004322 RValue<UInt> operator/=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004323 {
4324 return lhs = lhs / rhs;
4325 }
4326
John Bauman19bac1e2014-05-06 15:23:49 -04004327 RValue<UInt> operator%=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004328 {
4329 return lhs = lhs % rhs;
4330 }
4331
John Bauman19bac1e2014-05-06 15:23:49 -04004332 RValue<UInt> operator&=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004333 {
4334 return lhs = lhs & rhs;
4335 }
4336
John Bauman19bac1e2014-05-06 15:23:49 -04004337 RValue<UInt> operator|=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004338 {
4339 return lhs = lhs | rhs;
4340 }
4341
John Bauman19bac1e2014-05-06 15:23:49 -04004342 RValue<UInt> operator^=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004343 {
4344 return lhs = lhs ^ rhs;
4345 }
4346
John Bauman19bac1e2014-05-06 15:23:49 -04004347 RValue<UInt> operator<<=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004348 {
4349 return lhs = lhs << rhs;
4350 }
4351
John Bauman19bac1e2014-05-06 15:23:49 -04004352 RValue<UInt> operator>>=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004353 {
4354 return lhs = lhs >> rhs;
4355 }
4356
John Bauman19bac1e2014-05-06 15:23:49 -04004357 RValue<UInt> operator+(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004358 {
4359 return val;
4360 }
4361
John Bauman19bac1e2014-05-06 15:23:49 -04004362 RValue<UInt> operator-(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004363 {
4364 return RValue<UInt>(Nucleus::createNeg(val.value));
4365 }
4366
John Bauman19bac1e2014-05-06 15:23:49 -04004367 RValue<UInt> operator~(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004368 {
4369 return RValue<UInt>(Nucleus::createNot(val.value));
4370 }
4371
4372 RValue<UInt> operator++(const UInt &val, int) // Post-increment
4373 {
4374 RValue<UInt> res = val;
4375
Nicolas Capens19336542016-09-26 10:32:29 -04004376 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04004377 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004378
4379 return res;
4380 }
4381
4382 const UInt &operator++(const UInt &val) // Pre-increment
4383 {
Nicolas Capens19336542016-09-26 10:32:29 -04004384 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04004385 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004386
4387 return val;
4388 }
4389
4390 RValue<UInt> operator--(const UInt &val, int) // Post-decrement
4391 {
4392 RValue<UInt> res = val;
4393
Nicolas Capens19336542016-09-26 10:32:29 -04004394 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04004395 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004396
4397 return res;
4398 }
4399
4400 const UInt &operator--(const UInt &val) // Pre-decrement
4401 {
Nicolas Capens19336542016-09-26 10:32:29 -04004402 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04004403 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004404
4405 return val;
4406 }
4407
John Bauman19bac1e2014-05-06 15:23:49 -04004408 RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y)
4409 {
4410 return IfThenElse(x > y, x, y);
4411 }
4412
4413 RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y)
4414 {
4415 return IfThenElse(x < y, x, y);
4416 }
4417
4418 RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max)
4419 {
4420 return Min(Max(x, min), max);
4421 }
4422
4423 RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004424 {
4425 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
4426 }
4427
John Bauman19bac1e2014-05-06 15:23:49 -04004428 RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004429 {
4430 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
4431 }
4432
John Bauman19bac1e2014-05-06 15:23:49 -04004433 RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004434 {
4435 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
4436 }
4437
John Bauman19bac1e2014-05-06 15:23:49 -04004438 RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004439 {
4440 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
4441 }
4442
John Bauman19bac1e2014-05-06 15:23:49 -04004443 RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004444 {
4445 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
4446 }
4447
John Bauman19bac1e2014-05-06 15:23:49 -04004448 RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004449 {
4450 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
4451 }
4452
John Bauman19bac1e2014-05-06 15:23:49 -04004453// RValue<UInt> RoundUInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04004454// {
4455// return x86::cvtss2si(val); // FIXME: Unsigned
4456//
John Bauman66b8ab22014-05-06 15:57:45 -04004457// // return IfThenElse(val > 0.0f, Int(val + 0.5f), Int(val - 0.5f));
John Bauman89401822014-05-06 15:04:28 -04004458// }
4459
John Bauman19bac1e2014-05-06 15:23:49 -04004460 Type *UInt::getType()
John Bauman89401822014-05-06 15:04:28 -04004461 {
Nicolas Capensac230122016-09-20 14:30:06 -04004462 return T(llvm::Type::getInt32Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04004463 }
4464
John Bauman19bac1e2014-05-06 15:23:49 -04004465// Int2::Int2(RValue<Int> cast)
4466// {
John Bauman19bac1e2014-05-06 15:23:49 -04004467// Value *extend = Nucleus::createZExt(cast.value, Long::getType());
4468// Value *vector = Nucleus::createBitCast(extend, Int2::getType());
John Bauman66b8ab22014-05-06 15:57:45 -04004469//
Nicolas Capense89cd582016-09-30 14:23:47 -04004470// int shuffle[2] = {0, 0};
4471// Value *replicate = Nucleus::createShuffleVector(vector, vector, shuffle);
John Bauman19bac1e2014-05-06 15:23:49 -04004472//
John Bauman66b8ab22014-05-06 15:57:45 -04004473// storeValue(replicate);
John Bauman19bac1e2014-05-06 15:23:49 -04004474// }
John Bauman89401822014-05-06 15:04:28 -04004475
John Bauman19bac1e2014-05-06 15:23:49 -04004476 Int2::Int2(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04004477 {
Nicolas Capens22008782016-10-20 01:11:47 -04004478 Value *long2 = Nucleus::createBitCast(cast.value, T(VectorType::get(Long::getType(), 2)));
Nicolas Capense95d5342016-09-30 11:37:28 -04004479 Value *element = Nucleus::createExtractElement(long2, Long::getType(), 0);
John Bauman89401822014-05-06 15:04:28 -04004480 Value *int2 = Nucleus::createBitCast(element, Int2::getType());
4481
John Bauman66b8ab22014-05-06 15:57:45 -04004482 storeValue(int2);
John Bauman89401822014-05-06 15:04:28 -04004483 }
4484
4485 Int2::Int2()
4486 {
4487 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004488 }
4489
4490 Int2::Int2(int x, int y)
4491 {
4492 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004493
Nicolas Capens13ac2322016-10-13 14:52:12 -04004494 int64_t constantVector[2] = {x, y};
4495 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(Int::getType(), 2))));
John Bauman89401822014-05-06 15:04:28 -04004496
John Bauman66b8ab22014-05-06 15:57:45 -04004497 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04004498 }
4499
John Bauman19bac1e2014-05-06 15:23:49 -04004500 Int2::Int2(RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004501 {
4502 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004503
John Bauman66b8ab22014-05-06 15:57:45 -04004504 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004505 }
4506
4507 Int2::Int2(const Int2 &rhs)
4508 {
4509 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004510
John Bauman66b8ab22014-05-06 15:57:45 -04004511 Value *value = rhs.loadValue();
4512 storeValue(value);
4513 }
4514
4515 Int2::Int2(const Reference<Int2> &rhs)
4516 {
4517 // xy.parent = this;
4518
4519 Value *value = rhs.loadValue();
4520 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004521 }
4522
Nicolas Capens62abb552016-01-05 12:03:47 -05004523 Int2::Int2(RValue<Int> lo, RValue<Int> hi)
4524 {
Nicolas Capensb40a2562016-01-05 00:08:45 -05004525 if(CPUID::supportsMMX2())
4526 {
4527 // movd mm0, lo
4528 // movd mm1, hi
4529 // punpckldq mm0, mm1
4530 storeValue(As<Int2>(UnpackLow(As<Int2>(Long1(RValue<UInt>(lo))), As<Int2>(Long1(RValue<UInt>(hi))))).value);
4531 }
4532 else
4533 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004534 int shuffle[2] = {0, 1};
4535 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 -05004536
Nicolas Capensb40a2562016-01-05 00:08:45 -05004537 storeValue(Nucleus::createBitCast(packed, Int2::getType()));
4538 }
Nicolas Capens62abb552016-01-05 12:03:47 -05004539 }
4540
John Bauman19bac1e2014-05-06 15:23:49 -04004541 RValue<Int2> Int2::operator=(RValue<Int2> rhs) const
John Bauman89401822014-05-06 15:04:28 -04004542 {
John Bauman66b8ab22014-05-06 15:57:45 -04004543 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004544
4545 return rhs;
4546 }
4547
4548 RValue<Int2> Int2::operator=(const Int2 &rhs) const
4549 {
John Bauman66b8ab22014-05-06 15:57:45 -04004550 Value *value = rhs.loadValue();
4551 storeValue(value);
4552
4553 return RValue<Int2>(value);
4554 }
4555
4556 RValue<Int2> Int2::operator=(const Reference<Int2> &rhs) const
4557 {
4558 Value *value = rhs.loadValue();
4559 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004560
4561 return RValue<Int2>(value);
4562 }
4563
John Bauman19bac1e2014-05-06 15:23:49 -04004564 RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004565 {
John Bauman19bac1e2014-05-06 15:23:49 -04004566 if(CPUID::supportsMMX2())
4567 {
4568 return x86::paddd(lhs, rhs);
4569 }
4570 else
4571 {
4572 return RValue<Int2>(Nucleus::createAdd(lhs.value, rhs.value));
4573 }
John Bauman89401822014-05-06 15:04:28 -04004574 }
4575
John Bauman19bac1e2014-05-06 15:23:49 -04004576 RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004577 {
John Bauman19bac1e2014-05-06 15:23:49 -04004578 if(CPUID::supportsMMX2())
4579 {
4580 return x86::psubd(lhs, rhs);
4581 }
4582 else
4583 {
4584 return RValue<Int2>(Nucleus::createSub(lhs.value, rhs.value));
4585 }
John Bauman89401822014-05-06 15:04:28 -04004586 }
4587
John Bauman19bac1e2014-05-06 15:23:49 -04004588// RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs)
4589// {
4590// return RValue<Int2>(Nucleus::createMul(lhs.value, rhs.value));
4591// }
4592
4593// RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs)
4594// {
4595// return RValue<Int2>(Nucleus::createSDiv(lhs.value, rhs.value));
4596// }
4597
4598// RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs)
4599// {
4600// return RValue<Int2>(Nucleus::createSRem(lhs.value, rhs.value));
4601// }
4602
4603 RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004604 {
John Bauman19bac1e2014-05-06 15:23:49 -04004605 if(CPUID::supportsMMX2())
4606 {
4607 return As<Int2>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
4608 }
4609 else
4610 {
4611 return RValue<Int2>(Nucleus::createAnd(lhs.value, rhs.value));
4612 }
John Bauman89401822014-05-06 15:04:28 -04004613 }
4614
John Bauman19bac1e2014-05-06 15:23:49 -04004615 RValue<Int2> operator|(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004616 {
John Bauman19bac1e2014-05-06 15:23:49 -04004617 if(CPUID::supportsMMX2())
4618 {
4619 return As<Int2>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
4620 }
4621 else
4622 {
4623 return RValue<Int2>(Nucleus::createOr(lhs.value, rhs.value));
4624 }
John Bauman89401822014-05-06 15:04:28 -04004625 }
4626
John Bauman19bac1e2014-05-06 15:23:49 -04004627 RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004628 {
John Bauman19bac1e2014-05-06 15:23:49 -04004629 if(CPUID::supportsMMX2())
4630 {
4631 return As<Int2>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
4632 }
4633 else
4634 {
4635 return RValue<Int2>(Nucleus::createXor(lhs.value, rhs.value));
4636 }
John Bauman89401822014-05-06 15:04:28 -04004637 }
4638
John Bauman19bac1e2014-05-06 15:23:49 -04004639 RValue<Int2> operator<<(RValue<Int2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004640 {
4641 // return RValue<Int2>(Nucleus::createShl(lhs.value, rhs.value));
4642
4643 return x86::pslld(lhs, rhs);
4644 }
4645
John Bauman19bac1e2014-05-06 15:23:49 -04004646 RValue<Int2> operator>>(RValue<Int2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004647 {
4648 // return RValue<Int2>(Nucleus::createAShr(lhs.value, rhs.value));
4649
4650 return x86::psrad(lhs, rhs);
4651 }
4652
John Bauman19bac1e2014-05-06 15:23:49 -04004653 RValue<Int2> operator<<(RValue<Int2> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004654 {
4655 // return RValue<Int2>(Nucleus::createShl(lhs.value, rhs.value));
4656
4657 return x86::pslld(lhs, rhs);
4658 }
4659
John Bauman19bac1e2014-05-06 15:23:49 -04004660 RValue<Int2> operator>>(RValue<Int2> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004661 {
4662 // return RValue<Int2>(Nucleus::createAShr(lhs.value, rhs.value));
4663
4664 return x86::psrad(lhs, rhs);
4665 }
4666
John Bauman19bac1e2014-05-06 15:23:49 -04004667 RValue<Int2> operator+=(const Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004668 {
4669 return lhs = lhs + rhs;
4670 }
4671
John Bauman19bac1e2014-05-06 15:23:49 -04004672 RValue<Int2> operator-=(const Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004673 {
4674 return lhs = lhs - rhs;
4675 }
4676
John Bauman19bac1e2014-05-06 15:23:49 -04004677// RValue<Int2> operator*=(const Int2 &lhs, RValue<Int2> rhs)
4678// {
4679// return lhs = lhs * rhs;
4680// }
John Bauman89401822014-05-06 15:04:28 -04004681
John Bauman19bac1e2014-05-06 15:23:49 -04004682// RValue<Int2> operator/=(const Int2 &lhs, RValue<Int2> rhs)
4683// {
4684// return lhs = lhs / rhs;
4685// }
John Bauman89401822014-05-06 15:04:28 -04004686
John Bauman19bac1e2014-05-06 15:23:49 -04004687// RValue<Int2> operator%=(const Int2 &lhs, RValue<Int2> rhs)
4688// {
4689// return lhs = lhs % rhs;
4690// }
John Bauman89401822014-05-06 15:04:28 -04004691
John Bauman19bac1e2014-05-06 15:23:49 -04004692 RValue<Int2> operator&=(const Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004693 {
4694 return lhs = lhs & rhs;
4695 }
4696
John Bauman19bac1e2014-05-06 15:23:49 -04004697 RValue<Int2> operator|=(const Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004698 {
4699 return lhs = lhs | rhs;
4700 }
4701
John Bauman19bac1e2014-05-06 15:23:49 -04004702 RValue<Int2> operator^=(const Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004703 {
4704 return lhs = lhs ^ rhs;
4705 }
4706
4707 RValue<Int2> operator<<=(const Int2 &lhs, unsigned char rhs)
4708 {
4709 return lhs = lhs << rhs;
4710 }
4711
4712 RValue<Int2> operator>>=(const Int2 &lhs, unsigned char rhs)
4713 {
4714 return lhs = lhs >> rhs;
4715 }
4716
John Bauman19bac1e2014-05-06 15:23:49 -04004717 RValue<Int2> operator<<=(const Int2 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004718 {
4719 return lhs = lhs << rhs;
4720 }
4721
John Bauman19bac1e2014-05-06 15:23:49 -04004722 RValue<Int2> operator>>=(const Int2 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004723 {
4724 return lhs = lhs >> rhs;
4725 }
4726
John Bauman19bac1e2014-05-06 15:23:49 -04004727// RValue<Int2> operator+(RValue<Int2> val)
4728// {
4729// return val;
4730// }
4731
4732// RValue<Int2> operator-(RValue<Int2> val)
4733// {
4734// return RValue<Int2>(Nucleus::createNeg(val.value));
4735// }
4736
4737 RValue<Int2> operator~(RValue<Int2> val)
John Bauman89401822014-05-06 15:04:28 -04004738 {
John Bauman19bac1e2014-05-06 15:23:49 -04004739 if(CPUID::supportsMMX2())
4740 {
4741 return val ^ Int2(0xFFFFFFFF, 0xFFFFFFFF);
4742 }
4743 else
4744 {
4745 return RValue<Int2>(Nucleus::createNot(val.value));
4746 }
John Bauman89401822014-05-06 15:04:28 -04004747 }
4748
John Bauman19bac1e2014-05-06 15:23:49 -04004749 RValue<Long1> UnpackLow(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04004750 {
John Bauman19bac1e2014-05-06 15:23:49 -04004751 if(CPUID::supportsMMX2())
4752 {
4753 return x86::punpckldq(x, y);
4754 }
4755 else
4756 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004757 int shuffle[2] = {0, 2};
4758 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04004759
John Bauman19bac1e2014-05-06 15:23:49 -04004760 return RValue<Long1>(Nucleus::createBitCast(packed, Long1::getType()));
4761 }
John Bauman89401822014-05-06 15:04:28 -04004762 }
John Bauman66b8ab22014-05-06 15:57:45 -04004763
John Bauman19bac1e2014-05-06 15:23:49 -04004764 RValue<Long1> UnpackHigh(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04004765 {
John Bauman19bac1e2014-05-06 15:23:49 -04004766 if(CPUID::supportsMMX2())
4767 {
4768 return x86::punpckhdq(x, y);
4769 }
4770 else
4771 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004772 int shuffle[2] = {1, 3};
4773 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04004774
John Bauman19bac1e2014-05-06 15:23:49 -04004775 return RValue<Long1>(Nucleus::createBitCast(packed, Long1::getType()));
4776 }
John Bauman89401822014-05-06 15:04:28 -04004777 }
4778
John Bauman19bac1e2014-05-06 15:23:49 -04004779 RValue<Int> Extract(RValue<Int2> val, int i)
John Bauman89401822014-05-06 15:04:28 -04004780 {
4781 if(false) // FIXME: LLVM does not generate optimal code
4782 {
Nicolas Capense95d5342016-09-30 11:37:28 -04004783 return RValue<Int>(Nucleus::createExtractElement(val.value, Int::getType(), i));
John Bauman89401822014-05-06 15:04:28 -04004784 }
4785 else
4786 {
4787 if(i == 0)
4788 {
Nicolas Capense95d5342016-09-30 11:37:28 -04004789 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 -04004790 }
4791 else
4792 {
4793 Int2 val2 = As<Int2>(UnpackHigh(val, val));
4794
4795 return Extract(val2, 0);
4796 }
4797 }
4798 }
4799
Nicolas Capensfff3c9b2015-05-13 23:40:44 -04004800 RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i)
4801 {
Nicolas Capensac230122016-09-20 14:30:06 -04004802 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 -04004803 }
John Bauman89401822014-05-06 15:04:28 -04004804
John Bauman19bac1e2014-05-06 15:23:49 -04004805 Type *Int2::getType()
John Bauman89401822014-05-06 15:04:28 -04004806 {
John Bauman19bac1e2014-05-06 15:23:49 -04004807 if(CPUID::supportsMMX2())
4808 {
4809 return MMX::getType();
4810 }
4811 else
4812 {
Nicolas Capensac230122016-09-20 14:30:06 -04004813 return T(VectorType::get(Int::getType(), 2));
John Bauman19bac1e2014-05-06 15:23:49 -04004814 }
John Bauman89401822014-05-06 15:04:28 -04004815 }
4816
4817 UInt2::UInt2()
4818 {
4819 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004820 }
4821
4822 UInt2::UInt2(unsigned int x, unsigned int y)
4823 {
4824 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004825
Nicolas Capens13ac2322016-10-13 14:52:12 -04004826 int64_t constantVector[2] = {x, y};
4827 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(UInt::getType(), 2))));
John Bauman89401822014-05-06 15:04:28 -04004828
John Bauman66b8ab22014-05-06 15:57:45 -04004829 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04004830 }
4831
John Bauman19bac1e2014-05-06 15:23:49 -04004832 UInt2::UInt2(RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004833 {
4834 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004835
John Bauman66b8ab22014-05-06 15:57:45 -04004836 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004837 }
4838
4839 UInt2::UInt2(const UInt2 &rhs)
4840 {
4841 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004842
John Bauman66b8ab22014-05-06 15:57:45 -04004843 Value *value = rhs.loadValue();
4844 storeValue(value);
4845 }
4846
4847 UInt2::UInt2(const Reference<UInt2> &rhs)
4848 {
4849 // xy.parent = this;
4850
4851 Value *value = rhs.loadValue();
4852 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004853 }
4854
John Bauman19bac1e2014-05-06 15:23:49 -04004855 RValue<UInt2> UInt2::operator=(RValue<UInt2> rhs) const
John Bauman89401822014-05-06 15:04:28 -04004856 {
John Bauman66b8ab22014-05-06 15:57:45 -04004857 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004858
4859 return rhs;
4860 }
4861
4862 RValue<UInt2> UInt2::operator=(const UInt2 &rhs) const
4863 {
John Bauman66b8ab22014-05-06 15:57:45 -04004864 Value *value = rhs.loadValue();
4865 storeValue(value);
4866
4867 return RValue<UInt2>(value);
4868 }
4869
4870 RValue<UInt2> UInt2::operator=(const Reference<UInt2> &rhs) const
4871 {
4872 Value *value = rhs.loadValue();
4873 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004874
4875 return RValue<UInt2>(value);
4876 }
4877
John Bauman19bac1e2014-05-06 15:23:49 -04004878 RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004879 {
John Bauman19bac1e2014-05-06 15:23:49 -04004880 if(CPUID::supportsMMX2())
4881 {
4882 return As<UInt2>(x86::paddd(As<Int2>(lhs), As<Int2>(rhs)));
4883 }
4884 else
4885 {
4886 return RValue<UInt2>(Nucleus::createAdd(lhs.value, rhs.value));
4887 }
John Bauman89401822014-05-06 15:04:28 -04004888 }
4889
John Bauman19bac1e2014-05-06 15:23:49 -04004890 RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004891 {
John Bauman19bac1e2014-05-06 15:23:49 -04004892 if(CPUID::supportsMMX2())
4893 {
4894 return As<UInt2>(x86::psubd(As<Int2>(lhs), As<Int2>(rhs)));
4895 }
4896 else
4897 {
4898 return RValue<UInt2>(Nucleus::createSub(lhs.value, rhs.value));
4899 }
John Bauman89401822014-05-06 15:04:28 -04004900 }
4901
John Bauman19bac1e2014-05-06 15:23:49 -04004902// RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs)
4903// {
4904// return RValue<UInt2>(Nucleus::createMul(lhs.value, rhs.value));
4905// }
4906
4907// RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs)
4908// {
4909// return RValue<UInt2>(Nucleus::createUDiv(lhs.value, rhs.value));
4910// }
4911
4912// RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs)
4913// {
4914// return RValue<UInt2>(Nucleus::createURem(lhs.value, rhs.value));
4915// }
4916
4917 RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004918 {
John Bauman19bac1e2014-05-06 15:23:49 -04004919 if(CPUID::supportsMMX2())
4920 {
4921 return As<UInt2>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
4922 }
4923 else
4924 {
4925 return RValue<UInt2>(Nucleus::createAnd(lhs.value, rhs.value));
4926 }
John Bauman89401822014-05-06 15:04:28 -04004927 }
4928
John Bauman19bac1e2014-05-06 15:23:49 -04004929 RValue<UInt2> operator|(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004930 {
John Bauman19bac1e2014-05-06 15:23:49 -04004931 if(CPUID::supportsMMX2())
4932 {
4933 return As<UInt2>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
4934 }
4935 else
4936 {
4937 return RValue<UInt2>(Nucleus::createOr(lhs.value, rhs.value));
4938 }
John Bauman89401822014-05-06 15:04:28 -04004939 }
4940
John Bauman19bac1e2014-05-06 15:23:49 -04004941 RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004942 {
John Bauman19bac1e2014-05-06 15:23:49 -04004943 if(CPUID::supportsMMX2())
4944 {
4945 return As<UInt2>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
4946 }
4947 else
4948 {
4949 return RValue<UInt2>(Nucleus::createXor(lhs.value, rhs.value));
4950 }
John Bauman89401822014-05-06 15:04:28 -04004951 }
4952
John Bauman19bac1e2014-05-06 15:23:49 -04004953 RValue<UInt2> operator<<(RValue<UInt2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004954 {
4955 // return RValue<UInt2>(Nucleus::createShl(lhs.value, rhs.value));
4956
4957 return As<UInt2>(x86::pslld(As<Int2>(lhs), rhs));
4958 }
4959
John Bauman19bac1e2014-05-06 15:23:49 -04004960 RValue<UInt2> operator>>(RValue<UInt2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004961 {
4962 // return RValue<UInt2>(Nucleus::createLShr(lhs.value, rhs.value));
4963
4964 return x86::psrld(lhs, rhs);
4965 }
4966
John Bauman19bac1e2014-05-06 15:23:49 -04004967 RValue<UInt2> operator<<(RValue<UInt2> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004968 {
4969 // return RValue<UInt2>(Nucleus::createShl(lhs.value, rhs.value));
4970
4971 return As<UInt2>(x86::pslld(As<Int2>(lhs), rhs));
4972 }
4973
John Bauman19bac1e2014-05-06 15:23:49 -04004974 RValue<UInt2> operator>>(RValue<UInt2> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004975 {
4976 // return RValue<UInt2>(Nucleus::createLShr(lhs.value, rhs.value));
4977
4978 return x86::psrld(lhs, rhs);
4979 }
4980
John Bauman19bac1e2014-05-06 15:23:49 -04004981 RValue<UInt2> operator+=(const UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004982 {
4983 return lhs = lhs + rhs;
4984 }
4985
John Bauman19bac1e2014-05-06 15:23:49 -04004986 RValue<UInt2> operator-=(const UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004987 {
4988 return lhs = lhs - rhs;
4989 }
4990
John Bauman19bac1e2014-05-06 15:23:49 -04004991// RValue<UInt2> operator*=(const UInt2 &lhs, RValue<UInt2> rhs)
4992// {
4993// return lhs = lhs * rhs;
4994// }
John Bauman89401822014-05-06 15:04:28 -04004995
John Bauman19bac1e2014-05-06 15:23:49 -04004996// RValue<UInt2> operator/=(const UInt2 &lhs, RValue<UInt2> rhs)
4997// {
4998// return lhs = lhs / rhs;
4999// }
John Bauman89401822014-05-06 15:04:28 -04005000
John Bauman19bac1e2014-05-06 15:23:49 -04005001// RValue<UInt2> operator%=(const UInt2 &lhs, RValue<UInt2> rhs)
5002// {
5003// return lhs = lhs % rhs;
5004// }
John Bauman89401822014-05-06 15:04:28 -04005005
John Bauman19bac1e2014-05-06 15:23:49 -04005006 RValue<UInt2> operator&=(const UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005007 {
5008 return lhs = lhs & rhs;
5009 }
5010
John Bauman19bac1e2014-05-06 15:23:49 -04005011 RValue<UInt2> operator|=(const UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005012 {
5013 return lhs = lhs | rhs;
5014 }
5015
John Bauman19bac1e2014-05-06 15:23:49 -04005016 RValue<UInt2> operator^=(const UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005017 {
5018 return lhs = lhs ^ rhs;
5019 }
5020
5021 RValue<UInt2> operator<<=(const UInt2 &lhs, unsigned char rhs)
5022 {
5023 return lhs = lhs << rhs;
5024 }
5025
5026 RValue<UInt2> operator>>=(const UInt2 &lhs, unsigned char rhs)
5027 {
5028 return lhs = lhs >> rhs;
5029 }
5030
John Bauman19bac1e2014-05-06 15:23:49 -04005031 RValue<UInt2> operator<<=(const UInt2 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04005032 {
5033 return lhs = lhs << rhs;
5034 }
5035
John Bauman19bac1e2014-05-06 15:23:49 -04005036 RValue<UInt2> operator>>=(const UInt2 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04005037 {
5038 return lhs = lhs >> rhs;
5039 }
5040
John Bauman19bac1e2014-05-06 15:23:49 -04005041// RValue<UInt2> operator+(RValue<UInt2> val)
5042// {
5043// return val;
5044// }
5045
5046// RValue<UInt2> operator-(RValue<UInt2> val)
5047// {
5048// return RValue<UInt2>(Nucleus::createNeg(val.value));
5049// }
5050
5051 RValue<UInt2> operator~(RValue<UInt2> val)
John Bauman89401822014-05-06 15:04:28 -04005052 {
John Bauman19bac1e2014-05-06 15:23:49 -04005053 if(CPUID::supportsMMX2())
5054 {
5055 return val ^ UInt2(0xFFFFFFFF, 0xFFFFFFFF);
5056 }
5057 else
5058 {
5059 return RValue<UInt2>(Nucleus::createNot(val.value));
5060 }
John Bauman89401822014-05-06 15:04:28 -04005061 }
5062
John Bauman19bac1e2014-05-06 15:23:49 -04005063 Type *UInt2::getType()
John Bauman89401822014-05-06 15:04:28 -04005064 {
John Bauman19bac1e2014-05-06 15:23:49 -04005065 if(CPUID::supportsMMX2())
5066 {
5067 return MMX::getType();
5068 }
5069 else
5070 {
Nicolas Capensac230122016-09-20 14:30:06 -04005071 return T(VectorType::get(UInt::getType(), 2));
John Bauman19bac1e2014-05-06 15:23:49 -04005072 }
John Bauman89401822014-05-06 15:04:28 -04005073 }
5074
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005075 Int4::Int4(RValue<Byte4> cast)
5076 {
5077 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
Nicolas Capens19336542016-09-26 10:32:29 -04005078 Value *a = Nucleus::createInsertElement(V(UndefValue::get(Int4::getType())), x, 0);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005079
5080 Value *e;
5081
5082 if (CPUID::supportsSSE4_1())
5083 {
5084 e = x86::pmovzxbd(RValue<Int4>(a)).value;
5085 }
5086 else
5087 {
Nicolas Capense89cd582016-09-30 14:23:47 -04005088 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 -04005089 Value *b = Nucleus::createBitCast(a, Byte16::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04005090 Value *c = Nucleus::createShuffleVector(b, V(Nucleus::createNullValue(Byte16::getType())), swizzle);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005091
Nicolas Capense89cd582016-09-30 14:23:47 -04005092 int swizzle2[8] = {0, 8, 1, 9, 2, 10, 3, 11};
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005093 Value *d = Nucleus::createBitCast(c, Short8::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04005094 e = Nucleus::createShuffleVector(d, V(Nucleus::createNullValue(Short8::getType())), swizzle2);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005095 }
5096
5097 Value *f = Nucleus::createBitCast(e, Int4::getType());
5098 storeValue(f);
5099 }
5100
5101 Int4::Int4(RValue<SByte4> cast)
5102 {
5103 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
Nicolas Capens19336542016-09-26 10:32:29 -04005104 Value *a = Nucleus::createInsertElement(V(UndefValue::get(Int4::getType())), x, 0);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005105
5106 Value *g;
5107
5108 if (CPUID::supportsSSE4_1())
5109 {
5110 g = x86::pmovsxbd(RValue<Int4>(a)).value;
5111 }
5112 else
5113 {
Nicolas Capense89cd582016-09-30 14:23:47 -04005114 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 -04005115 Value *b = Nucleus::createBitCast(a, Byte16::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04005116 Value *c = Nucleus::createShuffleVector(b, b, swizzle);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005117
Nicolas Capense89cd582016-09-30 14:23:47 -04005118 int swizzle2[8] = {0, 0, 1, 1, 2, 2, 3, 3};
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005119 Value *d = Nucleus::createBitCast(c, Short8::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04005120 Value *e = Nucleus::createShuffleVector(d, d, swizzle2);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005121
5122 Value *f = Nucleus::createBitCast(e, Int4::getType());
5123 // g = Nucleus::createAShr(f, Nucleus::createConstantInt(24));
5124 g = x86::psrad(RValue<Int4>(f), 24).value;
5125 }
5126
5127 storeValue(g);
5128 }
5129
John Bauman19bac1e2014-05-06 15:23:49 -04005130 Int4::Int4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005131 {
5132 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005133
5134 Value *xyzw = Nucleus::createFPToSI(cast.value, Int4::getType());
John Bauman89401822014-05-06 15:04:28 -04005135
John Bauman66b8ab22014-05-06 15:57:45 -04005136 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04005137 }
5138
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005139 Int4::Int4(RValue<Short4> cast)
5140 {
Nicolas Capens22008782016-10-20 01:11:47 -04005141 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005142 Value *element = Nucleus::createBitCast(cast.value, Long::getType());
5143 long2 = Nucleus::createInsertElement(long2, element, 0);
5144 RValue<Int4> vector = RValue<Int4>(Nucleus::createBitCast(long2, Int4::getType()));
Nicolas Capens05b3d662016-02-25 23:58:33 -05005145
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005146 if(CPUID::supportsSSE4_1())
5147 {
5148 storeValue(x86::pmovsxwd(vector).value);
5149 }
5150 else
5151 {
5152 Value *b = Nucleus::createBitCast(vector.value, Short8::getType());
5153
Nicolas Capense89cd582016-09-30 14:23:47 -04005154 int swizzle[8] = {0, 0, 1, 1, 2, 2, 3, 3};
5155 Value *c = Nucleus::createShuffleVector(b, b, swizzle);
Nicolas Capens6ce5c332015-10-28 01:58:18 -04005156 Value *d = Nucleus::createBitCast(c, Int4::getType());
5157 storeValue(d);
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005158
5159 // Each Short is packed into each Int in the (Short | Short) format.
5160 // Shifting by 16 will retrieve the original Short value.
5161 // Shitfing an Int will propagate the sign bit, which will work
5162 // for both positive and negative values of a Short.
5163 *this >>= 16;
5164 }
5165 }
5166
5167 Int4::Int4(RValue<UShort4> cast)
5168 {
Nicolas Capens22008782016-10-20 01:11:47 -04005169 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005170 Value *element = Nucleus::createBitCast(cast.value, Long::getType());
5171 long2 = Nucleus::createInsertElement(long2, element, 0);
5172 RValue<Int4> vector = RValue<Int4>(Nucleus::createBitCast(long2, Int4::getType()));
5173
5174 if(CPUID::supportsSSE4_1())
5175 {
5176 storeValue(x86::pmovzxwd(RValue<Int4>(vector)).value);
5177 }
5178 else
5179 {
5180 Value *b = Nucleus::createBitCast(vector.value, Short8::getType());
5181
Nicolas Capense89cd582016-09-30 14:23:47 -04005182 int swizzle[8] = {0, 8, 1, 9, 2, 10, 3, 11};
5183 Value *c = Nucleus::createShuffleVector(b, V(Nucleus::createNullValue(Short8::getType())), swizzle);
Nicolas Capens6ce5c332015-10-28 01:58:18 -04005184 Value *d = Nucleus::createBitCast(c, Int4::getType());
5185 storeValue(d);
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005186 }
5187 }
5188
John Bauman89401822014-05-06 15:04:28 -04005189 Int4::Int4()
5190 {
5191 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005192 }
5193
5194 Int4::Int4(int xyzw)
5195 {
5196 constant(xyzw, xyzw, xyzw, xyzw);
5197 }
5198
5199 Int4::Int4(int x, int yzw)
5200 {
5201 constant(x, yzw, yzw, yzw);
5202 }
5203
5204 Int4::Int4(int x, int y, int zw)
5205 {
5206 constant(x, y, zw, zw);
5207 }
5208
5209 Int4::Int4(int x, int y, int z, int w)
5210 {
5211 constant(x, y, z, w);
5212 }
5213
5214 void Int4::constant(int x, int y, int z, int w)
5215 {
5216 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005217
Nicolas Capens13ac2322016-10-13 14:52:12 -04005218 int64_t constantVector[4] = {x, y, z, w};
5219 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04005220 }
5221
John Bauman19bac1e2014-05-06 15:23:49 -04005222 Int4::Int4(RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005223 {
5224 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005225
John Bauman66b8ab22014-05-06 15:57:45 -04005226 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005227 }
5228
5229 Int4::Int4(const Int4 &rhs)
5230 {
5231 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005232
John Bauman66b8ab22014-05-06 15:57:45 -04005233 Value *value = rhs.loadValue();
5234 storeValue(value);
5235 }
5236
5237 Int4::Int4(const Reference<Int4> &rhs)
5238 {
5239 // xyzw.parent = this;
5240
5241 Value *value = rhs.loadValue();
5242 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005243 }
5244
John Bauman19bac1e2014-05-06 15:23:49 -04005245 Int4::Int4(RValue<UInt4> rhs)
5246 {
5247 // xyzw.parent = this;
John Bauman19bac1e2014-05-06 15:23:49 -04005248
John Bauman66b8ab22014-05-06 15:57:45 -04005249 storeValue(rhs.value);
John Bauman19bac1e2014-05-06 15:23:49 -04005250 }
5251
5252 Int4::Int4(const UInt4 &rhs)
5253 {
5254 // xyzw.parent = this;
John Bauman19bac1e2014-05-06 15:23:49 -04005255
John Bauman66b8ab22014-05-06 15:57:45 -04005256 Value *value = rhs.loadValue();
5257 storeValue(value);
5258 }
5259
5260 Int4::Int4(const Reference<UInt4> &rhs)
5261 {
5262 // xyzw.parent = this;
5263
5264 Value *value = rhs.loadValue();
5265 storeValue(value);
John Bauman19bac1e2014-05-06 15:23:49 -04005266 }
5267
Nicolas Capens62abb552016-01-05 12:03:47 -05005268 Int4::Int4(RValue<Int2> lo, RValue<Int2> hi)
5269 {
Nicolas Capens24c8cf02016-08-15 15:33:14 -04005270 // xyzw.parent = this;
5271
Nicolas Capens62abb552016-01-05 12:03:47 -05005272 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
5273 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
5274
Nicolas Capens22008782016-10-20 01:11:47 -04005275 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Nicolas Capens62abb552016-01-05 12:03:47 -05005276 long2 = Nucleus::createInsertElement(long2, loLong, 0);
5277 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
5278 Value *int4 = Nucleus::createBitCast(long2, Int4::getType());
5279
5280 storeValue(int4);
5281 }
5282
Nicolas Capens24c8cf02016-08-15 15:33:14 -04005283 Int4::Int4(RValue<Int> rhs)
5284 {
5285 // xyzw.parent = this;
5286
5287 Value *vector = loadValue();
5288 Value *insert = Nucleus::createInsertElement(vector, rhs.value, 0);
5289
Nicolas Capense89cd582016-09-30 14:23:47 -04005290 int swizzle[4] = {0, 0, 0, 0};
5291 Value *replicate = Nucleus::createShuffleVector(insert, insert, swizzle);
Nicolas Capens24c8cf02016-08-15 15:33:14 -04005292
5293 storeValue(replicate);
5294 }
5295
5296 Int4::Int4(const Int &rhs)
5297 {
5298 // xyzw.parent = this;
5299
5300 *this = RValue<Int>(rhs.loadValue());
5301 }
5302
5303 Int4::Int4(const Reference<Int> &rhs)
5304 {
5305 // xyzw.parent = this;
5306
5307 *this = RValue<Int>(rhs.loadValue());
5308 }
5309
John Bauman19bac1e2014-05-06 15:23:49 -04005310 RValue<Int4> Int4::operator=(RValue<Int4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04005311 {
John Bauman66b8ab22014-05-06 15:57:45 -04005312 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005313
5314 return rhs;
5315 }
5316
5317 RValue<Int4> Int4::operator=(const Int4 &rhs) const
5318 {
John Bauman66b8ab22014-05-06 15:57:45 -04005319 Value *value = rhs.loadValue();
5320 storeValue(value);
5321
5322 return RValue<Int4>(value);
5323 }
5324
5325 RValue<Int4> Int4::operator=(const Reference<Int4> &rhs) const
5326 {
5327 Value *value = rhs.loadValue();
5328 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005329
5330 return RValue<Int4>(value);
5331 }
5332
John Bauman19bac1e2014-05-06 15:23:49 -04005333 RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005334 {
5335 return RValue<Int4>(Nucleus::createAdd(lhs.value, rhs.value));
5336 }
5337
John Bauman19bac1e2014-05-06 15:23:49 -04005338 RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005339 {
5340 return RValue<Int4>(Nucleus::createSub(lhs.value, rhs.value));
5341 }
5342
John Bauman19bac1e2014-05-06 15:23:49 -04005343 RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005344 {
5345 return RValue<Int4>(Nucleus::createMul(lhs.value, rhs.value));
5346 }
5347
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005348 RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs)
5349 {
5350 return RValue<Int4>(Nucleus::createSDiv(lhs.value, rhs.value));
5351 }
John Bauman89401822014-05-06 15:04:28 -04005352
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005353 RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs)
5354 {
5355 return RValue<Int4>(Nucleus::createSRem(lhs.value, rhs.value));
5356 }
John Bauman89401822014-05-06 15:04:28 -04005357
John Bauman19bac1e2014-05-06 15:23:49 -04005358 RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005359 {
5360 return RValue<Int4>(Nucleus::createAnd(lhs.value, rhs.value));
5361 }
5362
John Bauman19bac1e2014-05-06 15:23:49 -04005363 RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005364 {
5365 return RValue<Int4>(Nucleus::createOr(lhs.value, rhs.value));
5366 }
5367
John Bauman19bac1e2014-05-06 15:23:49 -04005368 RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005369 {
5370 return RValue<Int4>(Nucleus::createXor(lhs.value, rhs.value));
5371 }
5372
John Bauman19bac1e2014-05-06 15:23:49 -04005373 RValue<Int4> operator<<(RValue<Int4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005374 {
John Bauman89401822014-05-06 15:04:28 -04005375 return x86::pslld(lhs, rhs);
5376 }
5377
John Bauman19bac1e2014-05-06 15:23:49 -04005378 RValue<Int4> operator>>(RValue<Int4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005379 {
John Bauman89401822014-05-06 15:04:28 -04005380 return x86::psrad(lhs, rhs);
5381 }
5382
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005383 RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs)
5384 {
5385 return RValue<Int4>(Nucleus::createShl(lhs.value, rhs.value));
5386 }
5387
5388 RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs)
5389 {
5390 return RValue<Int4>(Nucleus::createAShr(lhs.value, rhs.value));
5391 }
5392
John Bauman19bac1e2014-05-06 15:23:49 -04005393 RValue<Int4> operator+=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005394 {
5395 return lhs = lhs + rhs;
5396 }
5397
John Bauman19bac1e2014-05-06 15:23:49 -04005398 RValue<Int4> operator-=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005399 {
5400 return lhs = lhs - rhs;
5401 }
5402
John Bauman19bac1e2014-05-06 15:23:49 -04005403 RValue<Int4> operator*=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005404 {
5405 return lhs = lhs * rhs;
5406 }
5407
John Bauman19bac1e2014-05-06 15:23:49 -04005408// RValue<Int4> operator/=(const Int4 &lhs, RValue<Int4> rhs)
5409// {
5410// return lhs = lhs / rhs;
5411// }
John Bauman89401822014-05-06 15:04:28 -04005412
John Bauman19bac1e2014-05-06 15:23:49 -04005413// RValue<Int4> operator%=(const Int4 &lhs, RValue<Int4> rhs)
5414// {
5415// return lhs = lhs % rhs;
5416// }
John Bauman89401822014-05-06 15:04:28 -04005417
John Bauman19bac1e2014-05-06 15:23:49 -04005418 RValue<Int4> operator&=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005419 {
5420 return lhs = lhs & rhs;
5421 }
5422
John Bauman19bac1e2014-05-06 15:23:49 -04005423 RValue<Int4> operator|=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005424 {
5425 return lhs = lhs | rhs;
5426 }
5427
John Bauman19bac1e2014-05-06 15:23:49 -04005428 RValue<Int4> operator^=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005429 {
5430 return lhs = lhs ^ rhs;
5431 }
5432
5433 RValue<Int4> operator<<=(const Int4 &lhs, unsigned char rhs)
5434 {
5435 return lhs = lhs << rhs;
5436 }
5437
5438 RValue<Int4> operator>>=(const Int4 &lhs, unsigned char rhs)
5439 {
5440 return lhs = lhs >> rhs;
5441 }
5442
John Bauman19bac1e2014-05-06 15:23:49 -04005443 RValue<Int4> operator+(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005444 {
5445 return val;
5446 }
5447
John Bauman19bac1e2014-05-06 15:23:49 -04005448 RValue<Int4> operator-(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005449 {
5450 return RValue<Int4>(Nucleus::createNeg(val.value));
5451 }
5452
John Bauman19bac1e2014-05-06 15:23:49 -04005453 RValue<Int4> operator~(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005454 {
5455 return RValue<Int4>(Nucleus::createNot(val.value));
5456 }
5457
John Bauman19bac1e2014-05-06 15:23:49 -04005458 RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y)
5459 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005460 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
Alexis Hetufb603992016-04-26 11:50:40 -04005461 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5462 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
5463 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005464 }
5465
5466 RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y)
5467 {
5468 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLT(x.value, y.value), Int4::getType()));
5469 }
5470
5471 RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y)
5472 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005473 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5474 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5475 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLE(x.value, y.value), Int4::getType()));
5476 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGT(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005477 }
5478
5479 RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y)
5480 {
5481 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
5482 }
5483
5484 RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y)
5485 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005486 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5487 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5488 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGE(x.value, y.value), Int4::getType()));
5489 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLT(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005490 }
5491
5492 RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y)
5493 {
5494 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGT(x.value, y.value), Int4::getType()));
5495 }
5496
5497 RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y)
5498 {
5499 if(CPUID::supportsSSE4_1())
5500 {
5501 return x86::pmaxsd(x, y);
5502 }
5503 else
5504 {
5505 RValue<Int4> greater = CmpNLE(x, y);
5506 return x & greater | y & ~greater;
5507 }
5508 }
5509
5510 RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y)
5511 {
5512 if(CPUID::supportsSSE4_1())
5513 {
5514 return x86::pminsd(x, y);
5515 }
5516 else
5517 {
5518 RValue<Int4> less = CmpLT(x, y);
5519 return x & less | y & ~less;
5520 }
5521 }
5522
5523 RValue<Int4> RoundInt(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005524 {
5525 return x86::cvtps2dq(cast);
5526 }
5527
John Bauman19bac1e2014-05-06 15:23:49 -04005528 RValue<Short8> Pack(RValue<Int4> x, RValue<Int4> y)
John Bauman89401822014-05-06 15:04:28 -04005529 {
5530 return x86::packssdw(x, y);
5531 }
5532
John Bauman19bac1e2014-05-06 15:23:49 -04005533 RValue<Int> Extract(RValue<Int4> x, int i)
John Bauman89401822014-05-06 15:04:28 -04005534 {
Nicolas Capense95d5342016-09-30 11:37:28 -04005535 return RValue<Int>(Nucleus::createExtractElement(x.value, Int::getType(), i));
John Bauman89401822014-05-06 15:04:28 -04005536 }
5537
John Bauman19bac1e2014-05-06 15:23:49 -04005538 RValue<Int4> Insert(RValue<Int4> x, RValue<Int> element, int i)
John Bauman89401822014-05-06 15:04:28 -04005539 {
5540 return RValue<Int4>(Nucleus::createInsertElement(x.value, element.value, i));
5541 }
5542
John Bauman19bac1e2014-05-06 15:23:49 -04005543 RValue<Int> SignMask(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04005544 {
5545 return x86::movmskps(As<Float4>(x));
5546 }
5547
John Bauman19bac1e2014-05-06 15:23:49 -04005548 RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04005549 {
Nicolas Capense95d5342016-09-30 11:37:28 -04005550 return RValue<Int4>(createSwizzle4(x.value, select));
John Bauman89401822014-05-06 15:04:28 -04005551 }
5552
John Bauman19bac1e2014-05-06 15:23:49 -04005553 Type *Int4::getType()
John Bauman89401822014-05-06 15:04:28 -04005554 {
Nicolas Capensac230122016-09-20 14:30:06 -04005555 return T(VectorType::get(Int::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04005556 }
5557
John Bauman19bac1e2014-05-06 15:23:49 -04005558 UInt4::UInt4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005559 {
5560 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005561
Alexis Hetu764d1422016-09-28 08:44:22 -04005562 // Note: createFPToUI is broken, must perform conversion using createFPtoSI
5563 // Value *xyzw = Nucleus::createFPToUI(cast.value, UInt4::getType());
John Bauman89401822014-05-06 15:04:28 -04005564
Alexis Hetu764d1422016-09-28 08:44:22 -04005565 // Smallest positive value representable in UInt, but not in Int
5566 const unsigned int ustart = 0x80000000u;
5567 const float ustartf = float(ustart);
5568
5569 // Check if the value can be represented as an Int
5570 Int4 uiValue = CmpNLT(cast, Float4(ustartf));
5571 // If the value is too large, subtract ustart and re-add it after conversion.
5572 uiValue = (uiValue & As<Int4>(As<UInt4>(Int4(cast - Float4(ustartf))) + UInt4(ustart))) |
5573 // Otherwise, just convert normally
5574 (~uiValue & Int4(cast));
5575 // If the value is negative, store 0, otherwise store the result of the conversion
5576 storeValue((~(As<Int4>(cast) >> 31) & uiValue).value);
John Bauman89401822014-05-06 15:04:28 -04005577 }
5578
5579 UInt4::UInt4()
5580 {
5581 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005582 }
5583
John Bauman19bac1e2014-05-06 15:23:49 -04005584 UInt4::UInt4(int xyzw)
5585 {
5586 constant(xyzw, xyzw, xyzw, xyzw);
5587 }
5588
5589 UInt4::UInt4(int x, int yzw)
5590 {
5591 constant(x, yzw, yzw, yzw);
5592 }
5593
5594 UInt4::UInt4(int x, int y, int zw)
5595 {
5596 constant(x, y, zw, zw);
5597 }
5598
5599 UInt4::UInt4(int x, int y, int z, int w)
5600 {
5601 constant(x, y, z, w);
5602 }
5603
5604 void UInt4::constant(int x, int y, int z, int w)
John Bauman89401822014-05-06 15:04:28 -04005605 {
5606 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005607
Nicolas Capens13ac2322016-10-13 14:52:12 -04005608 int64_t constantVector[4] = {x, y, z, w};
5609 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04005610 }
5611
John Bauman19bac1e2014-05-06 15:23:49 -04005612 UInt4::UInt4(RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005613 {
5614 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005615
John Bauman66b8ab22014-05-06 15:57:45 -04005616 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005617 }
5618
5619 UInt4::UInt4(const UInt4 &rhs)
5620 {
5621 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005622
John Bauman66b8ab22014-05-06 15:57:45 -04005623 Value *value = rhs.loadValue();
5624 storeValue(value);
5625 }
5626
5627 UInt4::UInt4(const Reference<UInt4> &rhs)
5628 {
5629 // xyzw.parent = this;
5630
5631 Value *value = rhs.loadValue();
5632 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005633 }
5634
John Bauman19bac1e2014-05-06 15:23:49 -04005635 UInt4::UInt4(RValue<Int4> rhs)
5636 {
5637 // xyzw.parent = this;
John Bauman19bac1e2014-05-06 15:23:49 -04005638
John Bauman66b8ab22014-05-06 15:57:45 -04005639 storeValue(rhs.value);
John Bauman19bac1e2014-05-06 15:23:49 -04005640 }
5641
5642 UInt4::UInt4(const Int4 &rhs)
5643 {
5644 // xyzw.parent = this;
John Bauman19bac1e2014-05-06 15:23:49 -04005645
John Bauman66b8ab22014-05-06 15:57:45 -04005646 Value *value = rhs.loadValue();
5647 storeValue(value);
5648 }
5649
5650 UInt4::UInt4(const Reference<Int4> &rhs)
5651 {
5652 // xyzw.parent = this;
5653
5654 Value *value = rhs.loadValue();
5655 storeValue(value);
John Bauman19bac1e2014-05-06 15:23:49 -04005656 }
5657
Nicolas Capens62abb552016-01-05 12:03:47 -05005658 UInt4::UInt4(RValue<UInt2> lo, RValue<UInt2> hi)
5659 {
5660 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
5661 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
5662
Nicolas Capens22008782016-10-20 01:11:47 -04005663 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Nicolas Capens62abb552016-01-05 12:03:47 -05005664 long2 = Nucleus::createInsertElement(long2, loLong, 0);
5665 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
5666 Value *uint4 = Nucleus::createBitCast(long2, Int4::getType());
5667
5668 storeValue(uint4);
5669 }
5670
John Bauman19bac1e2014-05-06 15:23:49 -04005671 RValue<UInt4> UInt4::operator=(RValue<UInt4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04005672 {
John Bauman66b8ab22014-05-06 15:57:45 -04005673 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005674
5675 return rhs;
5676 }
5677
5678 RValue<UInt4> UInt4::operator=(const UInt4 &rhs) const
5679 {
John Bauman66b8ab22014-05-06 15:57:45 -04005680 Value *value = rhs.loadValue();
5681 storeValue(value);
5682
5683 return RValue<UInt4>(value);
5684 }
5685
5686 RValue<UInt4> UInt4::operator=(const Reference<UInt4> &rhs) const
5687 {
5688 Value *value = rhs.loadValue();
5689 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005690
5691 return RValue<UInt4>(value);
5692 }
5693
John Bauman19bac1e2014-05-06 15:23:49 -04005694 RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005695 {
5696 return RValue<UInt4>(Nucleus::createAdd(lhs.value, rhs.value));
5697 }
5698
John Bauman19bac1e2014-05-06 15:23:49 -04005699 RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005700 {
5701 return RValue<UInt4>(Nucleus::createSub(lhs.value, rhs.value));
5702 }
5703
John Bauman19bac1e2014-05-06 15:23:49 -04005704 RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005705 {
5706 return RValue<UInt4>(Nucleus::createMul(lhs.value, rhs.value));
5707 }
5708
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005709 RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs)
5710 {
5711 return RValue<UInt4>(Nucleus::createUDiv(lhs.value, rhs.value));
5712 }
John Bauman89401822014-05-06 15:04:28 -04005713
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005714 RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs)
5715 {
5716 return RValue<UInt4>(Nucleus::createURem(lhs.value, rhs.value));
5717 }
John Bauman89401822014-05-06 15:04:28 -04005718
John Bauman19bac1e2014-05-06 15:23:49 -04005719 RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005720 {
5721 return RValue<UInt4>(Nucleus::createAnd(lhs.value, rhs.value));
5722 }
5723
John Bauman19bac1e2014-05-06 15:23:49 -04005724 RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005725 {
5726 return RValue<UInt4>(Nucleus::createOr(lhs.value, rhs.value));
5727 }
5728
John Bauman19bac1e2014-05-06 15:23:49 -04005729 RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005730 {
5731 return RValue<UInt4>(Nucleus::createXor(lhs.value, rhs.value));
5732 }
5733
John Bauman19bac1e2014-05-06 15:23:49 -04005734 RValue<UInt4> operator<<(RValue<UInt4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005735 {
John Bauman89401822014-05-06 15:04:28 -04005736 return As<UInt4>(x86::pslld(As<Int4>(lhs), rhs));
5737 }
5738
John Bauman19bac1e2014-05-06 15:23:49 -04005739 RValue<UInt4> operator>>(RValue<UInt4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005740 {
John Bauman89401822014-05-06 15:04:28 -04005741 return x86::psrld(lhs, rhs);
5742 }
5743
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005744 RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs)
5745 {
5746 return RValue<UInt4>(Nucleus::createShl(lhs.value, rhs.value));
5747 }
5748
5749 RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs)
5750 {
5751 return RValue<UInt4>(Nucleus::createLShr(lhs.value, rhs.value));
5752 }
5753
John Bauman19bac1e2014-05-06 15:23:49 -04005754 RValue<UInt4> operator+=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005755 {
5756 return lhs = lhs + rhs;
5757 }
5758
John Bauman19bac1e2014-05-06 15:23:49 -04005759 RValue<UInt4> operator-=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005760 {
5761 return lhs = lhs - rhs;
5762 }
5763
John Bauman19bac1e2014-05-06 15:23:49 -04005764 RValue<UInt4> operator*=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005765 {
5766 return lhs = lhs * rhs;
5767 }
5768
John Bauman19bac1e2014-05-06 15:23:49 -04005769// RValue<UInt4> operator/=(const UInt4 &lhs, RValue<UInt4> rhs)
5770// {
5771// return lhs = lhs / rhs;
5772// }
John Bauman89401822014-05-06 15:04:28 -04005773
John Bauman19bac1e2014-05-06 15:23:49 -04005774// RValue<UInt4> operator%=(const UInt4 &lhs, RValue<UInt4> rhs)
5775// {
5776// return lhs = lhs % rhs;
5777// }
John Bauman89401822014-05-06 15:04:28 -04005778
John Bauman19bac1e2014-05-06 15:23:49 -04005779 RValue<UInt4> operator&=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005780 {
5781 return lhs = lhs & rhs;
5782 }
5783
John Bauman19bac1e2014-05-06 15:23:49 -04005784 RValue<UInt4> operator|=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005785 {
5786 return lhs = lhs | rhs;
5787 }
5788
John Bauman19bac1e2014-05-06 15:23:49 -04005789 RValue<UInt4> operator^=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005790 {
5791 return lhs = lhs ^ rhs;
5792 }
5793
5794 RValue<UInt4> operator<<=(const UInt4 &lhs, unsigned char rhs)
5795 {
5796 return lhs = lhs << rhs;
5797 }
5798
5799 RValue<UInt4> operator>>=(const UInt4 &lhs, unsigned char rhs)
5800 {
5801 return lhs = lhs >> rhs;
5802 }
5803
John Bauman19bac1e2014-05-06 15:23:49 -04005804 RValue<UInt4> operator+(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04005805 {
5806 return val;
5807 }
5808
John Bauman19bac1e2014-05-06 15:23:49 -04005809 RValue<UInt4> operator-(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04005810 {
5811 return RValue<UInt4>(Nucleus::createNeg(val.value));
5812 }
5813
John Bauman19bac1e2014-05-06 15:23:49 -04005814 RValue<UInt4> operator~(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04005815 {
5816 return RValue<UInt4>(Nucleus::createNot(val.value));
5817 }
5818
John Bauman19bac1e2014-05-06 15:23:49 -04005819 RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y)
5820 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005821 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
Alexis Hetufb603992016-04-26 11:50:40 -04005822 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5823 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
5824 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005825 }
5826
5827 RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y)
5828 {
5829 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULT(x.value, y.value), Int4::getType()));
5830 }
5831
5832 RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y)
5833 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005834 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5835 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5836 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULE(x.value, y.value), Int4::getType()));
5837 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGT(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005838 }
5839
5840 RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y)
5841 {
5842 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
5843 }
5844
5845 RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y)
5846 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005847 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5848 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5849 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGE(x.value, y.value), Int4::getType()));
5850 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULT(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005851 }
5852
5853 RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y)
5854 {
5855 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGT(x.value, y.value), Int4::getType()));
5856 }
5857
5858 RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y)
5859 {
5860 if(CPUID::supportsSSE4_1())
5861 {
5862 return x86::pmaxud(x, y);
5863 }
5864 else
5865 {
5866 RValue<UInt4> greater = CmpNLE(x, y);
5867 return x & greater | y & ~greater;
5868 }
5869 }
5870
5871 RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y)
5872 {
5873 if(CPUID::supportsSSE4_1())
5874 {
5875 return x86::pminud(x, y);
5876 }
5877 else
5878 {
5879 RValue<UInt4> less = CmpLT(x, y);
5880 return x & less | y & ~less;
5881 }
5882 }
5883
5884 RValue<UShort8> Pack(RValue<UInt4> x, RValue<UInt4> y)
John Bauman89401822014-05-06 15:04:28 -04005885 {
5886 return x86::packusdw(x, y); // FIXME: Fallback required
5887 }
5888
John Bauman19bac1e2014-05-06 15:23:49 -04005889 Type *UInt4::getType()
John Bauman89401822014-05-06 15:04:28 -04005890 {
Nicolas Capensac230122016-09-20 14:30:06 -04005891 return T(VectorType::get(UInt::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04005892 }
5893
John Bauman19bac1e2014-05-06 15:23:49 -04005894 Float::Float(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04005895 {
John Bauman89401822014-05-06 15:04:28 -04005896 Value *integer = Nucleus::createSIToFP(cast.value, Float::getType());
5897
John Bauman66b8ab22014-05-06 15:57:45 -04005898 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04005899 }
5900
5901 Float::Float()
5902 {
John Bauman66b8ab22014-05-06 15:57:45 -04005903
John Bauman89401822014-05-06 15:04:28 -04005904 }
5905
5906 Float::Float(float x)
5907 {
John Bauman66b8ab22014-05-06 15:57:45 -04005908 storeValue(Nucleus::createConstantFloat(x));
John Bauman89401822014-05-06 15:04:28 -04005909 }
5910
John Bauman19bac1e2014-05-06 15:23:49 -04005911 Float::Float(RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005912 {
John Bauman66b8ab22014-05-06 15:57:45 -04005913 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005914 }
5915
5916 Float::Float(const Float &rhs)
5917 {
John Bauman66b8ab22014-05-06 15:57:45 -04005918 Value *value = rhs.loadValue();
5919 storeValue(value);
5920 }
John Bauman89401822014-05-06 15:04:28 -04005921
John Bauman66b8ab22014-05-06 15:57:45 -04005922 Float::Float(const Reference<Float> &rhs)
5923 {
5924 Value *value = rhs.loadValue();
5925 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005926 }
5927
John Bauman19bac1e2014-05-06 15:23:49 -04005928 RValue<Float> Float::operator=(RValue<Float> rhs) const
John Bauman89401822014-05-06 15:04:28 -04005929 {
John Bauman66b8ab22014-05-06 15:57:45 -04005930 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005931
5932 return rhs;
5933 }
5934
5935 RValue<Float> Float::operator=(const Float &rhs) const
5936 {
John Bauman66b8ab22014-05-06 15:57:45 -04005937 Value *value = rhs.loadValue();
5938 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005939
5940 return RValue<Float>(value);
5941 }
5942
John Bauman66b8ab22014-05-06 15:57:45 -04005943 RValue<Float> Float::operator=(const Reference<Float> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04005944 {
John Bauman66b8ab22014-05-06 15:57:45 -04005945 Value *value = rhs.loadValue();
5946 storeValue(value);
5947
5948 return RValue<Float>(value);
John Bauman89401822014-05-06 15:04:28 -04005949 }
5950
John Bauman19bac1e2014-05-06 15:23:49 -04005951 RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005952 {
5953 return RValue<Float>(Nucleus::createFAdd(lhs.value, rhs.value));
5954 }
5955
John Bauman19bac1e2014-05-06 15:23:49 -04005956 RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005957 {
5958 return RValue<Float>(Nucleus::createFSub(lhs.value, rhs.value));
5959 }
5960
John Bauman19bac1e2014-05-06 15:23:49 -04005961 RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005962 {
5963 return RValue<Float>(Nucleus::createFMul(lhs.value, rhs.value));
5964 }
5965
John Bauman19bac1e2014-05-06 15:23:49 -04005966 RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005967 {
5968 return RValue<Float>(Nucleus::createFDiv(lhs.value, rhs.value));
5969 }
5970
John Bauman19bac1e2014-05-06 15:23:49 -04005971 RValue<Float> operator+=(const Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005972 {
5973 return lhs = lhs + rhs;
5974 }
5975
John Bauman19bac1e2014-05-06 15:23:49 -04005976 RValue<Float> operator-=(const Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005977 {
5978 return lhs = lhs - rhs;
5979 }
5980
John Bauman19bac1e2014-05-06 15:23:49 -04005981 RValue<Float> operator*=(const Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005982 {
5983 return lhs = lhs * rhs;
5984 }
5985
John Bauman19bac1e2014-05-06 15:23:49 -04005986 RValue<Float> operator/=(const Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005987 {
5988 return lhs = lhs / rhs;
5989 }
5990
John Bauman19bac1e2014-05-06 15:23:49 -04005991 RValue<Float> operator+(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04005992 {
5993 return val;
5994 }
5995
John Bauman19bac1e2014-05-06 15:23:49 -04005996 RValue<Float> operator-(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04005997 {
5998 return RValue<Float>(Nucleus::createFNeg(val.value));
5999 }
6000
John Bauman19bac1e2014-05-06 15:23:49 -04006001 RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006002 {
6003 return RValue<Bool>(Nucleus::createFCmpOLT(lhs.value, rhs.value));
6004 }
6005
John Bauman19bac1e2014-05-06 15:23:49 -04006006 RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006007 {
6008 return RValue<Bool>(Nucleus::createFCmpOLE(lhs.value, rhs.value));
6009 }
6010
John Bauman19bac1e2014-05-06 15:23:49 -04006011 RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006012 {
6013 return RValue<Bool>(Nucleus::createFCmpOGT(lhs.value, rhs.value));
6014 }
6015
John Bauman19bac1e2014-05-06 15:23:49 -04006016 RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006017 {
6018 return RValue<Bool>(Nucleus::createFCmpOGE(lhs.value, rhs.value));
6019 }
6020
John Bauman19bac1e2014-05-06 15:23:49 -04006021 RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006022 {
6023 return RValue<Bool>(Nucleus::createFCmpONE(lhs.value, rhs.value));
6024 }
6025
John Bauman19bac1e2014-05-06 15:23:49 -04006026 RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006027 {
6028 return RValue<Bool>(Nucleus::createFCmpOEQ(lhs.value, rhs.value));
6029 }
6030
John Bauman19bac1e2014-05-06 15:23:49 -04006031 RValue<Float> Abs(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006032 {
John Bauman66b8ab22014-05-06 15:57:45 -04006033 return IfThenElse(x > 0.0f, x, -x);
John Bauman89401822014-05-06 15:04:28 -04006034 }
6035
John Bauman19bac1e2014-05-06 15:23:49 -04006036 RValue<Float> Max(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006037 {
6038 return IfThenElse(x > y, x, y);
6039 }
6040
John Bauman19bac1e2014-05-06 15:23:49 -04006041 RValue<Float> Min(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006042 {
6043 return IfThenElse(x < y, x, y);
6044 }
6045
Nicolas Capens05b3d662016-02-25 23:58:33 -05006046 RValue<Float> Rcp_pp(RValue<Float> x, bool exactAtPow2)
John Bauman89401822014-05-06 15:04:28 -04006047 {
Nicolas Capens05b3d662016-02-25 23:58:33 -05006048 if(exactAtPow2)
6049 {
6050 // rcpss uses a piecewise-linear approximation which minimizes the relative error
6051 // but is not exact at power-of-two values. Rectify by multiplying by the inverse.
6052 return x86::rcpss(x) * Float(1.0f / _mm_cvtss_f32(_mm_rcp_ss(_mm_set_ps1(1.0f))));
6053 }
6054 else
6055 {
6056 return x86::rcpss(x);
6057 }
John Bauman89401822014-05-06 15:04:28 -04006058 }
John Bauman66b8ab22014-05-06 15:57:45 -04006059
John Bauman19bac1e2014-05-06 15:23:49 -04006060 RValue<Float> RcpSqrt_pp(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006061 {
6062 return x86::rsqrtss(x);
6063 }
6064
John Bauman19bac1e2014-05-06 15:23:49 -04006065 RValue<Float> Sqrt(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006066 {
6067 return x86::sqrtss(x);
6068 }
6069
John Bauman19bac1e2014-05-06 15:23:49 -04006070 RValue<Float> Round(RValue<Float> x)
6071 {
6072 if(CPUID::supportsSSE4_1())
6073 {
6074 return x86::roundss(x, 0);
6075 }
6076 else
6077 {
6078 return Float4(Round(Float4(x))).x;
6079 }
6080 }
6081
6082 RValue<Float> Trunc(RValue<Float> x)
6083 {
6084 if(CPUID::supportsSSE4_1())
6085 {
6086 return x86::roundss(x, 3);
6087 }
6088 else
6089 {
6090 return Float(Int(x)); // Rounded toward zero
6091 }
6092 }
6093
6094 RValue<Float> Frac(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006095 {
6096 if(CPUID::supportsSSE4_1())
6097 {
6098 return x - x86::floorss(x);
6099 }
6100 else
6101 {
John Bauman19bac1e2014-05-06 15:23:49 -04006102 return Float4(Frac(Float4(x))).x;
John Bauman89401822014-05-06 15:04:28 -04006103 }
6104 }
6105
John Bauman19bac1e2014-05-06 15:23:49 -04006106 RValue<Float> Floor(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006107 {
6108 if(CPUID::supportsSSE4_1())
6109 {
6110 return x86::floorss(x);
6111 }
6112 else
6113 {
6114 return Float4(Floor(Float4(x))).x;
6115 }
6116 }
6117
John Bauman19bac1e2014-05-06 15:23:49 -04006118 RValue<Float> Ceil(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006119 {
John Bauman19bac1e2014-05-06 15:23:49 -04006120 if(CPUID::supportsSSE4_1())
6121 {
6122 return x86::ceilss(x);
6123 }
6124 else
6125 {
6126 return Float4(Ceil(Float4(x))).x;
6127 }
John Bauman89401822014-05-06 15:04:28 -04006128 }
6129
John Bauman19bac1e2014-05-06 15:23:49 -04006130 Type *Float::getType()
John Bauman89401822014-05-06 15:04:28 -04006131 {
Nicolas Capensac230122016-09-20 14:30:06 -04006132 return T(llvm::Type::getFloatTy(*::context));
John Bauman89401822014-05-06 15:04:28 -04006133 }
6134
John Bauman19bac1e2014-05-06 15:23:49 -04006135 Float2::Float2(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04006136 {
6137 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006138
Nicolas Capens22008782016-10-20 01:11:47 -04006139 Value *int64x2 = Nucleus::createBitCast(cast.value, T(VectorType::get(Long::getType(), 2)));
Nicolas Capense95d5342016-09-30 11:37:28 -04006140 Value *int64 = Nucleus::createExtractElement(int64x2, Long::getType(), 0);
John Bauman89401822014-05-06 15:04:28 -04006141 Value *float2 = Nucleus::createBitCast(int64, Float2::getType());
6142
John Bauman66b8ab22014-05-06 15:57:45 -04006143 storeValue(float2);
John Bauman89401822014-05-06 15:04:28 -04006144 }
6145
John Bauman19bac1e2014-05-06 15:23:49 -04006146 Type *Float2::getType()
John Bauman89401822014-05-06 15:04:28 -04006147 {
Nicolas Capensac230122016-09-20 14:30:06 -04006148 return T(VectorType::get(Float::getType(), 2));
John Bauman89401822014-05-06 15:04:28 -04006149 }
6150
John Bauman19bac1e2014-05-06 15:23:49 -04006151 Float4::Float4(RValue<Byte4> cast)
John Bauman89401822014-05-06 15:04:28 -04006152 {
6153 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006154
6155 #if 0
6156 Value *xyzw = Nucleus::createUIToFP(cast.value, Float4::getType()); // FIXME: Crashes
6157 #elif 0
John Bauman66b8ab22014-05-06 15:57:45 -04006158 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04006159
6160 Value *i8x = Nucleus::createExtractElement(cast.value, 0);
6161 Value *f32x = Nucleus::createUIToFP(i8x, Float::getType());
6162 Value *x = Nucleus::createInsertElement(vector, f32x, 0);
6163
Nicolas Capens19336542016-09-26 10:32:29 -04006164 Value *i8y = Nucleus::createExtractElement(cast.value, V(Nucleus::createConstantInt(1)));
John Bauman89401822014-05-06 15:04:28 -04006165 Value *f32y = Nucleus::createUIToFP(i8y, Float::getType());
Nicolas Capens19336542016-09-26 10:32:29 -04006166 Value *xy = Nucleus::createInsertElement(x, f32y, V(Nucleus::createConstantInt(1)));
John Bauman89401822014-05-06 15:04:28 -04006167
6168 Value *i8z = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(2));
6169 Value *f32z = Nucleus::createUIToFP(i8z, Float::getType());
6170 Value *xyz = Nucleus::createInsertElement(xy, f32z, Nucleus::createConstantInt(2));
6171
6172 Value *i8w = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(3));
6173 Value *f32w = Nucleus::createUIToFP(i8w, Float::getType());
6174 Value *xyzw = Nucleus::createInsertElement(xyz, f32w, Nucleus::createConstantInt(3));
6175 #else
Meng-Lin Wu601d0052016-06-10 14:18:41 -04006176 Value *a = Int4(cast).loadValue();
6177 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04006178 #endif
John Bauman66b8ab22014-05-06 15:57:45 -04006179
6180 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04006181 }
6182
John Bauman19bac1e2014-05-06 15:23:49 -04006183 Float4::Float4(RValue<SByte4> cast)
John Bauman89401822014-05-06 15:04:28 -04006184 {
6185 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006186
6187 #if 0
6188 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType()); // FIXME: Crashes
6189 #elif 0
John Bauman66b8ab22014-05-06 15:57:45 -04006190 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04006191
6192 Value *i8x = Nucleus::createExtractElement(cast.value, 0);
6193 Value *f32x = Nucleus::createSIToFP(i8x, Float::getType());
6194 Value *x = Nucleus::createInsertElement(vector, f32x, 0);
6195
Nicolas Capens19336542016-09-26 10:32:29 -04006196 Value *i8y = Nucleus::createExtractElement(cast.value, V(Nucleus::createConstantInt(1)));
John Bauman89401822014-05-06 15:04:28 -04006197 Value *f32y = Nucleus::createSIToFP(i8y, Float::getType());
Nicolas Capens19336542016-09-26 10:32:29 -04006198 Value *xy = Nucleus::createInsertElement(x, f32y, V(Nucleus::createConstantInt(1)));
John Bauman89401822014-05-06 15:04:28 -04006199
6200 Value *i8z = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(2));
6201 Value *f32z = Nucleus::createSIToFP(i8z, Float::getType());
6202 Value *xyz = Nucleus::createInsertElement(xy, f32z, Nucleus::createConstantInt(2));
6203
6204 Value *i8w = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(3));
6205 Value *f32w = Nucleus::createSIToFP(i8w, Float::getType());
6206 Value *xyzw = Nucleus::createInsertElement(xyz, f32w, Nucleus::createConstantInt(3));
6207 #else
Meng-Lin Wu601d0052016-06-10 14:18:41 -04006208 Value *a = Int4(cast).loadValue();
6209 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04006210 #endif
John Bauman66b8ab22014-05-06 15:57:45 -04006211
6212 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04006213 }
6214
John Bauman19bac1e2014-05-06 15:23:49 -04006215 Float4::Float4(RValue<Short4> cast)
John Bauman89401822014-05-06 15:04:28 -04006216 {
6217 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006218
Alexis Hetu2aa852f2015-10-14 16:32:39 -04006219 Int4 c(cast);
6220 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
John Bauman89401822014-05-06 15:04:28 -04006221 }
6222
John Bauman19bac1e2014-05-06 15:23:49 -04006223 Float4::Float4(RValue<UShort4> cast)
John Bauman89401822014-05-06 15:04:28 -04006224 {
6225 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006226
Alexis Hetu2aa852f2015-10-14 16:32:39 -04006227 Int4 c(cast);
6228 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
John Bauman89401822014-05-06 15:04:28 -04006229 }
6230
John Bauman19bac1e2014-05-06 15:23:49 -04006231 Float4::Float4(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04006232 {
6233 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006234
6235 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04006236
John Bauman66b8ab22014-05-06 15:57:45 -04006237 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04006238 }
6239
John Bauman19bac1e2014-05-06 15:23:49 -04006240 Float4::Float4(RValue<UInt4> cast)
John Bauman89401822014-05-06 15:04:28 -04006241 {
6242 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006243
6244 Value *xyzw = Nucleus::createUIToFP(cast.value, Float4::getType());
6245
John Bauman66b8ab22014-05-06 15:57:45 -04006246 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04006247 }
6248
6249 Float4::Float4()
6250 {
6251 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006252 }
John Bauman66b8ab22014-05-06 15:57:45 -04006253
John Bauman89401822014-05-06 15:04:28 -04006254 Float4::Float4(float xyzw)
6255 {
6256 constant(xyzw, xyzw, xyzw, xyzw);
6257 }
6258
6259 Float4::Float4(float x, float yzw)
6260 {
6261 constant(x, yzw, yzw, yzw);
6262 }
6263
6264 Float4::Float4(float x, float y, float zw)
6265 {
6266 constant(x, y, zw, zw);
6267 }
6268
6269 Float4::Float4(float x, float y, float z, float w)
6270 {
6271 constant(x, y, z, w);
6272 }
6273
6274 void Float4::constant(float x, float y, float z, float w)
6275 {
6276 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006277
Nicolas Capens13ac2322016-10-13 14:52:12 -04006278 double constantVector[4] = {x, y, z, w};
6279 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04006280 }
6281
John Bauman19bac1e2014-05-06 15:23:49 -04006282 Float4::Float4(RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006283 {
6284 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006285
John Bauman66b8ab22014-05-06 15:57:45 -04006286 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04006287 }
6288
6289 Float4::Float4(const Float4 &rhs)
6290 {
6291 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006292
John Bauman66b8ab22014-05-06 15:57:45 -04006293 Value *value = rhs.loadValue();
6294 storeValue(value);
6295 }
6296
6297 Float4::Float4(const Reference<Float4> &rhs)
6298 {
6299 xyzw.parent = this;
6300
6301 Value *value = rhs.loadValue();
6302 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04006303 }
6304
John Bauman19bac1e2014-05-06 15:23:49 -04006305 Float4::Float4(RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006306 {
6307 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006308
John Bauman66b8ab22014-05-06 15:57:45 -04006309 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04006310 Value *insert = Nucleus::createInsertElement(vector, rhs.value, 0);
6311
Nicolas Capense89cd582016-09-30 14:23:47 -04006312 int swizzle[4] = {0, 0, 0, 0};
6313 Value *replicate = Nucleus::createShuffleVector(insert, insert, swizzle);
John Bauman89401822014-05-06 15:04:28 -04006314
John Bauman66b8ab22014-05-06 15:57:45 -04006315 storeValue(replicate);
John Bauman89401822014-05-06 15:04:28 -04006316 }
6317
6318 Float4::Float4(const Float &rhs)
6319 {
6320 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006321
John Bauman66b8ab22014-05-06 15:57:45 -04006322 *this = RValue<Float>(rhs.loadValue());
6323 }
John Bauman89401822014-05-06 15:04:28 -04006324
John Bauman66b8ab22014-05-06 15:57:45 -04006325 Float4::Float4(const Reference<Float> &rhs)
6326 {
6327 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006328
John Bauman66b8ab22014-05-06 15:57:45 -04006329 *this = RValue<Float>(rhs.loadValue());
John Bauman89401822014-05-06 15:04:28 -04006330 }
6331
6332 RValue<Float4> Float4::operator=(float x) const
6333 {
6334 return *this = Float4(x, x, x, x);
6335 }
6336
John Bauman19bac1e2014-05-06 15:23:49 -04006337 RValue<Float4> Float4::operator=(RValue<Float4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04006338 {
John Bauman66b8ab22014-05-06 15:57:45 -04006339 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04006340
6341 return rhs;
6342 }
6343
6344 RValue<Float4> Float4::operator=(const Float4 &rhs) const
6345 {
John Bauman66b8ab22014-05-06 15:57:45 -04006346 Value *value = rhs.loadValue();
6347 storeValue(value);
6348
6349 return RValue<Float4>(value);
6350 }
6351
6352 RValue<Float4> Float4::operator=(const Reference<Float4> &rhs) const
6353 {
6354 Value *value = rhs.loadValue();
6355 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04006356
6357 return RValue<Float4>(value);
6358 }
6359
John Bauman19bac1e2014-05-06 15:23:49 -04006360 RValue<Float4> Float4::operator=(RValue<Float> rhs) const
John Bauman89401822014-05-06 15:04:28 -04006361 {
6362 return *this = Float4(rhs);
6363 }
6364
6365 RValue<Float4> Float4::operator=(const Float &rhs) const
6366 {
6367 return *this = Float4(rhs);
6368 }
6369
John Bauman66b8ab22014-05-06 15:57:45 -04006370 RValue<Float4> Float4::operator=(const Reference<Float> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04006371 {
John Bauman66b8ab22014-05-06 15:57:45 -04006372 return *this = Float4(rhs);
John Bauman89401822014-05-06 15:04:28 -04006373 }
6374
John Bauman19bac1e2014-05-06 15:23:49 -04006375 RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006376 {
6377 return RValue<Float4>(Nucleus::createFAdd(lhs.value, rhs.value));
6378 }
6379
John Bauman19bac1e2014-05-06 15:23:49 -04006380 RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006381 {
6382 return RValue<Float4>(Nucleus::createFSub(lhs.value, rhs.value));
6383 }
6384
John Bauman19bac1e2014-05-06 15:23:49 -04006385 RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006386 {
6387 return RValue<Float4>(Nucleus::createFMul(lhs.value, rhs.value));
6388 }
6389
John Bauman19bac1e2014-05-06 15:23:49 -04006390 RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006391 {
6392 return RValue<Float4>(Nucleus::createFDiv(lhs.value, rhs.value));
6393 }
6394
John Bauman19bac1e2014-05-06 15:23:49 -04006395 RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006396 {
6397 return RValue<Float4>(Nucleus::createFRem(lhs.value, rhs.value));
6398 }
6399
John Bauman19bac1e2014-05-06 15:23:49 -04006400 RValue<Float4> operator+=(const Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006401 {
6402 return lhs = lhs + rhs;
6403 }
6404
John Bauman19bac1e2014-05-06 15:23:49 -04006405 RValue<Float4> operator-=(const Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006406 {
6407 return lhs = lhs - rhs;
6408 }
6409
John Bauman19bac1e2014-05-06 15:23:49 -04006410 RValue<Float4> operator*=(const Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006411 {
6412 return lhs = lhs * rhs;
6413 }
6414
John Bauman19bac1e2014-05-06 15:23:49 -04006415 RValue<Float4> operator/=(const Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006416 {
6417 return lhs = lhs / rhs;
6418 }
6419
John Bauman19bac1e2014-05-06 15:23:49 -04006420 RValue<Float4> operator%=(const Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006421 {
6422 return lhs = lhs % rhs;
6423 }
6424
John Bauman19bac1e2014-05-06 15:23:49 -04006425 RValue<Float4> operator+(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006426 {
6427 return val;
6428 }
6429
John Bauman19bac1e2014-05-06 15:23:49 -04006430 RValue<Float4> operator-(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006431 {
6432 return RValue<Float4>(Nucleus::createFNeg(val.value));
6433 }
6434
John Bauman19bac1e2014-05-06 15:23:49 -04006435 RValue<Float4> Abs(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006436 {
6437 Value *vector = Nucleus::createBitCast(x.value, Int4::getType());
Nicolas Capens13ac2322016-10-13 14:52:12 -04006438 int64_t constantVector[4] = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF};
6439 Value *result = Nucleus::createAnd(vector, V(Nucleus::createConstantVector(constantVector, Int4::getType())));
John Bauman89401822014-05-06 15:04:28 -04006440
6441 return RValue<Float4>(Nucleus::createBitCast(result, Float4::getType()));
6442 }
6443
John Bauman19bac1e2014-05-06 15:23:49 -04006444 RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006445 {
6446 return x86::maxps(x, y);
6447 }
6448
John Bauman19bac1e2014-05-06 15:23:49 -04006449 RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006450 {
6451 return x86::minps(x, y);
6452 }
6453
Nicolas Capens05b3d662016-02-25 23:58:33 -05006454 RValue<Float4> Rcp_pp(RValue<Float4> x, bool exactAtPow2)
John Bauman89401822014-05-06 15:04:28 -04006455 {
Nicolas Capens05b3d662016-02-25 23:58:33 -05006456 if(exactAtPow2)
6457 {
6458 // rcpps uses a piecewise-linear approximation which minimizes the relative error
6459 // but is not exact at power-of-two values. Rectify by multiplying by the inverse.
6460 return x86::rcpps(x) * Float4(1.0f / _mm_cvtss_f32(_mm_rcp_ss(_mm_set_ps1(1.0f))));
6461 }
6462 else
6463 {
6464 return x86::rcpps(x);
6465 }
John Bauman89401822014-05-06 15:04:28 -04006466 }
John Bauman66b8ab22014-05-06 15:57:45 -04006467
John Bauman19bac1e2014-05-06 15:23:49 -04006468 RValue<Float4> RcpSqrt_pp(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006469 {
6470 return x86::rsqrtps(x);
6471 }
6472
John Bauman19bac1e2014-05-06 15:23:49 -04006473 RValue<Float4> Sqrt(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006474 {
6475 return x86::sqrtps(x);
6476 }
6477
John Bauman19bac1e2014-05-06 15:23:49 -04006478 RValue<Float4> Insert(const Float4 &val, RValue<Float> element, int i)
John Bauman89401822014-05-06 15:04:28 -04006479 {
Nicolas Capens19336542016-09-26 10:32:29 -04006480 Value *value = val.loadValue();
6481 Value *insert = Nucleus::createInsertElement(value, element.value, i);
John Bauman89401822014-05-06 15:04:28 -04006482
6483 val = RValue<Float4>(insert);
6484
6485 return val;
6486 }
6487
John Bauman19bac1e2014-05-06 15:23:49 -04006488 RValue<Float> Extract(RValue<Float4> x, int i)
John Bauman89401822014-05-06 15:04:28 -04006489 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006490 return RValue<Float>(Nucleus::createExtractElement(x.value, Float::getType(), i));
John Bauman89401822014-05-06 15:04:28 -04006491 }
6492
John Bauman19bac1e2014-05-06 15:23:49 -04006493 RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04006494 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006495 return RValue<Float4>(createSwizzle4(x.value, select));
John Bauman89401822014-05-06 15:04:28 -04006496 }
6497
John Bauman19bac1e2014-05-06 15:23:49 -04006498 RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006499 {
Nicolas Capense89cd582016-09-30 14:23:47 -04006500 int shuffle[4] =
6501 {
6502 ((imm >> 0) & 0x03) + 0,
6503 ((imm >> 2) & 0x03) + 0,
6504 ((imm >> 4) & 0x03) + 4,
6505 ((imm >> 6) & 0x03) + 4,
6506 };
John Bauman89401822014-05-06 15:04:28 -04006507
Nicolas Capense89cd582016-09-30 14:23:47 -04006508 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
John Bauman89401822014-05-06 15:04:28 -04006509 }
6510
John Bauman19bac1e2014-05-06 15:23:49 -04006511 RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006512 {
Nicolas Capense89cd582016-09-30 14:23:47 -04006513 int shuffle[4] = {0, 4, 1, 5};
6514 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
John Bauman89401822014-05-06 15:04:28 -04006515 }
6516
John Bauman19bac1e2014-05-06 15:23:49 -04006517 RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006518 {
Nicolas Capense89cd582016-09-30 14:23:47 -04006519 int shuffle[4] = {2, 6, 3, 7};
6520 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
John Bauman89401822014-05-06 15:04:28 -04006521 }
John Bauman66b8ab22014-05-06 15:57:45 -04006522
John Bauman19bac1e2014-05-06 15:23:49 -04006523 RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04006524 {
John Bauman66b8ab22014-05-06 15:57:45 -04006525 Value *vector = lhs.loadValue();
Nicolas Capense95d5342016-09-30 11:37:28 -04006526 Value *shuffle = createMask4(vector, rhs.value, select);
John Bauman66b8ab22014-05-06 15:57:45 -04006527 lhs.storeValue(shuffle);
John Bauman89401822014-05-06 15:04:28 -04006528
6529 return RValue<Float4>(shuffle);
6530 }
6531
John Bauman19bac1e2014-05-06 15:23:49 -04006532 RValue<Int> SignMask(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006533 {
6534 return x86::movmskps(x);
6535 }
6536
John Bauman19bac1e2014-05-06 15:23:49 -04006537 RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006538 {
6539 // return As<Int4>(x86::cmpeqps(x, y));
6540 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOEQ(x.value, y.value), Int4::getType()));
6541 }
6542
John Bauman19bac1e2014-05-06 15:23:49 -04006543 RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006544 {
6545 // return As<Int4>(x86::cmpltps(x, y));
6546 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOLT(x.value, y.value), Int4::getType()));
6547 }
6548
John Bauman19bac1e2014-05-06 15:23:49 -04006549 RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006550 {
6551 // return As<Int4>(x86::cmpleps(x, y));
6552 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOLE(x.value, y.value), Int4::getType()));
6553 }
6554
John Bauman19bac1e2014-05-06 15:23:49 -04006555 RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006556 {
6557 // return As<Int4>(x86::cmpneqps(x, y));
6558 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpONE(x.value, y.value), Int4::getType()));
6559 }
6560
John Bauman19bac1e2014-05-06 15:23:49 -04006561 RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006562 {
6563 // return As<Int4>(x86::cmpnltps(x, y));
6564 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOGE(x.value, y.value), Int4::getType()));
6565 }
6566
John Bauman19bac1e2014-05-06 15:23:49 -04006567 RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006568 {
6569 // return As<Int4>(x86::cmpnleps(x, y));
6570 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOGT(x.value, y.value), Int4::getType()));
6571 }
6572
John Bauman19bac1e2014-05-06 15:23:49 -04006573 RValue<Float4> Round(RValue<Float4> x)
6574 {
6575 if(CPUID::supportsSSE4_1())
6576 {
6577 return x86::roundps(x, 0);
6578 }
6579 else
6580 {
6581 return Float4(RoundInt(x));
6582 }
6583 }
6584
6585 RValue<Float4> Trunc(RValue<Float4> x)
6586 {
6587 if(CPUID::supportsSSE4_1())
6588 {
6589 return x86::roundps(x, 3);
6590 }
6591 else
6592 {
6593 return Float4(Int4(x)); // Rounded toward zero
6594 }
6595 }
6596
6597 RValue<Float4> Frac(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006598 {
6599 if(CPUID::supportsSSE4_1())
6600 {
6601 return x - x86::floorps(x);
6602 }
6603 else
6604 {
John Bauman19bac1e2014-05-06 15:23:49 -04006605 Float4 frc = x - Float4(Int4(x)); // Signed fractional part
John Bauman89401822014-05-06 15:04:28 -04006606
John Bauman19bac1e2014-05-06 15:23:49 -04006607 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 -04006608 }
6609 }
6610
John Bauman19bac1e2014-05-06 15:23:49 -04006611 RValue<Float4> Floor(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006612 {
6613 if(CPUID::supportsSSE4_1())
6614 {
6615 return x86::floorps(x);
6616 }
6617 else
6618 {
John Bauman19bac1e2014-05-06 15:23:49 -04006619 return x - Frac(x);
John Bauman89401822014-05-06 15:04:28 -04006620 }
6621 }
6622
John Bauman19bac1e2014-05-06 15:23:49 -04006623 RValue<Float4> Ceil(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006624 {
John Bauman19bac1e2014-05-06 15:23:49 -04006625 if(CPUID::supportsSSE4_1())
6626 {
6627 return x86::ceilps(x);
6628 }
6629 else
6630 {
6631 return -Floor(-x);
6632 }
John Bauman89401822014-05-06 15:04:28 -04006633 }
6634
John Bauman19bac1e2014-05-06 15:23:49 -04006635 Type *Float4::getType()
John Bauman89401822014-05-06 15:04:28 -04006636 {
Nicolas Capensac230122016-09-20 14:30:06 -04006637 return T(VectorType::get(Float::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04006638 }
6639
Nicolas Capens81f18302016-01-14 09:32:35 -05006640 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006641 {
Nicolas Capens6d738712016-09-30 04:15:22 -04006642 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), V(Nucleus::createConstantInt(offset))));
John Bauman89401822014-05-06 15:04:28 -04006643 }
6644
Nicolas Capens81f18302016-01-14 09:32:35 -05006645 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006646 {
Nicolas Capens6d738712016-09-30 04:15:22 -04006647 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value));
John Bauman89401822014-05-06 15:04:28 -04006648 }
6649
Nicolas Capens81f18302016-01-14 09:32:35 -05006650 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006651 {
Nicolas Capens6d738712016-09-30 04:15:22 -04006652 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value));
John Bauman89401822014-05-06 15:04:28 -04006653 }
6654
Nicolas Capens81f18302016-01-14 09:32:35 -05006655 RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006656 {
6657 return lhs = lhs + offset;
6658 }
6659
Nicolas Capens81f18302016-01-14 09:32:35 -05006660 RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006661 {
6662 return lhs = lhs + offset;
6663 }
6664
Nicolas Capens81f18302016-01-14 09:32:35 -05006665 RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006666 {
6667 return lhs = lhs + offset;
6668 }
6669
Nicolas Capens81f18302016-01-14 09:32:35 -05006670 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006671 {
6672 return lhs + -offset;
6673 }
6674
Nicolas Capens81f18302016-01-14 09:32:35 -05006675 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006676 {
6677 return lhs + -offset;
6678 }
6679
Nicolas Capens81f18302016-01-14 09:32:35 -05006680 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006681 {
6682 return lhs + -offset;
6683 }
6684
Nicolas Capens81f18302016-01-14 09:32:35 -05006685 RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006686 {
6687 return lhs = lhs - offset;
6688 }
6689
Nicolas Capens81f18302016-01-14 09:32:35 -05006690 RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006691 {
6692 return lhs = lhs - offset;
6693 }
6694
Nicolas Capens81f18302016-01-14 09:32:35 -05006695 RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006696 {
6697 return lhs = lhs - offset;
6698 }
6699
6700 void Return()
6701 {
John Bauman89401822014-05-06 15:04:28 -04006702 Nucleus::createRetVoid();
6703 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
John Bauman19bac1e2014-05-06 15:23:49 -04006704 Nucleus::createUnreachable();
6705 }
6706
6707 void Return(bool ret)
6708 {
Nicolas Capens19336542016-09-26 10:32:29 -04006709 Nucleus::createRet(V(Nucleus::createConstantBool(ret)));
John Bauman19bac1e2014-05-06 15:23:49 -04006710 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
6711 Nucleus::createUnreachable();
John Bauman89401822014-05-06 15:04:28 -04006712 }
6713
6714 void Return(const Int &ret)
6715 {
John Bauman66b8ab22014-05-06 15:57:45 -04006716 Nucleus::createRet(ret.loadValue());
John Bauman89401822014-05-06 15:04:28 -04006717 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
John Bauman19bac1e2014-05-06 15:23:49 -04006718 Nucleus::createUnreachable();
John Bauman89401822014-05-06 15:04:28 -04006719 }
6720
6721 BasicBlock *beginLoop()
6722 {
6723 BasicBlock *loopBB = Nucleus::createBasicBlock();
6724
6725 Nucleus::createBr(loopBB);
John Bauman66b8ab22014-05-06 15:57:45 -04006726 Nucleus::setInsertBlock(loopBB);
John Bauman89401822014-05-06 15:04:28 -04006727
6728 return loopBB;
6729 }
6730
John Bauman19bac1e2014-05-06 15:23:49 -04006731 bool branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB)
John Bauman89401822014-05-06 15:04:28 -04006732 {
6733 Nucleus::createCondBr(cmp.value, bodyBB, endBB);
John Bauman66b8ab22014-05-06 15:57:45 -04006734 Nucleus::setInsertBlock(bodyBB);
6735
John Bauman89401822014-05-06 15:04:28 -04006736 return true;
6737 }
6738
Nicolas Capens9ed1a182016-10-24 09:52:23 -04006739 void endIf(BasicBlock *falseBB)
6740 {
6741 ::falseBB = falseBB;
6742 }
6743
John Bauman89401822014-05-06 15:04:28 -04006744 bool elseBlock(BasicBlock *falseBB)
6745 {
Nicolas Capens9ed1a182016-10-24 09:52:23 -04006746 assert(falseBB && "Else not preceded by If");
John Bauman89401822014-05-06 15:04:28 -04006747 falseBB->back().eraseFromParent();
John Bauman66b8ab22014-05-06 15:57:45 -04006748 Nucleus::setInsertBlock(falseBB);
John Bauman89401822014-05-06 15:04:28 -04006749
6750 return true;
6751 }
6752
Nicolas Capens9ed1a182016-10-24 09:52:23 -04006753 BasicBlock *beginElse()
6754 {
6755 BasicBlock *falseBB = ::falseBB;
6756 ::falseBB = nullptr;
6757
6758 return falseBB;
6759 }
6760
John Bauman89401822014-05-06 15:04:28 -04006761 RValue<Long> Ticks()
6762 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006763 llvm::Function *rdtsc = Intrinsic::getDeclaration(::module, Intrinsic::readcyclecounter);
John Bauman89401822014-05-06 15:04:28 -04006764
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006765 return RValue<Long>(V(::builder->CreateCall(rdtsc)));
John Bauman89401822014-05-06 15:04:28 -04006766 }
John Bauman89401822014-05-06 15:04:28 -04006767}
6768
6769namespace sw
6770{
6771 namespace x86
6772 {
John Bauman19bac1e2014-05-06 15:23:49 -04006773 RValue<Int> cvtss2si(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006774 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006775 llvm::Function *cvtss2si = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cvtss2si);
John Bauman66b8ab22014-05-06 15:57:45 -04006776
John Bauman89401822014-05-06 15:04:28 -04006777 Float4 vector;
6778 vector.x = val;
6779
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006780 return RValue<Int>(V(::builder->CreateCall(cvtss2si, RValue<Float4>(vector).value)));
John Bauman89401822014-05-06 15:04:28 -04006781 }
6782
John Bauman19bac1e2014-05-06 15:23:49 -04006783 RValue<Int2> cvtps2pi(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006784 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006785 llvm::Function *cvtps2pi = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cvtps2pi);
John Bauman89401822014-05-06 15:04:28 -04006786
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006787 return RValue<Int2>(V(::builder->CreateCall(cvtps2pi, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006788 }
6789
John Bauman19bac1e2014-05-06 15:23:49 -04006790 RValue<Int2> cvttps2pi(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006791 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006792 llvm::Function *cvttps2pi = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cvttps2pi);
John Bauman89401822014-05-06 15:04:28 -04006793
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006794 return RValue<Int2>(V(::builder->CreateCall(cvttps2pi, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006795 }
6796
John Bauman19bac1e2014-05-06 15:23:49 -04006797 RValue<Int4> cvtps2dq(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006798 {
6799 if(CPUID::supportsSSE2())
6800 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006801 llvm::Function *cvtps2dq = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_cvtps2dq);
John Bauman89401822014-05-06 15:04:28 -04006802
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006803 return RValue<Int4>(V(::builder->CreateCall(cvtps2dq, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006804 }
6805 else
6806 {
6807 Int2 lo = x86::cvtps2pi(val);
6808 Int2 hi = x86::cvtps2pi(Swizzle(val, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04006809
Nicolas Capens62abb552016-01-05 12:03:47 -05006810 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04006811 }
6812 }
6813
John Bauman19bac1e2014-05-06 15:23:49 -04006814 RValue<Float> rcpss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006815 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006816 llvm::Function *rcpss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rcp_ss);
John Bauman89401822014-05-06 15:04:28 -04006817
Nicolas Capens19336542016-09-26 10:32:29 -04006818 Value *vector = Nucleus::createInsertElement(V(UndefValue::get(Float4::getType())), val.value, 0);
John Bauman66b8ab22014-05-06 15:57:45 -04006819
Nicolas Capense95d5342016-09-30 11:37:28 -04006820 return RValue<Float>(Nucleus::createExtractElement(V(::builder->CreateCall(rcpss, vector)), Float::getType(), 0));
John Bauman89401822014-05-06 15:04:28 -04006821 }
6822
John Bauman19bac1e2014-05-06 15:23:49 -04006823 RValue<Float> sqrtss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006824 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006825 llvm::Function *sqrtss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_sqrt_ss);
John Bauman89401822014-05-06 15:04:28 -04006826
Nicolas Capens19336542016-09-26 10:32:29 -04006827 Value *vector = Nucleus::createInsertElement(V(UndefValue::get(Float4::getType())), val.value, 0);
John Bauman66b8ab22014-05-06 15:57:45 -04006828
Nicolas Capense95d5342016-09-30 11:37:28 -04006829 return RValue<Float>(Nucleus::createExtractElement(V(::builder->CreateCall(sqrtss, vector)), Float::getType(), 0));
John Bauman89401822014-05-06 15:04:28 -04006830 }
6831
John Bauman19bac1e2014-05-06 15:23:49 -04006832 RValue<Float> rsqrtss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006833 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006834 llvm::Function *rsqrtss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rsqrt_ss);
John Bauman66b8ab22014-05-06 15:57:45 -04006835
Nicolas Capens19336542016-09-26 10:32:29 -04006836 Value *vector = Nucleus::createInsertElement(V(UndefValue::get(Float4::getType())), val.value, 0);
John Bauman89401822014-05-06 15:04:28 -04006837
Nicolas Capense95d5342016-09-30 11:37:28 -04006838 return RValue<Float>(Nucleus::createExtractElement(V(::builder->CreateCall(rsqrtss, vector)), Float::getType(), 0));
John Bauman89401822014-05-06 15:04:28 -04006839 }
6840
John Bauman19bac1e2014-05-06 15:23:49 -04006841 RValue<Float4> rcpps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006842 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006843 llvm::Function *rcpps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rcp_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04006844
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006845 return RValue<Float4>(V(::builder->CreateCall(rcpps, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006846 }
6847
John Bauman19bac1e2014-05-06 15:23:49 -04006848 RValue<Float4> sqrtps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006849 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006850 llvm::Function *sqrtps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_sqrt_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04006851
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006852 return RValue<Float4>(V(::builder->CreateCall(sqrtps, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006853 }
6854
John Bauman19bac1e2014-05-06 15:23:49 -04006855 RValue<Float4> rsqrtps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006856 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006857 llvm::Function *rsqrtps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rsqrt_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04006858
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006859 return RValue<Float4>(V(::builder->CreateCall(rsqrtps, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006860 }
6861
John Bauman19bac1e2014-05-06 15:23:49 -04006862 RValue<Float4> maxps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006863 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006864 llvm::Function *maxps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_max_ps);
John Bauman89401822014-05-06 15:04:28 -04006865
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006866 return RValue<Float4>(V(::builder->CreateCall2(maxps, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04006867 }
6868
John Bauman19bac1e2014-05-06 15:23:49 -04006869 RValue<Float4> minps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006870 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006871 llvm::Function *minps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_min_ps);
John Bauman89401822014-05-06 15:04:28 -04006872
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006873 return RValue<Float4>(V(::builder->CreateCall2(minps, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04006874 }
6875
John Bauman19bac1e2014-05-06 15:23:49 -04006876 RValue<Float> roundss(RValue<Float> val, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006877 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006878 llvm::Function *roundss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_round_ss);
John Bauman89401822014-05-06 15:04:28 -04006879
Nicolas Capens19336542016-09-26 10:32:29 -04006880 Value *undef = V(UndefValue::get(Float4::getType()));
John Bauman89401822014-05-06 15:04:28 -04006881 Value *vector = Nucleus::createInsertElement(undef, val.value, 0);
6882
Nicolas Capense95d5342016-09-30 11:37:28 -04006883 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 -04006884 }
6885
John Bauman19bac1e2014-05-06 15:23:49 -04006886 RValue<Float> floorss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006887 {
6888 return roundss(val, 1);
6889 }
6890
John Bauman19bac1e2014-05-06 15:23:49 -04006891 RValue<Float> ceilss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006892 {
6893 return roundss(val, 2);
6894 }
6895
John Bauman19bac1e2014-05-06 15:23:49 -04006896 RValue<Float4> roundps(RValue<Float4> val, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006897 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006898 llvm::Function *roundps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_round_ps);
John Bauman89401822014-05-06 15:04:28 -04006899
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006900 return RValue<Float4>(V(::builder->CreateCall2(roundps, val.value, V(Nucleus::createConstantInt(imm)))));
John Bauman89401822014-05-06 15:04:28 -04006901 }
6902
John Bauman19bac1e2014-05-06 15:23:49 -04006903 RValue<Float4> floorps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006904 {
6905 return roundps(val, 1);
6906 }
6907
John Bauman19bac1e2014-05-06 15:23:49 -04006908 RValue<Float4> ceilps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006909 {
6910 return roundps(val, 2);
6911 }
6912
John Bauman19bac1e2014-05-06 15:23:49 -04006913 RValue<Float4> cmpps(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006914 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006915 llvm::Function *cmpps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cmp_ps);
John Bauman89401822014-05-06 15:04:28 -04006916
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006917 return RValue<Float4>(V(::builder->CreateCall3(cmpps, x.value, y.value, V(Nucleus::createConstantByte(imm)))));
John Bauman89401822014-05-06 15:04:28 -04006918 }
6919
John Bauman19bac1e2014-05-06 15:23:49 -04006920 RValue<Float4> cmpeqps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006921 {
6922 return cmpps(x, y, 0);
6923 }
6924
John Bauman19bac1e2014-05-06 15:23:49 -04006925 RValue<Float4> cmpltps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006926 {
6927 return cmpps(x, y, 1);
6928 }
6929
John Bauman19bac1e2014-05-06 15:23:49 -04006930 RValue<Float4> cmpleps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006931 {
6932 return cmpps(x, y, 2);
6933 }
6934
John Bauman19bac1e2014-05-06 15:23:49 -04006935 RValue<Float4> cmpunordps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006936 {
6937 return cmpps(x, y, 3);
6938 }
6939
John Bauman19bac1e2014-05-06 15:23:49 -04006940 RValue<Float4> cmpneqps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006941 {
6942 return cmpps(x, y, 4);
6943 }
6944
John Bauman19bac1e2014-05-06 15:23:49 -04006945 RValue<Float4> cmpnltps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006946 {
6947 return cmpps(x, y, 5);
6948 }
6949
John Bauman19bac1e2014-05-06 15:23:49 -04006950 RValue<Float4> cmpnleps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006951 {
6952 return cmpps(x, y, 6);
6953 }
6954
John Bauman19bac1e2014-05-06 15:23:49 -04006955 RValue<Float4> cmpordps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006956 {
6957 return cmpps(x, y, 7);
6958 }
6959
John Bauman19bac1e2014-05-06 15:23:49 -04006960 RValue<Float> cmpss(RValue<Float> x, RValue<Float> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006961 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006962 llvm::Function *cmpss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cmp_ss);
John Bauman89401822014-05-06 15:04:28 -04006963
Nicolas Capens19336542016-09-26 10:32:29 -04006964 Value *vector1 = Nucleus::createInsertElement(V(UndefValue::get(Float4::getType())), x.value, 0);
6965 Value *vector2 = Nucleus::createInsertElement(V(UndefValue::get(Float4::getType())), y.value, 0);
John Bauman89401822014-05-06 15:04:28 -04006966
Nicolas Capense95d5342016-09-30 11:37:28 -04006967 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 -04006968 }
6969
John Bauman19bac1e2014-05-06 15:23:49 -04006970 RValue<Float> cmpeqss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006971 {
6972 return cmpss(x, y, 0);
6973 }
6974
John Bauman19bac1e2014-05-06 15:23:49 -04006975 RValue<Float> cmpltss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006976 {
6977 return cmpss(x, y, 1);
6978 }
6979
John Bauman19bac1e2014-05-06 15:23:49 -04006980 RValue<Float> cmpless(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006981 {
6982 return cmpss(x, y, 2);
6983 }
6984
John Bauman19bac1e2014-05-06 15:23:49 -04006985 RValue<Float> cmpunordss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006986 {
6987 return cmpss(x, y, 3);
6988 }
6989
John Bauman19bac1e2014-05-06 15:23:49 -04006990 RValue<Float> cmpneqss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006991 {
6992 return cmpss(x, y, 4);
6993 }
6994
John Bauman19bac1e2014-05-06 15:23:49 -04006995 RValue<Float> cmpnltss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006996 {
6997 return cmpss(x, y, 5);
6998 }
6999
John Bauman19bac1e2014-05-06 15:23:49 -04007000 RValue<Float> cmpnless(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007001 {
7002 return cmpss(x, y, 6);
7003 }
7004
John Bauman19bac1e2014-05-06 15:23:49 -04007005 RValue<Float> cmpordss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007006 {
7007 return cmpss(x, y, 7);
7008 }
7009
Alexis Hetu0f448072016-03-18 10:56:08 -04007010 RValue<Int4> pabsd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007011 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007012 llvm::Function *pabsd = Intrinsic::getDeclaration(::module, Intrinsic::x86_ssse3_pabs_d_128);
John Bauman89401822014-05-06 15:04:28 -04007013
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007014 return RValue<Int4>(V(::builder->CreateCall(pabsd, x.value)));
John Bauman89401822014-05-06 15:04:28 -04007015 }
7016
John Bauman19bac1e2014-05-06 15:23:49 -04007017 RValue<Short4> paddsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007018 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007019 llvm::Function *paddsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padds_w);
John Bauman89401822014-05-06 15:04:28 -04007020
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007021 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(paddsw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007022 }
John Bauman66b8ab22014-05-06 15:57:45 -04007023
John Bauman19bac1e2014-05-06 15:23:49 -04007024 RValue<Short4> psubsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007025 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007026 llvm::Function *psubsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubs_w);
John Bauman89401822014-05-06 15:04:28 -04007027
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007028 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(psubsw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007029 }
7030
John Bauman19bac1e2014-05-06 15:23:49 -04007031 RValue<UShort4> paddusw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007032 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007033 llvm::Function *paddusw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_paddus_w);
John Bauman89401822014-05-06 15:04:28 -04007034
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007035 return As<UShort4>(RValue<MMX>(V(::builder->CreateCall2(paddusw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007036 }
John Bauman66b8ab22014-05-06 15:57:45 -04007037
John Bauman19bac1e2014-05-06 15:23:49 -04007038 RValue<UShort4> psubusw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007039 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007040 llvm::Function *psubusw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubus_w);
John Bauman89401822014-05-06 15:04:28 -04007041
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007042 return As<UShort4>(RValue<MMX>(V(::builder->CreateCall2(psubusw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007043 }
7044
John Bauman19bac1e2014-05-06 15:23:49 -04007045 RValue<SByte8> paddsb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04007046 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007047 llvm::Function *paddsb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padds_b);
John Bauman89401822014-05-06 15:04:28 -04007048
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007049 return As<SByte8>(RValue<MMX>(V(::builder->CreateCall2(paddsb, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007050 }
John Bauman66b8ab22014-05-06 15:57:45 -04007051
John Bauman19bac1e2014-05-06 15:23:49 -04007052 RValue<SByte8> psubsb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04007053 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007054 llvm::Function *psubsb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubs_b);
John Bauman89401822014-05-06 15:04:28 -04007055
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007056 return As<SByte8>(RValue<MMX>(V(::builder->CreateCall2(psubsb, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007057 }
John Bauman66b8ab22014-05-06 15:57:45 -04007058
John Bauman19bac1e2014-05-06 15:23:49 -04007059 RValue<Byte8> paddusb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04007060 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007061 llvm::Function *paddusb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_paddus_b);
John Bauman89401822014-05-06 15:04:28 -04007062
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007063 return As<Byte8>(RValue<MMX>(V(::builder->CreateCall2(paddusb, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007064 }
John Bauman66b8ab22014-05-06 15:57:45 -04007065
John Bauman19bac1e2014-05-06 15:23:49 -04007066 RValue<Byte8> psubusb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04007067 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007068 llvm::Function *psubusb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubus_b);
John Bauman89401822014-05-06 15:04:28 -04007069
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007070 return As<Byte8>(RValue<MMX>(V(::builder->CreateCall2(psubusb, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007071 }
7072
John Bauman19bac1e2014-05-06 15:23:49 -04007073 RValue<Short4> paddw(RValue<Short4> x, RValue<Short4> y)
7074 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007075 llvm::Function *paddw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padd_w);
John Bauman19bac1e2014-05-06 15:23:49 -04007076
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007077 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(paddw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007078 }
7079
7080 RValue<Short4> psubw(RValue<Short4> x, RValue<Short4> y)
7081 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007082 llvm::Function *psubw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psub_w);
John Bauman19bac1e2014-05-06 15:23:49 -04007083
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007084 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(psubw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007085 }
7086
7087 RValue<Short4> pmullw(RValue<Short4> x, RValue<Short4> y)
7088 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007089 llvm::Function *pmullw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmull_w);
John Bauman19bac1e2014-05-06 15:23:49 -04007090
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007091 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(pmullw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007092 }
7093
7094 RValue<Short4> pand(RValue<Short4> x, RValue<Short4> y)
7095 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007096 llvm::Function *pand = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pand);
John Bauman19bac1e2014-05-06 15:23:49 -04007097
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007098 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(pand, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007099 }
7100
7101 RValue<Short4> por(RValue<Short4> x, RValue<Short4> y)
7102 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007103 llvm::Function *por = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_por);
John Bauman19bac1e2014-05-06 15:23:49 -04007104
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007105 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(por, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007106 }
7107
7108 RValue<Short4> pxor(RValue<Short4> x, RValue<Short4> y)
7109 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007110 llvm::Function *pxor = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pxor);
John Bauman19bac1e2014-05-06 15:23:49 -04007111
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007112 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(pxor, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007113 }
7114
7115 RValue<Short4> pshufw(RValue<Short4> x, unsigned char y)
7116 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007117 llvm::Function *pshufw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_pshuf_w);
John Bauman19bac1e2014-05-06 15:23:49 -04007118
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007119 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(pshufw, As<MMX>(x).value, V(Nucleus::createConstantByte(y))))));
John Bauman19bac1e2014-05-06 15:23:49 -04007120 }
7121
7122 RValue<Int2> punpcklwd(RValue<Short4> x, RValue<Short4> y)
7123 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007124 llvm::Function *punpcklwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpcklwd);
John Bauman19bac1e2014-05-06 15:23:49 -04007125
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007126 return As<Int2>(RValue<MMX>(V(::builder->CreateCall2(punpcklwd, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007127 }
7128
7129 RValue<Int2> punpckhwd(RValue<Short4> x, RValue<Short4> y)
7130 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007131 llvm::Function *punpckhwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckhwd);
John Bauman19bac1e2014-05-06 15:23:49 -04007132
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007133 return As<Int2>(RValue<MMX>(V(::builder->CreateCall2(punpckhwd, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007134 }
7135
7136 RValue<Short4> pinsrw(RValue<Short4> x, RValue<Int> y, unsigned int i)
7137 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007138 llvm::Function *pinsrw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pinsr_w);
John Bauman19bac1e2014-05-06 15:23:49 -04007139
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007140 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 -04007141 }
7142
7143 RValue<Int> pextrw(RValue<Short4> x, unsigned int i)
7144 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007145 llvm::Function *pextrw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pextr_w);
John Bauman19bac1e2014-05-06 15:23:49 -04007146
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007147 return RValue<Int>(V(::builder->CreateCall2(pextrw, As<MMX>(x).value, V(Nucleus::createConstantInt(i)))));
John Bauman19bac1e2014-05-06 15:23:49 -04007148 }
7149
7150 RValue<Long1> punpckldq(RValue<Int2> x, RValue<Int2> y)
7151 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007152 llvm::Function *punpckldq = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckldq);
John Bauman19bac1e2014-05-06 15:23:49 -04007153
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007154 return As<Long1>(RValue<MMX>(V(::builder->CreateCall2(punpckldq, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007155 }
7156
7157 RValue<Long1> punpckhdq(RValue<Int2> x, RValue<Int2> y)
7158 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007159 llvm::Function *punpckhdq = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckhdq);
John Bauman19bac1e2014-05-06 15:23:49 -04007160
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007161 return As<Long1>(RValue<MMX>(V(::builder->CreateCall2(punpckhdq, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007162 }
7163
7164 RValue<Short4> punpcklbw(RValue<Byte8> x, RValue<Byte8> y)
7165 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007166 llvm::Function *punpcklbw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpcklbw);
John Bauman19bac1e2014-05-06 15:23:49 -04007167
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007168 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(punpcklbw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007169 }
7170
7171 RValue<Short4> punpckhbw(RValue<Byte8> x, RValue<Byte8> y)
7172 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007173 llvm::Function *punpckhbw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckhbw);
John Bauman19bac1e2014-05-06 15:23:49 -04007174
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007175 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(punpckhbw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007176 }
7177
7178 RValue<Byte8> paddb(RValue<Byte8> x, RValue<Byte8> y)
7179 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007180 llvm::Function *paddb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padd_b);
John Bauman19bac1e2014-05-06 15:23:49 -04007181
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007182 return As<Byte8>(RValue<MMX>(V(::builder->CreateCall2(paddb, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007183 }
7184
7185 RValue<Byte8> psubb(RValue<Byte8> x, RValue<Byte8> y)
7186 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007187 llvm::Function *psubb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psub_b);
John Bauman19bac1e2014-05-06 15:23:49 -04007188
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007189 return As<Byte8>(RValue<MMX>(V(::builder->CreateCall2(psubb, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007190 }
7191
7192 RValue<Int2> paddd(RValue<Int2> x, RValue<Int2> y)
7193 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007194 llvm::Function *paddd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padd_d);
John Bauman19bac1e2014-05-06 15:23:49 -04007195
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007196 return As<Int2>(RValue<MMX>(V(::builder->CreateCall2(paddd, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007197 }
7198
7199 RValue<Int2> psubd(RValue<Int2> x, RValue<Int2> y)
7200 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007201 llvm::Function *psubd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psub_d);
John Bauman19bac1e2014-05-06 15:23:49 -04007202
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007203 return As<Int2>(RValue<MMX>(V(::builder->CreateCall2(psubd, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman19bac1e2014-05-06 15:23:49 -04007204 }
7205
7206 RValue<UShort4> pavgw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007207 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007208 llvm::Function *pavgw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pavg_w);
John Bauman89401822014-05-06 15:04:28 -04007209
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007210 return As<UShort4>(RValue<MMX>(V(::builder->CreateCall2(pavgw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007211 }
7212
John Bauman19bac1e2014-05-06 15:23:49 -04007213 RValue<Short4> pmaxsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007214 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007215 llvm::Function *pmaxsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmaxs_w);
John Bauman89401822014-05-06 15:04:28 -04007216
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007217 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(pmaxsw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007218 }
7219
John Bauman19bac1e2014-05-06 15:23:49 -04007220 RValue<Short4> pminsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007221 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007222 llvm::Function *pminsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmins_w);
John Bauman89401822014-05-06 15:04:28 -04007223
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007224 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(pminsw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007225 }
7226
John Bauman19bac1e2014-05-06 15:23:49 -04007227 RValue<Short4> pcmpgtw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007228 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007229 llvm::Function *pcmpgtw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpgt_w);
John Bauman89401822014-05-06 15:04:28 -04007230
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007231 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(pcmpgtw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007232 }
7233
John Bauman19bac1e2014-05-06 15:23:49 -04007234 RValue<Short4> pcmpeqw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007235 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007236 llvm::Function *pcmpeqw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpeq_w);
John Bauman89401822014-05-06 15:04:28 -04007237
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007238 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(pcmpeqw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007239 }
7240
John Bauman19bac1e2014-05-06 15:23:49 -04007241 RValue<Byte8> pcmpgtb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04007242 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007243 llvm::Function *pcmpgtb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpgt_b);
John Bauman89401822014-05-06 15:04:28 -04007244
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007245 return As<Byte8>(RValue<MMX>(V(::builder->CreateCall2(pcmpgtb, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007246 }
7247
John Bauman19bac1e2014-05-06 15:23:49 -04007248 RValue<Byte8> pcmpeqb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04007249 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007250 llvm::Function *pcmpeqb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpeq_b);
John Bauman89401822014-05-06 15:04:28 -04007251
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007252 return As<Byte8>(RValue<MMX>(V(::builder->CreateCall2(pcmpeqb, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007253 }
7254
John Bauman19bac1e2014-05-06 15:23:49 -04007255 RValue<Short4> packssdw(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04007256 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007257 llvm::Function *packssdw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_packssdw);
John Bauman89401822014-05-06 15:04:28 -04007258
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007259 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(packssdw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007260 }
7261
John Bauman19bac1e2014-05-06 15:23:49 -04007262 RValue<Short8> packssdw(RValue<Int4> x, RValue<Int4> y)
John Bauman89401822014-05-06 15:04:28 -04007263 {
7264 if(CPUID::supportsSSE2())
7265 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007266 llvm::Function *packssdw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_packssdw_128);
John Bauman89401822014-05-06 15:04:28 -04007267
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007268 return RValue<Short8>(V(::builder->CreateCall2(packssdw, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04007269 }
7270 else
7271 {
7272 Int2 loX = Int2(x);
7273 Int2 hiX = Int2(Swizzle(x, 0xEE));
7274
7275 Int2 loY = Int2(y);
7276 Int2 hiY = Int2(Swizzle(y, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04007277
John Bauman89401822014-05-06 15:04:28 -04007278 Short4 lo = x86::packssdw(loX, hiX);
7279 Short4 hi = x86::packssdw(loY, hiY);
John Bauman66b8ab22014-05-06 15:57:45 -04007280
Nicolas Capens62abb552016-01-05 12:03:47 -05007281 return Short8(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007282 }
7283 }
7284
John Bauman19bac1e2014-05-06 15:23:49 -04007285 RValue<SByte8> packsswb(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007286 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007287 llvm::Function *packsswb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_packsswb);
John Bauman89401822014-05-06 15:04:28 -04007288
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007289 return As<SByte8>(RValue<MMX>(V(::builder->CreateCall2(packsswb, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007290 }
7291
John Bauman19bac1e2014-05-06 15:23:49 -04007292 RValue<Byte8> packuswb(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007293 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007294 llvm::Function *packuswb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_packuswb);
John Bauman89401822014-05-06 15:04:28 -04007295
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007296 return As<Byte8>(RValue<MMX>(V(::builder->CreateCall2(packuswb, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007297 }
7298
John Bauman19bac1e2014-05-06 15:23:49 -04007299 RValue<UShort8> packusdw(RValue<UInt4> x, RValue<UInt4> y)
John Bauman89401822014-05-06 15:04:28 -04007300 {
7301 if(CPUID::supportsSSE4_1())
7302 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007303 llvm::Function *packusdw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_packusdw);
John Bauman66b8ab22014-05-06 15:57:45 -04007304
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007305 return RValue<UShort8>(V(::builder->CreateCall2(packusdw, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04007306 }
7307 else
7308 {
7309 // FIXME: Not an exact replacement!
John Bauman19bac1e2014-05-06 15:23:49 -04007310 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 -04007311 }
7312 }
7313
John Bauman19bac1e2014-05-06 15:23:49 -04007314 RValue<UShort4> psrlw(RValue<UShort4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007315 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007316 llvm::Function *psrlw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrli_w);
John Bauman89401822014-05-06 15:04:28 -04007317
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007318 return As<UShort4>(RValue<MMX>(V(::builder->CreateCall2(psrlw, As<MMX>(x).value, V(Nucleus::createConstantInt(y))))));
John Bauman89401822014-05-06 15:04:28 -04007319 }
7320
John Bauman19bac1e2014-05-06 15:23:49 -04007321 RValue<UShort8> psrlw(RValue<UShort8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007322 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007323 llvm::Function *psrlw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrli_w);
John Bauman89401822014-05-06 15:04:28 -04007324
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007325 return RValue<UShort8>(V(::builder->CreateCall2(psrlw, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007326 }
7327
John Bauman19bac1e2014-05-06 15:23:49 -04007328 RValue<Short4> psraw(RValue<Short4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007329 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007330 llvm::Function *psraw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrai_w);
John Bauman89401822014-05-06 15:04:28 -04007331
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007332 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(psraw, As<MMX>(x).value, V(Nucleus::createConstantInt(y))))));
John Bauman89401822014-05-06 15:04:28 -04007333 }
7334
John Bauman19bac1e2014-05-06 15:23:49 -04007335 RValue<Short8> psraw(RValue<Short8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007336 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007337 llvm::Function *psraw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrai_w);
John Bauman89401822014-05-06 15:04:28 -04007338
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007339 return RValue<Short8>(V(::builder->CreateCall2(psraw, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007340 }
7341
John Bauman19bac1e2014-05-06 15:23:49 -04007342 RValue<Short4> psllw(RValue<Short4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007343 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007344 llvm::Function *psllw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pslli_w);
John Bauman89401822014-05-06 15:04:28 -04007345
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007346 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(psllw, As<MMX>(x).value, V(Nucleus::createConstantInt(y))))));
John Bauman89401822014-05-06 15:04:28 -04007347 }
7348
John Bauman19bac1e2014-05-06 15:23:49 -04007349 RValue<Short8> psllw(RValue<Short8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007350 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007351 llvm::Function *psllw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pslli_w);
John Bauman89401822014-05-06 15:04:28 -04007352
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007353 return RValue<Short8>(V(::builder->CreateCall2(psllw, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007354 }
7355
John Bauman19bac1e2014-05-06 15:23:49 -04007356 RValue<Int2> pslld(RValue<Int2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007357 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007358 llvm::Function *pslld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pslli_d);
John Bauman89401822014-05-06 15:04:28 -04007359
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007360 return As<Int2>(RValue<MMX>(V(::builder->CreateCall2(pslld, As<MMX>(x).value, V(Nucleus::createConstantInt(y))))));
John Bauman89401822014-05-06 15:04:28 -04007361 }
7362
John Bauman19bac1e2014-05-06 15:23:49 -04007363 RValue<Int4> pslld(RValue<Int4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007364 {
7365 if(CPUID::supportsSSE2())
7366 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007367 llvm::Function *pslld = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pslli_d);
John Bauman89401822014-05-06 15:04:28 -04007368
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007369 return RValue<Int4>(V(::builder->CreateCall2(pslld, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007370 }
7371 else
7372 {
7373 Int2 lo = Int2(x);
7374 Int2 hi = Int2(Swizzle(x, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04007375
John Bauman89401822014-05-06 15:04:28 -04007376 lo = x86::pslld(lo, y);
7377 hi = x86::pslld(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04007378
Nicolas Capens62abb552016-01-05 12:03:47 -05007379 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007380 }
7381 }
7382
John Bauman19bac1e2014-05-06 15:23:49 -04007383 RValue<Int2> psrad(RValue<Int2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007384 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007385 llvm::Function *psrad = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrai_d);
John Bauman89401822014-05-06 15:04:28 -04007386
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007387 return As<Int2>(RValue<MMX>(V(::builder->CreateCall2(psrad, As<MMX>(x).value, V(Nucleus::createConstantInt(y))))));
John Bauman89401822014-05-06 15:04:28 -04007388 }
7389
John Bauman19bac1e2014-05-06 15:23:49 -04007390 RValue<Int4> psrad(RValue<Int4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007391 {
7392 if(CPUID::supportsSSE2())
7393 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007394 llvm::Function *psrad = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrai_d);
John Bauman89401822014-05-06 15:04:28 -04007395
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007396 return RValue<Int4>(V(::builder->CreateCall2(psrad, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007397 }
7398 else
7399 {
7400 Int2 lo = Int2(x);
7401 Int2 hi = Int2(Swizzle(x, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04007402
John Bauman89401822014-05-06 15:04:28 -04007403 lo = x86::psrad(lo, y);
7404 hi = x86::psrad(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04007405
Nicolas Capens62abb552016-01-05 12:03:47 -05007406 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007407 }
7408 }
7409
John Bauman19bac1e2014-05-06 15:23:49 -04007410 RValue<UInt2> psrld(RValue<UInt2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007411 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007412 llvm::Function *psrld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrli_d);
John Bauman89401822014-05-06 15:04:28 -04007413
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007414 return As<UInt2>(RValue<MMX>(V(::builder->CreateCall2(psrld, As<MMX>(x).value, V(Nucleus::createConstantInt(y))))));
John Bauman89401822014-05-06 15:04:28 -04007415 }
7416
John Bauman19bac1e2014-05-06 15:23:49 -04007417 RValue<UInt4> psrld(RValue<UInt4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007418 {
7419 if(CPUID::supportsSSE2())
7420 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007421 llvm::Function *psrld = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrli_d);
John Bauman89401822014-05-06 15:04:28 -04007422
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007423 return RValue<UInt4>(V(::builder->CreateCall2(psrld, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007424 }
7425 else
7426 {
7427 UInt2 lo = As<UInt2>(Int2(As<Int4>(x)));
7428 UInt2 hi = As<UInt2>(Int2(Swizzle(As<Int4>(x), 0xEE)));
John Bauman66b8ab22014-05-06 15:57:45 -04007429
John Bauman89401822014-05-06 15:04:28 -04007430 lo = x86::psrld(lo, y);
7431 hi = x86::psrld(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04007432
Nicolas Capens62abb552016-01-05 12:03:47 -05007433 return UInt4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007434 }
7435 }
7436
John Bauman19bac1e2014-05-06 15:23:49 -04007437 RValue<UShort4> psrlw(RValue<UShort4> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007438 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007439 llvm::Function *psrlw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrl_w);
John Bauman89401822014-05-06 15:04:28 -04007440
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007441 return As<UShort4>(RValue<MMX>(V(::builder->CreateCall2(psrlw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007442 }
7443
John Bauman19bac1e2014-05-06 15:23:49 -04007444 RValue<Short4> psraw(RValue<Short4> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007445 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007446 llvm::Function *psraw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psra_w);
John Bauman89401822014-05-06 15:04:28 -04007447
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007448 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(psraw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007449 }
7450
John Bauman19bac1e2014-05-06 15:23:49 -04007451 RValue<Short4> psllw(RValue<Short4> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007452 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007453 llvm::Function *psllw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psll_w);
John Bauman89401822014-05-06 15:04:28 -04007454
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007455 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(psllw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007456 }
7457
John Bauman19bac1e2014-05-06 15:23:49 -04007458 RValue<Int2> pslld(RValue<Int2> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007459 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007460 llvm::Function *pslld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psll_d);
John Bauman89401822014-05-06 15:04:28 -04007461
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007462 return As<Int2>(RValue<MMX>(V(::builder->CreateCall2(pslld, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007463 }
7464
John Bauman19bac1e2014-05-06 15:23:49 -04007465 RValue<UInt2> psrld(RValue<UInt2> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007466 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007467 llvm::Function *psrld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrl_d);
John Bauman89401822014-05-06 15:04:28 -04007468
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007469 return As<UInt2>(RValue<MMX>(V(::builder->CreateCall2(psrld, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007470 }
7471
John Bauman19bac1e2014-05-06 15:23:49 -04007472 RValue<Int2> psrad(RValue<Int2> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007473 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007474 llvm::Function *psrld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psra_d);
John Bauman89401822014-05-06 15:04:28 -04007475
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007476 return As<Int2>(RValue<MMX>(V(::builder->CreateCall2(psrld, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007477 }
7478
John Bauman19bac1e2014-05-06 15:23:49 -04007479 RValue<Int4> pmaxsd(RValue<Int4> x, RValue<Int4> y)
7480 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007481 llvm::Function *pmaxsd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmaxsd);
John Bauman19bac1e2014-05-06 15:23:49 -04007482
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007483 return RValue<Int4>(V(::builder->CreateCall2(pmaxsd, x.value, y.value)));
John Bauman19bac1e2014-05-06 15:23:49 -04007484 }
7485
7486 RValue<Int4> pminsd(RValue<Int4> x, RValue<Int4> y)
7487 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007488 llvm::Function *pminsd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pminsd);
John Bauman19bac1e2014-05-06 15:23:49 -04007489
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007490 return RValue<Int4>(V(::builder->CreateCall2(pminsd, x.value, y.value)));
John Bauman19bac1e2014-05-06 15:23:49 -04007491 }
7492
7493 RValue<UInt4> pmaxud(RValue<UInt4> x, RValue<UInt4> y)
7494 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007495 llvm::Function *pmaxud = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmaxud);
John Bauman19bac1e2014-05-06 15:23:49 -04007496
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007497 return RValue<UInt4>(V(::builder->CreateCall2(pmaxud, x.value, y.value)));
John Bauman19bac1e2014-05-06 15:23:49 -04007498 }
7499
7500 RValue<UInt4> pminud(RValue<UInt4> x, RValue<UInt4> y)
7501 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007502 llvm::Function *pminud = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pminud);
John Bauman19bac1e2014-05-06 15:23:49 -04007503
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007504 return RValue<UInt4>(V(::builder->CreateCall2(pminud, x.value, y.value)));
John Bauman19bac1e2014-05-06 15:23:49 -04007505 }
7506
7507 RValue<Short4> pmulhw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007508 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007509 llvm::Function *pmulhw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmulh_w);
John Bauman89401822014-05-06 15:04:28 -04007510
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007511 return As<Short4>(RValue<MMX>(V(::builder->CreateCall2(pmulhw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007512 }
7513
John Bauman19bac1e2014-05-06 15:23:49 -04007514 RValue<UShort4> pmulhuw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007515 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007516 llvm::Function *pmulhuw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmulhu_w);
John Bauman89401822014-05-06 15:04:28 -04007517
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007518 return As<UShort4>(RValue<MMX>(V(::builder->CreateCall2(pmulhuw, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007519 }
7520
John Bauman19bac1e2014-05-06 15:23:49 -04007521 RValue<Int2> pmaddwd(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007522 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007523 llvm::Function *pmaddwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmadd_wd);
John Bauman89401822014-05-06 15:04:28 -04007524
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007525 return As<Int2>(RValue<MMX>(V(::builder->CreateCall2(pmaddwd, As<MMX>(x).value, As<MMX>(y).value))));
John Bauman89401822014-05-06 15:04:28 -04007526 }
7527
John Bauman19bac1e2014-05-06 15:23:49 -04007528 RValue<Short8> pmulhw(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04007529 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007530 llvm::Function *pmulhw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pmulh_w);
John Bauman89401822014-05-06 15:04:28 -04007531
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007532 return RValue<Short8>(V(::builder->CreateCall2(pmulhw, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04007533 }
7534
John Bauman19bac1e2014-05-06 15:23:49 -04007535 RValue<UShort8> pmulhuw(RValue<UShort8> x, RValue<UShort8> y)
John Bauman89401822014-05-06 15:04:28 -04007536 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007537 llvm::Function *pmulhuw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pmulhu_w);
John Bauman89401822014-05-06 15:04:28 -04007538
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007539 return RValue<UShort8>(V(::builder->CreateCall2(pmulhuw, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04007540 }
7541
John Bauman19bac1e2014-05-06 15:23:49 -04007542 RValue<Int4> pmaddwd(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04007543 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007544 llvm::Function *pmaddwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pmadd_wd);
John Bauman89401822014-05-06 15:04:28 -04007545
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007546 return RValue<Int4>(V(::builder->CreateCall2(pmaddwd, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04007547 }
7548
John Bauman19bac1e2014-05-06 15:23:49 -04007549 RValue<Int> movmskps(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04007550 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007551 llvm::Function *movmskps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_movmsk_ps);
John Bauman89401822014-05-06 15:04:28 -04007552
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007553 return RValue<Int>(V(::builder->CreateCall(movmskps, x.value)));
John Bauman89401822014-05-06 15:04:28 -04007554 }
7555
John Bauman19bac1e2014-05-06 15:23:49 -04007556 RValue<Int> pmovmskb(RValue<Byte8> x)
John Bauman89401822014-05-06 15:04:28 -04007557 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007558 llvm::Function *pmovmskb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmovmskb);
John Bauman89401822014-05-06 15:04:28 -04007559
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007560 return RValue<Int>(V(::builder->CreateCall(pmovmskb, As<MMX>(x).value)));
John Bauman89401822014-05-06 15:04:28 -04007561 }
7562
Nicolas Capens81f18302016-01-14 09:32:35 -05007563 //RValue<Int2> movd(RValue<Pointer<Int>> x)
John Bauman89401822014-05-06 15:04:28 -04007564 //{
7565 // Value *element = Nucleus::createLoad(x.value);
7566
7567 //// Value *int2 = UndefValue::get(Int2::getType());
7568 //// int2 = Nucleus::createInsertElement(int2, element, ConstantInt::get(Int::getType(), 0));
7569
7570 // Value *int2 = Nucleus::createBitCast(Nucleus::createZExt(element, Long::getType()), Int2::getType());
7571
7572 // return RValue<Int2>(int2);
7573 //}
7574
John Bauman19bac1e2014-05-06 15:23:49 -04007575 //RValue<Int2> movdq2q(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007576 //{
Nicolas Capens22008782016-10-20 01:11:47 -04007577 // Value *long2 = Nucleus::createBitCast(x.value, T(VectorType::get(Long::getType(), 2)));
John Bauman89401822014-05-06 15:04:28 -04007578 // Value *element = Nucleus::createExtractElement(long2, ConstantInt::get(Int::getType(), 0));
7579
7580 // return RValue<Int2>(Nucleus::createBitCast(element, Int2::getType()));
7581 //}
7582
John Bauman19bac1e2014-05-06 15:23:49 -04007583 RValue<Int4> pmovzxbd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007584 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007585 llvm::Function *pmovzxbd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovzxbd);
John Bauman66b8ab22014-05-06 15:57:45 -04007586
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007587 return RValue<Int4>(V(::builder->CreateCall(pmovzxbd, Nucleus::createBitCast(x.value, Byte16::getType()))));
John Bauman89401822014-05-06 15:04:28 -04007588 }
7589
John Bauman19bac1e2014-05-06 15:23:49 -04007590 RValue<Int4> pmovsxbd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007591 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007592 llvm::Function *pmovsxbd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovsxbd);
John Bauman66b8ab22014-05-06 15:57:45 -04007593
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007594 return RValue<Int4>(V(::builder->CreateCall(pmovsxbd, Nucleus::createBitCast(x.value, SByte16::getType()))));
John Bauman89401822014-05-06 15:04:28 -04007595 }
7596
John Bauman19bac1e2014-05-06 15:23:49 -04007597 RValue<Int4> pmovzxwd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007598 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007599 llvm::Function *pmovzxwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovzxwd);
John Bauman66b8ab22014-05-06 15:57:45 -04007600
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007601 return RValue<Int4>(V(::builder->CreateCall(pmovzxwd, Nucleus::createBitCast(x.value, UShort8::getType()))));
John Bauman89401822014-05-06 15:04:28 -04007602 }
7603
John Bauman19bac1e2014-05-06 15:23:49 -04007604 RValue<Int4> pmovsxwd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007605 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007606 llvm::Function *pmovsxwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovsxwd);
John Bauman66b8ab22014-05-06 15:57:45 -04007607
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007608 return RValue<Int4>(V(::builder->CreateCall(pmovsxwd, Nucleus::createBitCast(x.value, Short8::getType()))));
John Bauman89401822014-05-06 15:04:28 -04007609 }
7610
7611 void emms()
7612 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007613 llvm::Function *emms = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_emms);
John Bauman89401822014-05-06 15:04:28 -04007614
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007615 V(::builder->CreateCall(emms));
John Bauman89401822014-05-06 15:04:28 -04007616 }
7617 }
7618}