blob: 42578fe7a282a407470551dd2ee1eb84b4382dc7 [file] [log] [blame]
Nicolas Capens0bac2852016-05-07 06:09:58 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
John Bauman89401822014-05-06 15:04:28 -04002//
Nicolas Capens0bac2852016-05-07 06:09:58 -04003// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
John Bauman89401822014-05-06 15:04:28 -04006//
Nicolas Capens0bac2852016-05-07 06:09:58 -04007// http://www.apache.org/licenses/LICENSE-2.0
John Bauman89401822014-05-06 15:04:28 -04008//
Nicolas Capens0bac2852016-05-07 06:09:58 -04009// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
John Bauman89401822014-05-06 15:04:28 -040014
15#include "Nucleus.hpp"
16
17#include "llvm/Support/IRBuilder.h"
18#include "llvm/Function.h"
19#include "llvm/GlobalVariable.h"
20#include "llvm/Module.h"
21#include "llvm/LLVMContext.h"
22#include "llvm/Constants.h"
23#include "llvm/Intrinsics.h"
John Bauman66b8ab22014-05-06 15:57:45 -040024#include "llvm/PassManager.h"
John Bauman89401822014-05-06 15:04:28 -040025#include "llvm/Analysis/LoopPass.h"
26#include "llvm/Transforms/Scalar.h"
27#include "llvm/Target/TargetData.h"
John Bauman89401822014-05-06 15:04:28 -040028#include "llvm/Target/TargetOptions.h"
John Bauman19bac1e2014-05-06 15:23:49 -040029#include "llvm/Support/TargetSelect.h"
John Bauman89401822014-05-06 15:04:28 -040030#include "../lib/ExecutionEngine/JIT/JIT.h"
John Bauman89401822014-05-06 15:04:28 -040031
Nicolas Capensdaa5d912016-09-28 16:56:36 -040032#include "LLVMRoutine.hpp"
33#include "LLVMRoutineManager.hpp"
John Bauman89401822014-05-06 15:04:28 -040034#include "x86.hpp"
35#include "CPUID.hpp"
36#include "Thread.hpp"
37#include "Memory.hpp"
Nicolas Capens3bbc5e12016-09-27 10:49:52 -040038#include "MutexLock.hpp"
John Bauman89401822014-05-06 15:04:28 -040039
Nicolas Capens05b3d662016-02-25 23:58:33 -050040#include <xmmintrin.h>
John Bauman89401822014-05-06 15:04:28 -040041#include <fstream>
42
Nicolas Capenscb122582014-05-06 23:34:44 -040043#if defined(__x86_64__) && defined(_WIN32)
John Bauman66b8ab22014-05-06 15:57:45 -040044extern "C" void X86CompilationCallback()
45{
46 assert(false); // UNIMPLEMENTED
47}
48#endif
49
John Bauman89401822014-05-06 15:04:28 -040050extern "C"
51{
52 bool (*CodeAnalystInitialize)() = 0;
53 void (*CodeAnalystCompleteJITLog)() = 0;
54 bool (*CodeAnalystLogJITCode)(const void *jitCodeStartAddr, unsigned int jitCodeSize, const wchar_t *functionName) = 0;
55}
56
57namespace llvm
58{
59 extern bool JITEmitDebugInfo;
60}
61
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -040062namespace
63{
Nicolas Capensdaa5d912016-09-28 16:56:36 -040064 sw::LLVMRoutineManager *routineManager = nullptr;
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -040065 llvm::ExecutionEngine *executionEngine = nullptr;
66 llvm::IRBuilder<> *builder = nullptr;
67 llvm::LLVMContext *context = nullptr;
68 llvm::Module *module = nullptr;
69 llvm::Function *function = nullptr;
Nicolas Capens3bbc5e12016-09-27 10:49:52 -040070
71 sw::BackoffLock codegenMutex;
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -040072}
73
John Bauman89401822014-05-06 15:04:28 -040074namespace sw
75{
John Bauman89401822014-05-06 15:04:28 -040076 using namespace llvm;
John Bauman89401822014-05-06 15:04:28 -040077
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -040078 Optimization optimization[10] = {InstructionCombining, Disabled};
John Bauman89401822014-05-06 15:04:28 -040079
Nicolas Capensc8b67a42016-09-25 15:02:52 -040080 class Type : public llvm::Type {};
Nicolas Capens19336542016-09-26 10:32:29 -040081 class Value : public llvm::Value {};
Nicolas Capensb98fe5c2016-11-09 12:24:06 -050082 class SwitchCases : public llvm::SwitchInst {};
Nicolas Capensc8b67a42016-09-25 15:02:52 -040083 class BasicBlock : public llvm::BasicBlock {};
Nicolas Capensac230122016-09-20 14:30:06 -040084
85 inline Type *T(llvm::Type *t)
86 {
87 return reinterpret_cast<Type*>(t);
88 }
89
Nicolas Capens19336542016-09-26 10:32:29 -040090 inline Value *V(llvm::Value *t)
91 {
92 return reinterpret_cast<Value*>(t);
93 }
94
Nicolas Capensac230122016-09-20 14:30:06 -040095 inline std::vector<llvm::Type*> &T(std::vector<Type*> &t)
96 {
97 return reinterpret_cast<std::vector<llvm::Type*>&>(t);
98 }
99
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400100 inline BasicBlock *B(llvm::BasicBlock *t)
101 {
102 return reinterpret_cast<BasicBlock*>(t);
103 }
104
John Bauman89401822014-05-06 15:04:28 -0400105 Nucleus::Nucleus()
106 {
Nicolas Capens3bbc5e12016-09-27 10:49:52 -0400107 ::codegenMutex.lock(); // Reactor and LLVM are currently not thread safe
Nicolas Capensb7ea9842015-04-01 10:54:59 -0400108
John Bauman19bac1e2014-05-06 15:23:49 -0400109 InitializeNativeTarget();
John Bauman89401822014-05-06 15:04:28 -0400110 JITEmitDebugInfo = false;
111
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400112 if(!::context)
John Bauman89401822014-05-06 15:04:28 -0400113 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400114 ::context = new LLVMContext();
John Bauman89401822014-05-06 15:04:28 -0400115 }
116
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400117 ::module = new Module("", *::context);
Nicolas Capensdaa5d912016-09-28 16:56:36 -0400118 ::routineManager = new LLVMRoutineManager();
John Bauman66b8ab22014-05-06 15:57:45 -0400119
John Bauman89401822014-05-06 15:04:28 -0400120 #if defined(__x86_64__)
121 const char *architecture = "x86-64";
122 #else
123 const char *architecture = "x86";
124 #endif
125
126 SmallVector<std::string, 1> MAttrs;
127 MAttrs.push_back(CPUID::supportsMMX() ? "+mmx" : "-mmx");
128 MAttrs.push_back(CPUID::supportsCMOV() ? "+cmov" : "-cmov");
129 MAttrs.push_back(CPUID::supportsSSE() ? "+sse" : "-sse");
130 MAttrs.push_back(CPUID::supportsSSE2() ? "+sse2" : "-sse2");
131 MAttrs.push_back(CPUID::supportsSSE3() ? "+sse3" : "-sse3");
132 MAttrs.push_back(CPUID::supportsSSSE3() ? "+ssse3" : "-ssse3");
133 MAttrs.push_back(CPUID::supportsSSE4_1() ? "+sse41" : "-sse41");
134
John Bauman19bac1e2014-05-06 15:23:49 -0400135 std::string error;
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400136 TargetMachine *targetMachine = EngineBuilder::selectTarget(::module, architecture, "", MAttrs, Reloc::Default, CodeModel::JITDefault, &error);
137 ::executionEngine = JIT::createJIT(::module, 0, ::routineManager, CodeGenOpt::Aggressive, true, targetMachine);
John Bauman89401822014-05-06 15:04:28 -0400138
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400139 if(!::builder)
John Bauman89401822014-05-06 15:04:28 -0400140 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400141 ::builder = new IRBuilder<>(*::context);
John Bauman89401822014-05-06 15:04:28 -0400142
John Bauman66b8ab22014-05-06 15:57:45 -0400143 #if defined(_WIN32)
144 HMODULE CodeAnalyst = LoadLibrary("CAJitNtfyLib.dll");
145 if(CodeAnalyst)
146 {
147 CodeAnalystInitialize = (bool(*)())GetProcAddress(CodeAnalyst, "CAJIT_Initialize");
148 CodeAnalystCompleteJITLog = (void(*)())GetProcAddress(CodeAnalyst, "CAJIT_CompleteJITLog");
149 CodeAnalystLogJITCode = (bool(*)(const void*, unsigned int, const wchar_t*))GetProcAddress(CodeAnalyst, "CAJIT_LogJITCode");
150
151 CodeAnalystInitialize();
152 }
153 #endif
John Bauman89401822014-05-06 15:04:28 -0400154 }
155 }
156
157 Nucleus::~Nucleus()
158 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400159 delete ::executionEngine;
160 ::executionEngine = nullptr;
John Bauman89401822014-05-06 15:04:28 -0400161
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400162 ::routineManager = nullptr;
163 ::function = nullptr;
164 ::module = nullptr;
Nicolas Capensb7ea9842015-04-01 10:54:59 -0400165
Nicolas Capens3bbc5e12016-09-27 10:49:52 -0400166 ::codegenMutex.unlock();
John Bauman89401822014-05-06 15:04:28 -0400167 }
168
169 Routine *Nucleus::acquireRoutine(const wchar_t *name, bool runOptimizations)
170 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400171 if(::builder->GetInsertBlock()->empty() || !::builder->GetInsertBlock()->back().isTerminator())
John Bauman19bac1e2014-05-06 15:23:49 -0400172 {
Nicolas Capensac230122016-09-20 14:30:06 -0400173 llvm::Type *type = ::function->getReturnType();
John Bauman19bac1e2014-05-06 15:23:49 -0400174
175 if(type->isVoidTy())
176 {
177 createRetVoid();
178 }
179 else
180 {
Nicolas Capens19336542016-09-26 10:32:29 -0400181 createRet(V(UndefValue::get(type)));
John Bauman19bac1e2014-05-06 15:23:49 -0400182 }
183 }
John Bauman89401822014-05-06 15:04:28 -0400184
185 if(false)
186 {
John Bauman66b8ab22014-05-06 15:57:45 -0400187 std::string error;
188 raw_fd_ostream file("llvm-dump-unopt.txt", error);
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400189 ::module->print(file, 0);
John Bauman89401822014-05-06 15:04:28 -0400190 }
191
192 if(runOptimizations)
193 {
194 optimize();
195 }
196
197 if(false)
198 {
John Bauman66b8ab22014-05-06 15:57:45 -0400199 std::string error;
200 raw_fd_ostream file("llvm-dump-opt.txt", error);
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400201 ::module->print(file, 0);
John Bauman89401822014-05-06 15:04:28 -0400202 }
203
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400204 void *entry = ::executionEngine->getPointerToFunction(::function);
Nicolas Capensdaa5d912016-09-28 16:56:36 -0400205 LLVMRoutine *routine = ::routineManager->acquireRoutine(entry);
John Bauman89401822014-05-06 15:04:28 -0400206
207 if(CodeAnalystLogJITCode)
208 {
Nicolas Capensd946e0a2014-06-26 11:31:08 -0400209 CodeAnalystLogJITCode(routine->getEntry(), routine->getCodeSize(), name);
John Bauman89401822014-05-06 15:04:28 -0400210 }
211
212 return routine;
213 }
214
215 void Nucleus::optimize()
216 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400217 static PassManager *passManager = nullptr;
John Bauman66b8ab22014-05-06 15:57:45 -0400218
John Bauman89401822014-05-06 15:04:28 -0400219 if(!passManager)
220 {
221 passManager = new PassManager();
222
223 UnsafeFPMath = true;
224 // NoInfsFPMath = true;
225 // NoNaNsFPMath = true;
226
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400227 passManager->add(new TargetData(*::executionEngine->getTargetData()));
John Bauman89401822014-05-06 15:04:28 -0400228 passManager->add(createScalarReplAggregatesPass());
229
230 for(int pass = 0; pass < 10 && optimization[pass] != Disabled; pass++)
231 {
232 switch(optimization[pass])
233 {
234 case Disabled: break;
235 case CFGSimplification: passManager->add(createCFGSimplificationPass()); break;
236 case LICM: passManager->add(createLICMPass()); break;
237 case AggressiveDCE: passManager->add(createAggressiveDCEPass()); break;
238 case GVN: passManager->add(createGVNPass()); break;
239 case InstructionCombining: passManager->add(createInstructionCombiningPass()); break;
240 case Reassociate: passManager->add(createReassociatePass()); break;
241 case DeadStoreElimination: passManager->add(createDeadStoreEliminationPass()); break;
242 case SCCP: passManager->add(createSCCPPass()); break;
John Bauman19bac1e2014-05-06 15:23:49 -0400243 case ScalarReplAggregates: passManager->add(createScalarReplAggregatesPass()); break;
John Bauman89401822014-05-06 15:04:28 -0400244 default:
245 assert(false);
246 }
247 }
248 }
249
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400250 passManager->run(*::module);
John Bauman89401822014-05-06 15:04:28 -0400251 }
252
John Bauman19bac1e2014-05-06 15:23:49 -0400253 Value *Nucleus::allocateStackVariable(Type *type, int arraySize)
John Bauman89401822014-05-06 15:04:28 -0400254 {
255 // Need to allocate it in the entry block for mem2reg to work
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400256 llvm::BasicBlock &entryBlock = ::function->getEntryBlock();
John Bauman89401822014-05-06 15:04:28 -0400257
258 Instruction *declaration;
259
260 if(arraySize)
261 {
262 declaration = new AllocaInst(type, Nucleus::createConstantInt(arraySize));
263 }
264 else
265 {
266 declaration = new AllocaInst(type, (Value*)0);
267 }
268
269 entryBlock.getInstList().push_front(declaration);
270
Nicolas Capens19336542016-09-26 10:32:29 -0400271 return V(declaration);
John Bauman89401822014-05-06 15:04:28 -0400272 }
273
274 BasicBlock *Nucleus::createBasicBlock()
275 {
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400276 return B(BasicBlock::Create(*::context, "", ::function));
John Bauman89401822014-05-06 15:04:28 -0400277 }
278
279 BasicBlock *Nucleus::getInsertBlock()
280 {
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400281 return B(::builder->GetInsertBlock());
John Bauman89401822014-05-06 15:04:28 -0400282 }
283
284 void Nucleus::setInsertBlock(BasicBlock *basicBlock)
285 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400286 // assert(::builder->GetInsertBlock()->back().isTerminator());
287 return ::builder->SetInsertPoint(basicBlock);
John Bauman89401822014-05-06 15:04:28 -0400288 }
289
Nicolas Capensac230122016-09-20 14:30:06 -0400290 void Nucleus::createFunction(Type *ReturnType, std::vector<Type*> &Params)
John Bauman89401822014-05-06 15:04:28 -0400291 {
Nicolas Capensac230122016-09-20 14:30:06 -0400292 llvm::FunctionType *functionType = llvm::FunctionType::get(ReturnType, T(Params), false);
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400293 ::function = llvm::Function::Create(functionType, llvm::GlobalValue::InternalLinkage, "", ::module);
294 ::function->setCallingConv(llvm::CallingConv::C);
John Bauman89401822014-05-06 15:04:28 -0400295
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400296 ::builder->SetInsertPoint(BasicBlock::Create(*::context, "", ::function));
John Bauman89401822014-05-06 15:04:28 -0400297 }
298
Nicolas Capens19336542016-09-26 10:32:29 -0400299 Value *Nucleus::getArgument(unsigned int index)
John Bauman89401822014-05-06 15:04:28 -0400300 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400301 llvm::Function::arg_iterator args = ::function->arg_begin();
John Bauman89401822014-05-06 15:04:28 -0400302
303 while(index)
304 {
305 args++;
306 index--;
307 }
308
Nicolas Capens19336542016-09-26 10:32:29 -0400309 return V(&*args);
John Bauman89401822014-05-06 15:04:28 -0400310 }
311
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400312 void Nucleus::createRetVoid()
John Bauman89401822014-05-06 15:04:28 -0400313 {
John Bauman66b8ab22014-05-06 15:57:45 -0400314 x86::emms();
315
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400316 ::builder->CreateRetVoid();
John Bauman89401822014-05-06 15:04:28 -0400317 }
318
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400319 void Nucleus::createRet(Value *v)
John Bauman89401822014-05-06 15:04:28 -0400320 {
John Bauman66b8ab22014-05-06 15:57:45 -0400321 x86::emms();
322
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400323 ::builder->CreateRet(v);
John Bauman89401822014-05-06 15:04:28 -0400324 }
325
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400326 void Nucleus::createBr(BasicBlock *dest)
John Bauman89401822014-05-06 15:04:28 -0400327 {
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400328 ::builder->CreateBr(dest);
John Bauman89401822014-05-06 15:04:28 -0400329 }
330
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400331 void Nucleus::createCondBr(Value *cond, BasicBlock *ifTrue, BasicBlock *ifFalse)
John Bauman89401822014-05-06 15:04:28 -0400332 {
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400333 ::builder->CreateCondBr(cond, ifTrue, ifFalse);
John Bauman89401822014-05-06 15:04:28 -0400334 }
335
336 Value *Nucleus::createAdd(Value *lhs, Value *rhs)
337 {
Nicolas Capens19336542016-09-26 10:32:29 -0400338 return V(::builder->CreateAdd(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400339 }
340
341 Value *Nucleus::createSub(Value *lhs, Value *rhs)
342 {
Nicolas Capens19336542016-09-26 10:32:29 -0400343 return V(::builder->CreateSub(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400344 }
345
346 Value *Nucleus::createMul(Value *lhs, Value *rhs)
347 {
Nicolas Capens19336542016-09-26 10:32:29 -0400348 return V(::builder->CreateMul(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400349 }
350
351 Value *Nucleus::createUDiv(Value *lhs, Value *rhs)
352 {
Nicolas Capens19336542016-09-26 10:32:29 -0400353 return V(::builder->CreateUDiv(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400354 }
355
356 Value *Nucleus::createSDiv(Value *lhs, Value *rhs)
357 {
Nicolas Capens19336542016-09-26 10:32:29 -0400358 return V(::builder->CreateSDiv(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400359 }
360
361 Value *Nucleus::createFAdd(Value *lhs, Value *rhs)
362 {
Nicolas Capens19336542016-09-26 10:32:29 -0400363 return V(::builder->CreateFAdd(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400364 }
365
366 Value *Nucleus::createFSub(Value *lhs, Value *rhs)
367 {
Nicolas Capens19336542016-09-26 10:32:29 -0400368 return V(::builder->CreateFSub(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400369 }
370
371 Value *Nucleus::createFMul(Value *lhs, Value *rhs)
372 {
Nicolas Capens19336542016-09-26 10:32:29 -0400373 return V(::builder->CreateFMul(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400374 }
375
376 Value *Nucleus::createFDiv(Value *lhs, Value *rhs)
377 {
Nicolas Capens19336542016-09-26 10:32:29 -0400378 return V(::builder->CreateFDiv(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400379 }
380
381 Value *Nucleus::createURem(Value *lhs, Value *rhs)
382 {
Nicolas Capens19336542016-09-26 10:32:29 -0400383 return V(::builder->CreateURem(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400384 }
385
386 Value *Nucleus::createSRem(Value *lhs, Value *rhs)
387 {
Nicolas Capens19336542016-09-26 10:32:29 -0400388 return V(::builder->CreateSRem(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400389 }
390
391 Value *Nucleus::createFRem(Value *lhs, Value *rhs)
392 {
Nicolas Capens19336542016-09-26 10:32:29 -0400393 return V(::builder->CreateFRem(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400394 }
395
396 Value *Nucleus::createShl(Value *lhs, Value *rhs)
397 {
Nicolas Capens19336542016-09-26 10:32:29 -0400398 return V(::builder->CreateShl(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400399 }
400
401 Value *Nucleus::createLShr(Value *lhs, Value *rhs)
402 {
Nicolas Capens19336542016-09-26 10:32:29 -0400403 return V(::builder->CreateLShr(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400404 }
405
406 Value *Nucleus::createAShr(Value *lhs, Value *rhs)
407 {
Nicolas Capens19336542016-09-26 10:32:29 -0400408 return V(::builder->CreateAShr(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400409 }
410
411 Value *Nucleus::createAnd(Value *lhs, Value *rhs)
412 {
Nicolas Capens19336542016-09-26 10:32:29 -0400413 return V(::builder->CreateAnd(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400414 }
415
416 Value *Nucleus::createOr(Value *lhs, Value *rhs)
417 {
Nicolas Capens19336542016-09-26 10:32:29 -0400418 return V(::builder->CreateOr(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400419 }
420
421 Value *Nucleus::createXor(Value *lhs, Value *rhs)
422 {
Nicolas Capens19336542016-09-26 10:32:29 -0400423 return V(::builder->CreateXor(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400424 }
425
Nicolas Capens19336542016-09-26 10:32:29 -0400426 Value *Nucleus::createNeg(Value *v)
John Bauman89401822014-05-06 15:04:28 -0400427 {
Nicolas Capens19336542016-09-26 10:32:29 -0400428 return V(::builder->CreateNeg(v));
John Bauman89401822014-05-06 15:04:28 -0400429 }
430
Nicolas Capens19336542016-09-26 10:32:29 -0400431 Value *Nucleus::createFNeg(Value *v)
John Bauman89401822014-05-06 15:04:28 -0400432 {
Nicolas Capens19336542016-09-26 10:32:29 -0400433 return V(::builder->CreateFNeg(v));
John Bauman89401822014-05-06 15:04:28 -0400434 }
435
Nicolas Capens19336542016-09-26 10:32:29 -0400436 Value *Nucleus::createNot(Value *v)
John Bauman89401822014-05-06 15:04:28 -0400437 {
Nicolas Capens19336542016-09-26 10:32:29 -0400438 return V(::builder->CreateNot(v));
John Bauman89401822014-05-06 15:04:28 -0400439 }
440
Nicolas Capense12780d2016-09-27 14:18:07 -0400441 Value *Nucleus::createLoad(Value *ptr, Type *type, bool isVolatile, unsigned int align)
John Bauman89401822014-05-06 15:04:28 -0400442 {
Nicolas Capense12780d2016-09-27 14:18:07 -0400443 assert(ptr->getType()->getContainedType(0) == type);
Nicolas Capens19336542016-09-26 10:32:29 -0400444 return V(::builder->Insert(new LoadInst(ptr, "", isVolatile, align)));
John Bauman89401822014-05-06 15:04:28 -0400445 }
446
Nicolas Capens6d738712016-09-30 04:15:22 -0400447 Value *Nucleus::createStore(Value *value, Value *ptr, Type *type, bool isVolatile, unsigned int align)
John Bauman89401822014-05-06 15:04:28 -0400448 {
Nicolas Capens6d738712016-09-30 04:15:22 -0400449 assert(ptr->getType()->getContainedType(0) == type);
Nicolas Capensb955d5b2016-09-28 22:36:28 -0400450 ::builder->Insert(new StoreInst(value, ptr, isVolatile, align));
451 return value;
John Bauman89401822014-05-06 15:04:28 -0400452 }
453
Nicolas Capens6d738712016-09-30 04:15:22 -0400454 Value *Nucleus::createGEP(Value *ptr, Type *type, Value *index)
John Bauman89401822014-05-06 15:04:28 -0400455 {
Nicolas Capens6d738712016-09-30 04:15:22 -0400456 assert(ptr->getType()->getContainedType(0) == type);
Nicolas Capens19336542016-09-26 10:32:29 -0400457 return V(::builder->CreateGEP(ptr, index));
John Bauman89401822014-05-06 15:04:28 -0400458 }
459
John Bauman19bac1e2014-05-06 15:23:49 -0400460 Value *Nucleus::createAtomicAdd(Value *ptr, Value *value)
461 {
Nicolas Capens19336542016-09-26 10:32:29 -0400462 return V(::builder->CreateAtomicRMW(AtomicRMWInst::Add, ptr, value, SequentiallyConsistent));
John Bauman19bac1e2014-05-06 15:23:49 -0400463 }
464
Nicolas Capens19336542016-09-26 10:32:29 -0400465 Value *Nucleus::createTrunc(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400466 {
Nicolas Capens19336542016-09-26 10:32:29 -0400467 return V(::builder->CreateTrunc(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400468 }
469
Nicolas Capens19336542016-09-26 10:32:29 -0400470 Value *Nucleus::createZExt(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400471 {
Nicolas Capens19336542016-09-26 10:32:29 -0400472 return V(::builder->CreateZExt(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400473 }
474
Nicolas Capens19336542016-09-26 10:32:29 -0400475 Value *Nucleus::createSExt(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400476 {
Nicolas Capens19336542016-09-26 10:32:29 -0400477 return V(::builder->CreateSExt(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400478 }
479
Nicolas Capens19336542016-09-26 10:32:29 -0400480 Value *Nucleus::createFPToSI(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400481 {
Nicolas Capens19336542016-09-26 10:32:29 -0400482 return V(::builder->CreateFPToSI(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400483 }
484
Nicolas Capens19336542016-09-26 10:32:29 -0400485 Value *Nucleus::createSIToFP(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400486 {
Nicolas Capens19336542016-09-26 10:32:29 -0400487 return V(::builder->CreateSIToFP(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400488 }
489
Nicolas Capens19336542016-09-26 10:32:29 -0400490 Value *Nucleus::createFPTrunc(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400491 {
Nicolas Capens19336542016-09-26 10:32:29 -0400492 return V(::builder->CreateFPTrunc(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400493 }
494
Nicolas Capens19336542016-09-26 10:32:29 -0400495 Value *Nucleus::createFPExt(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400496 {
Nicolas Capens19336542016-09-26 10:32:29 -0400497 return V(::builder->CreateFPExt(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400498 }
499
Nicolas Capens19336542016-09-26 10:32:29 -0400500 Value *Nucleus::createBitCast(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400501 {
Nicolas Capens19336542016-09-26 10:32:29 -0400502 return V(::builder->CreateBitCast(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400503 }
504
John Bauman89401822014-05-06 15:04:28 -0400505 Value *Nucleus::createICmpEQ(Value *lhs, Value *rhs)
506 {
Nicolas Capens19336542016-09-26 10:32:29 -0400507 return V(::builder->CreateICmpEQ(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400508 }
509
510 Value *Nucleus::createICmpNE(Value *lhs, Value *rhs)
511 {
Nicolas Capens19336542016-09-26 10:32:29 -0400512 return V(::builder->CreateICmpNE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400513 }
514
515 Value *Nucleus::createICmpUGT(Value *lhs, Value *rhs)
516 {
Nicolas Capens19336542016-09-26 10:32:29 -0400517 return V(::builder->CreateICmpUGT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400518 }
519
520 Value *Nucleus::createICmpUGE(Value *lhs, Value *rhs)
521 {
Nicolas Capens19336542016-09-26 10:32:29 -0400522 return V(::builder->CreateICmpUGE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400523 }
524
525 Value *Nucleus::createICmpULT(Value *lhs, Value *rhs)
526 {
Nicolas Capens19336542016-09-26 10:32:29 -0400527 return V(::builder->CreateICmpULT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400528 }
529
530 Value *Nucleus::createICmpULE(Value *lhs, Value *rhs)
531 {
Nicolas Capens19336542016-09-26 10:32:29 -0400532 return V(::builder->CreateICmpULE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400533 }
534
535 Value *Nucleus::createICmpSGT(Value *lhs, Value *rhs)
536 {
Nicolas Capens19336542016-09-26 10:32:29 -0400537 return V(::builder->CreateICmpSGT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400538 }
539
540 Value *Nucleus::createICmpSGE(Value *lhs, Value *rhs)
541 {
Nicolas Capens19336542016-09-26 10:32:29 -0400542 return V(::builder->CreateICmpSGE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400543 }
544
545 Value *Nucleus::createICmpSLT(Value *lhs, Value *rhs)
546 {
Nicolas Capens19336542016-09-26 10:32:29 -0400547 return V(::builder->CreateICmpSLT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400548 }
549
550 Value *Nucleus::createICmpSLE(Value *lhs, Value *rhs)
551 {
Nicolas Capens19336542016-09-26 10:32:29 -0400552 return V(::builder->CreateICmpSLE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400553 }
554
555 Value *Nucleus::createFCmpOEQ(Value *lhs, Value *rhs)
556 {
Nicolas Capens19336542016-09-26 10:32:29 -0400557 return V(::builder->CreateFCmpOEQ(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400558 }
559
560 Value *Nucleus::createFCmpOGT(Value *lhs, Value *rhs)
561 {
Nicolas Capens19336542016-09-26 10:32:29 -0400562 return V(::builder->CreateFCmpOGT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400563 }
564
565 Value *Nucleus::createFCmpOGE(Value *lhs, Value *rhs)
566 {
Nicolas Capens19336542016-09-26 10:32:29 -0400567 return V(::builder->CreateFCmpOGE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400568 }
569
570 Value *Nucleus::createFCmpOLT(Value *lhs, Value *rhs)
571 {
Nicolas Capens19336542016-09-26 10:32:29 -0400572 return V(::builder->CreateFCmpOLT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400573 }
574
575 Value *Nucleus::createFCmpOLE(Value *lhs, Value *rhs)
576 {
Nicolas Capens19336542016-09-26 10:32:29 -0400577 return V(::builder->CreateFCmpOLE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400578 }
579
580 Value *Nucleus::createFCmpONE(Value *lhs, Value *rhs)
581 {
Nicolas Capens19336542016-09-26 10:32:29 -0400582 return V(::builder->CreateFCmpONE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400583 }
584
585 Value *Nucleus::createFCmpORD(Value *lhs, Value *rhs)
586 {
Nicolas Capens19336542016-09-26 10:32:29 -0400587 return V(::builder->CreateFCmpORD(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400588 }
589
590 Value *Nucleus::createFCmpUNO(Value *lhs, Value *rhs)
591 {
Nicolas Capens19336542016-09-26 10:32:29 -0400592 return V(::builder->CreateFCmpUNO(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400593 }
594
595 Value *Nucleus::createFCmpUEQ(Value *lhs, Value *rhs)
596 {
Nicolas Capens19336542016-09-26 10:32:29 -0400597 return V(::builder->CreateFCmpUEQ(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400598 }
599
600 Value *Nucleus::createFCmpUGT(Value *lhs, Value *rhs)
601 {
Nicolas Capens19336542016-09-26 10:32:29 -0400602 return V(::builder->CreateFCmpUGT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400603 }
604
605 Value *Nucleus::createFCmpUGE(Value *lhs, Value *rhs)
606 {
Nicolas Capens19336542016-09-26 10:32:29 -0400607 return V(::builder->CreateFCmpUGE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400608 }
609
610 Value *Nucleus::createFCmpULT(Value *lhs, Value *rhs)
611 {
Nicolas Capens19336542016-09-26 10:32:29 -0400612 return V(::builder->CreateFCmpULT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400613 }
614
615 Value *Nucleus::createFCmpULE(Value *lhs, Value *rhs)
616 {
Nicolas Capens19336542016-09-26 10:32:29 -0400617 return V(::builder->CreateFCmpULE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400618 }
619
620 Value *Nucleus::createFCmpUNE(Value *lhs, Value *rhs)
621 {
Nicolas Capens19336542016-09-26 10:32:29 -0400622 return V(::builder->CreateFCmpULE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400623 }
624
Nicolas Capense95d5342016-09-30 11:37:28 -0400625 Value *Nucleus::createExtractElement(Value *vector, Type *type, int index)
John Bauman89401822014-05-06 15:04:28 -0400626 {
Nicolas Capense95d5342016-09-30 11:37:28 -0400627 assert(vector->getType()->getContainedType(0) == type);
Nicolas Capens19336542016-09-26 10:32:29 -0400628 return V(::builder->CreateExtractElement(vector, createConstantInt(index)));
John Bauman89401822014-05-06 15:04:28 -0400629 }
630
631 Value *Nucleus::createInsertElement(Value *vector, Value *element, int index)
632 {
Nicolas Capens19336542016-09-26 10:32:29 -0400633 return V(::builder->CreateInsertElement(vector, element, createConstantInt(index)));
John Bauman89401822014-05-06 15:04:28 -0400634 }
635
Nicolas Capense89cd582016-09-30 14:23:47 -0400636 Value *Nucleus::createShuffleVector(Value *V1, Value *V2, const int *select)
John Bauman89401822014-05-06 15:04:28 -0400637 {
Nicolas Capense89cd582016-09-30 14:23:47 -0400638 int size = llvm::cast<llvm::VectorType>(V1->getType())->getNumElements();
639 const int maxSize = 16;
640 llvm::Constant *swizzle[maxSize];
641 assert(size <= maxSize);
642
643 for(int i = 0; i < size; i++)
644 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400645 swizzle[i] = llvm::ConstantInt::get(Type::getInt32Ty(*::context), select[i]);
Nicolas Capense89cd582016-09-30 14:23:47 -0400646 }
647
648 llvm::Value *shuffle = llvm::ConstantVector::get(llvm::ArrayRef<llvm::Constant*>(swizzle, size));
649
650 return V(::builder->CreateShuffleVector(V1, V2, shuffle));
John Bauman89401822014-05-06 15:04:28 -0400651 }
652
653 Value *Nucleus::createSelect(Value *C, Value *ifTrue, Value *ifFalse)
654 {
Nicolas Capens19336542016-09-26 10:32:29 -0400655 return V(::builder->CreateSelect(C, ifTrue, ifFalse));
John Bauman89401822014-05-06 15:04:28 -0400656 }
657
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500658 SwitchCases *Nucleus::createSwitch(Value *control, BasicBlock *defaultBranch, unsigned numCases)
John Bauman89401822014-05-06 15:04:28 -0400659 {
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500660 return reinterpret_cast<SwitchCases*>(::builder->CreateSwitch(control, defaultBranch, numCases));
John Bauman89401822014-05-06 15:04:28 -0400661 }
662
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500663 void Nucleus::addSwitchCase(SwitchCases *switchCases, int label, BasicBlock *branch)
John Bauman89401822014-05-06 15:04:28 -0400664 {
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500665 switchCases->addCase(llvm::ConstantInt::get(Type::getInt32Ty(*::context), label, true), branch);
John Bauman89401822014-05-06 15:04:28 -0400666 }
667
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400668 void Nucleus::createUnreachable()
John Bauman89401822014-05-06 15:04:28 -0400669 {
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400670 ::builder->CreateUnreachable();
John Bauman89401822014-05-06 15:04:28 -0400671 }
672
Nicolas Capense95d5342016-09-30 11:37:28 -0400673 static Value *createSwizzle4(Value *val, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -0400674 {
Nicolas Capense89cd582016-09-30 14:23:47 -0400675 int swizzle[4] =
676 {
677 (select >> 0) & 0x03,
678 (select >> 2) & 0x03,
679 (select >> 4) & 0x03,
680 (select >> 6) & 0x03,
681 };
John Bauman89401822014-05-06 15:04:28 -0400682
Nicolas Capense89cd582016-09-30 14:23:47 -0400683 return Nucleus::createShuffleVector(val, val, swizzle);
John Bauman89401822014-05-06 15:04:28 -0400684 }
685
Nicolas Capense95d5342016-09-30 11:37:28 -0400686 static Value *createMask4(Value *lhs, Value *rhs, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -0400687 {
688 bool mask[4] = {false, false, false, false};
689
690 mask[(select >> 0) & 0x03] = true;
691 mask[(select >> 2) & 0x03] = true;
692 mask[(select >> 4) & 0x03] = true;
693 mask[(select >> 6) & 0x03] = true;
694
Nicolas Capense89cd582016-09-30 14:23:47 -0400695 int swizzle[4] =
696 {
697 mask[0] ? 4 : 0,
698 mask[1] ? 5 : 1,
699 mask[2] ? 6 : 2,
700 mask[3] ? 7 : 3,
701 };
John Bauman89401822014-05-06 15:04:28 -0400702
Nicolas Capensa29d6532016-12-05 21:38:09 -0500703 return Nucleus::createShuffleVector(lhs, rhs, swizzle);
John Bauman89401822014-05-06 15:04:28 -0400704 }
705
Nicolas Capensac230122016-09-20 14:30:06 -0400706 Type *Nucleus::getPointerType(Type *ElementType)
John Bauman89401822014-05-06 15:04:28 -0400707 {
Nicolas Capensac230122016-09-20 14:30:06 -0400708 return T(llvm::PointerType::get(ElementType, 0));
John Bauman89401822014-05-06 15:04:28 -0400709 }
710
Nicolas Capens13ac2322016-10-13 14:52:12 -0400711 Value *Nucleus::createNullValue(Type *Ty)
John Bauman89401822014-05-06 15:04:28 -0400712 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400713 return V(llvm::Constant::getNullValue(Ty));
John Bauman89401822014-05-06 15:04:28 -0400714 }
715
Nicolas Capens13ac2322016-10-13 14:52:12 -0400716 Value *Nucleus::createConstantLong(int64_t i)
John Bauman89401822014-05-06 15:04:28 -0400717 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400718 return V(llvm::ConstantInt::get(Type::getInt64Ty(*::context), i, true));
John Bauman89401822014-05-06 15:04:28 -0400719 }
720
Nicolas Capens13ac2322016-10-13 14:52:12 -0400721 Value *Nucleus::createConstantInt(int i)
John Bauman89401822014-05-06 15:04:28 -0400722 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400723 return V(llvm::ConstantInt::get(Type::getInt32Ty(*::context), i, true));
John Bauman89401822014-05-06 15:04:28 -0400724 }
725
Nicolas Capens13ac2322016-10-13 14:52:12 -0400726 Value *Nucleus::createConstantInt(unsigned int i)
John Bauman89401822014-05-06 15:04:28 -0400727 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400728 return V(llvm::ConstantInt::get(Type::getInt32Ty(*::context), i, false));
John Bauman89401822014-05-06 15:04:28 -0400729 }
730
Nicolas Capens13ac2322016-10-13 14:52:12 -0400731 Value *Nucleus::createConstantBool(bool b)
John Bauman89401822014-05-06 15:04:28 -0400732 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400733 return V(llvm::ConstantInt::get(Type::getInt1Ty(*::context), b));
John Bauman89401822014-05-06 15:04:28 -0400734 }
735
Nicolas Capens13ac2322016-10-13 14:52:12 -0400736 Value *Nucleus::createConstantByte(signed char i)
John Bauman89401822014-05-06 15:04:28 -0400737 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400738 return V(llvm::ConstantInt::get(Type::getInt8Ty(*::context), i, true));
John Bauman89401822014-05-06 15:04:28 -0400739 }
740
Nicolas Capens13ac2322016-10-13 14:52:12 -0400741 Value *Nucleus::createConstantByte(unsigned char i)
John Bauman89401822014-05-06 15:04:28 -0400742 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400743 return V(llvm::ConstantInt::get(Type::getInt8Ty(*::context), i, false));
John Bauman89401822014-05-06 15:04:28 -0400744 }
745
Nicolas Capens13ac2322016-10-13 14:52:12 -0400746 Value *Nucleus::createConstantShort(short i)
John Bauman89401822014-05-06 15:04:28 -0400747 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400748 return V(llvm::ConstantInt::get(Type::getInt16Ty(*::context), i, true));
John Bauman89401822014-05-06 15:04:28 -0400749 }
750
Nicolas Capens13ac2322016-10-13 14:52:12 -0400751 Value *Nucleus::createConstantShort(unsigned short i)
John Bauman89401822014-05-06 15:04:28 -0400752 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400753 return V(llvm::ConstantInt::get(Type::getInt16Ty(*::context), i, false));
John Bauman89401822014-05-06 15:04:28 -0400754 }
755
Nicolas Capens13ac2322016-10-13 14:52:12 -0400756 Value *Nucleus::createConstantFloat(float x)
John Bauman89401822014-05-06 15:04:28 -0400757 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400758 return V(llvm::ConstantFP::get(Float::getType(), x));
John Bauman89401822014-05-06 15:04:28 -0400759 }
760
Nicolas Capens13ac2322016-10-13 14:52:12 -0400761 Value *Nucleus::createNullPointer(Type *Ty)
John Bauman89401822014-05-06 15:04:28 -0400762 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400763 return V(llvm::ConstantPointerNull::get(llvm::PointerType::get(Ty, 0)));
John Bauman89401822014-05-06 15:04:28 -0400764 }
765
Nicolas Capens13ac2322016-10-13 14:52:12 -0400766 Value *Nucleus::createConstantVector(const int64_t *constants, Type *type)
John Bauman89401822014-05-06 15:04:28 -0400767 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400768 assert(llvm::isa<VectorType>(type));
769 const int numConstants = llvm::cast<VectorType>(type)->getNumElements();
770 assert(numConstants <= 16);
771 llvm::Constant *constantVector[16];
772
773 for(int i = 0; i < numConstants; i++)
774 {
775 constantVector[i] = llvm::ConstantInt::get(type->getContainedType(0), constants[i]);
776 }
777
778 return V(llvm::ConstantVector::get(llvm::ArrayRef<llvm::Constant*>(constantVector, numConstants)));
779 }
780
781 Value *Nucleus::createConstantVector(const double *constants, Type *type)
782 {
783 assert(llvm::isa<VectorType>(type));
784 const int numConstants = llvm::cast<VectorType>(type)->getNumElements();
785 assert(numConstants <= 8);
786 llvm::Constant *constantVector[8];
787
788 for(int i = 0; i < numConstants; i++)
789 {
790 constantVector[i] = llvm::ConstantFP::get(type->getContainedType(0), constants[i]);
791 }
792
793 return V(llvm::ConstantVector::get(llvm::ArrayRef<llvm::Constant*>(constantVector, numConstants)));
John Bauman89401822014-05-06 15:04:28 -0400794 }
795
John Bauman19bac1e2014-05-06 15:23:49 -0400796 Type *Void::getType()
John Bauman89401822014-05-06 15:04:28 -0400797 {
Nicolas Capensac230122016-09-20 14:30:06 -0400798 return T(llvm::Type::getVoidTy(*::context));
John Bauman89401822014-05-06 15:04:28 -0400799 }
800
Nicolas Capens297d26e2016-11-18 12:52:17 -0500801 class MMX : public LValue<MMX>
Nicolas Capens4f738a12016-09-20 15:46:16 -0400802 {
803 public:
804 static Type *getType();
805 };
806
John Bauman19bac1e2014-05-06 15:23:49 -0400807 Type *MMX::getType()
808 {
Nicolas Capensac230122016-09-20 14:30:06 -0400809 return T(llvm::Type::getX86_MMXTy(*::context));
John Bauman19bac1e2014-05-06 15:23:49 -0400810 }
811
Nicolas Capens81f18302016-01-14 09:32:35 -0500812 Bool::Bool(Argument<Bool> argument)
John Bauman89401822014-05-06 15:04:28 -0400813 {
Nicolas Capens81f18302016-01-14 09:32:35 -0500814 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -0400815 }
816
John Bauman89401822014-05-06 15:04:28 -0400817 Bool::Bool(bool x)
818 {
John Bauman66b8ab22014-05-06 15:57:45 -0400819 storeValue(Nucleus::createConstantBool(x));
John Bauman89401822014-05-06 15:04:28 -0400820 }
821
John Bauman19bac1e2014-05-06 15:23:49 -0400822 Bool::Bool(RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400823 {
John Bauman66b8ab22014-05-06 15:57:45 -0400824 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400825 }
826
827 Bool::Bool(const Bool &rhs)
828 {
John Bauman66b8ab22014-05-06 15:57:45 -0400829 Value *value = rhs.loadValue();
830 storeValue(value);
831 }
John Bauman89401822014-05-06 15:04:28 -0400832
John Bauman66b8ab22014-05-06 15:57:45 -0400833 Bool::Bool(const Reference<Bool> &rhs)
834 {
835 Value *value = rhs.loadValue();
836 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400837 }
838
Nicolas Capens96d4e092016-11-18 14:22:38 -0500839 RValue<Bool> Bool::operator=(RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400840 {
John Bauman66b8ab22014-05-06 15:57:45 -0400841 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400842
843 return rhs;
844 }
845
Nicolas Capens96d4e092016-11-18 14:22:38 -0500846 RValue<Bool> Bool::operator=(const Bool &rhs)
John Bauman89401822014-05-06 15:04:28 -0400847 {
John Bauman66b8ab22014-05-06 15:57:45 -0400848 Value *value = rhs.loadValue();
849 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400850
851 return RValue<Bool>(value);
852 }
853
Nicolas Capens96d4e092016-11-18 14:22:38 -0500854 RValue<Bool> Bool::operator=(const Reference<Bool> &rhs)
John Bauman89401822014-05-06 15:04:28 -0400855 {
John Bauman66b8ab22014-05-06 15:57:45 -0400856 Value *value = rhs.loadValue();
857 storeValue(value);
858
859 return RValue<Bool>(value);
John Bauman89401822014-05-06 15:04:28 -0400860 }
861
John Bauman19bac1e2014-05-06 15:23:49 -0400862 RValue<Bool> operator!(RValue<Bool> val)
John Bauman89401822014-05-06 15:04:28 -0400863 {
864 return RValue<Bool>(Nucleus::createNot(val.value));
865 }
866
John Bauman19bac1e2014-05-06 15:23:49 -0400867 RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400868 {
869 return RValue<Bool>(Nucleus::createAnd(lhs.value, rhs.value));
870 }
871
John Bauman19bac1e2014-05-06 15:23:49 -0400872 RValue<Bool> operator||(RValue<Bool> lhs, RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400873 {
874 return RValue<Bool>(Nucleus::createOr(lhs.value, rhs.value));
875 }
876
John Bauman19bac1e2014-05-06 15:23:49 -0400877 Type *Bool::getType()
John Bauman89401822014-05-06 15:04:28 -0400878 {
Nicolas Capensac230122016-09-20 14:30:06 -0400879 return T(llvm::Type::getInt1Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -0400880 }
881
Nicolas Capens81f18302016-01-14 09:32:35 -0500882 Byte::Byte(Argument<Byte> argument)
John Bauman89401822014-05-06 15:04:28 -0400883 {
Nicolas Capens81f18302016-01-14 09:32:35 -0500884 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -0400885 }
886
John Bauman19bac1e2014-05-06 15:23:49 -0400887 Byte::Byte(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -0400888 {
John Bauman89401822014-05-06 15:04:28 -0400889 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
890
John Bauman66b8ab22014-05-06 15:57:45 -0400891 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -0400892 }
893
Alexis Hetu77dfab42015-11-23 13:31:22 -0500894 Byte::Byte(RValue<UInt> cast)
895 {
896 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
897
898 storeValue(integer);
899 }
900
901 Byte::Byte(RValue<UShort> cast)
902 {
903 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
904
905 storeValue(integer);
906 }
907
John Bauman89401822014-05-06 15:04:28 -0400908 Byte::Byte(int x)
909 {
John Bauman66b8ab22014-05-06 15:57:45 -0400910 storeValue(Nucleus::createConstantByte((unsigned char)x));
John Bauman89401822014-05-06 15:04:28 -0400911 }
912
913 Byte::Byte(unsigned char x)
914 {
John Bauman66b8ab22014-05-06 15:57:45 -0400915 storeValue(Nucleus::createConstantByte(x));
John Bauman89401822014-05-06 15:04:28 -0400916 }
917
John Bauman19bac1e2014-05-06 15:23:49 -0400918 Byte::Byte(RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400919 {
John Bauman66b8ab22014-05-06 15:57:45 -0400920 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400921 }
922
923 Byte::Byte(const Byte &rhs)
924 {
John Bauman66b8ab22014-05-06 15:57:45 -0400925 Value *value = rhs.loadValue();
926 storeValue(value);
927 }
John Bauman89401822014-05-06 15:04:28 -0400928
John Bauman66b8ab22014-05-06 15:57:45 -0400929 Byte::Byte(const Reference<Byte> &rhs)
930 {
931 Value *value = rhs.loadValue();
932 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400933 }
934
Nicolas Capens96d4e092016-11-18 14:22:38 -0500935 RValue<Byte> Byte::operator=(RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400936 {
John Bauman66b8ab22014-05-06 15:57:45 -0400937 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400938
939 return rhs;
940 }
941
Nicolas Capens96445fe2016-12-15 14:45:13 -0500942 RValue<Byte> Byte::operator=(const Byte &rhs)
John Bauman89401822014-05-06 15:04:28 -0400943 {
John Bauman66b8ab22014-05-06 15:57:45 -0400944 Value *value = rhs.loadValue();
945 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400946
947 return RValue<Byte>(value);
948 }
949
Nicolas Capens96d4e092016-11-18 14:22:38 -0500950 RValue<Byte> Byte::operator=(const Reference<Byte> &rhs)
John Bauman89401822014-05-06 15:04:28 -0400951 {
John Bauman66b8ab22014-05-06 15:57:45 -0400952 Value *value = rhs.loadValue();
953 storeValue(value);
954
955 return RValue<Byte>(value);
John Bauman89401822014-05-06 15:04:28 -0400956 }
957
John Bauman19bac1e2014-05-06 15:23:49 -0400958 RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400959 {
960 return RValue<Byte>(Nucleus::createAdd(lhs.value, rhs.value));
961 }
962
John Bauman19bac1e2014-05-06 15:23:49 -0400963 RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400964 {
965 return RValue<Byte>(Nucleus::createSub(lhs.value, rhs.value));
966 }
967
John Bauman19bac1e2014-05-06 15:23:49 -0400968 RValue<Byte> operator*(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400969 {
970 return RValue<Byte>(Nucleus::createMul(lhs.value, rhs.value));
971 }
972
John Bauman19bac1e2014-05-06 15:23:49 -0400973 RValue<Byte> operator/(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400974 {
975 return RValue<Byte>(Nucleus::createUDiv(lhs.value, rhs.value));
976 }
977
John Bauman19bac1e2014-05-06 15:23:49 -0400978 RValue<Byte> operator%(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400979 {
980 return RValue<Byte>(Nucleus::createURem(lhs.value, rhs.value));
981 }
982
John Bauman19bac1e2014-05-06 15:23:49 -0400983 RValue<Byte> operator&(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400984 {
985 return RValue<Byte>(Nucleus::createAnd(lhs.value, rhs.value));
986 }
987
John Bauman19bac1e2014-05-06 15:23:49 -0400988 RValue<Byte> operator|(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400989 {
990 return RValue<Byte>(Nucleus::createOr(lhs.value, rhs.value));
991 }
992
John Bauman19bac1e2014-05-06 15:23:49 -0400993 RValue<Byte> operator^(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400994 {
995 return RValue<Byte>(Nucleus::createXor(lhs.value, rhs.value));
996 }
997
John Bauman19bac1e2014-05-06 15:23:49 -0400998 RValue<Byte> operator<<(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400999 {
1000 return RValue<Byte>(Nucleus::createShl(lhs.value, rhs.value));
1001 }
1002
John Bauman19bac1e2014-05-06 15:23:49 -04001003 RValue<Byte> operator>>(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001004 {
1005 return RValue<Byte>(Nucleus::createLShr(lhs.value, rhs.value));
1006 }
1007
Nicolas Capens96d4e092016-11-18 14:22:38 -05001008 RValue<Byte> operator+=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001009 {
1010 return lhs = lhs + rhs;
1011 }
1012
Nicolas Capens96d4e092016-11-18 14:22:38 -05001013 RValue<Byte> operator-=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001014 {
1015 return lhs = lhs - rhs;
1016 }
1017
Nicolas Capens96d4e092016-11-18 14:22:38 -05001018 RValue<Byte> operator*=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001019 {
1020 return lhs = lhs * rhs;
1021 }
1022
Nicolas Capens96d4e092016-11-18 14:22:38 -05001023 RValue<Byte> operator/=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001024 {
1025 return lhs = lhs / rhs;
1026 }
1027
Nicolas Capens96d4e092016-11-18 14:22:38 -05001028 RValue<Byte> operator%=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001029 {
1030 return lhs = lhs % rhs;
1031 }
1032
Nicolas Capens96d4e092016-11-18 14:22:38 -05001033 RValue<Byte> operator&=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001034 {
1035 return lhs = lhs & rhs;
1036 }
1037
Nicolas Capens96d4e092016-11-18 14:22:38 -05001038 RValue<Byte> operator|=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001039 {
1040 return lhs = lhs | rhs;
1041 }
1042
Nicolas Capens96d4e092016-11-18 14:22:38 -05001043 RValue<Byte> operator^=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001044 {
1045 return lhs = lhs ^ rhs;
1046 }
1047
Nicolas Capens96d4e092016-11-18 14:22:38 -05001048 RValue<Byte> operator<<=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001049 {
1050 return lhs = lhs << rhs;
1051 }
1052
Nicolas Capens96d4e092016-11-18 14:22:38 -05001053 RValue<Byte> operator>>=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001054 {
1055 return lhs = lhs >> rhs;
1056 }
1057
John Bauman19bac1e2014-05-06 15:23:49 -04001058 RValue<Byte> operator+(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001059 {
1060 return val;
1061 }
1062
John Bauman19bac1e2014-05-06 15:23:49 -04001063 RValue<Byte> operator-(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001064 {
1065 return RValue<Byte>(Nucleus::createNeg(val.value));
1066 }
1067
John Bauman19bac1e2014-05-06 15:23:49 -04001068 RValue<Byte> operator~(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001069 {
1070 return RValue<Byte>(Nucleus::createNot(val.value));
1071 }
1072
Nicolas Capens96d4e092016-11-18 14:22:38 -05001073 RValue<Byte> operator++(Byte &val, int) // Post-increment
John Bauman89401822014-05-06 15:04:28 -04001074 {
1075 RValue<Byte> res = val;
1076
Nicolas Capens19336542016-09-26 10:32:29 -04001077 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantByte((unsigned char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001078 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001079
1080 return res;
1081 }
1082
Nicolas Capens96d4e092016-11-18 14:22:38 -05001083 const Byte &operator++(Byte &val) // Pre-increment
John Bauman89401822014-05-06 15:04:28 -04001084 {
Nicolas Capens19336542016-09-26 10:32:29 -04001085 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantByte((unsigned char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001086 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001087
1088 return val;
1089 }
1090
Nicolas Capens96d4e092016-11-18 14:22:38 -05001091 RValue<Byte> operator--(Byte &val, int) // Post-decrement
John Bauman89401822014-05-06 15:04:28 -04001092 {
1093 RValue<Byte> res = val;
1094
Nicolas Capens19336542016-09-26 10:32:29 -04001095 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantByte((unsigned char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001096 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001097
1098 return res;
1099 }
1100
Nicolas Capens96d4e092016-11-18 14:22:38 -05001101 const Byte &operator--(Byte &val) // Pre-decrement
John Bauman89401822014-05-06 15:04:28 -04001102 {
Nicolas Capens19336542016-09-26 10:32:29 -04001103 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantByte((unsigned char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001104 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001105
1106 return val;
1107 }
1108
John Bauman19bac1e2014-05-06 15:23:49 -04001109 RValue<Bool> operator<(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001110 {
1111 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1112 }
1113
John Bauman19bac1e2014-05-06 15:23:49 -04001114 RValue<Bool> operator<=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001115 {
1116 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1117 }
1118
John Bauman19bac1e2014-05-06 15:23:49 -04001119 RValue<Bool> operator>(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001120 {
1121 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1122 }
1123
John Bauman19bac1e2014-05-06 15:23:49 -04001124 RValue<Bool> operator>=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001125 {
1126 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1127 }
1128
John Bauman19bac1e2014-05-06 15:23:49 -04001129 RValue<Bool> operator!=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001130 {
1131 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1132 }
1133
John Bauman19bac1e2014-05-06 15:23:49 -04001134 RValue<Bool> operator==(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001135 {
1136 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1137 }
1138
John Bauman19bac1e2014-05-06 15:23:49 -04001139 Type *Byte::getType()
John Bauman89401822014-05-06 15:04:28 -04001140 {
Nicolas Capensac230122016-09-20 14:30:06 -04001141 return T(llvm::Type::getInt8Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001142 }
1143
Nicolas Capens81f18302016-01-14 09:32:35 -05001144 SByte::SByte(Argument<SByte> argument)
John Bauman89401822014-05-06 15:04:28 -04001145 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001146 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001147 }
1148
Alexis Hetu77dfab42015-11-23 13:31:22 -05001149 SByte::SByte(RValue<Int> cast)
1150 {
1151 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1152
1153 storeValue(integer);
1154 }
1155
1156 SByte::SByte(RValue<Short> cast)
1157 {
1158 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1159
1160 storeValue(integer);
1161 }
1162
John Bauman89401822014-05-06 15:04:28 -04001163 SByte::SByte(signed char x)
1164 {
John Bauman66b8ab22014-05-06 15:57:45 -04001165 storeValue(Nucleus::createConstantByte(x));
John Bauman89401822014-05-06 15:04:28 -04001166 }
1167
John Bauman19bac1e2014-05-06 15:23:49 -04001168 SByte::SByte(RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001169 {
John Bauman66b8ab22014-05-06 15:57:45 -04001170 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001171 }
1172
1173 SByte::SByte(const SByte &rhs)
1174 {
John Bauman66b8ab22014-05-06 15:57:45 -04001175 Value *value = rhs.loadValue();
1176 storeValue(value);
1177 }
John Bauman89401822014-05-06 15:04:28 -04001178
John Bauman66b8ab22014-05-06 15:57:45 -04001179 SByte::SByte(const Reference<SByte> &rhs)
1180 {
1181 Value *value = rhs.loadValue();
1182 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001183 }
1184
Nicolas Capens96d4e092016-11-18 14:22:38 -05001185 RValue<SByte> SByte::operator=(RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001186 {
John Bauman66b8ab22014-05-06 15:57:45 -04001187 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001188
1189 return rhs;
1190 }
1191
Nicolas Capens96d4e092016-11-18 14:22:38 -05001192 RValue<SByte> SByte::operator=(const SByte &rhs)
John Bauman89401822014-05-06 15:04:28 -04001193 {
John Bauman66b8ab22014-05-06 15:57:45 -04001194 Value *value = rhs.loadValue();
1195 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001196
1197 return RValue<SByte>(value);
1198 }
1199
Nicolas Capens96d4e092016-11-18 14:22:38 -05001200 RValue<SByte> SByte::operator=(const Reference<SByte> &rhs)
John Bauman89401822014-05-06 15:04:28 -04001201 {
John Bauman66b8ab22014-05-06 15:57:45 -04001202 Value *value = rhs.loadValue();
1203 storeValue(value);
1204
1205 return RValue<SByte>(value);
John Bauman89401822014-05-06 15:04:28 -04001206 }
1207
John Bauman19bac1e2014-05-06 15:23:49 -04001208 RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001209 {
1210 return RValue<SByte>(Nucleus::createAdd(lhs.value, rhs.value));
1211 }
1212
John Bauman19bac1e2014-05-06 15:23:49 -04001213 RValue<SByte> operator-(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001214 {
1215 return RValue<SByte>(Nucleus::createSub(lhs.value, rhs.value));
1216 }
1217
John Bauman19bac1e2014-05-06 15:23:49 -04001218 RValue<SByte> operator*(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001219 {
1220 return RValue<SByte>(Nucleus::createMul(lhs.value, rhs.value));
1221 }
1222
John Bauman19bac1e2014-05-06 15:23:49 -04001223 RValue<SByte> operator/(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001224 {
1225 return RValue<SByte>(Nucleus::createSDiv(lhs.value, rhs.value));
1226 }
1227
John Bauman19bac1e2014-05-06 15:23:49 -04001228 RValue<SByte> operator%(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001229 {
1230 return RValue<SByte>(Nucleus::createSRem(lhs.value, rhs.value));
1231 }
1232
John Bauman19bac1e2014-05-06 15:23:49 -04001233 RValue<SByte> operator&(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001234 {
1235 return RValue<SByte>(Nucleus::createAnd(lhs.value, rhs.value));
1236 }
1237
John Bauman19bac1e2014-05-06 15:23:49 -04001238 RValue<SByte> operator|(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001239 {
1240 return RValue<SByte>(Nucleus::createOr(lhs.value, rhs.value));
1241 }
1242
John Bauman19bac1e2014-05-06 15:23:49 -04001243 RValue<SByte> operator^(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001244 {
1245 return RValue<SByte>(Nucleus::createXor(lhs.value, rhs.value));
1246 }
1247
John Bauman19bac1e2014-05-06 15:23:49 -04001248 RValue<SByte> operator<<(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001249 {
1250 return RValue<SByte>(Nucleus::createShl(lhs.value, rhs.value));
1251 }
1252
John Bauman19bac1e2014-05-06 15:23:49 -04001253 RValue<SByte> operator>>(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001254 {
1255 return RValue<SByte>(Nucleus::createAShr(lhs.value, rhs.value));
1256 }
1257
Nicolas Capens96d4e092016-11-18 14:22:38 -05001258 RValue<SByte> operator+=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001259 {
1260 return lhs = lhs + rhs;
1261 }
1262
Nicolas Capens96d4e092016-11-18 14:22:38 -05001263 RValue<SByte> operator-=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001264 {
1265 return lhs = lhs - rhs;
1266 }
1267
Nicolas Capens96d4e092016-11-18 14:22:38 -05001268 RValue<SByte> operator*=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001269 {
1270 return lhs = lhs * rhs;
1271 }
1272
Nicolas Capens96d4e092016-11-18 14:22:38 -05001273 RValue<SByte> operator/=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001274 {
1275 return lhs = lhs / rhs;
1276 }
1277
Nicolas Capens96d4e092016-11-18 14:22:38 -05001278 RValue<SByte> operator%=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001279 {
1280 return lhs = lhs % rhs;
1281 }
1282
Nicolas Capens96d4e092016-11-18 14:22:38 -05001283 RValue<SByte> operator&=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001284 {
1285 return lhs = lhs & rhs;
1286 }
1287
Nicolas Capens96d4e092016-11-18 14:22:38 -05001288 RValue<SByte> operator|=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001289 {
1290 return lhs = lhs | rhs;
1291 }
1292
Nicolas Capens96d4e092016-11-18 14:22:38 -05001293 RValue<SByte> operator^=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001294 {
1295 return lhs = lhs ^ rhs;
1296 }
1297
Nicolas Capens96d4e092016-11-18 14:22:38 -05001298 RValue<SByte> operator<<=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001299 {
1300 return lhs = lhs << rhs;
1301 }
1302
Nicolas Capens96d4e092016-11-18 14:22:38 -05001303 RValue<SByte> operator>>=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001304 {
1305 return lhs = lhs >> rhs;
1306 }
1307
John Bauman19bac1e2014-05-06 15:23:49 -04001308 RValue<SByte> operator+(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001309 {
1310 return val;
1311 }
1312
John Bauman19bac1e2014-05-06 15:23:49 -04001313 RValue<SByte> operator-(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001314 {
1315 return RValue<SByte>(Nucleus::createNeg(val.value));
1316 }
1317
John Bauman19bac1e2014-05-06 15:23:49 -04001318 RValue<SByte> operator~(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001319 {
1320 return RValue<SByte>(Nucleus::createNot(val.value));
1321 }
1322
Nicolas Capens96d4e092016-11-18 14:22:38 -05001323 RValue<SByte> operator++(SByte &val, int) // Post-increment
John Bauman89401822014-05-06 15:04:28 -04001324 {
1325 RValue<SByte> res = val;
1326
Nicolas Capens19336542016-09-26 10:32:29 -04001327 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantByte((signed char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001328 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001329
1330 return res;
1331 }
1332
Nicolas Capens96d4e092016-11-18 14:22:38 -05001333 const SByte &operator++(SByte &val) // Pre-increment
John Bauman89401822014-05-06 15:04:28 -04001334 {
Nicolas Capens19336542016-09-26 10:32:29 -04001335 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantByte((signed char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001336 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001337
1338 return val;
1339 }
1340
Nicolas Capens96d4e092016-11-18 14:22:38 -05001341 RValue<SByte> operator--(SByte &val, int) // Post-decrement
John Bauman89401822014-05-06 15:04:28 -04001342 {
1343 RValue<SByte> res = val;
1344
Nicolas Capens19336542016-09-26 10:32:29 -04001345 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantByte((signed char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001346 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001347
1348 return res;
1349 }
1350
Nicolas Capens96d4e092016-11-18 14:22:38 -05001351 const SByte &operator--(SByte &val) // Pre-decrement
John Bauman89401822014-05-06 15:04:28 -04001352 {
Nicolas Capens19336542016-09-26 10:32:29 -04001353 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantByte((signed char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001354 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001355
1356 return val;
1357 }
1358
John Bauman19bac1e2014-05-06 15:23:49 -04001359 RValue<Bool> operator<(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001360 {
1361 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
1362 }
1363
John Bauman19bac1e2014-05-06 15:23:49 -04001364 RValue<Bool> operator<=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001365 {
1366 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
1367 }
1368
John Bauman19bac1e2014-05-06 15:23:49 -04001369 RValue<Bool> operator>(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001370 {
1371 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
1372 }
1373
John Bauman19bac1e2014-05-06 15:23:49 -04001374 RValue<Bool> operator>=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001375 {
1376 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
1377 }
1378
John Bauman19bac1e2014-05-06 15:23:49 -04001379 RValue<Bool> operator!=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001380 {
1381 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1382 }
1383
John Bauman19bac1e2014-05-06 15:23:49 -04001384 RValue<Bool> operator==(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001385 {
1386 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1387 }
1388
John Bauman19bac1e2014-05-06 15:23:49 -04001389 Type *SByte::getType()
John Bauman89401822014-05-06 15:04:28 -04001390 {
Nicolas Capensac230122016-09-20 14:30:06 -04001391 return T(llvm::Type::getInt8Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001392 }
1393
Nicolas Capens81f18302016-01-14 09:32:35 -05001394 Short::Short(Argument<Short> argument)
John Bauman89401822014-05-06 15:04:28 -04001395 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001396 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001397 }
1398
John Bauman19bac1e2014-05-06 15:23:49 -04001399 Short::Short(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04001400 {
John Bauman89401822014-05-06 15:04:28 -04001401 Value *integer = Nucleus::createTrunc(cast.value, Short::getType());
1402
John Bauman66b8ab22014-05-06 15:57:45 -04001403 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04001404 }
1405
John Bauman89401822014-05-06 15:04:28 -04001406 Short::Short(short x)
1407 {
John Bauman66b8ab22014-05-06 15:57:45 -04001408 storeValue(Nucleus::createConstantShort(x));
John Bauman89401822014-05-06 15:04:28 -04001409 }
1410
John Bauman19bac1e2014-05-06 15:23:49 -04001411 Short::Short(RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001412 {
John Bauman66b8ab22014-05-06 15:57:45 -04001413 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001414 }
1415
1416 Short::Short(const Short &rhs)
1417 {
John Bauman66b8ab22014-05-06 15:57:45 -04001418 Value *value = rhs.loadValue();
1419 storeValue(value);
1420 }
John Bauman89401822014-05-06 15:04:28 -04001421
John Bauman66b8ab22014-05-06 15:57:45 -04001422 Short::Short(const Reference<Short> &rhs)
1423 {
1424 Value *value = rhs.loadValue();
1425 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001426 }
1427
Nicolas Capens96d4e092016-11-18 14:22:38 -05001428 RValue<Short> Short::operator=(RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001429 {
John Bauman66b8ab22014-05-06 15:57:45 -04001430 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001431
1432 return rhs;
1433 }
1434
Nicolas Capens96d4e092016-11-18 14:22:38 -05001435 RValue<Short> Short::operator=(const Short &rhs)
John Bauman89401822014-05-06 15:04:28 -04001436 {
John Bauman66b8ab22014-05-06 15:57:45 -04001437 Value *value = rhs.loadValue();
1438 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001439
1440 return RValue<Short>(value);
1441 }
1442
Nicolas Capens96d4e092016-11-18 14:22:38 -05001443 RValue<Short> Short::operator=(const Reference<Short> &rhs)
John Bauman89401822014-05-06 15:04:28 -04001444 {
John Bauman66b8ab22014-05-06 15:57:45 -04001445 Value *value = rhs.loadValue();
1446 storeValue(value);
1447
1448 return RValue<Short>(value);
John Bauman89401822014-05-06 15:04:28 -04001449 }
1450
John Bauman19bac1e2014-05-06 15:23:49 -04001451 RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001452 {
1453 return RValue<Short>(Nucleus::createAdd(lhs.value, rhs.value));
1454 }
1455
John Bauman19bac1e2014-05-06 15:23:49 -04001456 RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001457 {
1458 return RValue<Short>(Nucleus::createSub(lhs.value, rhs.value));
1459 }
1460
John Bauman19bac1e2014-05-06 15:23:49 -04001461 RValue<Short> operator*(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001462 {
1463 return RValue<Short>(Nucleus::createMul(lhs.value, rhs.value));
1464 }
1465
John Bauman19bac1e2014-05-06 15:23:49 -04001466 RValue<Short> operator/(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001467 {
1468 return RValue<Short>(Nucleus::createSDiv(lhs.value, rhs.value));
1469 }
1470
John Bauman19bac1e2014-05-06 15:23:49 -04001471 RValue<Short> operator%(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001472 {
1473 return RValue<Short>(Nucleus::createSRem(lhs.value, rhs.value));
1474 }
1475
John Bauman19bac1e2014-05-06 15:23:49 -04001476 RValue<Short> operator&(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001477 {
1478 return RValue<Short>(Nucleus::createAnd(lhs.value, rhs.value));
1479 }
1480
John Bauman19bac1e2014-05-06 15:23:49 -04001481 RValue<Short> operator|(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001482 {
1483 return RValue<Short>(Nucleus::createOr(lhs.value, rhs.value));
1484 }
1485
John Bauman19bac1e2014-05-06 15:23:49 -04001486 RValue<Short> operator^(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001487 {
1488 return RValue<Short>(Nucleus::createXor(lhs.value, rhs.value));
1489 }
1490
John Bauman19bac1e2014-05-06 15:23:49 -04001491 RValue<Short> operator<<(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001492 {
1493 return RValue<Short>(Nucleus::createShl(lhs.value, rhs.value));
1494 }
1495
John Bauman19bac1e2014-05-06 15:23:49 -04001496 RValue<Short> operator>>(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001497 {
1498 return RValue<Short>(Nucleus::createAShr(lhs.value, rhs.value));
1499 }
1500
Nicolas Capens96d4e092016-11-18 14:22:38 -05001501 RValue<Short> operator+=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001502 {
1503 return lhs = lhs + rhs;
1504 }
1505
Nicolas Capens96d4e092016-11-18 14:22:38 -05001506 RValue<Short> operator-=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001507 {
1508 return lhs = lhs - rhs;
1509 }
1510
Nicolas Capens96d4e092016-11-18 14:22:38 -05001511 RValue<Short> operator*=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001512 {
1513 return lhs = lhs * rhs;
1514 }
1515
Nicolas Capens96d4e092016-11-18 14:22:38 -05001516 RValue<Short> operator/=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001517 {
1518 return lhs = lhs / rhs;
1519 }
1520
Nicolas Capens96d4e092016-11-18 14:22:38 -05001521 RValue<Short> operator%=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001522 {
1523 return lhs = lhs % rhs;
1524 }
1525
Nicolas Capens96d4e092016-11-18 14:22:38 -05001526 RValue<Short> operator&=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001527 {
1528 return lhs = lhs & rhs;
1529 }
1530
Nicolas Capens96d4e092016-11-18 14:22:38 -05001531 RValue<Short> operator|=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001532 {
1533 return lhs = lhs | rhs;
1534 }
1535
Nicolas Capens96d4e092016-11-18 14:22:38 -05001536 RValue<Short> operator^=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001537 {
1538 return lhs = lhs ^ rhs;
1539 }
1540
Nicolas Capens96d4e092016-11-18 14:22:38 -05001541 RValue<Short> operator<<=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001542 {
1543 return lhs = lhs << rhs;
1544 }
1545
Nicolas Capens96d4e092016-11-18 14:22:38 -05001546 RValue<Short> operator>>=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001547 {
1548 return lhs = lhs >> rhs;
1549 }
1550
John Bauman19bac1e2014-05-06 15:23:49 -04001551 RValue<Short> operator+(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001552 {
1553 return val;
1554 }
1555
John Bauman19bac1e2014-05-06 15:23:49 -04001556 RValue<Short> operator-(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001557 {
1558 return RValue<Short>(Nucleus::createNeg(val.value));
1559 }
1560
John Bauman19bac1e2014-05-06 15:23:49 -04001561 RValue<Short> operator~(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001562 {
1563 return RValue<Short>(Nucleus::createNot(val.value));
1564 }
1565
Nicolas Capens96d4e092016-11-18 14:22:38 -05001566 RValue<Short> operator++(Short &val, int) // Post-increment
John Bauman89401822014-05-06 15:04:28 -04001567 {
1568 RValue<Short> res = val;
1569
Nicolas Capens19336542016-09-26 10:32:29 -04001570 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantShort((short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001571 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001572
1573 return res;
1574 }
1575
Nicolas Capens96d4e092016-11-18 14:22:38 -05001576 const Short &operator++(Short &val) // Pre-increment
John Bauman89401822014-05-06 15:04:28 -04001577 {
Nicolas Capens19336542016-09-26 10:32:29 -04001578 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantShort((short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001579 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001580
1581 return val;
1582 }
1583
Nicolas Capens96d4e092016-11-18 14:22:38 -05001584 RValue<Short> operator--(Short &val, int) // Post-decrement
John Bauman89401822014-05-06 15:04:28 -04001585 {
1586 RValue<Short> res = val;
1587
Nicolas Capens19336542016-09-26 10:32:29 -04001588 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantShort((short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001589 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001590
1591 return res;
1592 }
1593
Nicolas Capens96d4e092016-11-18 14:22:38 -05001594 const Short &operator--(Short &val) // Pre-decrement
John Bauman89401822014-05-06 15:04:28 -04001595 {
Nicolas Capens19336542016-09-26 10:32:29 -04001596 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantShort((short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001597 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001598
1599 return val;
1600 }
1601
John Bauman19bac1e2014-05-06 15:23:49 -04001602 RValue<Bool> operator<(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001603 {
1604 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
1605 }
1606
John Bauman19bac1e2014-05-06 15:23:49 -04001607 RValue<Bool> operator<=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001608 {
1609 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
1610 }
1611
John Bauman19bac1e2014-05-06 15:23:49 -04001612 RValue<Bool> operator>(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001613 {
1614 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
1615 }
1616
John Bauman19bac1e2014-05-06 15:23:49 -04001617 RValue<Bool> operator>=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001618 {
1619 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
1620 }
1621
John Bauman19bac1e2014-05-06 15:23:49 -04001622 RValue<Bool> operator!=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001623 {
1624 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1625 }
1626
John Bauman19bac1e2014-05-06 15:23:49 -04001627 RValue<Bool> operator==(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001628 {
1629 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1630 }
1631
John Bauman19bac1e2014-05-06 15:23:49 -04001632 Type *Short::getType()
John Bauman89401822014-05-06 15:04:28 -04001633 {
Nicolas Capensac230122016-09-20 14:30:06 -04001634 return T(llvm::Type::getInt16Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001635 }
1636
Nicolas Capens81f18302016-01-14 09:32:35 -05001637 UShort::UShort(Argument<UShort> argument)
John Bauman89401822014-05-06 15:04:28 -04001638 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001639 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001640 }
1641
Alexis Hetu77dfab42015-11-23 13:31:22 -05001642 UShort::UShort(RValue<UInt> cast)
1643 {
1644 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
1645
1646 storeValue(integer);
1647 }
1648
Alexis Hetu75b650f2015-11-19 17:40:15 -05001649 UShort::UShort(RValue<Int> cast)
1650 {
1651 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
1652
1653 storeValue(integer);
1654 }
1655
John Bauman89401822014-05-06 15:04:28 -04001656 UShort::UShort(unsigned short x)
1657 {
John Bauman66b8ab22014-05-06 15:57:45 -04001658 storeValue(Nucleus::createConstantShort(x));
John Bauman89401822014-05-06 15:04:28 -04001659 }
1660
John Bauman19bac1e2014-05-06 15:23:49 -04001661 UShort::UShort(RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001662 {
John Bauman66b8ab22014-05-06 15:57:45 -04001663 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001664 }
1665
1666 UShort::UShort(const UShort &rhs)
1667 {
John Bauman66b8ab22014-05-06 15:57:45 -04001668 Value *value = rhs.loadValue();
1669 storeValue(value);
1670 }
John Bauman89401822014-05-06 15:04:28 -04001671
John Bauman66b8ab22014-05-06 15:57:45 -04001672 UShort::UShort(const Reference<UShort> &rhs)
1673 {
1674 Value *value = rhs.loadValue();
1675 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001676 }
1677
Nicolas Capens96d4e092016-11-18 14:22:38 -05001678 RValue<UShort> UShort::operator=(RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001679 {
John Bauman66b8ab22014-05-06 15:57:45 -04001680 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001681
1682 return rhs;
1683 }
1684
Nicolas Capens96d4e092016-11-18 14:22:38 -05001685 RValue<UShort> UShort::operator=(const UShort &rhs)
John Bauman89401822014-05-06 15:04:28 -04001686 {
John Bauman66b8ab22014-05-06 15:57:45 -04001687 Value *value = rhs.loadValue();
1688 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001689
1690 return RValue<UShort>(value);
1691 }
1692
Nicolas Capens96d4e092016-11-18 14:22:38 -05001693 RValue<UShort> UShort::operator=(const Reference<UShort> &rhs)
John Bauman89401822014-05-06 15:04:28 -04001694 {
John Bauman66b8ab22014-05-06 15:57:45 -04001695 Value *value = rhs.loadValue();
1696 storeValue(value);
1697
1698 return RValue<UShort>(value);
John Bauman89401822014-05-06 15:04:28 -04001699 }
1700
John Bauman19bac1e2014-05-06 15:23:49 -04001701 RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001702 {
1703 return RValue<UShort>(Nucleus::createAdd(lhs.value, rhs.value));
1704 }
1705
John Bauman19bac1e2014-05-06 15:23:49 -04001706 RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001707 {
1708 return RValue<UShort>(Nucleus::createSub(lhs.value, rhs.value));
1709 }
1710
John Bauman19bac1e2014-05-06 15:23:49 -04001711 RValue<UShort> operator*(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001712 {
1713 return RValue<UShort>(Nucleus::createMul(lhs.value, rhs.value));
1714 }
1715
John Bauman19bac1e2014-05-06 15:23:49 -04001716 RValue<UShort> operator/(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001717 {
1718 return RValue<UShort>(Nucleus::createUDiv(lhs.value, rhs.value));
1719 }
1720
John Bauman19bac1e2014-05-06 15:23:49 -04001721 RValue<UShort> operator%(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001722 {
1723 return RValue<UShort>(Nucleus::createURem(lhs.value, rhs.value));
1724 }
1725
John Bauman19bac1e2014-05-06 15:23:49 -04001726 RValue<UShort> operator&(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001727 {
1728 return RValue<UShort>(Nucleus::createAnd(lhs.value, rhs.value));
1729 }
1730
John Bauman19bac1e2014-05-06 15:23:49 -04001731 RValue<UShort> operator|(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001732 {
1733 return RValue<UShort>(Nucleus::createOr(lhs.value, rhs.value));
1734 }
1735
John Bauman19bac1e2014-05-06 15:23:49 -04001736 RValue<UShort> operator^(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001737 {
1738 return RValue<UShort>(Nucleus::createXor(lhs.value, rhs.value));
1739 }
1740
John Bauman19bac1e2014-05-06 15:23:49 -04001741 RValue<UShort> operator<<(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001742 {
1743 return RValue<UShort>(Nucleus::createShl(lhs.value, rhs.value));
1744 }
1745
John Bauman19bac1e2014-05-06 15:23:49 -04001746 RValue<UShort> operator>>(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001747 {
1748 return RValue<UShort>(Nucleus::createLShr(lhs.value, rhs.value));
1749 }
1750
Nicolas Capens96d4e092016-11-18 14:22:38 -05001751 RValue<UShort> operator+=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001752 {
1753 return lhs = lhs + rhs;
1754 }
1755
Nicolas Capens96d4e092016-11-18 14:22:38 -05001756 RValue<UShort> operator-=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001757 {
1758 return lhs = lhs - rhs;
1759 }
1760
Nicolas Capens96d4e092016-11-18 14:22:38 -05001761 RValue<UShort> operator*=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001762 {
1763 return lhs = lhs * rhs;
1764 }
1765
Nicolas Capens96d4e092016-11-18 14:22:38 -05001766 RValue<UShort> operator/=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001767 {
1768 return lhs = lhs / rhs;
1769 }
1770
Nicolas Capens96d4e092016-11-18 14:22:38 -05001771 RValue<UShort> operator%=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001772 {
1773 return lhs = lhs % rhs;
1774 }
1775
Nicolas Capens96d4e092016-11-18 14:22:38 -05001776 RValue<UShort> operator&=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001777 {
1778 return lhs = lhs & rhs;
1779 }
1780
Nicolas Capens96d4e092016-11-18 14:22:38 -05001781 RValue<UShort> operator|=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001782 {
1783 return lhs = lhs | rhs;
1784 }
1785
Nicolas Capens96d4e092016-11-18 14:22:38 -05001786 RValue<UShort> operator^=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001787 {
1788 return lhs = lhs ^ rhs;
1789 }
1790
Nicolas Capens96d4e092016-11-18 14:22:38 -05001791 RValue<UShort> operator<<=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001792 {
1793 return lhs = lhs << rhs;
1794 }
1795
Nicolas Capens96d4e092016-11-18 14:22:38 -05001796 RValue<UShort> operator>>=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001797 {
1798 return lhs = lhs >> rhs;
1799 }
1800
John Bauman19bac1e2014-05-06 15:23:49 -04001801 RValue<UShort> operator+(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001802 {
1803 return val;
1804 }
1805
John Bauman19bac1e2014-05-06 15:23:49 -04001806 RValue<UShort> operator-(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001807 {
1808 return RValue<UShort>(Nucleus::createNeg(val.value));
1809 }
1810
John Bauman19bac1e2014-05-06 15:23:49 -04001811 RValue<UShort> operator~(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001812 {
1813 return RValue<UShort>(Nucleus::createNot(val.value));
1814 }
1815
Nicolas Capens96d4e092016-11-18 14:22:38 -05001816 RValue<UShort> operator++(UShort &val, int) // Post-increment
John Bauman89401822014-05-06 15:04:28 -04001817 {
1818 RValue<UShort> res = val;
1819
Nicolas Capens19336542016-09-26 10:32:29 -04001820 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantShort((unsigned short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001821 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001822
1823 return res;
1824 }
1825
Nicolas Capens96d4e092016-11-18 14:22:38 -05001826 const UShort &operator++(UShort &val) // Pre-increment
John Bauman89401822014-05-06 15:04:28 -04001827 {
Nicolas Capens19336542016-09-26 10:32:29 -04001828 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantShort((unsigned short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001829 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001830
1831 return val;
1832 }
1833
Nicolas Capens96d4e092016-11-18 14:22:38 -05001834 RValue<UShort> operator--(UShort &val, int) // Post-decrement
John Bauman89401822014-05-06 15:04:28 -04001835 {
1836 RValue<UShort> res = val;
1837
Nicolas Capens19336542016-09-26 10:32:29 -04001838 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantShort((unsigned short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001839 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001840
1841 return res;
1842 }
1843
Nicolas Capens96d4e092016-11-18 14:22:38 -05001844 const UShort &operator--(UShort &val) // Pre-decrement
John Bauman89401822014-05-06 15:04:28 -04001845 {
Nicolas Capens19336542016-09-26 10:32:29 -04001846 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantShort((unsigned short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001847 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001848
1849 return val;
1850 }
1851
John Bauman19bac1e2014-05-06 15:23:49 -04001852 RValue<Bool> operator<(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001853 {
1854 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1855 }
1856
John Bauman19bac1e2014-05-06 15:23:49 -04001857 RValue<Bool> operator<=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001858 {
1859 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1860 }
1861
John Bauman19bac1e2014-05-06 15:23:49 -04001862 RValue<Bool> operator>(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001863 {
1864 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1865 }
1866
John Bauman19bac1e2014-05-06 15:23:49 -04001867 RValue<Bool> operator>=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001868 {
1869 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1870 }
1871
John Bauman19bac1e2014-05-06 15:23:49 -04001872 RValue<Bool> operator!=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001873 {
1874 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1875 }
1876
John Bauman19bac1e2014-05-06 15:23:49 -04001877 RValue<Bool> operator==(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001878 {
1879 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1880 }
1881
John Bauman19bac1e2014-05-06 15:23:49 -04001882 Type *UShort::getType()
John Bauman89401822014-05-06 15:04:28 -04001883 {
Nicolas Capensac230122016-09-20 14:30:06 -04001884 return T(llvm::Type::getInt16Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001885 }
1886
Nicolas Capens16b5f152016-10-13 13:39:01 -04001887 Byte4::Byte4(RValue<Byte8> cast)
1888 {
Nicolas Capens16b5f152016-10-13 13:39:01 -04001889 storeValue(Nucleus::createTrunc(Nucleus::createBitCast(cast.value, Long::getType()), Int::getType()));
1890 }
1891
1892 Byte4::Byte4(const Reference<Byte4> &rhs)
1893 {
Nicolas Capens16b5f152016-10-13 13:39:01 -04001894 Value *value = rhs.loadValue();
1895 storeValue(value);
1896 }
1897
John Bauman19bac1e2014-05-06 15:23:49 -04001898 Type *Byte4::getType()
John Bauman89401822014-05-06 15:04:28 -04001899 {
1900 #if 0
Nicolas Capensac230122016-09-20 14:30:06 -04001901 return T(VectorType::get(Byte::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04001902 #else
1903 return UInt::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
1904 #endif
1905 }
1906
John Bauman19bac1e2014-05-06 15:23:49 -04001907 Type *SByte4::getType()
John Bauman89401822014-05-06 15:04:28 -04001908 {
1909 #if 0
Nicolas Capensac230122016-09-20 14:30:06 -04001910 return T(VectorType::get(SByte::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04001911 #else
1912 return Int::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
1913 #endif
1914 }
1915
Nicolas Capens3bbc5e12016-09-27 10:49:52 -04001916 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 -04001917 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04001918 int64_t constantVector[8] = {x0, x1, x2, x3, x4, x5, x6, x7};
1919 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(Byte::getType(), 8))));
John Bauman89401822014-05-06 15:04:28 -04001920
John Bauman66b8ab22014-05-06 15:57:45 -04001921 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04001922 }
1923
John Bauman19bac1e2014-05-06 15:23:49 -04001924 Byte8::Byte8(RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04001925 {
John Bauman66b8ab22014-05-06 15:57:45 -04001926 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001927 }
1928
1929 Byte8::Byte8(const Byte8 &rhs)
1930 {
John Bauman66b8ab22014-05-06 15:57:45 -04001931 Value *value = rhs.loadValue();
1932 storeValue(value);
1933 }
1934
1935 Byte8::Byte8(const Reference<Byte8> &rhs)
1936 {
John Bauman66b8ab22014-05-06 15:57:45 -04001937 Value *value = rhs.loadValue();
1938 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001939 }
1940
Nicolas Capens96d4e092016-11-18 14:22:38 -05001941 RValue<Byte8> Byte8::operator=(RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04001942 {
John Bauman66b8ab22014-05-06 15:57:45 -04001943 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001944
1945 return rhs;
1946 }
1947
Nicolas Capens96d4e092016-11-18 14:22:38 -05001948 RValue<Byte8> Byte8::operator=(const Byte8 &rhs)
John Bauman89401822014-05-06 15:04:28 -04001949 {
John Bauman66b8ab22014-05-06 15:57:45 -04001950 Value *value = rhs.loadValue();
1951 storeValue(value);
1952
1953 return RValue<Byte8>(value);
1954 }
1955
Nicolas Capens96d4e092016-11-18 14:22:38 -05001956 RValue<Byte8> Byte8::operator=(const Reference<Byte8> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04001957 {
1958 Value *value = rhs.loadValue();
1959 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001960
1961 return RValue<Byte8>(value);
1962 }
1963
John Bauman19bac1e2014-05-06 15:23:49 -04001964 RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04001965 {
John Bauman19bac1e2014-05-06 15:23:49 -04001966 if(CPUID::supportsMMX2())
1967 {
1968 return x86::paddb(lhs, rhs);
1969 }
1970 else
1971 {
1972 return RValue<Byte8>(Nucleus::createAdd(lhs.value, rhs.value));
1973 }
John Bauman89401822014-05-06 15:04:28 -04001974 }
1975
John Bauman19bac1e2014-05-06 15:23:49 -04001976 RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04001977 {
John Bauman19bac1e2014-05-06 15:23:49 -04001978 if(CPUID::supportsMMX2())
1979 {
1980 return x86::psubb(lhs, rhs);
1981 }
1982 else
1983 {
1984 return RValue<Byte8>(Nucleus::createSub(lhs.value, rhs.value));
1985 }
John Bauman89401822014-05-06 15:04:28 -04001986 }
1987
John Bauman19bac1e2014-05-06 15:23:49 -04001988// RValue<Byte8> operator*(RValue<Byte8> lhs, RValue<Byte8> rhs)
1989// {
1990// return RValue<Byte8>(Nucleus::createMul(lhs.value, rhs.value));
1991// }
1992
1993// RValue<Byte8> operator/(RValue<Byte8> lhs, RValue<Byte8> rhs)
1994// {
1995// return RValue<Byte8>(Nucleus::createUDiv(lhs.value, rhs.value));
1996// }
1997
1998// RValue<Byte8> operator%(RValue<Byte8> lhs, RValue<Byte8> rhs)
1999// {
2000// return RValue<Byte8>(Nucleus::createURem(lhs.value, rhs.value));
2001// }
2002
2003 RValue<Byte8> operator&(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002004 {
John Bauman19bac1e2014-05-06 15:23:49 -04002005 if(CPUID::supportsMMX2())
2006 {
2007 return As<Byte8>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
2008 }
2009 else
2010 {
2011 return RValue<Byte8>(Nucleus::createAnd(lhs.value, rhs.value));
2012 }
John Bauman89401822014-05-06 15:04:28 -04002013 }
2014
John Bauman19bac1e2014-05-06 15:23:49 -04002015 RValue<Byte8> operator|(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002016 {
John Bauman19bac1e2014-05-06 15:23:49 -04002017 if(CPUID::supportsMMX2())
2018 {
2019 return As<Byte8>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
2020 }
2021 else
2022 {
2023 return RValue<Byte8>(Nucleus::createOr(lhs.value, rhs.value));
2024 }
John Bauman89401822014-05-06 15:04:28 -04002025 }
2026
John Bauman19bac1e2014-05-06 15:23:49 -04002027 RValue<Byte8> operator^(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002028 {
John Bauman19bac1e2014-05-06 15:23:49 -04002029 if(CPUID::supportsMMX2())
2030 {
2031 return As<Byte8>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
2032 }
2033 else
John Bauman66b8ab22014-05-06 15:57:45 -04002034 {
John Bauman19bac1e2014-05-06 15:23:49 -04002035 return RValue<Byte8>(Nucleus::createXor(lhs.value, rhs.value));
2036 }
John Bauman89401822014-05-06 15:04:28 -04002037 }
2038
John Bauman19bac1e2014-05-06 15:23:49 -04002039// RValue<Byte8> operator<<(RValue<Byte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002040// {
2041// return RValue<Byte8>(Nucleus::createShl(lhs.value, rhs.value));
2042// }
2043
John Bauman19bac1e2014-05-06 15:23:49 -04002044// RValue<Byte8> operator>>(RValue<Byte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002045// {
2046// return RValue<Byte8>(Nucleus::createLShr(lhs.value, rhs.value));
2047// }
2048
Nicolas Capens96d4e092016-11-18 14:22:38 -05002049 RValue<Byte8> operator+=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002050 {
2051 return lhs = lhs + rhs;
2052 }
2053
Nicolas Capens96d4e092016-11-18 14:22:38 -05002054 RValue<Byte8> operator-=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002055 {
2056 return lhs = lhs - rhs;
2057 }
2058
Nicolas Capens96d4e092016-11-18 14:22:38 -05002059// RValue<Byte8> operator*=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002060// {
2061// return lhs = lhs * rhs;
2062// }
John Bauman89401822014-05-06 15:04:28 -04002063
Nicolas Capens96d4e092016-11-18 14:22:38 -05002064// RValue<Byte8> operator/=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002065// {
2066// return lhs = lhs / rhs;
2067// }
John Bauman89401822014-05-06 15:04:28 -04002068
Nicolas Capens96d4e092016-11-18 14:22:38 -05002069// RValue<Byte8> operator%=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002070// {
2071// return lhs = lhs % rhs;
2072// }
John Bauman89401822014-05-06 15:04:28 -04002073
Nicolas Capens96d4e092016-11-18 14:22:38 -05002074 RValue<Byte8> operator&=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002075 {
2076 return lhs = lhs & rhs;
2077 }
2078
Nicolas Capens96d4e092016-11-18 14:22:38 -05002079 RValue<Byte8> operator|=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002080 {
2081 return lhs = lhs | rhs;
2082 }
2083
Nicolas Capens96d4e092016-11-18 14:22:38 -05002084 RValue<Byte8> operator^=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002085 {
2086 return lhs = lhs ^ rhs;
2087 }
2088
Nicolas Capens96d4e092016-11-18 14:22:38 -05002089// RValue<Byte8> operator<<=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002090// {
2091// return lhs = lhs << rhs;
2092// }
2093
Nicolas Capens96d4e092016-11-18 14:22:38 -05002094// RValue<Byte8> operator>>=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002095// {
2096// return lhs = lhs >> rhs;
2097// }
2098
John Bauman19bac1e2014-05-06 15:23:49 -04002099// RValue<Byte8> operator+(RValue<Byte8> val)
2100// {
2101// return val;
2102// }
2103
2104// RValue<Byte8> operator-(RValue<Byte8> val)
2105// {
2106// return RValue<Byte8>(Nucleus::createNeg(val.value));
2107// }
2108
2109 RValue<Byte8> operator~(RValue<Byte8> val)
John Bauman89401822014-05-06 15:04:28 -04002110 {
John Bauman19bac1e2014-05-06 15:23:49 -04002111 if(CPUID::supportsMMX2())
2112 {
Nicolas Capens16b5f152016-10-13 13:39:01 -04002113 return val ^ Byte8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
John Bauman19bac1e2014-05-06 15:23:49 -04002114 }
2115 else
2116 {
2117 return RValue<Byte8>(Nucleus::createNot(val.value));
2118 }
John Bauman89401822014-05-06 15:04:28 -04002119 }
2120
John Bauman19bac1e2014-05-06 15:23:49 -04002121 RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002122 {
2123 return x86::paddusb(x, y);
2124 }
John Bauman66b8ab22014-05-06 15:57:45 -04002125
John Bauman19bac1e2014-05-06 15:23:49 -04002126 RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002127 {
2128 return x86::psubusb(x, y);
2129 }
2130
John Bauman19bac1e2014-05-06 15:23:49 -04002131 RValue<Short4> Unpack(RValue<Byte4> x)
John Bauman89401822014-05-06 15:04:28 -04002132 {
Nicolas Capens19336542016-09-26 10:32:29 -04002133 Value *int2 = Nucleus::createInsertElement(V(UndefValue::get(VectorType::get(Int::getType(), 2))), x.value, 0);
John Bauman19bac1e2014-05-06 15:23:49 -04002134 Value *byte8 = Nucleus::createBitCast(int2, Byte8::getType());
John Bauman89401822014-05-06 15:04:28 -04002135
John Bauman19bac1e2014-05-06 15:23:49 -04002136 return UnpackLow(RValue<Byte8>(byte8), RValue<Byte8>(byte8));
2137 }
John Bauman89401822014-05-06 15:04:28 -04002138
John Bauman19bac1e2014-05-06 15:23:49 -04002139 RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y)
2140 {
2141 if(CPUID::supportsMMX2())
2142 {
2143 return x86::punpcklbw(x, y);
2144 }
2145 else
2146 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002147 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11};
2148 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman19bac1e2014-05-06 15:23:49 -04002149
2150 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2151 }
John Bauman89401822014-05-06 15:04:28 -04002152 }
John Bauman66b8ab22014-05-06 15:57:45 -04002153
John Bauman19bac1e2014-05-06 15:23:49 -04002154 RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002155 {
John Bauman19bac1e2014-05-06 15:23:49 -04002156 if(CPUID::supportsMMX2())
2157 {
2158 return x86::punpckhbw(x, y);
2159 }
2160 else
2161 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002162 int shuffle[8] = {4, 12, 5, 13, 6, 14, 7, 15};
2163 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002164
John Bauman19bac1e2014-05-06 15:23:49 -04002165 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2166 }
John Bauman89401822014-05-06 15:04:28 -04002167 }
2168
John Bauman19bac1e2014-05-06 15:23:49 -04002169 RValue<Int> SignMask(RValue<Byte8> x)
John Bauman89401822014-05-06 15:04:28 -04002170 {
2171 return x86::pmovmskb(x);
2172 }
2173
John Bauman19bac1e2014-05-06 15:23:49 -04002174// RValue<Byte8> CmpGT(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002175// {
2176// return x86::pcmpgtb(x, y); // FIXME: Signedness
2177// }
John Bauman66b8ab22014-05-06 15:57:45 -04002178
John Bauman19bac1e2014-05-06 15:23:49 -04002179 RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002180 {
2181 return x86::pcmpeqb(x, y);
2182 }
2183
John Bauman19bac1e2014-05-06 15:23:49 -04002184 Type *Byte8::getType()
John Bauman89401822014-05-06 15:04:28 -04002185 {
John Bauman19bac1e2014-05-06 15:23:49 -04002186 if(CPUID::supportsMMX2())
2187 {
2188 return MMX::getType();
2189 }
2190 else
2191 {
Nicolas Capensac230122016-09-20 14:30:06 -04002192 return T(VectorType::get(Byte::getType(), 8));
John Bauman19bac1e2014-05-06 15:23:49 -04002193 }
John Bauman89401822014-05-06 15:04:28 -04002194 }
2195
Nicolas Capens3bbc5e12016-09-27 10:49:52 -04002196 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 -04002197 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04002198 int64_t constantVector[8] = {x0, x1, x2, x3, x4, x5, x6, x7};
2199 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(SByte::getType(), 8))));
John Bauman89401822014-05-06 15:04:28 -04002200
John Bauman66b8ab22014-05-06 15:57:45 -04002201 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04002202 }
2203
John Bauman19bac1e2014-05-06 15:23:49 -04002204 SByte8::SByte8(RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002205 {
John Bauman66b8ab22014-05-06 15:57:45 -04002206 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002207 }
2208
2209 SByte8::SByte8(const SByte8 &rhs)
2210 {
John Bauman66b8ab22014-05-06 15:57:45 -04002211 Value *value = rhs.loadValue();
2212 storeValue(value);
2213 }
2214
2215 SByte8::SByte8(const Reference<SByte8> &rhs)
2216 {
John Bauman66b8ab22014-05-06 15:57:45 -04002217 Value *value = rhs.loadValue();
2218 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002219 }
2220
Nicolas Capens96d4e092016-11-18 14:22:38 -05002221 RValue<SByte8> SByte8::operator=(RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002222 {
John Bauman66b8ab22014-05-06 15:57:45 -04002223 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002224
2225 return rhs;
2226 }
2227
Nicolas Capens96d4e092016-11-18 14:22:38 -05002228 RValue<SByte8> SByte8::operator=(const SByte8 &rhs)
John Bauman89401822014-05-06 15:04:28 -04002229 {
John Bauman66b8ab22014-05-06 15:57:45 -04002230 Value *value = rhs.loadValue();
2231 storeValue(value);
2232
2233 return RValue<SByte8>(value);
2234 }
2235
Nicolas Capens96d4e092016-11-18 14:22:38 -05002236 RValue<SByte8> SByte8::operator=(const Reference<SByte8> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04002237 {
2238 Value *value = rhs.loadValue();
2239 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002240
2241 return RValue<SByte8>(value);
2242 }
2243
John Bauman19bac1e2014-05-06 15:23:49 -04002244 RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002245 {
John Bauman19bac1e2014-05-06 15:23:49 -04002246 if(CPUID::supportsMMX2())
2247 {
2248 return As<SByte8>(x86::paddb(As<Byte8>(lhs), As<Byte8>(rhs)));
2249 }
2250 else
2251 {
2252 return RValue<SByte8>(Nucleus::createAdd(lhs.value, rhs.value));
2253 }
John Bauman89401822014-05-06 15:04:28 -04002254 }
2255
John Bauman19bac1e2014-05-06 15:23:49 -04002256 RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002257 {
John Bauman19bac1e2014-05-06 15:23:49 -04002258 if(CPUID::supportsMMX2())
2259 {
2260 return As<SByte8>(x86::psubb(As<Byte8>(lhs), As<Byte8>(rhs)));
2261 }
2262 else
2263 {
2264 return RValue<SByte8>(Nucleus::createSub(lhs.value, rhs.value));
2265 }
John Bauman89401822014-05-06 15:04:28 -04002266 }
2267
John Bauman19bac1e2014-05-06 15:23:49 -04002268// RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs)
2269// {
2270// return RValue<SByte8>(Nucleus::createMul(lhs.value, rhs.value));
2271// }
John Bauman89401822014-05-06 15:04:28 -04002272
John Bauman19bac1e2014-05-06 15:23:49 -04002273// RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs)
2274// {
2275// return RValue<SByte8>(Nucleus::createSDiv(lhs.value, rhs.value));
2276// }
John Bauman89401822014-05-06 15:04:28 -04002277
John Bauman19bac1e2014-05-06 15:23:49 -04002278// RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs)
2279// {
2280// return RValue<SByte8>(Nucleus::createSRem(lhs.value, rhs.value));
2281// }
John Bauman89401822014-05-06 15:04:28 -04002282
John Bauman19bac1e2014-05-06 15:23:49 -04002283 RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002284 {
2285 return RValue<SByte8>(Nucleus::createAnd(lhs.value, rhs.value));
2286 }
2287
John Bauman19bac1e2014-05-06 15:23:49 -04002288 RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002289 {
2290 return RValue<SByte8>(Nucleus::createOr(lhs.value, rhs.value));
2291 }
2292
John Bauman19bac1e2014-05-06 15:23:49 -04002293 RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002294 {
2295 return RValue<SByte8>(Nucleus::createXor(lhs.value, rhs.value));
2296 }
2297
John Bauman19bac1e2014-05-06 15:23:49 -04002298// RValue<SByte8> operator<<(RValue<SByte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002299// {
2300// return RValue<SByte8>(Nucleus::createShl(lhs.value, rhs.value));
2301// }
2302
John Bauman19bac1e2014-05-06 15:23:49 -04002303// RValue<SByte8> operator>>(RValue<SByte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002304// {
2305// return RValue<SByte8>(Nucleus::createAShr(lhs.value, rhs.value));
2306// }
2307
Nicolas Capens96d4e092016-11-18 14:22:38 -05002308 RValue<SByte8> operator+=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002309 {
2310 return lhs = lhs + rhs;
2311 }
2312
Nicolas Capens96d4e092016-11-18 14:22:38 -05002313 RValue<SByte8> operator-=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002314 {
2315 return lhs = lhs - rhs;
2316 }
2317
Nicolas Capens96d4e092016-11-18 14:22:38 -05002318// RValue<SByte8> operator*=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002319// {
2320// return lhs = lhs * rhs;
2321// }
John Bauman89401822014-05-06 15:04:28 -04002322
Nicolas Capens96d4e092016-11-18 14:22:38 -05002323// RValue<SByte8> operator/=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002324// {
2325// return lhs = lhs / rhs;
2326// }
John Bauman89401822014-05-06 15:04:28 -04002327
Nicolas Capens96d4e092016-11-18 14:22:38 -05002328// RValue<SByte8> operator%=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002329// {
2330// return lhs = lhs % rhs;
2331// }
John Bauman89401822014-05-06 15:04:28 -04002332
Nicolas Capens96d4e092016-11-18 14:22:38 -05002333 RValue<SByte8> operator&=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002334 {
2335 return lhs = lhs & rhs;
2336 }
2337
Nicolas Capens96d4e092016-11-18 14:22:38 -05002338 RValue<SByte8> operator|=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002339 {
2340 return lhs = lhs | rhs;
2341 }
2342
Nicolas Capens96d4e092016-11-18 14:22:38 -05002343 RValue<SByte8> operator^=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002344 {
2345 return lhs = lhs ^ rhs;
2346 }
2347
Nicolas Capens96d4e092016-11-18 14:22:38 -05002348// RValue<SByte8> operator<<=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002349// {
2350// return lhs = lhs << rhs;
2351// }
2352
Nicolas Capens96d4e092016-11-18 14:22:38 -05002353// RValue<SByte8> operator>>=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002354// {
2355// return lhs = lhs >> rhs;
2356// }
2357
John Bauman19bac1e2014-05-06 15:23:49 -04002358// RValue<SByte8> operator+(RValue<SByte8> val)
2359// {
2360// return val;
2361// }
2362
2363// RValue<SByte8> operator-(RValue<SByte8> val)
2364// {
2365// return RValue<SByte8>(Nucleus::createNeg(val.value));
2366// }
2367
2368 RValue<SByte8> operator~(RValue<SByte8> val)
John Bauman89401822014-05-06 15:04:28 -04002369 {
John Bauman19bac1e2014-05-06 15:23:49 -04002370 if(CPUID::supportsMMX2())
2371 {
Nicolas Capens16b5f152016-10-13 13:39:01 -04002372 return val ^ SByte8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
John Bauman19bac1e2014-05-06 15:23:49 -04002373 }
2374 else
2375 {
2376 return RValue<SByte8>(Nucleus::createNot(val.value));
2377 }
John Bauman89401822014-05-06 15:04:28 -04002378 }
2379
John Bauman19bac1e2014-05-06 15:23:49 -04002380 RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002381 {
2382 return x86::paddsb(x, y);
2383 }
John Bauman66b8ab22014-05-06 15:57:45 -04002384
John Bauman19bac1e2014-05-06 15:23:49 -04002385 RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002386 {
2387 return x86::psubsb(x, y);
2388 }
2389
John Bauman19bac1e2014-05-06 15:23:49 -04002390 RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002391 {
John Bauman19bac1e2014-05-06 15:23:49 -04002392 if(CPUID::supportsMMX2())
2393 {
2394 return As<Short4>(x86::punpcklbw(As<Byte8>(x), As<Byte8>(y)));
2395 }
2396 else
2397 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002398 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11};
2399 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002400
John Bauman19bac1e2014-05-06 15:23:49 -04002401 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2402 }
John Bauman89401822014-05-06 15:04:28 -04002403 }
John Bauman66b8ab22014-05-06 15:57:45 -04002404
John Bauman19bac1e2014-05-06 15:23:49 -04002405 RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002406 {
John Bauman19bac1e2014-05-06 15:23:49 -04002407 if(CPUID::supportsMMX2())
2408 {
2409 return As<Short4>(x86::punpckhbw(As<Byte8>(x), As<Byte8>(y)));
2410 }
2411 else
2412 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002413 int shuffle[8] = {4, 12, 5, 13, 6, 14, 7, 15};
2414 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002415
John Bauman19bac1e2014-05-06 15:23:49 -04002416 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2417 }
John Bauman89401822014-05-06 15:04:28 -04002418 }
2419
John Bauman19bac1e2014-05-06 15:23:49 -04002420 RValue<Int> SignMask(RValue<SByte8> x)
John Bauman89401822014-05-06 15:04:28 -04002421 {
2422 return x86::pmovmskb(As<Byte8>(x));
2423 }
2424
John Bauman19bac1e2014-05-06 15:23:49 -04002425 RValue<Byte8> CmpGT(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002426 {
2427 return x86::pcmpgtb(x, y);
2428 }
John Bauman66b8ab22014-05-06 15:57:45 -04002429
John Bauman19bac1e2014-05-06 15:23:49 -04002430 RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002431 {
2432 return x86::pcmpeqb(As<Byte8>(x), As<Byte8>(y));
2433 }
2434
John Bauman19bac1e2014-05-06 15:23:49 -04002435 Type *SByte8::getType()
John Bauman89401822014-05-06 15:04:28 -04002436 {
John Bauman19bac1e2014-05-06 15:23:49 -04002437 if(CPUID::supportsMMX2())
2438 {
2439 return MMX::getType();
2440 }
2441 else
2442 {
Nicolas Capensac230122016-09-20 14:30:06 -04002443 return T(VectorType::get(SByte::getType(), 8));
John Bauman19bac1e2014-05-06 15:23:49 -04002444 }
John Bauman89401822014-05-06 15:04:28 -04002445 }
2446
John Bauman19bac1e2014-05-06 15:23:49 -04002447 Byte16::Byte16(RValue<Byte16> rhs)
John Bauman89401822014-05-06 15:04:28 -04002448 {
John Bauman66b8ab22014-05-06 15:57:45 -04002449 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002450 }
2451
2452 Byte16::Byte16(const Byte16 &rhs)
2453 {
John Bauman66b8ab22014-05-06 15:57:45 -04002454 Value *value = rhs.loadValue();
2455 storeValue(value);
2456 }
2457
2458 Byte16::Byte16(const Reference<Byte16> &rhs)
2459 {
John Bauman66b8ab22014-05-06 15:57:45 -04002460 Value *value = rhs.loadValue();
2461 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002462 }
2463
Nicolas Capens96d4e092016-11-18 14:22:38 -05002464 RValue<Byte16> Byte16::operator=(RValue<Byte16> rhs)
John Bauman89401822014-05-06 15:04:28 -04002465 {
John Bauman66b8ab22014-05-06 15:57:45 -04002466 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002467
2468 return rhs;
2469 }
2470
Nicolas Capens96d4e092016-11-18 14:22:38 -05002471 RValue<Byte16> Byte16::operator=(const Byte16 &rhs)
John Bauman89401822014-05-06 15:04:28 -04002472 {
John Bauman66b8ab22014-05-06 15:57:45 -04002473 Value *value = rhs.loadValue();
2474 storeValue(value);
2475
2476 return RValue<Byte16>(value);
2477 }
2478
Nicolas Capens96d4e092016-11-18 14:22:38 -05002479 RValue<Byte16> Byte16::operator=(const Reference<Byte16> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04002480 {
2481 Value *value = rhs.loadValue();
2482 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002483
2484 return RValue<Byte16>(value);
2485 }
2486
John Bauman19bac1e2014-05-06 15:23:49 -04002487 Type *Byte16::getType()
John Bauman89401822014-05-06 15:04:28 -04002488 {
Nicolas Capensac230122016-09-20 14:30:06 -04002489 return T(VectorType::get(Byte::getType(), 16));
John Bauman89401822014-05-06 15:04:28 -04002490 }
2491
John Bauman19bac1e2014-05-06 15:23:49 -04002492 Type *SByte16::getType()
John Bauman89401822014-05-06 15:04:28 -04002493 {
Nicolas Capensac230122016-09-20 14:30:06 -04002494 return T( VectorType::get(SByte::getType(), 16));
John Bauman89401822014-05-06 15:04:28 -04002495 }
2496
Nicolas Capens16b5f152016-10-13 13:39:01 -04002497 Short2::Short2(RValue<Short4> cast)
2498 {
2499 storeValue(Nucleus::createTrunc(Nucleus::createBitCast(cast.value, Long::getType()), UInt::getType()));
2500 }
2501
2502 Type *Short2::getType()
2503 {
2504 #if 0
2505 return T(VectorType::get(Short::getType(), 2));
2506 #else
2507 return UInt::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
2508 #endif
2509 }
2510
2511 UShort2::UShort2(RValue<UShort4> cast)
2512 {
2513 storeValue(Nucleus::createTrunc(Nucleus::createBitCast(cast.value, Long::getType()), UInt::getType()));
2514 }
2515
2516 Type *UShort2::getType()
2517 {
2518 #if 0
2519 return T(VectorType::get(UShort::getType(), 2));
2520 #else
2521 return UInt::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
2522 #endif
2523 }
2524
John Bauman19bac1e2014-05-06 15:23:49 -04002525 Short4::Short4(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04002526 {
John Bauman89401822014-05-06 15:04:28 -04002527 Value *extend = Nucleus::createZExt(cast.value, Long::getType());
John Bauman19bac1e2014-05-06 15:23:49 -04002528 Value *swizzle = Swizzle(RValue<Short4>(extend), 0x00).value;
John Bauman66b8ab22014-05-06 15:57:45 -04002529
2530 storeValue(swizzle);
John Bauman89401822014-05-06 15:04:28 -04002531 }
2532
John Bauman19bac1e2014-05-06 15:23:49 -04002533 Short4::Short4(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04002534 {
John Bauman89401822014-05-06 15:04:28 -04002535 Value *short8 = Nucleus::createBitCast(cast.value, Short8::getType());
2536
2537 #if 0 // FIXME: Check codegen (pshuflw phshufhw pshufd)
2538 Constant *pack[8];
2539 pack[0] = Nucleus::createConstantInt(0);
2540 pack[1] = Nucleus::createConstantInt(2);
2541 pack[2] = Nucleus::createConstantInt(4);
2542 pack[3] = Nucleus::createConstantInt(6);
2543
2544 Value *short4 = Nucleus::createShuffleVector(short8, short8, Nucleus::createConstantVector(pack, 4));
2545 #else
2546 Value *packed;
2547
2548 // FIXME: Use Swizzle<Short8>
2549 if(!CPUID::supportsSSSE3())
2550 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002551 int pshuflw[8] = {0, 2, 0, 2, 4, 5, 6, 7};
2552 int pshufhw[8] = {0, 1, 2, 3, 4, 6, 4, 6};
John Bauman89401822014-05-06 15:04:28 -04002553
Nicolas Capense89cd582016-09-30 14:23:47 -04002554 Value *shuffle1 = Nucleus::createShuffleVector(short8, short8, pshuflw);
2555 Value *shuffle2 = Nucleus::createShuffleVector(shuffle1, shuffle1, pshufhw);
John Bauman89401822014-05-06 15:04:28 -04002556 Value *int4 = Nucleus::createBitCast(shuffle2, Int4::getType());
Nicolas Capense95d5342016-09-30 11:37:28 -04002557 packed = createSwizzle4(int4, 0x88);
John Bauman89401822014-05-06 15:04:28 -04002558 }
2559 else
2560 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002561 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 -04002562 Value *byte16 = Nucleus::createBitCast(cast.value, Byte16::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04002563 packed = Nucleus::createShuffleVector(byte16, byte16, pshufb);
John Bauman89401822014-05-06 15:04:28 -04002564 }
2565
2566 #if 0 // FIXME: No optimal instruction selection
Nicolas Capens22008782016-10-20 01:11:47 -04002567 Value *qword2 = Nucleus::createBitCast(packed, T(VectorType::get(Long::getType(), 2)));
John Bauman89401822014-05-06 15:04:28 -04002568 Value *element = Nucleus::createExtractElement(qword2, 0);
2569 Value *short4 = Nucleus::createBitCast(element, Short4::getType());
2570 #else // FIXME: Requires SSE
2571 Value *int2 = RValue<Int2>(Int2(RValue<Int4>(packed))).value;
2572 Value *short4 = Nucleus::createBitCast(int2, Short4::getType());
2573 #endif
2574 #endif
2575
John Bauman66b8ab22014-05-06 15:57:45 -04002576 storeValue(short4);
John Bauman89401822014-05-06 15:04:28 -04002577 }
2578
John Bauman19bac1e2014-05-06 15:23:49 -04002579// Short4::Short4(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04002580// {
2581// }
2582
John Bauman19bac1e2014-05-06 15:23:49 -04002583 Short4::Short4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04002584 {
John Bauman89401822014-05-06 15:04:28 -04002585 Int4 v4i32 = Int4(cast);
2586 v4i32 = As<Int4>(x86::packssdw(v4i32, v4i32));
John Bauman66b8ab22014-05-06 15:57:45 -04002587
2588 storeValue(As<Short4>(Int2(v4i32)).value);
John Bauman89401822014-05-06 15:04:28 -04002589 }
2590
John Bauman19bac1e2014-05-06 15:23:49 -04002591 Short4::Short4(short xyzw)
2592 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04002593 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
2594 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(Short::getType(), 4))));
John Bauman19bac1e2014-05-06 15:23:49 -04002595
John Bauman66b8ab22014-05-06 15:57:45 -04002596 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman19bac1e2014-05-06 15:23:49 -04002597 }
2598
John Bauman89401822014-05-06 15:04:28 -04002599 Short4::Short4(short x, short y, short z, short w)
2600 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04002601 int64_t constantVector[4] = {x, y, z, w};
2602 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(Short::getType(), 4))));
John Bauman19bac1e2014-05-06 15:23:49 -04002603
John Bauman66b8ab22014-05-06 15:57:45 -04002604 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04002605 }
2606
John Bauman19bac1e2014-05-06 15:23:49 -04002607 Short4::Short4(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002608 {
John Bauman66b8ab22014-05-06 15:57:45 -04002609 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002610 }
2611
2612 Short4::Short4(const Short4 &rhs)
2613 {
John Bauman66b8ab22014-05-06 15:57:45 -04002614 Value *value = rhs.loadValue();
2615 storeValue(value);
2616 }
2617
2618 Short4::Short4(const Reference<Short4> &rhs)
2619 {
John Bauman66b8ab22014-05-06 15:57:45 -04002620 Value *value = rhs.loadValue();
2621 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002622 }
2623
John Bauman19bac1e2014-05-06 15:23:49 -04002624 Short4::Short4(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002625 {
John Bauman66b8ab22014-05-06 15:57:45 -04002626 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002627 }
2628
2629 Short4::Short4(const UShort4 &rhs)
2630 {
John Bauman66b8ab22014-05-06 15:57:45 -04002631 storeValue(rhs.loadValue());
2632 }
2633
2634 Short4::Short4(const Reference<UShort4> &rhs)
2635 {
John Bauman66b8ab22014-05-06 15:57:45 -04002636 storeValue(rhs.loadValue());
John Bauman89401822014-05-06 15:04:28 -04002637 }
2638
Nicolas Capens96d4e092016-11-18 14:22:38 -05002639 RValue<Short4> Short4::operator=(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002640 {
John Bauman66b8ab22014-05-06 15:57:45 -04002641 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002642
2643 return rhs;
2644 }
2645
Nicolas Capens96d4e092016-11-18 14:22:38 -05002646 RValue<Short4> Short4::operator=(const Short4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04002647 {
John Bauman66b8ab22014-05-06 15:57:45 -04002648 Value *value = rhs.loadValue();
2649 storeValue(value);
2650
2651 return RValue<Short4>(value);
2652 }
2653
Nicolas Capens96d4e092016-11-18 14:22:38 -05002654 RValue<Short4> Short4::operator=(const Reference<Short4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04002655 {
2656 Value *value = rhs.loadValue();
2657 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002658
2659 return RValue<Short4>(value);
2660 }
2661
Nicolas Capens96d4e092016-11-18 14:22:38 -05002662 RValue<Short4> Short4::operator=(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002663 {
John Bauman66b8ab22014-05-06 15:57:45 -04002664 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002665
John Bauman66b8ab22014-05-06 15:57:45 -04002666 return RValue<Short4>(rhs);
John Bauman89401822014-05-06 15:04:28 -04002667 }
2668
Nicolas Capens96d4e092016-11-18 14:22:38 -05002669 RValue<Short4> Short4::operator=(const UShort4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04002670 {
John Bauman66b8ab22014-05-06 15:57:45 -04002671 Value *value = rhs.loadValue();
2672 storeValue(value);
2673
2674 return RValue<Short4>(value);
2675 }
2676
Nicolas Capens96d4e092016-11-18 14:22:38 -05002677 RValue<Short4> Short4::operator=(const Reference<UShort4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04002678 {
2679 Value *value = rhs.loadValue();
2680 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002681
2682 return RValue<Short4>(value);
2683 }
2684
John Bauman19bac1e2014-05-06 15:23:49 -04002685 RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002686 {
John Bauman19bac1e2014-05-06 15:23:49 -04002687 if(CPUID::supportsMMX2())
2688 {
2689 return x86::paddw(lhs, rhs);
2690 }
2691 else
2692 {
2693 return RValue<Short4>(Nucleus::createAdd(lhs.value, rhs.value));
2694 }
John Bauman89401822014-05-06 15:04:28 -04002695 }
2696
John Bauman19bac1e2014-05-06 15:23:49 -04002697 RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002698 {
John Bauman19bac1e2014-05-06 15:23:49 -04002699 if(CPUID::supportsMMX2())
2700 {
2701 return x86::psubw(lhs, rhs);
2702 }
2703 else
2704 {
2705 return RValue<Short4>(Nucleus::createSub(lhs.value, rhs.value));
2706 }
John Bauman89401822014-05-06 15:04:28 -04002707 }
2708
John Bauman19bac1e2014-05-06 15:23:49 -04002709 RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002710 {
John Bauman19bac1e2014-05-06 15:23:49 -04002711 if(CPUID::supportsMMX2())
2712 {
2713 return x86::pmullw(lhs, rhs);
2714 }
2715 else
2716 {
2717 return RValue<Short4>(Nucleus::createMul(lhs.value, rhs.value));
2718 }
John Bauman89401822014-05-06 15:04:28 -04002719 }
2720
John Bauman19bac1e2014-05-06 15:23:49 -04002721// RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs)
2722// {
2723// return RValue<Short4>(Nucleus::createSDiv(lhs.value, rhs.value));
2724// }
2725
2726// RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs)
2727// {
2728// return RValue<Short4>(Nucleus::createSRem(lhs.value, rhs.value));
2729// }
2730
2731 RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002732 {
John Bauman19bac1e2014-05-06 15:23:49 -04002733 if(CPUID::supportsMMX2())
2734 {
2735 return x86::pand(lhs, rhs);
2736 }
2737 else
2738 {
2739 return RValue<Short4>(Nucleus::createAnd(lhs.value, rhs.value));
2740 }
John Bauman89401822014-05-06 15:04:28 -04002741 }
2742
John Bauman19bac1e2014-05-06 15:23:49 -04002743 RValue<Short4> operator|(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002744 {
John Bauman19bac1e2014-05-06 15:23:49 -04002745 if(CPUID::supportsMMX2())
2746 {
2747 return x86::por(lhs, rhs);
2748 }
2749 else
2750 {
2751 return RValue<Short4>(Nucleus::createOr(lhs.value, rhs.value));
2752 }
John Bauman89401822014-05-06 15:04:28 -04002753 }
2754
John Bauman19bac1e2014-05-06 15:23:49 -04002755 RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002756 {
John Bauman19bac1e2014-05-06 15:23:49 -04002757 if(CPUID::supportsMMX2())
2758 {
2759 return x86::pxor(lhs, rhs);
2760 }
2761 else
2762 {
2763 return RValue<Short4>(Nucleus::createXor(lhs.value, rhs.value));
2764 }
John Bauman89401822014-05-06 15:04:28 -04002765 }
2766
John Bauman19bac1e2014-05-06 15:23:49 -04002767 RValue<Short4> operator<<(RValue<Short4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002768 {
2769 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
2770
2771 return x86::psllw(lhs, rhs);
2772 }
2773
John Bauman19bac1e2014-05-06 15:23:49 -04002774 RValue<Short4> operator>>(RValue<Short4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002775 {
2776 // return RValue<Short4>(Nucleus::createAShr(lhs.value, rhs.value));
2777
2778 return x86::psraw(lhs, rhs);
2779 }
2780
Nicolas Capens96d4e092016-11-18 14:22:38 -05002781 RValue<Short4> operator+=(Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002782 {
2783 return lhs = lhs + rhs;
2784 }
2785
Nicolas Capens96d4e092016-11-18 14:22:38 -05002786 RValue<Short4> operator-=(Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002787 {
2788 return lhs = lhs - rhs;
2789 }
2790
Nicolas Capens96d4e092016-11-18 14:22:38 -05002791 RValue<Short4> operator*=(Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002792 {
2793 return lhs = lhs * rhs;
2794 }
2795
Nicolas Capens96d4e092016-11-18 14:22:38 -05002796// RValue<Short4> operator/=(Short4 &lhs, RValue<Short4> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002797// {
2798// return lhs = lhs / rhs;
2799// }
John Bauman89401822014-05-06 15:04:28 -04002800
Nicolas Capens96d4e092016-11-18 14:22:38 -05002801// RValue<Short4> operator%=(Short4 &lhs, RValue<Short4> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002802// {
2803// return lhs = lhs % rhs;
2804// }
John Bauman89401822014-05-06 15:04:28 -04002805
Nicolas Capens96d4e092016-11-18 14:22:38 -05002806 RValue<Short4> operator&=(Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002807 {
2808 return lhs = lhs & rhs;
2809 }
2810
Nicolas Capens96d4e092016-11-18 14:22:38 -05002811 RValue<Short4> operator|=(Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002812 {
2813 return lhs = lhs | rhs;
2814 }
2815
Nicolas Capens96d4e092016-11-18 14:22:38 -05002816 RValue<Short4> operator^=(Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002817 {
2818 return lhs = lhs ^ rhs;
2819 }
2820
Nicolas Capens96d4e092016-11-18 14:22:38 -05002821 RValue<Short4> operator<<=(Short4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002822 {
2823 return lhs = lhs << rhs;
2824 }
2825
Nicolas Capens96d4e092016-11-18 14:22:38 -05002826 RValue<Short4> operator>>=(Short4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002827 {
2828 return lhs = lhs >> rhs;
2829 }
2830
John Bauman19bac1e2014-05-06 15:23:49 -04002831// RValue<Short4> operator+(RValue<Short4> val)
2832// {
2833// return val;
2834// }
2835
2836 RValue<Short4> operator-(RValue<Short4> val)
John Bauman89401822014-05-06 15:04:28 -04002837 {
John Bauman19bac1e2014-05-06 15:23:49 -04002838 if(CPUID::supportsMMX2())
2839 {
2840 return Short4(0, 0, 0, 0) - val;
2841 }
2842 else
2843 {
2844 return RValue<Short4>(Nucleus::createNeg(val.value));
2845 }
John Bauman89401822014-05-06 15:04:28 -04002846 }
2847
John Bauman19bac1e2014-05-06 15:23:49 -04002848 RValue<Short4> operator~(RValue<Short4> val)
John Bauman89401822014-05-06 15:04:28 -04002849 {
John Bauman19bac1e2014-05-06 15:23:49 -04002850 if(CPUID::supportsMMX2())
2851 {
2852 return val ^ Short4(0xFFFFu, 0xFFFFu, 0xFFFFu, 0xFFFFu);
2853 }
2854 else
2855 {
2856 return RValue<Short4>(Nucleus::createNot(val.value));
2857 }
John Bauman89401822014-05-06 15:04:28 -04002858 }
2859
John Bauman19bac1e2014-05-06 15:23:49 -04002860 RValue<Short4> RoundShort4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04002861 {
2862 RValue<Int4> v4i32 = x86::cvtps2dq(cast);
Nicolas Capens698633a2015-02-04 00:16:13 -05002863 RValue<Short8> v8i16 = x86::packssdw(v4i32, v4i32);
John Bauman66b8ab22014-05-06 15:57:45 -04002864
Nicolas Capens698633a2015-02-04 00:16:13 -05002865 return As<Short4>(Int2(As<Int4>(v8i16)));
John Bauman89401822014-05-06 15:04:28 -04002866 }
2867
John Bauman19bac1e2014-05-06 15:23:49 -04002868 RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002869 {
2870 return x86::pmaxsw(x, y);
2871 }
2872
John Bauman19bac1e2014-05-06 15:23:49 -04002873 RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002874 {
2875 return x86::pminsw(x, y);
2876 }
2877
John Bauman19bac1e2014-05-06 15:23:49 -04002878 RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002879 {
2880 return x86::paddsw(x, y);
2881 }
2882
John Bauman19bac1e2014-05-06 15:23:49 -04002883 RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002884 {
2885 return x86::psubsw(x, y);
2886 }
2887
John Bauman19bac1e2014-05-06 15:23:49 -04002888 RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002889 {
2890 return x86::pmulhw(x, y);
2891 }
2892
John Bauman19bac1e2014-05-06 15:23:49 -04002893 RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002894 {
2895 return x86::pmaddwd(x, y);
2896 }
2897
John Bauman19bac1e2014-05-06 15:23:49 -04002898 RValue<SByte8> Pack(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002899 {
2900 return x86::packsswb(x, y);
2901 }
2902
John Bauman19bac1e2014-05-06 15:23:49 -04002903 RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002904 {
John Bauman19bac1e2014-05-06 15:23:49 -04002905 if(CPUID::supportsMMX2())
2906 {
2907 return x86::punpcklwd(x, y);
2908 }
2909 else
2910 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002911 int shuffle[4] = {0, 4, 1, 5};
2912 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002913
John Bauman19bac1e2014-05-06 15:23:49 -04002914 return RValue<Int2>(Nucleus::createBitCast(packed, Int2::getType()));
2915 }
John Bauman89401822014-05-06 15:04:28 -04002916 }
2917
John Bauman19bac1e2014-05-06 15:23:49 -04002918 RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002919 {
John Bauman19bac1e2014-05-06 15:23:49 -04002920 if(CPUID::supportsMMX2())
2921 {
2922 return x86::punpckhwd(x, y);
2923 }
2924 else
2925 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002926 int shuffle[4] = {2, 6, 3, 7};
2927 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002928
John Bauman19bac1e2014-05-06 15:23:49 -04002929 return RValue<Int2>(Nucleus::createBitCast(packed, Int2::getType()));
2930 }
John Bauman89401822014-05-06 15:04:28 -04002931 }
2932
John Bauman19bac1e2014-05-06 15:23:49 -04002933 RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04002934 {
John Bauman19bac1e2014-05-06 15:23:49 -04002935 if(CPUID::supportsMMX2())
2936 {
2937 return x86::pshufw(x, select);
2938 }
2939 else
2940 {
Nicolas Capense95d5342016-09-30 11:37:28 -04002941 return RValue<Short4>(createSwizzle4(x.value, select));
John Bauman19bac1e2014-05-06 15:23:49 -04002942 }
John Bauman89401822014-05-06 15:04:28 -04002943 }
2944
John Bauman19bac1e2014-05-06 15:23:49 -04002945 RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i)
John Bauman89401822014-05-06 15:04:28 -04002946 {
John Bauman19bac1e2014-05-06 15:23:49 -04002947 if(CPUID::supportsMMX2())
2948 {
2949 return x86::pinsrw(val, Int(element), i);
2950 }
2951 else
2952 {
2953 return RValue<Short4>(Nucleus::createInsertElement(val.value, element.value, i));
2954 }
John Bauman89401822014-05-06 15:04:28 -04002955 }
2956
John Bauman19bac1e2014-05-06 15:23:49 -04002957 RValue<Short> Extract(RValue<Short4> val, int i)
John Bauman89401822014-05-06 15:04:28 -04002958 {
John Bauman19bac1e2014-05-06 15:23:49 -04002959 if(CPUID::supportsMMX2())
2960 {
2961 return Short(x86::pextrw(val, i));
2962 }
2963 else
2964 {
Nicolas Capense95d5342016-09-30 11:37:28 -04002965 return RValue<Short>(Nucleus::createExtractElement(val.value, Short::getType(), i));
John Bauman19bac1e2014-05-06 15:23:49 -04002966 }
John Bauman89401822014-05-06 15:04:28 -04002967 }
2968
John Bauman19bac1e2014-05-06 15:23:49 -04002969 RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002970 {
2971 return x86::pcmpgtw(x, y);
2972 }
2973
John Bauman19bac1e2014-05-06 15:23:49 -04002974 RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002975 {
2976 return x86::pcmpeqw(x, y);
2977 }
2978
John Bauman19bac1e2014-05-06 15:23:49 -04002979 Type *Short4::getType()
John Bauman89401822014-05-06 15:04:28 -04002980 {
John Bauman19bac1e2014-05-06 15:23:49 -04002981 if(CPUID::supportsMMX2())
2982 {
2983 return MMX::getType();
2984 }
2985 else
2986 {
Nicolas Capensac230122016-09-20 14:30:06 -04002987 return T(VectorType::get(Short::getType(), 4));
John Bauman19bac1e2014-05-06 15:23:49 -04002988 }
John Bauman89401822014-05-06 15:04:28 -04002989 }
2990
John Bauman19bac1e2014-05-06 15:23:49 -04002991 UShort4::UShort4(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04002992 {
John Bauman89401822014-05-06 15:04:28 -04002993 *this = Short4(cast);
2994 }
2995
John Bauman19bac1e2014-05-06 15:23:49 -04002996 UShort4::UShort4(RValue<Float4> cast, bool saturate)
John Bauman89401822014-05-06 15:04:28 -04002997 {
John Bauman89401822014-05-06 15:04:28 -04002998 Float4 sat;
2999
3000 if(saturate)
3001 {
3002 if(CPUID::supportsSSE4_1())
3003 {
3004 sat = Min(cast, Float4(0xFFFF)); // packusdw takes care of 0x0000 saturation
3005 }
3006 else
3007 {
3008 sat = Max(Min(cast, Float4(0xFFFF)), Float4(0x0000));
3009 }
3010 }
3011 else
3012 {
3013 sat = cast;
3014 }
3015
3016 Int4 int4(sat);
3017
3018 if(!saturate || !CPUID::supportsSSE4_1())
3019 {
Nicolas Capens3e7062b2017-01-17 14:01:33 -05003020 *this = Short4(int4);
John Bauman89401822014-05-06 15:04:28 -04003021 }
3022 else
3023 {
Nicolas Capens3e7062b2017-01-17 14:01:33 -05003024 *this = As<Short4>(Int2(As<Int4>(x86::packusdw(int4, int4))));
John Bauman89401822014-05-06 15:04:28 -04003025 }
3026 }
3027
Alexis Hetu90c7ad62016-06-27 11:50:40 -04003028 UShort4::UShort4(unsigned short xyzw)
3029 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04003030 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
3031 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(UShort::getType(), 4))));
Alexis Hetu90c7ad62016-06-27 11:50:40 -04003032
3033 storeValue(Nucleus::createBitCast(vector, getType()));
3034 }
3035
John Bauman89401822014-05-06 15:04:28 -04003036 UShort4::UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w)
3037 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04003038 int64_t constantVector[4] = {x, y, z, w};
3039 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(UShort::getType(), 4))));
John Bauman89401822014-05-06 15:04:28 -04003040
John Bauman66b8ab22014-05-06 15:57:45 -04003041 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04003042 }
3043
John Bauman19bac1e2014-05-06 15:23:49 -04003044 UShort4::UShort4(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003045 {
John Bauman66b8ab22014-05-06 15:57:45 -04003046 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003047 }
3048
3049 UShort4::UShort4(const UShort4 &rhs)
3050 {
John Bauman66b8ab22014-05-06 15:57:45 -04003051 Value *value = rhs.loadValue();
3052 storeValue(value);
3053 }
3054
3055 UShort4::UShort4(const Reference<UShort4> &rhs)
3056 {
John Bauman66b8ab22014-05-06 15:57:45 -04003057 Value *value = rhs.loadValue();
3058 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003059 }
3060
John Bauman19bac1e2014-05-06 15:23:49 -04003061 UShort4::UShort4(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003062 {
John Bauman66b8ab22014-05-06 15:57:45 -04003063 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003064 }
3065
3066 UShort4::UShort4(const Short4 &rhs)
3067 {
John Bauman66b8ab22014-05-06 15:57:45 -04003068 Value *value = rhs.loadValue();
3069 storeValue(value);
3070 }
3071
3072 UShort4::UShort4(const Reference<Short4> &rhs)
3073 {
John Bauman66b8ab22014-05-06 15:57:45 -04003074 Value *value = rhs.loadValue();
3075 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003076 }
3077
Nicolas Capens96d4e092016-11-18 14:22:38 -05003078 RValue<UShort4> UShort4::operator=(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003079 {
John Bauman66b8ab22014-05-06 15:57:45 -04003080 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003081
3082 return rhs;
3083 }
3084
Nicolas Capens96d4e092016-11-18 14:22:38 -05003085 RValue<UShort4> UShort4::operator=(const UShort4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04003086 {
John Bauman66b8ab22014-05-06 15:57:45 -04003087 Value *value = rhs.loadValue();
3088 storeValue(value);
3089
3090 return RValue<UShort4>(value);
3091 }
3092
Nicolas Capens96d4e092016-11-18 14:22:38 -05003093 RValue<UShort4> UShort4::operator=(const Reference<UShort4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04003094 {
3095 Value *value = rhs.loadValue();
3096 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003097
3098 return RValue<UShort4>(value);
3099 }
3100
Nicolas Capens96d4e092016-11-18 14:22:38 -05003101 RValue<UShort4> UShort4::operator=(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003102 {
John Bauman66b8ab22014-05-06 15:57:45 -04003103 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003104
John Bauman66b8ab22014-05-06 15:57:45 -04003105 return RValue<UShort4>(rhs);
John Bauman89401822014-05-06 15:04:28 -04003106 }
3107
Nicolas Capens96d4e092016-11-18 14:22:38 -05003108 RValue<UShort4> UShort4::operator=(const Short4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04003109 {
John Bauman66b8ab22014-05-06 15:57:45 -04003110 Value *value = rhs.loadValue();
3111 storeValue(value);
3112
3113 return RValue<UShort4>(value);
3114 }
3115
Nicolas Capens96d4e092016-11-18 14:22:38 -05003116 RValue<UShort4> UShort4::operator=(const Reference<Short4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04003117 {
3118 Value *value = rhs.loadValue();
3119 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003120
3121 return RValue<UShort4>(value);
3122 }
3123
John Bauman19bac1e2014-05-06 15:23:49 -04003124 RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003125 {
John Bauman19bac1e2014-05-06 15:23:49 -04003126 if(CPUID::supportsMMX2())
3127 {
3128 return As<UShort4>(x86::paddw(As<Short4>(lhs), As<Short4>(rhs)));
3129 }
3130 else
3131 {
3132 return RValue<UShort4>(Nucleus::createAdd(lhs.value, rhs.value));
3133 }
John Bauman89401822014-05-06 15:04:28 -04003134 }
3135
John Bauman19bac1e2014-05-06 15:23:49 -04003136 RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003137 {
John Bauman19bac1e2014-05-06 15:23:49 -04003138 if(CPUID::supportsMMX2())
3139 {
3140 return As<UShort4>(x86::psubw(As<Short4>(lhs), As<Short4>(rhs)));
3141 }
3142 else
3143 {
3144 return RValue<UShort4>(Nucleus::createSub(lhs.value, rhs.value));
3145 }
John Bauman89401822014-05-06 15:04:28 -04003146 }
3147
John Bauman19bac1e2014-05-06 15:23:49 -04003148 RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003149 {
John Bauman19bac1e2014-05-06 15:23:49 -04003150 if(CPUID::supportsMMX2())
3151 {
3152 return As<UShort4>(x86::pmullw(As<Short4>(lhs), As<Short4>(rhs)));
3153 }
3154 else
3155 {
3156 return RValue<UShort4>(Nucleus::createMul(lhs.value, rhs.value));
3157 }
John Bauman89401822014-05-06 15:04:28 -04003158 }
3159
Nicolas Capens16b5f152016-10-13 13:39:01 -04003160 RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs)
3161 {
3162 if(CPUID::supportsMMX2())
3163 {
3164 return As<UShort4>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
3165 }
3166 else
3167 {
3168 return RValue<UShort4>(Nucleus::createAnd(lhs.value, rhs.value));
3169 }
3170 }
3171
3172 RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs)
3173 {
3174 if(CPUID::supportsMMX2())
3175 {
3176 return As<UShort4>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
3177 }
3178 else
3179 {
3180 return RValue<UShort4>(Nucleus::createOr(lhs.value, rhs.value));
3181 }
3182 }
3183
3184 RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs)
3185 {
3186 if(CPUID::supportsMMX2())
3187 {
3188 return As<UShort4>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
3189 }
3190 else
3191 {
3192 return RValue<UShort4>(Nucleus::createXor(lhs.value, rhs.value));
3193 }
3194 }
3195
John Bauman19bac1e2014-05-06 15:23:49 -04003196 RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003197 {
3198 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
3199
3200 return As<UShort4>(x86::psllw(As<Short4>(lhs), rhs));
3201 }
3202
John Bauman19bac1e2014-05-06 15:23:49 -04003203 RValue<UShort4> operator>>(RValue<UShort4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003204 {
3205 // return RValue<Short4>(Nucleus::createLShr(lhs.value, rhs.value));
3206
3207 return x86::psrlw(lhs, rhs);
3208 }
3209
Nicolas Capens96d4e092016-11-18 14:22:38 -05003210 RValue<UShort4> operator<<=(UShort4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003211 {
3212 return lhs = lhs << rhs;
3213 }
3214
Nicolas Capens96d4e092016-11-18 14:22:38 -05003215 RValue<UShort4> operator>>=(UShort4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003216 {
3217 return lhs = lhs >> rhs;
3218 }
3219
John Bauman19bac1e2014-05-06 15:23:49 -04003220 RValue<UShort4> operator~(RValue<UShort4> val)
John Bauman89401822014-05-06 15:04:28 -04003221 {
John Bauman19bac1e2014-05-06 15:23:49 -04003222 if(CPUID::supportsMMX2())
3223 {
3224 return As<UShort4>(As<Short4>(val) ^ Short4(0xFFFFu, 0xFFFFu, 0xFFFFu, 0xFFFFu));
3225 }
3226 else
3227 {
3228 return RValue<UShort4>(Nucleus::createNot(val.value));
3229 }
John Bauman89401822014-05-06 15:04:28 -04003230 }
3231
John Bauman19bac1e2014-05-06 15:23:49 -04003232 RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003233 {
John Bauman66b8ab22014-05-06 15:57:45 -04003234 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 -04003235 }
3236
John Bauman19bac1e2014-05-06 15:23:49 -04003237 RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003238 {
John Bauman66b8ab22014-05-06 15:57:45 -04003239 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 -04003240 }
3241
John Bauman19bac1e2014-05-06 15:23:49 -04003242 RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003243 {
3244 return x86::paddusw(x, y);
3245 }
3246
John Bauman19bac1e2014-05-06 15:23:49 -04003247 RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003248 {
3249 return x86::psubusw(x, y);
3250 }
3251
John Bauman19bac1e2014-05-06 15:23:49 -04003252 RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003253 {
3254 return x86::pmulhuw(x, y);
3255 }
3256
John Bauman19bac1e2014-05-06 15:23:49 -04003257 RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003258 {
3259 return x86::pavgw(x, y);
3260 }
3261
John Bauman19bac1e2014-05-06 15:23:49 -04003262 RValue<Byte8> Pack(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003263 {
3264 return x86::packuswb(x, y);
3265 }
3266
John Bauman19bac1e2014-05-06 15:23:49 -04003267 Type *UShort4::getType()
John Bauman89401822014-05-06 15:04:28 -04003268 {
John Bauman19bac1e2014-05-06 15:23:49 -04003269 if(CPUID::supportsMMX2())
3270 {
3271 return MMX::getType();
3272 }
3273 else
3274 {
Nicolas Capensac230122016-09-20 14:30:06 -04003275 return T(VectorType::get(UShort::getType(), 4));
John Bauman19bac1e2014-05-06 15:23:49 -04003276 }
John Bauman89401822014-05-06 15:04:28 -04003277 }
3278
Nicolas Capens3e7062b2017-01-17 14:01:33 -05003279 Short8::Short8(short c)
3280 {
3281 int64_t constantVector[8] = {c, c, c, c, c, c, c, c};
3282 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3283 }
3284
John Bauman89401822014-05-06 15:04:28 -04003285 Short8::Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7)
3286 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04003287 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
3288 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04003289 }
3290
John Bauman19bac1e2014-05-06 15:23:49 -04003291 Short8::Short8(RValue<Short8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003292 {
John Bauman66b8ab22014-05-06 15:57:45 -04003293 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003294 }
3295
Nicolas Capensef8cd662016-06-30 15:34:40 -04003296 Short8::Short8(const Reference<Short8> &rhs)
3297 {
Nicolas Capensef8cd662016-06-30 15:34:40 -04003298 Value *value = rhs.loadValue();
3299 storeValue(value);
3300 }
3301
Nicolas Capens62abb552016-01-05 12:03:47 -05003302 Short8::Short8(RValue<Short4> lo, RValue<Short4> hi)
3303 {
3304 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
3305 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
3306
Nicolas Capens22008782016-10-20 01:11:47 -04003307 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Nicolas Capens62abb552016-01-05 12:03:47 -05003308 long2 = Nucleus::createInsertElement(long2, loLong, 0);
3309 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
3310 Value *short8 = Nucleus::createBitCast(long2, Short8::getType());
3311
3312 storeValue(short8);
3313 }
3314
John Bauman19bac1e2014-05-06 15:23:49 -04003315 RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003316 {
3317 return RValue<Short8>(Nucleus::createAdd(lhs.value, rhs.value));
3318 }
3319
John Bauman19bac1e2014-05-06 15:23:49 -04003320 RValue<Short8> operator&(RValue<Short8> lhs, RValue<Short8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003321 {
3322 return RValue<Short8>(Nucleus::createAnd(lhs.value, rhs.value));
3323 }
3324
John Bauman19bac1e2014-05-06 15:23:49 -04003325 RValue<Short8> operator<<(RValue<Short8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003326 {
3327 return x86::psllw(lhs, rhs); // FIXME: Fallback required
3328 }
3329
John Bauman19bac1e2014-05-06 15:23:49 -04003330 RValue<Short8> operator>>(RValue<Short8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003331 {
3332 return x86::psraw(lhs, rhs); // FIXME: Fallback required
3333 }
3334
John Bauman19bac1e2014-05-06 15:23:49 -04003335 RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04003336 {
3337 return x86::pmaddwd(x, y); // FIXME: Fallback required
3338 }
3339
Alexis Hetu0f448072016-03-18 10:56:08 -04003340 RValue<Int4> Abs(RValue<Int4> x)
3341 {
3342 if(CPUID::supportsSSSE3())
3343 {
3344 return x86::pabsd(x);
3345 }
3346 else
3347 {
3348 Int4 mask = (x >> 31);
3349 return (mask ^ x) - mask;
3350 }
3351 }
3352
John Bauman19bac1e2014-05-06 15:23:49 -04003353 RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04003354 {
3355 return x86::pmulhw(x, y); // FIXME: Fallback required
3356 }
3357
John Bauman19bac1e2014-05-06 15:23:49 -04003358 Type *Short8::getType()
John Bauman89401822014-05-06 15:04:28 -04003359 {
Nicolas Capensac230122016-09-20 14:30:06 -04003360 return T(VectorType::get(Short::getType(), 8));
John Bauman89401822014-05-06 15:04:28 -04003361 }
3362
Nicolas Capens3e7062b2017-01-17 14:01:33 -05003363 UShort8::UShort8(unsigned short c)
3364 {
3365 int64_t constantVector[8] = {c, c, c, c, c, c, c, c};
3366 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3367 }
3368
John Bauman89401822014-05-06 15:04:28 -04003369 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)
3370 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04003371 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
3372 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04003373 }
3374
John Bauman19bac1e2014-05-06 15:23:49 -04003375 UShort8::UShort8(RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003376 {
John Bauman66b8ab22014-05-06 15:57:45 -04003377 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003378 }
3379
Nicolas Capensef8cd662016-06-30 15:34:40 -04003380 UShort8::UShort8(const Reference<UShort8> &rhs)
3381 {
Nicolas Capensef8cd662016-06-30 15:34:40 -04003382 Value *value = rhs.loadValue();
3383 storeValue(value);
3384 }
3385
Nicolas Capens62abb552016-01-05 12:03:47 -05003386 UShort8::UShort8(RValue<UShort4> lo, RValue<UShort4> hi)
3387 {
3388 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
3389 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
3390
Nicolas Capens22008782016-10-20 01:11:47 -04003391 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Nicolas Capens62abb552016-01-05 12:03:47 -05003392 long2 = Nucleus::createInsertElement(long2, loLong, 0);
3393 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
3394 Value *short8 = Nucleus::createBitCast(long2, Short8::getType());
3395
3396 storeValue(short8);
3397 }
3398
Nicolas Capens96d4e092016-11-18 14:22:38 -05003399 RValue<UShort8> UShort8::operator=(RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003400 {
John Bauman66b8ab22014-05-06 15:57:45 -04003401 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003402
3403 return rhs;
3404 }
3405
Nicolas Capens96d4e092016-11-18 14:22:38 -05003406 RValue<UShort8> UShort8::operator=(const UShort8 &rhs)
John Bauman89401822014-05-06 15:04:28 -04003407 {
John Bauman66b8ab22014-05-06 15:57:45 -04003408 Value *value = rhs.loadValue();
3409 storeValue(value);
3410
3411 return RValue<UShort8>(value);
3412 }
3413
Nicolas Capens96d4e092016-11-18 14:22:38 -05003414 RValue<UShort8> UShort8::operator=(const Reference<UShort8> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04003415 {
3416 Value *value = rhs.loadValue();
3417 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003418
3419 return RValue<UShort8>(value);
3420 }
3421
John Bauman19bac1e2014-05-06 15:23:49 -04003422 RValue<UShort8> operator&(RValue<UShort8> lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003423 {
3424 return RValue<UShort8>(Nucleus::createAnd(lhs.value, rhs.value));
3425 }
3426
John Bauman19bac1e2014-05-06 15:23:49 -04003427 RValue<UShort8> operator<<(RValue<UShort8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003428 {
3429 return As<UShort8>(x86::psllw(As<Short8>(lhs), rhs)); // FIXME: Fallback required
3430 }
3431
John Bauman19bac1e2014-05-06 15:23:49 -04003432 RValue<UShort8> operator>>(RValue<UShort8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003433 {
3434 return x86::psrlw(lhs, rhs); // FIXME: Fallback required
3435 }
3436
John Bauman19bac1e2014-05-06 15:23:49 -04003437 RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003438 {
3439 return RValue<UShort8>(Nucleus::createAdd(lhs.value, rhs.value));
3440 }
3441
John Bauman19bac1e2014-05-06 15:23:49 -04003442 RValue<UShort8> operator*(RValue<UShort8> lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003443 {
3444 return RValue<UShort8>(Nucleus::createMul(lhs.value, rhs.value));
3445 }
3446
Nicolas Capens96d4e092016-11-18 14:22:38 -05003447 RValue<UShort8> operator+=(UShort8 &lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003448 {
3449 return lhs = lhs + rhs;
3450 }
3451
John Bauman19bac1e2014-05-06 15:23:49 -04003452 RValue<UShort8> operator~(RValue<UShort8> val)
John Bauman89401822014-05-06 15:04:28 -04003453 {
3454 return RValue<UShort8>(Nucleus::createNot(val.value));
3455 }
3456
John Bauman19bac1e2014-05-06 15:23:49 -04003457 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 -04003458 {
Nicolas Capense89cd582016-09-30 14:23:47 -04003459 int pshufb[16] =
3460 {
3461 select0 + 0,
3462 select0 + 1,
3463 select1 + 0,
3464 select1 + 1,
3465 select2 + 0,
3466 select2 + 1,
3467 select3 + 0,
3468 select3 + 1,
3469 select4 + 0,
3470 select4 + 1,
3471 select5 + 0,
3472 select5 + 1,
3473 select6 + 0,
3474 select6 + 1,
3475 select7 + 0,
3476 select7 + 1,
3477 };
John Bauman89401822014-05-06 15:04:28 -04003478
3479 Value *byte16 = Nucleus::createBitCast(x.value, Byte16::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04003480 Value *shuffle = Nucleus::createShuffleVector(byte16, byte16, pshufb);
John Bauman89401822014-05-06 15:04:28 -04003481 Value *short8 = Nucleus::createBitCast(shuffle, UShort8::getType());
3482
3483 return RValue<UShort8>(short8);
3484 }
3485
John Bauman19bac1e2014-05-06 15:23:49 -04003486 RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y)
John Bauman89401822014-05-06 15:04:28 -04003487 {
3488 return x86::pmulhuw(x, y); // FIXME: Fallback required
3489 }
3490
John Bauman19bac1e2014-05-06 15:23:49 -04003491 Type *UShort8::getType()
John Bauman89401822014-05-06 15:04:28 -04003492 {
Nicolas Capensac230122016-09-20 14:30:06 -04003493 return T(VectorType::get(UShort::getType(), 8));
John Bauman89401822014-05-06 15:04:28 -04003494 }
3495
Nicolas Capens81f18302016-01-14 09:32:35 -05003496 Int::Int(Argument<Int> argument)
John Bauman89401822014-05-06 15:04:28 -04003497 {
Nicolas Capens81f18302016-01-14 09:32:35 -05003498 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04003499 }
3500
John Bauman19bac1e2014-05-06 15:23:49 -04003501 Int::Int(RValue<Byte> cast)
John Bauman89401822014-05-06 15:04:28 -04003502 {
John Bauman89401822014-05-06 15:04:28 -04003503 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3504
John Bauman66b8ab22014-05-06 15:57:45 -04003505 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003506 }
3507
John Bauman19bac1e2014-05-06 15:23:49 -04003508 Int::Int(RValue<SByte> cast)
John Bauman89401822014-05-06 15:04:28 -04003509 {
John Bauman89401822014-05-06 15:04:28 -04003510 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3511
John Bauman66b8ab22014-05-06 15:57:45 -04003512 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003513 }
3514
John Bauman19bac1e2014-05-06 15:23:49 -04003515 Int::Int(RValue<Short> cast)
John Bauman89401822014-05-06 15:04:28 -04003516 {
John Bauman89401822014-05-06 15:04:28 -04003517 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3518
John Bauman66b8ab22014-05-06 15:57:45 -04003519 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003520 }
3521
John Bauman19bac1e2014-05-06 15:23:49 -04003522 Int::Int(RValue<UShort> cast)
John Bauman89401822014-05-06 15:04:28 -04003523 {
John Bauman89401822014-05-06 15:04:28 -04003524 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3525
John Bauman66b8ab22014-05-06 15:57:45 -04003526 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003527 }
3528
John Bauman19bac1e2014-05-06 15:23:49 -04003529 Int::Int(RValue<Int2> cast)
John Bauman89401822014-05-06 15:04:28 -04003530 {
John Bauman89401822014-05-06 15:04:28 -04003531 *this = Extract(cast, 0);
3532 }
3533
John Bauman19bac1e2014-05-06 15:23:49 -04003534 Int::Int(RValue<Long> cast)
John Bauman89401822014-05-06 15:04:28 -04003535 {
John Bauman89401822014-05-06 15:04:28 -04003536 Value *integer = Nucleus::createTrunc(cast.value, Int::getType());
3537
John Bauman66b8ab22014-05-06 15:57:45 -04003538 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003539 }
3540
John Bauman19bac1e2014-05-06 15:23:49 -04003541 Int::Int(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04003542 {
John Bauman89401822014-05-06 15:04:28 -04003543 Value *integer = Nucleus::createFPToSI(cast.value, Int::getType());
3544
John Bauman66b8ab22014-05-06 15:57:45 -04003545 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003546 }
3547
John Bauman89401822014-05-06 15:04:28 -04003548 Int::Int(int x)
3549 {
John Bauman66b8ab22014-05-06 15:57:45 -04003550 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04003551 }
3552
John Bauman19bac1e2014-05-06 15:23:49 -04003553 Int::Int(RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003554 {
John Bauman66b8ab22014-05-06 15:57:45 -04003555 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003556 }
3557
John Bauman19bac1e2014-05-06 15:23:49 -04003558 Int::Int(RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04003559 {
John Bauman66b8ab22014-05-06 15:57:45 -04003560 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003561 }
3562
3563 Int::Int(const Int &rhs)
3564 {
John Bauman66b8ab22014-05-06 15:57:45 -04003565 Value *value = rhs.loadValue();
3566 storeValue(value);
3567 }
John Bauman89401822014-05-06 15:04:28 -04003568
John Bauman66b8ab22014-05-06 15:57:45 -04003569 Int::Int(const Reference<Int> &rhs)
3570 {
3571 Value *value = rhs.loadValue();
3572 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003573 }
3574
3575 Int::Int(const UInt &rhs)
3576 {
John Bauman66b8ab22014-05-06 15:57:45 -04003577 Value *value = rhs.loadValue();
3578 storeValue(value);
3579 }
John Bauman89401822014-05-06 15:04:28 -04003580
John Bauman66b8ab22014-05-06 15:57:45 -04003581 Int::Int(const Reference<UInt> &rhs)
3582 {
3583 Value *value = rhs.loadValue();
3584 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003585 }
3586
Nicolas Capens96d4e092016-11-18 14:22:38 -05003587 RValue<Int> Int::operator=(int rhs)
John Bauman89401822014-05-06 15:04:28 -04003588 {
John Bauman66b8ab22014-05-06 15:57:45 -04003589 return RValue<Int>(storeValue(Nucleus::createConstantInt(rhs)));
John Bauman89401822014-05-06 15:04:28 -04003590 }
3591
Nicolas Capens96d4e092016-11-18 14:22:38 -05003592 RValue<Int> Int::operator=(RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003593 {
John Bauman66b8ab22014-05-06 15:57:45 -04003594 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003595
3596 return rhs;
3597 }
3598
Nicolas Capens96d4e092016-11-18 14:22:38 -05003599 RValue<Int> Int::operator=(RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04003600 {
John Bauman66b8ab22014-05-06 15:57:45 -04003601 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003602
John Bauman66b8ab22014-05-06 15:57:45 -04003603 return RValue<Int>(rhs);
John Bauman89401822014-05-06 15:04:28 -04003604 }
3605
Nicolas Capens96d4e092016-11-18 14:22:38 -05003606 RValue<Int> Int::operator=(const Int &rhs)
John Bauman89401822014-05-06 15:04:28 -04003607 {
John Bauman66b8ab22014-05-06 15:57:45 -04003608 Value *value = rhs.loadValue();
3609 storeValue(value);
3610
3611 return RValue<Int>(value);
3612 }
3613
Nicolas Capens96d4e092016-11-18 14:22:38 -05003614 RValue<Int> Int::operator=(const Reference<Int> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04003615 {
3616 Value *value = rhs.loadValue();
3617 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003618
3619 return RValue<Int>(value);
3620 }
3621
Nicolas Capens96d4e092016-11-18 14:22:38 -05003622 RValue<Int> Int::operator=(const UInt &rhs)
John Bauman89401822014-05-06 15:04:28 -04003623 {
John Bauman66b8ab22014-05-06 15:57:45 -04003624 Value *value = rhs.loadValue();
3625 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003626
3627 return RValue<Int>(value);
3628 }
3629
Nicolas Capens96d4e092016-11-18 14:22:38 -05003630 RValue<Int> Int::operator=(const Reference<UInt> &rhs)
John Bauman89401822014-05-06 15:04:28 -04003631 {
John Bauman66b8ab22014-05-06 15:57:45 -04003632 Value *value = rhs.loadValue();
3633 storeValue(value);
3634
3635 return RValue<Int>(value);
John Bauman89401822014-05-06 15:04:28 -04003636 }
3637
John Bauman19bac1e2014-05-06 15:23:49 -04003638 RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003639 {
3640 return RValue<Int>(Nucleus::createAdd(lhs.value, rhs.value));
3641 }
3642
John Bauman19bac1e2014-05-06 15:23:49 -04003643 RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003644 {
3645 return RValue<Int>(Nucleus::createSub(lhs.value, rhs.value));
3646 }
3647
John Bauman19bac1e2014-05-06 15:23:49 -04003648 RValue<Int> operator*(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003649 {
3650 return RValue<Int>(Nucleus::createMul(lhs.value, rhs.value));
3651 }
3652
John Bauman19bac1e2014-05-06 15:23:49 -04003653 RValue<Int> operator/(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003654 {
3655 return RValue<Int>(Nucleus::createSDiv(lhs.value, rhs.value));
3656 }
3657
John Bauman19bac1e2014-05-06 15:23:49 -04003658 RValue<Int> operator%(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003659 {
3660 return RValue<Int>(Nucleus::createSRem(lhs.value, rhs.value));
3661 }
3662
John Bauman19bac1e2014-05-06 15:23:49 -04003663 RValue<Int> operator&(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003664 {
3665 return RValue<Int>(Nucleus::createAnd(lhs.value, rhs.value));
3666 }
3667
John Bauman19bac1e2014-05-06 15:23:49 -04003668 RValue<Int> operator|(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003669 {
3670 return RValue<Int>(Nucleus::createOr(lhs.value, rhs.value));
3671 }
3672
John Bauman19bac1e2014-05-06 15:23:49 -04003673 RValue<Int> operator^(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003674 {
3675 return RValue<Int>(Nucleus::createXor(lhs.value, rhs.value));
3676 }
3677
John Bauman19bac1e2014-05-06 15:23:49 -04003678 RValue<Int> operator<<(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003679 {
3680 return RValue<Int>(Nucleus::createShl(lhs.value, rhs.value));
3681 }
3682
John Bauman19bac1e2014-05-06 15:23:49 -04003683 RValue<Int> operator>>(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003684 {
3685 return RValue<Int>(Nucleus::createAShr(lhs.value, rhs.value));
3686 }
3687
Nicolas Capens96d4e092016-11-18 14:22:38 -05003688 RValue<Int> operator+=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003689 {
3690 return lhs = lhs + rhs;
3691 }
3692
Nicolas Capens96d4e092016-11-18 14:22:38 -05003693 RValue<Int> operator-=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003694 {
3695 return lhs = lhs - rhs;
3696 }
3697
Nicolas Capens96d4e092016-11-18 14:22:38 -05003698 RValue<Int> operator*=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003699 {
3700 return lhs = lhs * rhs;
3701 }
3702
Nicolas Capens96d4e092016-11-18 14:22:38 -05003703 RValue<Int> operator/=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003704 {
3705 return lhs = lhs / rhs;
3706 }
3707
Nicolas Capens96d4e092016-11-18 14:22:38 -05003708 RValue<Int> operator%=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003709 {
3710 return lhs = lhs % rhs;
3711 }
3712
Nicolas Capens96d4e092016-11-18 14:22:38 -05003713 RValue<Int> operator&=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003714 {
3715 return lhs = lhs & rhs;
3716 }
3717
Nicolas Capens96d4e092016-11-18 14:22:38 -05003718 RValue<Int> operator|=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003719 {
3720 return lhs = lhs | rhs;
3721 }
3722
Nicolas Capens96d4e092016-11-18 14:22:38 -05003723 RValue<Int> operator^=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003724 {
3725 return lhs = lhs ^ rhs;
3726 }
3727
Nicolas Capens96d4e092016-11-18 14:22:38 -05003728 RValue<Int> operator<<=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003729 {
3730 return lhs = lhs << rhs;
3731 }
3732
Nicolas Capens96d4e092016-11-18 14:22:38 -05003733 RValue<Int> operator>>=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003734 {
3735 return lhs = lhs >> rhs;
3736 }
3737
John Bauman19bac1e2014-05-06 15:23:49 -04003738 RValue<Int> operator+(RValue<Int> val)
John Bauman89401822014-05-06 15:04:28 -04003739 {
3740 return val;
3741 }
3742
John Bauman19bac1e2014-05-06 15:23:49 -04003743 RValue<Int> operator-(RValue<Int> val)
John Bauman89401822014-05-06 15:04:28 -04003744 {
3745 return RValue<Int>(Nucleus::createNeg(val.value));
3746 }
3747
John Bauman19bac1e2014-05-06 15:23:49 -04003748 RValue<Int> operator~(RValue<Int> val)
John Bauman89401822014-05-06 15:04:28 -04003749 {
3750 return RValue<Int>(Nucleus::createNot(val.value));
3751 }
3752
Nicolas Capens96d4e092016-11-18 14:22:38 -05003753 RValue<Int> operator++(Int &val, int) // Post-increment
John Bauman89401822014-05-06 15:04:28 -04003754 {
3755 RValue<Int> res = val;
3756
Nicolas Capens19336542016-09-26 10:32:29 -04003757 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04003758 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04003759
3760 return res;
3761 }
3762
Nicolas Capens96d4e092016-11-18 14:22:38 -05003763 const Int &operator++(Int &val) // Pre-increment
John Bauman89401822014-05-06 15:04:28 -04003764 {
Nicolas Capens19336542016-09-26 10:32:29 -04003765 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04003766 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04003767
3768 return val;
3769 }
3770
Nicolas Capens96d4e092016-11-18 14:22:38 -05003771 RValue<Int> operator--(Int &val, int) // Post-decrement
John Bauman89401822014-05-06 15:04:28 -04003772 {
3773 RValue<Int> res = val;
3774
Nicolas Capens19336542016-09-26 10:32:29 -04003775 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04003776 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04003777
3778 return res;
3779 }
3780
Nicolas Capens96d4e092016-11-18 14:22:38 -05003781 const Int &operator--(Int &val) // Pre-decrement
John Bauman89401822014-05-06 15:04:28 -04003782 {
Nicolas Capens19336542016-09-26 10:32:29 -04003783 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04003784 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04003785
3786 return val;
3787 }
3788
John Bauman19bac1e2014-05-06 15:23:49 -04003789 RValue<Bool> operator<(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003790 {
3791 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
3792 }
3793
John Bauman19bac1e2014-05-06 15:23:49 -04003794 RValue<Bool> operator<=(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003795 {
3796 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
3797 }
3798
John Bauman19bac1e2014-05-06 15:23:49 -04003799 RValue<Bool> operator>(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003800 {
3801 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
3802 }
3803
John Bauman19bac1e2014-05-06 15:23:49 -04003804 RValue<Bool> operator>=(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003805 {
3806 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
3807 }
3808
John Bauman19bac1e2014-05-06 15:23:49 -04003809 RValue<Bool> operator!=(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003810 {
3811 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
3812 }
3813
John Bauman19bac1e2014-05-06 15:23:49 -04003814 RValue<Bool> operator==(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003815 {
3816 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
3817 }
3818
John Bauman19bac1e2014-05-06 15:23:49 -04003819 RValue<Int> Max(RValue<Int> x, RValue<Int> y)
3820 {
3821 return IfThenElse(x > y, x, y);
3822 }
3823
3824 RValue<Int> Min(RValue<Int> x, RValue<Int> y)
3825 {
3826 return IfThenElse(x < y, x, y);
3827 }
3828
3829 RValue<Int> Clamp(RValue<Int> x, RValue<Int> min, RValue<Int> max)
3830 {
3831 return Min(Max(x, min), max);
3832 }
3833
3834 RValue<Int> RoundInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04003835 {
3836 return x86::cvtss2si(cast);
3837
John Bauman66b8ab22014-05-06 15:57:45 -04003838 // return IfThenElse(val > 0.0f, Int(val + 0.5f), Int(val - 0.5f));
John Bauman89401822014-05-06 15:04:28 -04003839 }
3840
John Bauman19bac1e2014-05-06 15:23:49 -04003841 Type *Int::getType()
John Bauman89401822014-05-06 15:04:28 -04003842 {
Nicolas Capensac230122016-09-20 14:30:06 -04003843 return T(llvm::Type::getInt32Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04003844 }
3845
John Bauman19bac1e2014-05-06 15:23:49 -04003846 Long::Long(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04003847 {
John Bauman89401822014-05-06 15:04:28 -04003848 Value *integer = Nucleus::createSExt(cast.value, Long::getType());
3849
John Bauman66b8ab22014-05-06 15:57:45 -04003850 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003851 }
3852
John Bauman19bac1e2014-05-06 15:23:49 -04003853 Long::Long(RValue<UInt> cast)
John Bauman89401822014-05-06 15:04:28 -04003854 {
John Bauman89401822014-05-06 15:04:28 -04003855 Value *integer = Nucleus::createZExt(cast.value, Long::getType());
3856
John Bauman66b8ab22014-05-06 15:57:45 -04003857 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003858 }
3859
John Bauman19bac1e2014-05-06 15:23:49 -04003860 Long::Long(RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04003861 {
John Bauman66b8ab22014-05-06 15:57:45 -04003862 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003863 }
3864
Nicolas Capens96d4e092016-11-18 14:22:38 -05003865 RValue<Long> Long::operator=(int64_t rhs)
John Bauman89401822014-05-06 15:04:28 -04003866 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04003867 return RValue<Long>(storeValue(Nucleus::createConstantLong(rhs)));
John Bauman89401822014-05-06 15:04:28 -04003868 }
3869
Nicolas Capens96d4e092016-11-18 14:22:38 -05003870 RValue<Long> Long::operator=(RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04003871 {
John Bauman66b8ab22014-05-06 15:57:45 -04003872 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003873
3874 return rhs;
3875 }
3876
Nicolas Capens96d4e092016-11-18 14:22:38 -05003877 RValue<Long> Long::operator=(const Long &rhs)
John Bauman89401822014-05-06 15:04:28 -04003878 {
John Bauman66b8ab22014-05-06 15:57:45 -04003879 Value *value = rhs.loadValue();
3880 storeValue(value);
3881
3882 return RValue<Long>(value);
3883 }
3884
Nicolas Capens96d4e092016-11-18 14:22:38 -05003885 RValue<Long> Long::operator=(const Reference<Long> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04003886 {
3887 Value *value = rhs.loadValue();
3888 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003889
3890 return RValue<Long>(value);
3891 }
3892
John Bauman19bac1e2014-05-06 15:23:49 -04003893 RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04003894 {
3895 return RValue<Long>(Nucleus::createAdd(lhs.value, rhs.value));
3896 }
3897
John Bauman19bac1e2014-05-06 15:23:49 -04003898 RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04003899 {
3900 return RValue<Long>(Nucleus::createSub(lhs.value, rhs.value));
3901 }
3902
Nicolas Capens96d4e092016-11-18 14:22:38 -05003903 RValue<Long> operator+=(Long &lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04003904 {
3905 return lhs = lhs + rhs;
3906 }
3907
Nicolas Capens96d4e092016-11-18 14:22:38 -05003908 RValue<Long> operator-=(Long &lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04003909 {
3910 return lhs = lhs - rhs;
3911 }
3912
John Bauman66b8ab22014-05-06 15:57:45 -04003913 RValue<Long> AddAtomic(RValue<Pointer<Long> > x, RValue<Long> y)
John Bauman89401822014-05-06 15:04:28 -04003914 {
John Bauman19bac1e2014-05-06 15:23:49 -04003915 return RValue<Long>(Nucleus::createAtomicAdd(x.value, y.value));
John Bauman89401822014-05-06 15:04:28 -04003916 }
3917
John Bauman19bac1e2014-05-06 15:23:49 -04003918 Type *Long::getType()
John Bauman89401822014-05-06 15:04:28 -04003919 {
Nicolas Capensac230122016-09-20 14:30:06 -04003920 return T(llvm::Type::getInt64Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04003921 }
3922
Nicolas Capens81f18302016-01-14 09:32:35 -05003923 UInt::UInt(Argument<UInt> argument)
John Bauman89401822014-05-06 15:04:28 -04003924 {
Nicolas Capens81f18302016-01-14 09:32:35 -05003925 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04003926 }
3927
John Bauman19bac1e2014-05-06 15:23:49 -04003928 UInt::UInt(RValue<UShort> cast)
John Bauman89401822014-05-06 15:04:28 -04003929 {
John Bauman89401822014-05-06 15:04:28 -04003930 Value *integer = Nucleus::createZExt(cast.value, UInt::getType());
3931
John Bauman66b8ab22014-05-06 15:57:45 -04003932 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003933 }
3934
John Bauman19bac1e2014-05-06 15:23:49 -04003935 UInt::UInt(RValue<Long> cast)
John Bauman89401822014-05-06 15:04:28 -04003936 {
John Bauman89401822014-05-06 15:04:28 -04003937 Value *integer = Nucleus::createTrunc(cast.value, UInt::getType());
3938
John Bauman66b8ab22014-05-06 15:57:45 -04003939 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003940 }
3941
John Bauman19bac1e2014-05-06 15:23:49 -04003942 UInt::UInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04003943 {
Alexis Hetu764d1422016-09-28 08:44:22 -04003944 // Note: createFPToUI is broken, must perform conversion using createFPtoSI
3945 // Value *integer = Nucleus::createFPToUI(cast.value, UInt::getType());
John Bauman89401822014-05-06 15:04:28 -04003946
Alexis Hetu764d1422016-09-28 08:44:22 -04003947 // Smallest positive value representable in UInt, but not in Int
3948 const unsigned int ustart = 0x80000000u;
3949 const float ustartf = float(ustart);
3950
3951 // If the value is negative, store 0, otherwise store the result of the conversion
3952 storeValue((~(As<Int>(cast) >> 31) &
3953 // Check if the value can be represented as an Int
3954 IfThenElse(cast >= ustartf,
3955 // If the value is too large, subtract ustart and re-add it after conversion.
3956 As<Int>(As<UInt>(Int(cast - Float(ustartf))) + UInt(ustart)),
3957 // Otherwise, just convert normally
3958 Int(cast))).value);
John Bauman89401822014-05-06 15:04:28 -04003959 }
3960
John Bauman89401822014-05-06 15:04:28 -04003961 UInt::UInt(int x)
3962 {
John Bauman66b8ab22014-05-06 15:57:45 -04003963 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04003964 }
3965
3966 UInt::UInt(unsigned int x)
3967 {
John Bauman66b8ab22014-05-06 15:57:45 -04003968 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04003969 }
3970
John Bauman19bac1e2014-05-06 15:23:49 -04003971 UInt::UInt(RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04003972 {
John Bauman66b8ab22014-05-06 15:57:45 -04003973 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003974 }
3975
John Bauman19bac1e2014-05-06 15:23:49 -04003976 UInt::UInt(RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003977 {
John Bauman66b8ab22014-05-06 15:57:45 -04003978 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003979 }
3980
3981 UInt::UInt(const UInt &rhs)
3982 {
John Bauman66b8ab22014-05-06 15:57:45 -04003983 Value *value = rhs.loadValue();
3984 storeValue(value);
3985 }
John Bauman89401822014-05-06 15:04:28 -04003986
John Bauman66b8ab22014-05-06 15:57:45 -04003987 UInt::UInt(const Reference<UInt> &rhs)
3988 {
3989 Value *value = rhs.loadValue();
3990 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003991 }
3992
3993 UInt::UInt(const Int &rhs)
3994 {
John Bauman66b8ab22014-05-06 15:57:45 -04003995 Value *value = rhs.loadValue();
3996 storeValue(value);
3997 }
John Bauman89401822014-05-06 15:04:28 -04003998
John Bauman66b8ab22014-05-06 15:57:45 -04003999 UInt::UInt(const Reference<Int> &rhs)
4000 {
4001 Value *value = rhs.loadValue();
4002 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004003 }
4004
Nicolas Capens96d4e092016-11-18 14:22:38 -05004005 RValue<UInt> UInt::operator=(unsigned int rhs)
John Bauman89401822014-05-06 15:04:28 -04004006 {
John Bauman66b8ab22014-05-06 15:57:45 -04004007 return RValue<UInt>(storeValue(Nucleus::createConstantInt(rhs)));
John Bauman89401822014-05-06 15:04:28 -04004008 }
4009
Nicolas Capens96d4e092016-11-18 14:22:38 -05004010 RValue<UInt> UInt::operator=(RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004011 {
John Bauman66b8ab22014-05-06 15:57:45 -04004012 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004013
4014 return rhs;
4015 }
4016
Nicolas Capens96d4e092016-11-18 14:22:38 -05004017 RValue<UInt> UInt::operator=(RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004018 {
John Bauman66b8ab22014-05-06 15:57:45 -04004019 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004020
John Bauman66b8ab22014-05-06 15:57:45 -04004021 return RValue<UInt>(rhs);
John Bauman89401822014-05-06 15:04:28 -04004022 }
4023
Nicolas Capens96d4e092016-11-18 14:22:38 -05004024 RValue<UInt> UInt::operator=(const UInt &rhs)
John Bauman89401822014-05-06 15:04:28 -04004025 {
John Bauman66b8ab22014-05-06 15:57:45 -04004026 Value *value = rhs.loadValue();
4027 storeValue(value);
4028
4029 return RValue<UInt>(value);
4030 }
4031
Nicolas Capens96d4e092016-11-18 14:22:38 -05004032 RValue<UInt> UInt::operator=(const Reference<UInt> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04004033 {
4034 Value *value = rhs.loadValue();
4035 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004036
4037 return RValue<UInt>(value);
4038 }
4039
Nicolas Capens96d4e092016-11-18 14:22:38 -05004040 RValue<UInt> UInt::operator=(const Int &rhs)
John Bauman89401822014-05-06 15:04:28 -04004041 {
John Bauman66b8ab22014-05-06 15:57:45 -04004042 Value *value = rhs.loadValue();
4043 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004044
4045 return RValue<UInt>(value);
4046 }
4047
Nicolas Capens96d4e092016-11-18 14:22:38 -05004048 RValue<UInt> UInt::operator=(const Reference<Int> &rhs)
John Bauman89401822014-05-06 15:04:28 -04004049 {
John Bauman66b8ab22014-05-06 15:57:45 -04004050 Value *value = rhs.loadValue();
4051 storeValue(value);
4052
4053 return RValue<UInt>(value);
John Bauman89401822014-05-06 15:04:28 -04004054 }
4055
John Bauman19bac1e2014-05-06 15:23:49 -04004056 RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004057 {
4058 return RValue<UInt>(Nucleus::createAdd(lhs.value, rhs.value));
4059 }
4060
John Bauman19bac1e2014-05-06 15:23:49 -04004061 RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004062 {
4063 return RValue<UInt>(Nucleus::createSub(lhs.value, rhs.value));
4064 }
4065
John Bauman19bac1e2014-05-06 15:23:49 -04004066 RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004067 {
4068 return RValue<UInt>(Nucleus::createMul(lhs.value, rhs.value));
4069 }
4070
John Bauman19bac1e2014-05-06 15:23:49 -04004071 RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004072 {
4073 return RValue<UInt>(Nucleus::createUDiv(lhs.value, rhs.value));
4074 }
4075
John Bauman19bac1e2014-05-06 15:23:49 -04004076 RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004077 {
4078 return RValue<UInt>(Nucleus::createURem(lhs.value, rhs.value));
4079 }
4080
John Bauman19bac1e2014-05-06 15:23:49 -04004081 RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004082 {
4083 return RValue<UInt>(Nucleus::createAnd(lhs.value, rhs.value));
4084 }
4085
John Bauman19bac1e2014-05-06 15:23:49 -04004086 RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004087 {
4088 return RValue<UInt>(Nucleus::createOr(lhs.value, rhs.value));
4089 }
4090
John Bauman19bac1e2014-05-06 15:23:49 -04004091 RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004092 {
4093 return RValue<UInt>(Nucleus::createXor(lhs.value, rhs.value));
4094 }
4095
John Bauman19bac1e2014-05-06 15:23:49 -04004096 RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004097 {
4098 return RValue<UInt>(Nucleus::createShl(lhs.value, rhs.value));
4099 }
4100
John Bauman19bac1e2014-05-06 15:23:49 -04004101 RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004102 {
4103 return RValue<UInt>(Nucleus::createLShr(lhs.value, rhs.value));
4104 }
4105
Nicolas Capens96d4e092016-11-18 14:22:38 -05004106 RValue<UInt> operator+=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004107 {
4108 return lhs = lhs + rhs;
4109 }
4110
Nicolas Capens96d4e092016-11-18 14:22:38 -05004111 RValue<UInt> operator-=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004112 {
4113 return lhs = lhs - rhs;
4114 }
4115
Nicolas Capens96d4e092016-11-18 14:22:38 -05004116 RValue<UInt> operator*=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004117 {
4118 return lhs = lhs * rhs;
4119 }
4120
Nicolas Capens96d4e092016-11-18 14:22:38 -05004121 RValue<UInt> operator/=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004122 {
4123 return lhs = lhs / rhs;
4124 }
4125
Nicolas Capens96d4e092016-11-18 14:22:38 -05004126 RValue<UInt> operator%=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004127 {
4128 return lhs = lhs % rhs;
4129 }
4130
Nicolas Capens96d4e092016-11-18 14:22:38 -05004131 RValue<UInt> operator&=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004132 {
4133 return lhs = lhs & rhs;
4134 }
4135
Nicolas Capens96d4e092016-11-18 14:22:38 -05004136 RValue<UInt> operator|=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004137 {
4138 return lhs = lhs | rhs;
4139 }
4140
Nicolas Capens96d4e092016-11-18 14:22:38 -05004141 RValue<UInt> operator^=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004142 {
4143 return lhs = lhs ^ rhs;
4144 }
4145
Nicolas Capens96d4e092016-11-18 14:22:38 -05004146 RValue<UInt> operator<<=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004147 {
4148 return lhs = lhs << rhs;
4149 }
4150
Nicolas Capens96d4e092016-11-18 14:22:38 -05004151 RValue<UInt> operator>>=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004152 {
4153 return lhs = lhs >> rhs;
4154 }
4155
John Bauman19bac1e2014-05-06 15:23:49 -04004156 RValue<UInt> operator+(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004157 {
4158 return val;
4159 }
4160
John Bauman19bac1e2014-05-06 15:23:49 -04004161 RValue<UInt> operator-(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004162 {
4163 return RValue<UInt>(Nucleus::createNeg(val.value));
4164 }
4165
John Bauman19bac1e2014-05-06 15:23:49 -04004166 RValue<UInt> operator~(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004167 {
4168 return RValue<UInt>(Nucleus::createNot(val.value));
4169 }
4170
Nicolas Capens96d4e092016-11-18 14:22:38 -05004171 RValue<UInt> operator++(UInt &val, int) // Post-increment
John Bauman89401822014-05-06 15:04:28 -04004172 {
4173 RValue<UInt> res = val;
4174
Nicolas Capens19336542016-09-26 10:32:29 -04004175 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04004176 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004177
4178 return res;
4179 }
4180
Nicolas Capens96d4e092016-11-18 14:22:38 -05004181 const UInt &operator++(UInt &val) // Pre-increment
John Bauman89401822014-05-06 15:04:28 -04004182 {
Nicolas Capens19336542016-09-26 10:32:29 -04004183 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04004184 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004185
4186 return val;
4187 }
4188
Nicolas Capens96d4e092016-11-18 14:22:38 -05004189 RValue<UInt> operator--(UInt &val, int) // Post-decrement
John Bauman89401822014-05-06 15:04:28 -04004190 {
4191 RValue<UInt> res = val;
4192
Nicolas Capens19336542016-09-26 10:32:29 -04004193 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04004194 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004195
4196 return res;
4197 }
4198
Nicolas Capens96d4e092016-11-18 14:22:38 -05004199 const UInt &operator--(UInt &val) // Pre-decrement
John Bauman89401822014-05-06 15:04:28 -04004200 {
Nicolas Capens19336542016-09-26 10:32:29 -04004201 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04004202 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004203
4204 return val;
4205 }
4206
John Bauman19bac1e2014-05-06 15:23:49 -04004207 RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y)
4208 {
4209 return IfThenElse(x > y, x, y);
4210 }
4211
4212 RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y)
4213 {
4214 return IfThenElse(x < y, x, y);
4215 }
4216
4217 RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max)
4218 {
4219 return Min(Max(x, min), max);
4220 }
4221
4222 RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004223 {
4224 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
4225 }
4226
John Bauman19bac1e2014-05-06 15:23:49 -04004227 RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004228 {
4229 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
4230 }
4231
John Bauman19bac1e2014-05-06 15:23:49 -04004232 RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004233 {
4234 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
4235 }
4236
John Bauman19bac1e2014-05-06 15:23:49 -04004237 RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004238 {
4239 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
4240 }
4241
John Bauman19bac1e2014-05-06 15:23:49 -04004242 RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004243 {
4244 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
4245 }
4246
John Bauman19bac1e2014-05-06 15:23:49 -04004247 RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004248 {
4249 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
4250 }
4251
John Bauman19bac1e2014-05-06 15:23:49 -04004252// RValue<UInt> RoundUInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04004253// {
4254// return x86::cvtss2si(val); // FIXME: Unsigned
4255//
John Bauman66b8ab22014-05-06 15:57:45 -04004256// // return IfThenElse(val > 0.0f, Int(val + 0.5f), Int(val - 0.5f));
John Bauman89401822014-05-06 15:04:28 -04004257// }
4258
John Bauman19bac1e2014-05-06 15:23:49 -04004259 Type *UInt::getType()
John Bauman89401822014-05-06 15:04:28 -04004260 {
Nicolas Capensac230122016-09-20 14:30:06 -04004261 return T(llvm::Type::getInt32Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04004262 }
4263
John Bauman19bac1e2014-05-06 15:23:49 -04004264// Int2::Int2(RValue<Int> cast)
4265// {
John Bauman19bac1e2014-05-06 15:23:49 -04004266// Value *extend = Nucleus::createZExt(cast.value, Long::getType());
4267// Value *vector = Nucleus::createBitCast(extend, Int2::getType());
John Bauman66b8ab22014-05-06 15:57:45 -04004268//
Nicolas Capense89cd582016-09-30 14:23:47 -04004269// int shuffle[2] = {0, 0};
4270// Value *replicate = Nucleus::createShuffleVector(vector, vector, shuffle);
John Bauman19bac1e2014-05-06 15:23:49 -04004271//
John Bauman66b8ab22014-05-06 15:57:45 -04004272// storeValue(replicate);
John Bauman19bac1e2014-05-06 15:23:49 -04004273// }
John Bauman89401822014-05-06 15:04:28 -04004274
John Bauman19bac1e2014-05-06 15:23:49 -04004275 Int2::Int2(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04004276 {
Nicolas Capens22008782016-10-20 01:11:47 -04004277 Value *long2 = Nucleus::createBitCast(cast.value, T(VectorType::get(Long::getType(), 2)));
Nicolas Capense95d5342016-09-30 11:37:28 -04004278 Value *element = Nucleus::createExtractElement(long2, Long::getType(), 0);
John Bauman89401822014-05-06 15:04:28 -04004279 Value *int2 = Nucleus::createBitCast(element, Int2::getType());
4280
John Bauman66b8ab22014-05-06 15:57:45 -04004281 storeValue(int2);
John Bauman89401822014-05-06 15:04:28 -04004282 }
4283
John Bauman89401822014-05-06 15:04:28 -04004284 Int2::Int2(int x, int y)
4285 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04004286 int64_t constantVector[2] = {x, y};
4287 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(Int::getType(), 2))));
John Bauman89401822014-05-06 15:04:28 -04004288
John Bauman66b8ab22014-05-06 15:57:45 -04004289 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04004290 }
4291
John Bauman19bac1e2014-05-06 15:23:49 -04004292 Int2::Int2(RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004293 {
John Bauman66b8ab22014-05-06 15:57:45 -04004294 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004295 }
4296
4297 Int2::Int2(const Int2 &rhs)
4298 {
John Bauman66b8ab22014-05-06 15:57:45 -04004299 Value *value = rhs.loadValue();
4300 storeValue(value);
4301 }
4302
4303 Int2::Int2(const Reference<Int2> &rhs)
4304 {
John Bauman66b8ab22014-05-06 15:57:45 -04004305 Value *value = rhs.loadValue();
4306 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004307 }
4308
Nicolas Capens62abb552016-01-05 12:03:47 -05004309 Int2::Int2(RValue<Int> lo, RValue<Int> hi)
4310 {
Nicolas Capensb40a2562016-01-05 00:08:45 -05004311 if(CPUID::supportsMMX2())
4312 {
4313 // movd mm0, lo
4314 // movd mm1, hi
4315 // punpckldq mm0, mm1
Nicolas Capens45f187a2016-12-02 15:30:56 -05004316
4317 Value *loLong = Nucleus::createInsertElement(V(UndefValue::get(VectorType::get(Int::getType(), 2))), lo.value, 0);
4318 loLong = Nucleus::createInsertElement(loLong, V(ConstantInt::get(Int::getType(), 0)), 1);
4319 Value *hiLong = Nucleus::createInsertElement(V(UndefValue::get(VectorType::get(Int::getType(), 2))), hi.value, 0);
4320 hiLong = Nucleus::createInsertElement(hiLong, V(ConstantInt::get(Int::getType(), 0)), 1);
4321
4322 storeValue(As<Int2>(UnpackLow(As<Int2>(loLong), As<Int2>(hiLong))).value);
Nicolas Capensb40a2562016-01-05 00:08:45 -05004323 }
4324 else
4325 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004326 int shuffle[2] = {0, 1};
4327 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 -05004328
Nicolas Capensb40a2562016-01-05 00:08:45 -05004329 storeValue(Nucleus::createBitCast(packed, Int2::getType()));
4330 }
Nicolas Capens62abb552016-01-05 12:03:47 -05004331 }
4332
Nicolas Capens96d4e092016-11-18 14:22:38 -05004333 RValue<Int2> Int2::operator=(RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004334 {
John Bauman66b8ab22014-05-06 15:57:45 -04004335 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004336
4337 return rhs;
4338 }
4339
Nicolas Capens96d4e092016-11-18 14:22:38 -05004340 RValue<Int2> Int2::operator=(const Int2 &rhs)
John Bauman89401822014-05-06 15:04:28 -04004341 {
John Bauman66b8ab22014-05-06 15:57:45 -04004342 Value *value = rhs.loadValue();
4343 storeValue(value);
4344
4345 return RValue<Int2>(value);
4346 }
4347
Nicolas Capens96d4e092016-11-18 14:22:38 -05004348 RValue<Int2> Int2::operator=(const Reference<Int2> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04004349 {
4350 Value *value = rhs.loadValue();
4351 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004352
4353 return RValue<Int2>(value);
4354 }
4355
John Bauman19bac1e2014-05-06 15:23:49 -04004356 RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004357 {
John Bauman19bac1e2014-05-06 15:23:49 -04004358 if(CPUID::supportsMMX2())
4359 {
4360 return x86::paddd(lhs, rhs);
4361 }
4362 else
4363 {
4364 return RValue<Int2>(Nucleus::createAdd(lhs.value, rhs.value));
4365 }
John Bauman89401822014-05-06 15:04:28 -04004366 }
4367
John Bauman19bac1e2014-05-06 15:23:49 -04004368 RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004369 {
John Bauman19bac1e2014-05-06 15:23:49 -04004370 if(CPUID::supportsMMX2())
4371 {
4372 return x86::psubd(lhs, rhs);
4373 }
4374 else
4375 {
4376 return RValue<Int2>(Nucleus::createSub(lhs.value, rhs.value));
4377 }
John Bauman89401822014-05-06 15:04:28 -04004378 }
4379
John Bauman19bac1e2014-05-06 15:23:49 -04004380// RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs)
4381// {
4382// return RValue<Int2>(Nucleus::createMul(lhs.value, rhs.value));
4383// }
4384
4385// RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs)
4386// {
4387// return RValue<Int2>(Nucleus::createSDiv(lhs.value, rhs.value));
4388// }
4389
4390// RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs)
4391// {
4392// return RValue<Int2>(Nucleus::createSRem(lhs.value, rhs.value));
4393// }
4394
4395 RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004396 {
John Bauman19bac1e2014-05-06 15:23:49 -04004397 if(CPUID::supportsMMX2())
4398 {
4399 return As<Int2>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
4400 }
4401 else
4402 {
4403 return RValue<Int2>(Nucleus::createAnd(lhs.value, rhs.value));
4404 }
John Bauman89401822014-05-06 15:04:28 -04004405 }
4406
John Bauman19bac1e2014-05-06 15:23:49 -04004407 RValue<Int2> operator|(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004408 {
John Bauman19bac1e2014-05-06 15:23:49 -04004409 if(CPUID::supportsMMX2())
4410 {
4411 return As<Int2>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
4412 }
4413 else
4414 {
4415 return RValue<Int2>(Nucleus::createOr(lhs.value, rhs.value));
4416 }
John Bauman89401822014-05-06 15:04:28 -04004417 }
4418
John Bauman19bac1e2014-05-06 15:23:49 -04004419 RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004420 {
John Bauman19bac1e2014-05-06 15:23:49 -04004421 if(CPUID::supportsMMX2())
4422 {
4423 return As<Int2>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
4424 }
4425 else
4426 {
4427 return RValue<Int2>(Nucleus::createXor(lhs.value, rhs.value));
4428 }
John Bauman89401822014-05-06 15:04:28 -04004429 }
4430
John Bauman19bac1e2014-05-06 15:23:49 -04004431 RValue<Int2> operator<<(RValue<Int2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004432 {
4433 // return RValue<Int2>(Nucleus::createShl(lhs.value, rhs.value));
4434
4435 return x86::pslld(lhs, rhs);
4436 }
4437
John Bauman19bac1e2014-05-06 15:23:49 -04004438 RValue<Int2> operator>>(RValue<Int2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004439 {
4440 // return RValue<Int2>(Nucleus::createAShr(lhs.value, rhs.value));
4441
4442 return x86::psrad(lhs, rhs);
4443 }
4444
Nicolas Capens96d4e092016-11-18 14:22:38 -05004445 RValue<Int2> operator+=(Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004446 {
4447 return lhs = lhs + rhs;
4448 }
4449
Nicolas Capens96d4e092016-11-18 14:22:38 -05004450 RValue<Int2> operator-=(Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004451 {
4452 return lhs = lhs - rhs;
4453 }
4454
Nicolas Capens96d4e092016-11-18 14:22:38 -05004455// RValue<Int2> operator*=(Int2 &lhs, RValue<Int2> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04004456// {
4457// return lhs = lhs * rhs;
4458// }
John Bauman89401822014-05-06 15:04:28 -04004459
Nicolas Capens96d4e092016-11-18 14:22:38 -05004460// RValue<Int2> operator/=(Int2 &lhs, RValue<Int2> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04004461// {
4462// return lhs = lhs / rhs;
4463// }
John Bauman89401822014-05-06 15:04:28 -04004464
Nicolas Capens96d4e092016-11-18 14:22:38 -05004465// RValue<Int2> operator%=(Int2 &lhs, RValue<Int2> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04004466// {
4467// return lhs = lhs % rhs;
4468// }
John Bauman89401822014-05-06 15:04:28 -04004469
Nicolas Capens96d4e092016-11-18 14:22:38 -05004470 RValue<Int2> operator&=(Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004471 {
4472 return lhs = lhs & rhs;
4473 }
4474
Nicolas Capens96d4e092016-11-18 14:22:38 -05004475 RValue<Int2> operator|=(Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004476 {
4477 return lhs = lhs | rhs;
4478 }
4479
Nicolas Capens96d4e092016-11-18 14:22:38 -05004480 RValue<Int2> operator^=(Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004481 {
4482 return lhs = lhs ^ rhs;
4483 }
4484
Nicolas Capens96d4e092016-11-18 14:22:38 -05004485 RValue<Int2> operator<<=(Int2 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004486 {
4487 return lhs = lhs << rhs;
4488 }
4489
Nicolas Capens96d4e092016-11-18 14:22:38 -05004490 RValue<Int2> operator>>=(Int2 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004491 {
4492 return lhs = lhs >> rhs;
4493 }
4494
John Bauman19bac1e2014-05-06 15:23:49 -04004495// RValue<Int2> operator+(RValue<Int2> val)
4496// {
4497// return val;
4498// }
4499
4500// RValue<Int2> operator-(RValue<Int2> val)
4501// {
4502// return RValue<Int2>(Nucleus::createNeg(val.value));
4503// }
4504
4505 RValue<Int2> operator~(RValue<Int2> val)
John Bauman89401822014-05-06 15:04:28 -04004506 {
John Bauman19bac1e2014-05-06 15:23:49 -04004507 if(CPUID::supportsMMX2())
4508 {
4509 return val ^ Int2(0xFFFFFFFF, 0xFFFFFFFF);
4510 }
4511 else
4512 {
4513 return RValue<Int2>(Nucleus::createNot(val.value));
4514 }
John Bauman89401822014-05-06 15:04:28 -04004515 }
4516
Nicolas Capens45f187a2016-12-02 15:30:56 -05004517 RValue<Short4> UnpackLow(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04004518 {
John Bauman19bac1e2014-05-06 15:23:49 -04004519 if(CPUID::supportsMMX2())
4520 {
4521 return x86::punpckldq(x, y);
4522 }
4523 else
4524 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004525 int shuffle[2] = {0, 2};
4526 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04004527
Nicolas Capens45f187a2016-12-02 15:30:56 -05004528 return As<Short4>(packed);
John Bauman19bac1e2014-05-06 15:23:49 -04004529 }
John Bauman89401822014-05-06 15:04:28 -04004530 }
John Bauman66b8ab22014-05-06 15:57:45 -04004531
Nicolas Capens45f187a2016-12-02 15:30:56 -05004532 RValue<Short4> UnpackHigh(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04004533 {
John Bauman19bac1e2014-05-06 15:23:49 -04004534 if(CPUID::supportsMMX2())
4535 {
4536 return x86::punpckhdq(x, y);
4537 }
4538 else
4539 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004540 int shuffle[2] = {1, 3};
4541 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04004542
Nicolas Capens45f187a2016-12-02 15:30:56 -05004543 return As<Short4>(packed);
John Bauman19bac1e2014-05-06 15:23:49 -04004544 }
John Bauman89401822014-05-06 15:04:28 -04004545 }
4546
John Bauman19bac1e2014-05-06 15:23:49 -04004547 RValue<Int> Extract(RValue<Int2> val, int i)
John Bauman89401822014-05-06 15:04:28 -04004548 {
4549 if(false) // FIXME: LLVM does not generate optimal code
4550 {
Nicolas Capense95d5342016-09-30 11:37:28 -04004551 return RValue<Int>(Nucleus::createExtractElement(val.value, Int::getType(), i));
John Bauman89401822014-05-06 15:04:28 -04004552 }
4553 else
4554 {
4555 if(i == 0)
4556 {
Nicolas Capense95d5342016-09-30 11:37:28 -04004557 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 -04004558 }
4559 else
4560 {
4561 Int2 val2 = As<Int2>(UnpackHigh(val, val));
4562
4563 return Extract(val2, 0);
4564 }
4565 }
4566 }
4567
Nicolas Capensfff3c9b2015-05-13 23:40:44 -04004568 RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i)
4569 {
Nicolas Capensac230122016-09-20 14:30:06 -04004570 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 -04004571 }
John Bauman89401822014-05-06 15:04:28 -04004572
John Bauman19bac1e2014-05-06 15:23:49 -04004573 Type *Int2::getType()
John Bauman89401822014-05-06 15:04:28 -04004574 {
John Bauman19bac1e2014-05-06 15:23:49 -04004575 if(CPUID::supportsMMX2())
4576 {
4577 return MMX::getType();
4578 }
4579 else
4580 {
Nicolas Capensac230122016-09-20 14:30:06 -04004581 return T(VectorType::get(Int::getType(), 2));
John Bauman19bac1e2014-05-06 15:23:49 -04004582 }
John Bauman89401822014-05-06 15:04:28 -04004583 }
4584
John Bauman89401822014-05-06 15:04:28 -04004585 UInt2::UInt2(unsigned int x, unsigned int y)
4586 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04004587 int64_t constantVector[2] = {x, y};
4588 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(UInt::getType(), 2))));
John Bauman89401822014-05-06 15:04:28 -04004589
John Bauman66b8ab22014-05-06 15:57:45 -04004590 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04004591 }
4592
John Bauman19bac1e2014-05-06 15:23:49 -04004593 UInt2::UInt2(RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004594 {
John Bauman66b8ab22014-05-06 15:57:45 -04004595 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004596 }
4597
4598 UInt2::UInt2(const UInt2 &rhs)
4599 {
John Bauman66b8ab22014-05-06 15:57:45 -04004600 Value *value = rhs.loadValue();
4601 storeValue(value);
4602 }
4603
4604 UInt2::UInt2(const Reference<UInt2> &rhs)
4605 {
John Bauman66b8ab22014-05-06 15:57:45 -04004606 Value *value = rhs.loadValue();
4607 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004608 }
4609
Nicolas Capens96d4e092016-11-18 14:22:38 -05004610 RValue<UInt2> UInt2::operator=(RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004611 {
John Bauman66b8ab22014-05-06 15:57:45 -04004612 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004613
4614 return rhs;
4615 }
4616
Nicolas Capens96d4e092016-11-18 14:22:38 -05004617 RValue<UInt2> UInt2::operator=(const UInt2 &rhs)
John Bauman89401822014-05-06 15:04:28 -04004618 {
John Bauman66b8ab22014-05-06 15:57:45 -04004619 Value *value = rhs.loadValue();
4620 storeValue(value);
4621
4622 return RValue<UInt2>(value);
4623 }
4624
Nicolas Capens96d4e092016-11-18 14:22:38 -05004625 RValue<UInt2> UInt2::operator=(const Reference<UInt2> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04004626 {
4627 Value *value = rhs.loadValue();
4628 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004629
4630 return RValue<UInt2>(value);
4631 }
4632
John Bauman19bac1e2014-05-06 15:23:49 -04004633 RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004634 {
John Bauman19bac1e2014-05-06 15:23:49 -04004635 if(CPUID::supportsMMX2())
4636 {
4637 return As<UInt2>(x86::paddd(As<Int2>(lhs), As<Int2>(rhs)));
4638 }
4639 else
4640 {
4641 return RValue<UInt2>(Nucleus::createAdd(lhs.value, rhs.value));
4642 }
John Bauman89401822014-05-06 15:04:28 -04004643 }
4644
John Bauman19bac1e2014-05-06 15:23:49 -04004645 RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004646 {
John Bauman19bac1e2014-05-06 15:23:49 -04004647 if(CPUID::supportsMMX2())
4648 {
4649 return As<UInt2>(x86::psubd(As<Int2>(lhs), As<Int2>(rhs)));
4650 }
4651 else
4652 {
4653 return RValue<UInt2>(Nucleus::createSub(lhs.value, rhs.value));
4654 }
John Bauman89401822014-05-06 15:04:28 -04004655 }
4656
John Bauman19bac1e2014-05-06 15:23:49 -04004657// RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs)
4658// {
4659// return RValue<UInt2>(Nucleus::createMul(lhs.value, rhs.value));
4660// }
4661
4662// RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs)
4663// {
4664// return RValue<UInt2>(Nucleus::createUDiv(lhs.value, rhs.value));
4665// }
4666
4667// RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs)
4668// {
4669// return RValue<UInt2>(Nucleus::createURem(lhs.value, rhs.value));
4670// }
4671
4672 RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004673 {
John Bauman19bac1e2014-05-06 15:23:49 -04004674 if(CPUID::supportsMMX2())
4675 {
4676 return As<UInt2>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
4677 }
4678 else
4679 {
4680 return RValue<UInt2>(Nucleus::createAnd(lhs.value, rhs.value));
4681 }
John Bauman89401822014-05-06 15:04:28 -04004682 }
4683
John Bauman19bac1e2014-05-06 15:23:49 -04004684 RValue<UInt2> operator|(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004685 {
John Bauman19bac1e2014-05-06 15:23:49 -04004686 if(CPUID::supportsMMX2())
4687 {
4688 return As<UInt2>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
4689 }
4690 else
4691 {
4692 return RValue<UInt2>(Nucleus::createOr(lhs.value, rhs.value));
4693 }
John Bauman89401822014-05-06 15:04:28 -04004694 }
4695
John Bauman19bac1e2014-05-06 15:23:49 -04004696 RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004697 {
John Bauman19bac1e2014-05-06 15:23:49 -04004698 if(CPUID::supportsMMX2())
4699 {
4700 return As<UInt2>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
4701 }
4702 else
4703 {
4704 return RValue<UInt2>(Nucleus::createXor(lhs.value, rhs.value));
4705 }
John Bauman89401822014-05-06 15:04:28 -04004706 }
4707
John Bauman19bac1e2014-05-06 15:23:49 -04004708 RValue<UInt2> operator<<(RValue<UInt2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004709 {
4710 // return RValue<UInt2>(Nucleus::createShl(lhs.value, rhs.value));
4711
4712 return As<UInt2>(x86::pslld(As<Int2>(lhs), rhs));
4713 }
4714
John Bauman19bac1e2014-05-06 15:23:49 -04004715 RValue<UInt2> operator>>(RValue<UInt2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004716 {
4717 // return RValue<UInt2>(Nucleus::createLShr(lhs.value, rhs.value));
4718
4719 return x86::psrld(lhs, rhs);
4720 }
4721
Nicolas Capens96d4e092016-11-18 14:22:38 -05004722 RValue<UInt2> operator+=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004723 {
4724 return lhs = lhs + rhs;
4725 }
4726
Nicolas Capens96d4e092016-11-18 14:22:38 -05004727 RValue<UInt2> operator-=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004728 {
4729 return lhs = lhs - rhs;
4730 }
4731
Nicolas Capens96d4e092016-11-18 14:22:38 -05004732// RValue<UInt2> operator*=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04004733// {
4734// return lhs = lhs * rhs;
4735// }
John Bauman89401822014-05-06 15:04:28 -04004736
Nicolas Capens96d4e092016-11-18 14:22:38 -05004737// RValue<UInt2> operator/=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04004738// {
4739// return lhs = lhs / rhs;
4740// }
John Bauman89401822014-05-06 15:04:28 -04004741
Nicolas Capens96d4e092016-11-18 14:22:38 -05004742// RValue<UInt2> operator%=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04004743// {
4744// return lhs = lhs % rhs;
4745// }
John Bauman89401822014-05-06 15:04:28 -04004746
Nicolas Capens96d4e092016-11-18 14:22:38 -05004747 RValue<UInt2> operator&=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004748 {
4749 return lhs = lhs & rhs;
4750 }
4751
Nicolas Capens96d4e092016-11-18 14:22:38 -05004752 RValue<UInt2> operator|=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004753 {
4754 return lhs = lhs | rhs;
4755 }
4756
Nicolas Capens96d4e092016-11-18 14:22:38 -05004757 RValue<UInt2> operator^=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004758 {
4759 return lhs = lhs ^ rhs;
4760 }
4761
Nicolas Capens96d4e092016-11-18 14:22:38 -05004762 RValue<UInt2> operator<<=(UInt2 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004763 {
4764 return lhs = lhs << rhs;
4765 }
4766
Nicolas Capens96d4e092016-11-18 14:22:38 -05004767 RValue<UInt2> operator>>=(UInt2 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004768 {
4769 return lhs = lhs >> rhs;
4770 }
4771
John Bauman19bac1e2014-05-06 15:23:49 -04004772// RValue<UInt2> operator+(RValue<UInt2> val)
4773// {
4774// return val;
4775// }
4776
4777// RValue<UInt2> operator-(RValue<UInt2> val)
4778// {
4779// return RValue<UInt2>(Nucleus::createNeg(val.value));
4780// }
4781
4782 RValue<UInt2> operator~(RValue<UInt2> val)
John Bauman89401822014-05-06 15:04:28 -04004783 {
John Bauman19bac1e2014-05-06 15:23:49 -04004784 if(CPUID::supportsMMX2())
4785 {
4786 return val ^ UInt2(0xFFFFFFFF, 0xFFFFFFFF);
4787 }
4788 else
4789 {
4790 return RValue<UInt2>(Nucleus::createNot(val.value));
4791 }
John Bauman89401822014-05-06 15:04:28 -04004792 }
4793
John Bauman19bac1e2014-05-06 15:23:49 -04004794 Type *UInt2::getType()
John Bauman89401822014-05-06 15:04:28 -04004795 {
John Bauman19bac1e2014-05-06 15:23:49 -04004796 if(CPUID::supportsMMX2())
4797 {
4798 return MMX::getType();
4799 }
4800 else
4801 {
Nicolas Capensac230122016-09-20 14:30:06 -04004802 return T(VectorType::get(UInt::getType(), 2));
John Bauman19bac1e2014-05-06 15:23:49 -04004803 }
John Bauman89401822014-05-06 15:04:28 -04004804 }
4805
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004806 Int4::Int4(RValue<Byte4> cast)
4807 {
4808 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
Nicolas Capens19336542016-09-26 10:32:29 -04004809 Value *a = Nucleus::createInsertElement(V(UndefValue::get(Int4::getType())), x, 0);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004810
4811 Value *e;
4812
4813 if (CPUID::supportsSSE4_1())
4814 {
4815 e = x86::pmovzxbd(RValue<Int4>(a)).value;
4816 }
4817 else
4818 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004819 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 -04004820 Value *b = Nucleus::createBitCast(a, Byte16::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04004821 Value *c = Nucleus::createShuffleVector(b, V(Nucleus::createNullValue(Byte16::getType())), swizzle);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004822
Nicolas Capense89cd582016-09-30 14:23:47 -04004823 int swizzle2[8] = {0, 8, 1, 9, 2, 10, 3, 11};
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004824 Value *d = Nucleus::createBitCast(c, Short8::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04004825 e = Nucleus::createShuffleVector(d, V(Nucleus::createNullValue(Short8::getType())), swizzle2);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004826 }
4827
4828 Value *f = Nucleus::createBitCast(e, Int4::getType());
4829 storeValue(f);
4830 }
4831
4832 Int4::Int4(RValue<SByte4> cast)
4833 {
4834 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
Nicolas Capens19336542016-09-26 10:32:29 -04004835 Value *a = Nucleus::createInsertElement(V(UndefValue::get(Int4::getType())), x, 0);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004836
4837 Value *g;
4838
4839 if (CPUID::supportsSSE4_1())
4840 {
4841 g = x86::pmovsxbd(RValue<Int4>(a)).value;
4842 }
4843 else
4844 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004845 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 -04004846 Value *b = Nucleus::createBitCast(a, Byte16::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04004847 Value *c = Nucleus::createShuffleVector(b, b, swizzle);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004848
Nicolas Capense89cd582016-09-30 14:23:47 -04004849 int swizzle2[8] = {0, 0, 1, 1, 2, 2, 3, 3};
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004850 Value *d = Nucleus::createBitCast(c, Short8::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04004851 Value *e = Nucleus::createShuffleVector(d, d, swizzle2);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004852
4853 Value *f = Nucleus::createBitCast(e, Int4::getType());
4854 // g = Nucleus::createAShr(f, Nucleus::createConstantInt(24));
4855 g = x86::psrad(RValue<Int4>(f), 24).value;
4856 }
4857
4858 storeValue(g);
4859 }
4860
John Bauman19bac1e2014-05-06 15:23:49 -04004861 Int4::Int4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04004862 {
John Bauman89401822014-05-06 15:04:28 -04004863 Value *xyzw = Nucleus::createFPToSI(cast.value, Int4::getType());
John Bauman89401822014-05-06 15:04:28 -04004864
John Bauman66b8ab22014-05-06 15:57:45 -04004865 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04004866 }
4867
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004868 Int4::Int4(RValue<Short4> cast)
4869 {
Nicolas Capens22008782016-10-20 01:11:47 -04004870 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004871 Value *element = Nucleus::createBitCast(cast.value, Long::getType());
4872 long2 = Nucleus::createInsertElement(long2, element, 0);
4873 RValue<Int4> vector = RValue<Int4>(Nucleus::createBitCast(long2, Int4::getType()));
Nicolas Capens05b3d662016-02-25 23:58:33 -05004874
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004875 if(CPUID::supportsSSE4_1())
4876 {
4877 storeValue(x86::pmovsxwd(vector).value);
4878 }
4879 else
4880 {
4881 Value *b = Nucleus::createBitCast(vector.value, Short8::getType());
4882
Nicolas Capense89cd582016-09-30 14:23:47 -04004883 int swizzle[8] = {0, 0, 1, 1, 2, 2, 3, 3};
4884 Value *c = Nucleus::createShuffleVector(b, b, swizzle);
Nicolas Capens6ce5c332015-10-28 01:58:18 -04004885 Value *d = Nucleus::createBitCast(c, Int4::getType());
4886 storeValue(d);
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004887
4888 // Each Short is packed into each Int in the (Short | Short) format.
4889 // Shifting by 16 will retrieve the original Short value.
4890 // Shitfing an Int will propagate the sign bit, which will work
4891 // for both positive and negative values of a Short.
4892 *this >>= 16;
4893 }
4894 }
4895
4896 Int4::Int4(RValue<UShort4> cast)
4897 {
Nicolas Capens22008782016-10-20 01:11:47 -04004898 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004899 Value *element = Nucleus::createBitCast(cast.value, Long::getType());
4900 long2 = Nucleus::createInsertElement(long2, element, 0);
4901 RValue<Int4> vector = RValue<Int4>(Nucleus::createBitCast(long2, Int4::getType()));
4902
4903 if(CPUID::supportsSSE4_1())
4904 {
4905 storeValue(x86::pmovzxwd(RValue<Int4>(vector)).value);
4906 }
4907 else
4908 {
4909 Value *b = Nucleus::createBitCast(vector.value, Short8::getType());
4910
Nicolas Capense89cd582016-09-30 14:23:47 -04004911 int swizzle[8] = {0, 8, 1, 9, 2, 10, 3, 11};
4912 Value *c = Nucleus::createShuffleVector(b, V(Nucleus::createNullValue(Short8::getType())), swizzle);
Nicolas Capens6ce5c332015-10-28 01:58:18 -04004913 Value *d = Nucleus::createBitCast(c, Int4::getType());
4914 storeValue(d);
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004915 }
4916 }
4917
John Bauman89401822014-05-06 15:04:28 -04004918 Int4::Int4(int xyzw)
4919 {
4920 constant(xyzw, xyzw, xyzw, xyzw);
4921 }
4922
4923 Int4::Int4(int x, int yzw)
4924 {
4925 constant(x, yzw, yzw, yzw);
4926 }
4927
4928 Int4::Int4(int x, int y, int zw)
4929 {
4930 constant(x, y, zw, zw);
4931 }
4932
4933 Int4::Int4(int x, int y, int z, int w)
4934 {
4935 constant(x, y, z, w);
4936 }
4937
4938 void Int4::constant(int x, int y, int z, int w)
4939 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04004940 int64_t constantVector[4] = {x, y, z, w};
4941 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04004942 }
4943
John Bauman19bac1e2014-05-06 15:23:49 -04004944 Int4::Int4(RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04004945 {
John Bauman66b8ab22014-05-06 15:57:45 -04004946 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004947 }
4948
4949 Int4::Int4(const Int4 &rhs)
4950 {
John Bauman66b8ab22014-05-06 15:57:45 -04004951 Value *value = rhs.loadValue();
4952 storeValue(value);
4953 }
4954
4955 Int4::Int4(const Reference<Int4> &rhs)
4956 {
John Bauman66b8ab22014-05-06 15:57:45 -04004957 Value *value = rhs.loadValue();
4958 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004959 }
4960
John Bauman19bac1e2014-05-06 15:23:49 -04004961 Int4::Int4(RValue<UInt4> rhs)
4962 {
John Bauman66b8ab22014-05-06 15:57:45 -04004963 storeValue(rhs.value);
John Bauman19bac1e2014-05-06 15:23:49 -04004964 }
4965
4966 Int4::Int4(const UInt4 &rhs)
4967 {
John Bauman66b8ab22014-05-06 15:57:45 -04004968 Value *value = rhs.loadValue();
4969 storeValue(value);
4970 }
4971
4972 Int4::Int4(const Reference<UInt4> &rhs)
4973 {
John Bauman66b8ab22014-05-06 15:57:45 -04004974 Value *value = rhs.loadValue();
4975 storeValue(value);
John Bauman19bac1e2014-05-06 15:23:49 -04004976 }
4977
Nicolas Capens62abb552016-01-05 12:03:47 -05004978 Int4::Int4(RValue<Int2> lo, RValue<Int2> hi)
4979 {
4980 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
4981 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
4982
Nicolas Capens22008782016-10-20 01:11:47 -04004983 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Nicolas Capens62abb552016-01-05 12:03:47 -05004984 long2 = Nucleus::createInsertElement(long2, loLong, 0);
4985 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
4986 Value *int4 = Nucleus::createBitCast(long2, Int4::getType());
4987
4988 storeValue(int4);
4989 }
4990
Nicolas Capens24c8cf02016-08-15 15:33:14 -04004991 Int4::Int4(RValue<Int> rhs)
4992 {
Nicolas Capens24c8cf02016-08-15 15:33:14 -04004993 Value *vector = loadValue();
4994 Value *insert = Nucleus::createInsertElement(vector, rhs.value, 0);
4995
Nicolas Capense89cd582016-09-30 14:23:47 -04004996 int swizzle[4] = {0, 0, 0, 0};
4997 Value *replicate = Nucleus::createShuffleVector(insert, insert, swizzle);
Nicolas Capens24c8cf02016-08-15 15:33:14 -04004998
4999 storeValue(replicate);
5000 }
5001
5002 Int4::Int4(const Int &rhs)
5003 {
Nicolas Capens24c8cf02016-08-15 15:33:14 -04005004 *this = RValue<Int>(rhs.loadValue());
5005 }
5006
5007 Int4::Int4(const Reference<Int> &rhs)
5008 {
Nicolas Capens24c8cf02016-08-15 15:33:14 -04005009 *this = RValue<Int>(rhs.loadValue());
5010 }
5011
Nicolas Capens96d4e092016-11-18 14:22:38 -05005012 RValue<Int4> Int4::operator=(RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005013 {
John Bauman66b8ab22014-05-06 15:57:45 -04005014 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005015
5016 return rhs;
5017 }
5018
Nicolas Capens96d4e092016-11-18 14:22:38 -05005019 RValue<Int4> Int4::operator=(const Int4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04005020 {
John Bauman66b8ab22014-05-06 15:57:45 -04005021 Value *value = rhs.loadValue();
5022 storeValue(value);
5023
5024 return RValue<Int4>(value);
5025 }
5026
Nicolas Capens96d4e092016-11-18 14:22:38 -05005027 RValue<Int4> Int4::operator=(const Reference<Int4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04005028 {
5029 Value *value = rhs.loadValue();
5030 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005031
5032 return RValue<Int4>(value);
5033 }
5034
John Bauman19bac1e2014-05-06 15:23:49 -04005035 RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005036 {
5037 return RValue<Int4>(Nucleus::createAdd(lhs.value, rhs.value));
5038 }
5039
John Bauman19bac1e2014-05-06 15:23:49 -04005040 RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005041 {
5042 return RValue<Int4>(Nucleus::createSub(lhs.value, rhs.value));
5043 }
5044
John Bauman19bac1e2014-05-06 15:23:49 -04005045 RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005046 {
5047 return RValue<Int4>(Nucleus::createMul(lhs.value, rhs.value));
5048 }
5049
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005050 RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs)
5051 {
5052 return RValue<Int4>(Nucleus::createSDiv(lhs.value, rhs.value));
5053 }
John Bauman89401822014-05-06 15:04:28 -04005054
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005055 RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs)
5056 {
5057 return RValue<Int4>(Nucleus::createSRem(lhs.value, rhs.value));
5058 }
John Bauman89401822014-05-06 15:04:28 -04005059
John Bauman19bac1e2014-05-06 15:23:49 -04005060 RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005061 {
5062 return RValue<Int4>(Nucleus::createAnd(lhs.value, rhs.value));
5063 }
5064
John Bauman19bac1e2014-05-06 15:23:49 -04005065 RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005066 {
5067 return RValue<Int4>(Nucleus::createOr(lhs.value, rhs.value));
5068 }
5069
John Bauman19bac1e2014-05-06 15:23:49 -04005070 RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005071 {
5072 return RValue<Int4>(Nucleus::createXor(lhs.value, rhs.value));
5073 }
5074
John Bauman19bac1e2014-05-06 15:23:49 -04005075 RValue<Int4> operator<<(RValue<Int4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005076 {
John Bauman89401822014-05-06 15:04:28 -04005077 return x86::pslld(lhs, rhs);
5078 }
5079
John Bauman19bac1e2014-05-06 15:23:49 -04005080 RValue<Int4> operator>>(RValue<Int4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005081 {
John Bauman89401822014-05-06 15:04:28 -04005082 return x86::psrad(lhs, rhs);
5083 }
5084
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005085 RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs)
5086 {
5087 return RValue<Int4>(Nucleus::createShl(lhs.value, rhs.value));
5088 }
5089
5090 RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs)
5091 {
5092 return RValue<Int4>(Nucleus::createAShr(lhs.value, rhs.value));
5093 }
5094
Nicolas Capens96d4e092016-11-18 14:22:38 -05005095 RValue<Int4> operator+=(Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005096 {
5097 return lhs = lhs + rhs;
5098 }
5099
Nicolas Capens96d4e092016-11-18 14:22:38 -05005100 RValue<Int4> operator-=(Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005101 {
5102 return lhs = lhs - rhs;
5103 }
5104
Nicolas Capens96d4e092016-11-18 14:22:38 -05005105 RValue<Int4> operator*=(Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005106 {
5107 return lhs = lhs * rhs;
5108 }
5109
Nicolas Capens96d4e092016-11-18 14:22:38 -05005110// RValue<Int4> operator/=(Int4 &lhs, RValue<Int4> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04005111// {
5112// return lhs = lhs / rhs;
5113// }
John Bauman89401822014-05-06 15:04:28 -04005114
Nicolas Capens96d4e092016-11-18 14:22:38 -05005115// RValue<Int4> operator%=(Int4 &lhs, RValue<Int4> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04005116// {
5117// return lhs = lhs % rhs;
5118// }
John Bauman89401822014-05-06 15:04:28 -04005119
Nicolas Capens96d4e092016-11-18 14:22:38 -05005120 RValue<Int4> operator&=(Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005121 {
5122 return lhs = lhs & rhs;
5123 }
5124
Nicolas Capens96d4e092016-11-18 14:22:38 -05005125 RValue<Int4> operator|=(Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005126 {
5127 return lhs = lhs | rhs;
5128 }
5129
Nicolas Capens96d4e092016-11-18 14:22:38 -05005130 RValue<Int4> operator^=(Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005131 {
5132 return lhs = lhs ^ rhs;
5133 }
5134
Nicolas Capens96d4e092016-11-18 14:22:38 -05005135 RValue<Int4> operator<<=(Int4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005136 {
5137 return lhs = lhs << rhs;
5138 }
5139
Nicolas Capens96d4e092016-11-18 14:22:38 -05005140 RValue<Int4> operator>>=(Int4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005141 {
5142 return lhs = lhs >> rhs;
5143 }
5144
John Bauman19bac1e2014-05-06 15:23:49 -04005145 RValue<Int4> operator+(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005146 {
5147 return val;
5148 }
5149
John Bauman19bac1e2014-05-06 15:23:49 -04005150 RValue<Int4> operator-(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005151 {
5152 return RValue<Int4>(Nucleus::createNeg(val.value));
5153 }
5154
John Bauman19bac1e2014-05-06 15:23:49 -04005155 RValue<Int4> operator~(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005156 {
5157 return RValue<Int4>(Nucleus::createNot(val.value));
5158 }
5159
John Bauman19bac1e2014-05-06 15:23:49 -04005160 RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y)
5161 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005162 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
Alexis Hetufb603992016-04-26 11:50:40 -04005163 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5164 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
5165 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005166 }
5167
5168 RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y)
5169 {
5170 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLT(x.value, y.value), Int4::getType()));
5171 }
5172
5173 RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y)
5174 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005175 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5176 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5177 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLE(x.value, y.value), Int4::getType()));
5178 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGT(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005179 }
5180
5181 RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y)
5182 {
5183 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
5184 }
5185
5186 RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y)
5187 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005188 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5189 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5190 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGE(x.value, y.value), Int4::getType()));
5191 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLT(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005192 }
5193
5194 RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y)
5195 {
5196 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGT(x.value, y.value), Int4::getType()));
5197 }
5198
5199 RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y)
5200 {
5201 if(CPUID::supportsSSE4_1())
5202 {
5203 return x86::pmaxsd(x, y);
5204 }
5205 else
5206 {
5207 RValue<Int4> greater = CmpNLE(x, y);
5208 return x & greater | y & ~greater;
5209 }
5210 }
5211
5212 RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y)
5213 {
5214 if(CPUID::supportsSSE4_1())
5215 {
5216 return x86::pminsd(x, y);
5217 }
5218 else
5219 {
5220 RValue<Int4> less = CmpLT(x, y);
5221 return x & less | y & ~less;
5222 }
5223 }
5224
5225 RValue<Int4> RoundInt(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005226 {
5227 return x86::cvtps2dq(cast);
5228 }
5229
John Bauman19bac1e2014-05-06 15:23:49 -04005230 RValue<Short8> Pack(RValue<Int4> x, RValue<Int4> y)
John Bauman89401822014-05-06 15:04:28 -04005231 {
5232 return x86::packssdw(x, y);
5233 }
5234
John Bauman19bac1e2014-05-06 15:23:49 -04005235 RValue<Int> Extract(RValue<Int4> x, int i)
John Bauman89401822014-05-06 15:04:28 -04005236 {
Nicolas Capense95d5342016-09-30 11:37:28 -04005237 return RValue<Int>(Nucleus::createExtractElement(x.value, Int::getType(), i));
John Bauman89401822014-05-06 15:04:28 -04005238 }
5239
John Bauman19bac1e2014-05-06 15:23:49 -04005240 RValue<Int4> Insert(RValue<Int4> x, RValue<Int> element, int i)
John Bauman89401822014-05-06 15:04:28 -04005241 {
5242 return RValue<Int4>(Nucleus::createInsertElement(x.value, element.value, i));
5243 }
5244
John Bauman19bac1e2014-05-06 15:23:49 -04005245 RValue<Int> SignMask(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04005246 {
5247 return x86::movmskps(As<Float4>(x));
5248 }
5249
John Bauman19bac1e2014-05-06 15:23:49 -04005250 RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04005251 {
Nicolas Capense95d5342016-09-30 11:37:28 -04005252 return RValue<Int4>(createSwizzle4(x.value, select));
John Bauman89401822014-05-06 15:04:28 -04005253 }
5254
John Bauman19bac1e2014-05-06 15:23:49 -04005255 Type *Int4::getType()
John Bauman89401822014-05-06 15:04:28 -04005256 {
Nicolas Capensac230122016-09-20 14:30:06 -04005257 return T(VectorType::get(Int::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04005258 }
5259
John Bauman19bac1e2014-05-06 15:23:49 -04005260 UInt4::UInt4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005261 {
Alexis Hetu764d1422016-09-28 08:44:22 -04005262 // Note: createFPToUI is broken, must perform conversion using createFPtoSI
5263 // Value *xyzw = Nucleus::createFPToUI(cast.value, UInt4::getType());
John Bauman89401822014-05-06 15:04:28 -04005264
Alexis Hetu764d1422016-09-28 08:44:22 -04005265 // Smallest positive value representable in UInt, but not in Int
5266 const unsigned int ustart = 0x80000000u;
5267 const float ustartf = float(ustart);
5268
5269 // Check if the value can be represented as an Int
5270 Int4 uiValue = CmpNLT(cast, Float4(ustartf));
5271 // If the value is too large, subtract ustart and re-add it after conversion.
5272 uiValue = (uiValue & As<Int4>(As<UInt4>(Int4(cast - Float4(ustartf))) + UInt4(ustart))) |
5273 // Otherwise, just convert normally
5274 (~uiValue & Int4(cast));
5275 // If the value is negative, store 0, otherwise store the result of the conversion
5276 storeValue((~(As<Int4>(cast) >> 31) & uiValue).value);
John Bauman89401822014-05-06 15:04:28 -04005277 }
5278
John Bauman19bac1e2014-05-06 15:23:49 -04005279 UInt4::UInt4(int xyzw)
5280 {
5281 constant(xyzw, xyzw, xyzw, xyzw);
5282 }
5283
5284 UInt4::UInt4(int x, int yzw)
5285 {
5286 constant(x, yzw, yzw, yzw);
5287 }
5288
5289 UInt4::UInt4(int x, int y, int zw)
5290 {
5291 constant(x, y, zw, zw);
5292 }
5293
5294 UInt4::UInt4(int x, int y, int z, int w)
5295 {
5296 constant(x, y, z, w);
5297 }
5298
5299 void UInt4::constant(int x, int y, int z, int w)
John Bauman89401822014-05-06 15:04:28 -04005300 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04005301 int64_t constantVector[4] = {x, y, z, w};
5302 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04005303 }
5304
John Bauman19bac1e2014-05-06 15:23:49 -04005305 UInt4::UInt4(RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005306 {
John Bauman66b8ab22014-05-06 15:57:45 -04005307 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005308 }
5309
5310 UInt4::UInt4(const UInt4 &rhs)
5311 {
John Bauman66b8ab22014-05-06 15:57:45 -04005312 Value *value = rhs.loadValue();
5313 storeValue(value);
5314 }
5315
5316 UInt4::UInt4(const Reference<UInt4> &rhs)
5317 {
John Bauman66b8ab22014-05-06 15:57:45 -04005318 Value *value = rhs.loadValue();
5319 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005320 }
5321
John Bauman19bac1e2014-05-06 15:23:49 -04005322 UInt4::UInt4(RValue<Int4> rhs)
5323 {
John Bauman66b8ab22014-05-06 15:57:45 -04005324 storeValue(rhs.value);
John Bauman19bac1e2014-05-06 15:23:49 -04005325 }
5326
5327 UInt4::UInt4(const Int4 &rhs)
5328 {
John Bauman66b8ab22014-05-06 15:57:45 -04005329 Value *value = rhs.loadValue();
5330 storeValue(value);
5331 }
5332
5333 UInt4::UInt4(const Reference<Int4> &rhs)
5334 {
John Bauman66b8ab22014-05-06 15:57:45 -04005335 Value *value = rhs.loadValue();
5336 storeValue(value);
John Bauman19bac1e2014-05-06 15:23:49 -04005337 }
5338
Nicolas Capens62abb552016-01-05 12:03:47 -05005339 UInt4::UInt4(RValue<UInt2> lo, RValue<UInt2> hi)
5340 {
5341 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
5342 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
5343
Nicolas Capens22008782016-10-20 01:11:47 -04005344 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Nicolas Capens62abb552016-01-05 12:03:47 -05005345 long2 = Nucleus::createInsertElement(long2, loLong, 0);
5346 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
5347 Value *uint4 = Nucleus::createBitCast(long2, Int4::getType());
5348
5349 storeValue(uint4);
5350 }
5351
Nicolas Capens96d4e092016-11-18 14:22:38 -05005352 RValue<UInt4> UInt4::operator=(RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005353 {
John Bauman66b8ab22014-05-06 15:57:45 -04005354 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005355
5356 return rhs;
5357 }
5358
Nicolas Capens96d4e092016-11-18 14:22:38 -05005359 RValue<UInt4> UInt4::operator=(const UInt4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04005360 {
John Bauman66b8ab22014-05-06 15:57:45 -04005361 Value *value = rhs.loadValue();
5362 storeValue(value);
5363
5364 return RValue<UInt4>(value);
5365 }
5366
Nicolas Capens96d4e092016-11-18 14:22:38 -05005367 RValue<UInt4> UInt4::operator=(const Reference<UInt4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04005368 {
5369 Value *value = rhs.loadValue();
5370 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005371
5372 return RValue<UInt4>(value);
5373 }
5374
John Bauman19bac1e2014-05-06 15:23:49 -04005375 RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005376 {
5377 return RValue<UInt4>(Nucleus::createAdd(lhs.value, rhs.value));
5378 }
5379
John Bauman19bac1e2014-05-06 15:23:49 -04005380 RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005381 {
5382 return RValue<UInt4>(Nucleus::createSub(lhs.value, rhs.value));
5383 }
5384
John Bauman19bac1e2014-05-06 15:23:49 -04005385 RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005386 {
5387 return RValue<UInt4>(Nucleus::createMul(lhs.value, rhs.value));
5388 }
5389
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005390 RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs)
5391 {
5392 return RValue<UInt4>(Nucleus::createUDiv(lhs.value, rhs.value));
5393 }
John Bauman89401822014-05-06 15:04:28 -04005394
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005395 RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs)
5396 {
5397 return RValue<UInt4>(Nucleus::createURem(lhs.value, rhs.value));
5398 }
John Bauman89401822014-05-06 15:04:28 -04005399
John Bauman19bac1e2014-05-06 15:23:49 -04005400 RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005401 {
5402 return RValue<UInt4>(Nucleus::createAnd(lhs.value, rhs.value));
5403 }
5404
John Bauman19bac1e2014-05-06 15:23:49 -04005405 RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005406 {
5407 return RValue<UInt4>(Nucleus::createOr(lhs.value, rhs.value));
5408 }
5409
John Bauman19bac1e2014-05-06 15:23:49 -04005410 RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005411 {
5412 return RValue<UInt4>(Nucleus::createXor(lhs.value, rhs.value));
5413 }
5414
John Bauman19bac1e2014-05-06 15:23:49 -04005415 RValue<UInt4> operator<<(RValue<UInt4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005416 {
John Bauman89401822014-05-06 15:04:28 -04005417 return As<UInt4>(x86::pslld(As<Int4>(lhs), rhs));
5418 }
5419
John Bauman19bac1e2014-05-06 15:23:49 -04005420 RValue<UInt4> operator>>(RValue<UInt4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005421 {
John Bauman89401822014-05-06 15:04:28 -04005422 return x86::psrld(lhs, rhs);
5423 }
5424
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005425 RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs)
5426 {
5427 return RValue<UInt4>(Nucleus::createShl(lhs.value, rhs.value));
5428 }
5429
5430 RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs)
5431 {
5432 return RValue<UInt4>(Nucleus::createLShr(lhs.value, rhs.value));
5433 }
5434
Nicolas Capens96d4e092016-11-18 14:22:38 -05005435 RValue<UInt4> operator+=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005436 {
5437 return lhs = lhs + rhs;
5438 }
5439
Nicolas Capens96d4e092016-11-18 14:22:38 -05005440 RValue<UInt4> operator-=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005441 {
5442 return lhs = lhs - rhs;
5443 }
5444
Nicolas Capens96d4e092016-11-18 14:22:38 -05005445 RValue<UInt4> operator*=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005446 {
5447 return lhs = lhs * rhs;
5448 }
5449
Nicolas Capens96d4e092016-11-18 14:22:38 -05005450// RValue<UInt4> operator/=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04005451// {
5452// return lhs = lhs / rhs;
5453// }
John Bauman89401822014-05-06 15:04:28 -04005454
Nicolas Capens96d4e092016-11-18 14:22:38 -05005455// RValue<UInt4> operator%=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04005456// {
5457// return lhs = lhs % rhs;
5458// }
John Bauman89401822014-05-06 15:04:28 -04005459
Nicolas Capens96d4e092016-11-18 14:22:38 -05005460 RValue<UInt4> operator&=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005461 {
5462 return lhs = lhs & rhs;
5463 }
5464
Nicolas Capens96d4e092016-11-18 14:22:38 -05005465 RValue<UInt4> operator|=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005466 {
5467 return lhs = lhs | rhs;
5468 }
5469
Nicolas Capens96d4e092016-11-18 14:22:38 -05005470 RValue<UInt4> operator^=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005471 {
5472 return lhs = lhs ^ rhs;
5473 }
5474
Nicolas Capens96d4e092016-11-18 14:22:38 -05005475 RValue<UInt4> operator<<=(UInt4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005476 {
5477 return lhs = lhs << rhs;
5478 }
5479
Nicolas Capens96d4e092016-11-18 14:22:38 -05005480 RValue<UInt4> operator>>=(UInt4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005481 {
5482 return lhs = lhs >> rhs;
5483 }
5484
John Bauman19bac1e2014-05-06 15:23:49 -04005485 RValue<UInt4> operator+(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04005486 {
5487 return val;
5488 }
5489
John Bauman19bac1e2014-05-06 15:23:49 -04005490 RValue<UInt4> operator-(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04005491 {
5492 return RValue<UInt4>(Nucleus::createNeg(val.value));
5493 }
5494
John Bauman19bac1e2014-05-06 15:23:49 -04005495 RValue<UInt4> operator~(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04005496 {
5497 return RValue<UInt4>(Nucleus::createNot(val.value));
5498 }
5499
John Bauman19bac1e2014-05-06 15:23:49 -04005500 RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y)
5501 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005502 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
Alexis Hetufb603992016-04-26 11:50:40 -04005503 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5504 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
5505 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005506 }
5507
5508 RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y)
5509 {
5510 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULT(x.value, y.value), Int4::getType()));
5511 }
5512
5513 RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y)
5514 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005515 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5516 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5517 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULE(x.value, y.value), Int4::getType()));
5518 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGT(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005519 }
5520
5521 RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y)
5522 {
5523 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
5524 }
5525
5526 RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y)
5527 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005528 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5529 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5530 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGE(x.value, y.value), Int4::getType()));
5531 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULT(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005532 }
5533
5534 RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y)
5535 {
5536 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGT(x.value, y.value), Int4::getType()));
5537 }
5538
5539 RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y)
5540 {
5541 if(CPUID::supportsSSE4_1())
5542 {
5543 return x86::pmaxud(x, y);
5544 }
5545 else
5546 {
5547 RValue<UInt4> greater = CmpNLE(x, y);
5548 return x & greater | y & ~greater;
5549 }
5550 }
5551
5552 RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y)
5553 {
5554 if(CPUID::supportsSSE4_1())
5555 {
5556 return x86::pminud(x, y);
5557 }
5558 else
5559 {
5560 RValue<UInt4> less = CmpLT(x, y);
5561 return x & less | y & ~less;
5562 }
5563 }
5564
5565 RValue<UShort8> Pack(RValue<UInt4> x, RValue<UInt4> y)
John Bauman89401822014-05-06 15:04:28 -04005566 {
Nicolas Capens3e7062b2017-01-17 14:01:33 -05005567 return x86::packusdw(As<Int4>(x), As<Int4>(y));
John Bauman89401822014-05-06 15:04:28 -04005568 }
5569
John Bauman19bac1e2014-05-06 15:23:49 -04005570 Type *UInt4::getType()
John Bauman89401822014-05-06 15:04:28 -04005571 {
Nicolas Capensac230122016-09-20 14:30:06 -04005572 return T(VectorType::get(UInt::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04005573 }
5574
John Bauman19bac1e2014-05-06 15:23:49 -04005575 Float::Float(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04005576 {
John Bauman89401822014-05-06 15:04:28 -04005577 Value *integer = Nucleus::createSIToFP(cast.value, Float::getType());
5578
John Bauman66b8ab22014-05-06 15:57:45 -04005579 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04005580 }
5581
John Bauman89401822014-05-06 15:04:28 -04005582 Float::Float(float x)
5583 {
John Bauman66b8ab22014-05-06 15:57:45 -04005584 storeValue(Nucleus::createConstantFloat(x));
John Bauman89401822014-05-06 15:04:28 -04005585 }
5586
John Bauman19bac1e2014-05-06 15:23:49 -04005587 Float::Float(RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005588 {
John Bauman66b8ab22014-05-06 15:57:45 -04005589 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005590 }
5591
5592 Float::Float(const Float &rhs)
5593 {
John Bauman66b8ab22014-05-06 15:57:45 -04005594 Value *value = rhs.loadValue();
5595 storeValue(value);
5596 }
John Bauman89401822014-05-06 15:04:28 -04005597
John Bauman66b8ab22014-05-06 15:57:45 -04005598 Float::Float(const Reference<Float> &rhs)
5599 {
5600 Value *value = rhs.loadValue();
5601 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005602 }
5603
Nicolas Capens96d4e092016-11-18 14:22:38 -05005604 RValue<Float> Float::operator=(RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005605 {
John Bauman66b8ab22014-05-06 15:57:45 -04005606 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005607
5608 return rhs;
5609 }
5610
Nicolas Capens96d4e092016-11-18 14:22:38 -05005611 RValue<Float> Float::operator=(const Float &rhs)
John Bauman89401822014-05-06 15:04:28 -04005612 {
John Bauman66b8ab22014-05-06 15:57:45 -04005613 Value *value = rhs.loadValue();
5614 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005615
5616 return RValue<Float>(value);
5617 }
5618
Nicolas Capens96d4e092016-11-18 14:22:38 -05005619 RValue<Float> Float::operator=(const Reference<Float> &rhs)
John Bauman89401822014-05-06 15:04:28 -04005620 {
John Bauman66b8ab22014-05-06 15:57:45 -04005621 Value *value = rhs.loadValue();
5622 storeValue(value);
5623
5624 return RValue<Float>(value);
John Bauman89401822014-05-06 15:04:28 -04005625 }
5626
John Bauman19bac1e2014-05-06 15:23:49 -04005627 RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005628 {
5629 return RValue<Float>(Nucleus::createFAdd(lhs.value, rhs.value));
5630 }
5631
John Bauman19bac1e2014-05-06 15:23:49 -04005632 RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005633 {
5634 return RValue<Float>(Nucleus::createFSub(lhs.value, rhs.value));
5635 }
5636
John Bauman19bac1e2014-05-06 15:23:49 -04005637 RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005638 {
5639 return RValue<Float>(Nucleus::createFMul(lhs.value, rhs.value));
5640 }
5641
John Bauman19bac1e2014-05-06 15:23:49 -04005642 RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005643 {
5644 return RValue<Float>(Nucleus::createFDiv(lhs.value, rhs.value));
5645 }
5646
Nicolas Capens96d4e092016-11-18 14:22:38 -05005647 RValue<Float> operator+=(Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005648 {
5649 return lhs = lhs + rhs;
5650 }
5651
Nicolas Capens96d4e092016-11-18 14:22:38 -05005652 RValue<Float> operator-=(Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005653 {
5654 return lhs = lhs - rhs;
5655 }
5656
Nicolas Capens96d4e092016-11-18 14:22:38 -05005657 RValue<Float> operator*=(Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005658 {
5659 return lhs = lhs * rhs;
5660 }
5661
Nicolas Capens96d4e092016-11-18 14:22:38 -05005662 RValue<Float> operator/=(Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005663 {
5664 return lhs = lhs / rhs;
5665 }
5666
John Bauman19bac1e2014-05-06 15:23:49 -04005667 RValue<Float> operator+(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04005668 {
5669 return val;
5670 }
5671
John Bauman19bac1e2014-05-06 15:23:49 -04005672 RValue<Float> operator-(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04005673 {
5674 return RValue<Float>(Nucleus::createFNeg(val.value));
5675 }
5676
John Bauman19bac1e2014-05-06 15:23:49 -04005677 RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005678 {
5679 return RValue<Bool>(Nucleus::createFCmpOLT(lhs.value, rhs.value));
5680 }
5681
John Bauman19bac1e2014-05-06 15:23:49 -04005682 RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005683 {
5684 return RValue<Bool>(Nucleus::createFCmpOLE(lhs.value, rhs.value));
5685 }
5686
John Bauman19bac1e2014-05-06 15:23:49 -04005687 RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005688 {
5689 return RValue<Bool>(Nucleus::createFCmpOGT(lhs.value, rhs.value));
5690 }
5691
John Bauman19bac1e2014-05-06 15:23:49 -04005692 RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005693 {
5694 return RValue<Bool>(Nucleus::createFCmpOGE(lhs.value, rhs.value));
5695 }
5696
John Bauman19bac1e2014-05-06 15:23:49 -04005697 RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005698 {
5699 return RValue<Bool>(Nucleus::createFCmpONE(lhs.value, rhs.value));
5700 }
5701
John Bauman19bac1e2014-05-06 15:23:49 -04005702 RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005703 {
5704 return RValue<Bool>(Nucleus::createFCmpOEQ(lhs.value, rhs.value));
5705 }
5706
John Bauman19bac1e2014-05-06 15:23:49 -04005707 RValue<Float> Abs(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04005708 {
John Bauman66b8ab22014-05-06 15:57:45 -04005709 return IfThenElse(x > 0.0f, x, -x);
John Bauman89401822014-05-06 15:04:28 -04005710 }
5711
John Bauman19bac1e2014-05-06 15:23:49 -04005712 RValue<Float> Max(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04005713 {
5714 return IfThenElse(x > y, x, y);
5715 }
5716
John Bauman19bac1e2014-05-06 15:23:49 -04005717 RValue<Float> Min(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04005718 {
5719 return IfThenElse(x < y, x, y);
5720 }
5721
Nicolas Capens05b3d662016-02-25 23:58:33 -05005722 RValue<Float> Rcp_pp(RValue<Float> x, bool exactAtPow2)
John Bauman89401822014-05-06 15:04:28 -04005723 {
Nicolas Capens05b3d662016-02-25 23:58:33 -05005724 if(exactAtPow2)
5725 {
5726 // rcpss uses a piecewise-linear approximation which minimizes the relative error
5727 // but is not exact at power-of-two values. Rectify by multiplying by the inverse.
5728 return x86::rcpss(x) * Float(1.0f / _mm_cvtss_f32(_mm_rcp_ss(_mm_set_ps1(1.0f))));
5729 }
5730 else
5731 {
5732 return x86::rcpss(x);
5733 }
John Bauman89401822014-05-06 15:04:28 -04005734 }
John Bauman66b8ab22014-05-06 15:57:45 -04005735
John Bauman19bac1e2014-05-06 15:23:49 -04005736 RValue<Float> RcpSqrt_pp(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04005737 {
5738 return x86::rsqrtss(x);
5739 }
5740
John Bauman19bac1e2014-05-06 15:23:49 -04005741 RValue<Float> Sqrt(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04005742 {
5743 return x86::sqrtss(x);
5744 }
5745
John Bauman19bac1e2014-05-06 15:23:49 -04005746 RValue<Float> Round(RValue<Float> x)
5747 {
5748 if(CPUID::supportsSSE4_1())
5749 {
5750 return x86::roundss(x, 0);
5751 }
5752 else
5753 {
5754 return Float4(Round(Float4(x))).x;
5755 }
5756 }
5757
5758 RValue<Float> Trunc(RValue<Float> x)
5759 {
5760 if(CPUID::supportsSSE4_1())
5761 {
5762 return x86::roundss(x, 3);
5763 }
5764 else
5765 {
5766 return Float(Int(x)); // Rounded toward zero
5767 }
5768 }
5769
5770 RValue<Float> Frac(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04005771 {
5772 if(CPUID::supportsSSE4_1())
5773 {
5774 return x - x86::floorss(x);
5775 }
5776 else
5777 {
John Bauman19bac1e2014-05-06 15:23:49 -04005778 return Float4(Frac(Float4(x))).x;
John Bauman89401822014-05-06 15:04:28 -04005779 }
5780 }
5781
John Bauman19bac1e2014-05-06 15:23:49 -04005782 RValue<Float> Floor(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04005783 {
5784 if(CPUID::supportsSSE4_1())
5785 {
5786 return x86::floorss(x);
5787 }
5788 else
5789 {
5790 return Float4(Floor(Float4(x))).x;
5791 }
5792 }
5793
John Bauman19bac1e2014-05-06 15:23:49 -04005794 RValue<Float> Ceil(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04005795 {
John Bauman19bac1e2014-05-06 15:23:49 -04005796 if(CPUID::supportsSSE4_1())
5797 {
5798 return x86::ceilss(x);
5799 }
5800 else
5801 {
5802 return Float4(Ceil(Float4(x))).x;
5803 }
John Bauman89401822014-05-06 15:04:28 -04005804 }
5805
John Bauman19bac1e2014-05-06 15:23:49 -04005806 Type *Float::getType()
John Bauman89401822014-05-06 15:04:28 -04005807 {
Nicolas Capensac230122016-09-20 14:30:06 -04005808 return T(llvm::Type::getFloatTy(*::context));
John Bauman89401822014-05-06 15:04:28 -04005809 }
5810
John Bauman19bac1e2014-05-06 15:23:49 -04005811 Float2::Float2(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005812 {
Nicolas Capens22008782016-10-20 01:11:47 -04005813 Value *int64x2 = Nucleus::createBitCast(cast.value, T(VectorType::get(Long::getType(), 2)));
Nicolas Capense95d5342016-09-30 11:37:28 -04005814 Value *int64 = Nucleus::createExtractElement(int64x2, Long::getType(), 0);
John Bauman89401822014-05-06 15:04:28 -04005815 Value *float2 = Nucleus::createBitCast(int64, Float2::getType());
5816
John Bauman66b8ab22014-05-06 15:57:45 -04005817 storeValue(float2);
John Bauman89401822014-05-06 15:04:28 -04005818 }
5819
John Bauman19bac1e2014-05-06 15:23:49 -04005820 Type *Float2::getType()
John Bauman89401822014-05-06 15:04:28 -04005821 {
Nicolas Capensac230122016-09-20 14:30:06 -04005822 return T(VectorType::get(Float::getType(), 2));
John Bauman89401822014-05-06 15:04:28 -04005823 }
5824
Nicolas Capensa25311a2017-01-16 17:19:00 -05005825 Float4::Float4(RValue<Byte4> cast) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005826 {
John Bauman89401822014-05-06 15:04:28 -04005827 #if 0
5828 Value *xyzw = Nucleus::createUIToFP(cast.value, Float4::getType()); // FIXME: Crashes
5829 #elif 0
John Bauman66b8ab22014-05-06 15:57:45 -04005830 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04005831
5832 Value *i8x = Nucleus::createExtractElement(cast.value, 0);
5833 Value *f32x = Nucleus::createUIToFP(i8x, Float::getType());
5834 Value *x = Nucleus::createInsertElement(vector, f32x, 0);
5835
Nicolas Capens19336542016-09-26 10:32:29 -04005836 Value *i8y = Nucleus::createExtractElement(cast.value, V(Nucleus::createConstantInt(1)));
John Bauman89401822014-05-06 15:04:28 -04005837 Value *f32y = Nucleus::createUIToFP(i8y, Float::getType());
Nicolas Capens19336542016-09-26 10:32:29 -04005838 Value *xy = Nucleus::createInsertElement(x, f32y, V(Nucleus::createConstantInt(1)));
John Bauman89401822014-05-06 15:04:28 -04005839
5840 Value *i8z = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(2));
5841 Value *f32z = Nucleus::createUIToFP(i8z, Float::getType());
5842 Value *xyz = Nucleus::createInsertElement(xy, f32z, Nucleus::createConstantInt(2));
5843
5844 Value *i8w = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(3));
5845 Value *f32w = Nucleus::createUIToFP(i8w, Float::getType());
5846 Value *xyzw = Nucleus::createInsertElement(xyz, f32w, Nucleus::createConstantInt(3));
5847 #else
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005848 Value *a = Int4(cast).loadValue();
5849 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04005850 #endif
John Bauman66b8ab22014-05-06 15:57:45 -04005851
5852 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04005853 }
5854
Nicolas Capensa25311a2017-01-16 17:19:00 -05005855 Float4::Float4(RValue<SByte4> cast) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005856 {
John Bauman89401822014-05-06 15:04:28 -04005857 #if 0
5858 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType()); // FIXME: Crashes
5859 #elif 0
John Bauman66b8ab22014-05-06 15:57:45 -04005860 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04005861
5862 Value *i8x = Nucleus::createExtractElement(cast.value, 0);
5863 Value *f32x = Nucleus::createSIToFP(i8x, Float::getType());
5864 Value *x = Nucleus::createInsertElement(vector, f32x, 0);
5865
Nicolas Capens19336542016-09-26 10:32:29 -04005866 Value *i8y = Nucleus::createExtractElement(cast.value, V(Nucleus::createConstantInt(1)));
John Bauman89401822014-05-06 15:04:28 -04005867 Value *f32y = Nucleus::createSIToFP(i8y, Float::getType());
Nicolas Capens19336542016-09-26 10:32:29 -04005868 Value *xy = Nucleus::createInsertElement(x, f32y, V(Nucleus::createConstantInt(1)));
John Bauman89401822014-05-06 15:04:28 -04005869
5870 Value *i8z = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(2));
5871 Value *f32z = Nucleus::createSIToFP(i8z, Float::getType());
5872 Value *xyz = Nucleus::createInsertElement(xy, f32z, Nucleus::createConstantInt(2));
5873
5874 Value *i8w = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(3));
5875 Value *f32w = Nucleus::createSIToFP(i8w, Float::getType());
5876 Value *xyzw = Nucleus::createInsertElement(xyz, f32w, Nucleus::createConstantInt(3));
5877 #else
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005878 Value *a = Int4(cast).loadValue();
5879 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04005880 #endif
John Bauman66b8ab22014-05-06 15:57:45 -04005881
5882 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04005883 }
5884
Nicolas Capensa25311a2017-01-16 17:19:00 -05005885 Float4::Float4(RValue<Short4> cast) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005886 {
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005887 Int4 c(cast);
5888 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
John Bauman89401822014-05-06 15:04:28 -04005889 }
5890
Nicolas Capensa25311a2017-01-16 17:19:00 -05005891 Float4::Float4(RValue<UShort4> cast) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005892 {
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005893 Int4 c(cast);
5894 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
John Bauman89401822014-05-06 15:04:28 -04005895 }
5896
Nicolas Capensa25311a2017-01-16 17:19:00 -05005897 Float4::Float4(RValue<Int4> cast) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005898 {
John Bauman89401822014-05-06 15:04:28 -04005899 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04005900
John Bauman66b8ab22014-05-06 15:57:45 -04005901 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04005902 }
5903
Nicolas Capensa25311a2017-01-16 17:19:00 -05005904 Float4::Float4(RValue<UInt4> cast) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005905 {
Nicolas Capens96445fe2016-12-15 14:45:13 -05005906 RValue<Float4> result = Float4(Int4(cast & UInt4(0x7FFFFFFF))) +
5907 As<Float4>((As<Int4>(cast) >> 31) & As<Int4>(Float4(0x80000000u)));
John Bauman89401822014-05-06 15:04:28 -04005908
Nicolas Capens96445fe2016-12-15 14:45:13 -05005909 storeValue(result.value);
John Bauman89401822014-05-06 15:04:28 -04005910 }
5911
Nicolas Capensa25311a2017-01-16 17:19:00 -05005912 Float4::Float4() : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005913 {
John Bauman89401822014-05-06 15:04:28 -04005914 }
John Bauman66b8ab22014-05-06 15:57:45 -04005915
Nicolas Capensa25311a2017-01-16 17:19:00 -05005916 Float4::Float4(float xyzw) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005917 {
5918 constant(xyzw, xyzw, xyzw, xyzw);
5919 }
5920
Nicolas Capensa25311a2017-01-16 17:19:00 -05005921 Float4::Float4(float x, float yzw) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005922 {
5923 constant(x, yzw, yzw, yzw);
5924 }
5925
Nicolas Capensa25311a2017-01-16 17:19:00 -05005926 Float4::Float4(float x, float y, float zw) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005927 {
5928 constant(x, y, zw, zw);
5929 }
5930
Nicolas Capensa25311a2017-01-16 17:19:00 -05005931 Float4::Float4(float x, float y, float z, float w) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005932 {
5933 constant(x, y, z, w);
5934 }
5935
5936 void Float4::constant(float x, float y, float z, float w)
5937 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04005938 double constantVector[4] = {x, y, z, w};
5939 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04005940 }
5941
Nicolas Capensa25311a2017-01-16 17:19:00 -05005942 Float4::Float4(RValue<Float4> rhs) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005943 {
John Bauman66b8ab22014-05-06 15:57:45 -04005944 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005945 }
5946
Nicolas Capensa25311a2017-01-16 17:19:00 -05005947 Float4::Float4(const Float4 &rhs) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005948 {
John Bauman66b8ab22014-05-06 15:57:45 -04005949 Value *value = rhs.loadValue();
5950 storeValue(value);
5951 }
5952
Nicolas Capensa25311a2017-01-16 17:19:00 -05005953 Float4::Float4(const Reference<Float4> &rhs) : FloatXYZW(this)
John Bauman66b8ab22014-05-06 15:57:45 -04005954 {
John Bauman66b8ab22014-05-06 15:57:45 -04005955 Value *value = rhs.loadValue();
5956 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005957 }
5958
Nicolas Capensa25311a2017-01-16 17:19:00 -05005959 Float4::Float4(RValue<Float> rhs) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005960 {
John Bauman66b8ab22014-05-06 15:57:45 -04005961 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04005962 Value *insert = Nucleus::createInsertElement(vector, rhs.value, 0);
5963
Nicolas Capense89cd582016-09-30 14:23:47 -04005964 int swizzle[4] = {0, 0, 0, 0};
5965 Value *replicate = Nucleus::createShuffleVector(insert, insert, swizzle);
John Bauman89401822014-05-06 15:04:28 -04005966
John Bauman66b8ab22014-05-06 15:57:45 -04005967 storeValue(replicate);
John Bauman89401822014-05-06 15:04:28 -04005968 }
5969
Nicolas Capensa25311a2017-01-16 17:19:00 -05005970 Float4::Float4(const Float &rhs) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005971 {
John Bauman66b8ab22014-05-06 15:57:45 -04005972 *this = RValue<Float>(rhs.loadValue());
5973 }
John Bauman89401822014-05-06 15:04:28 -04005974
Nicolas Capensa25311a2017-01-16 17:19:00 -05005975 Float4::Float4(const Reference<Float> &rhs) : FloatXYZW(this)
John Bauman66b8ab22014-05-06 15:57:45 -04005976 {
John Bauman66b8ab22014-05-06 15:57:45 -04005977 *this = RValue<Float>(rhs.loadValue());
John Bauman89401822014-05-06 15:04:28 -04005978 }
5979
Nicolas Capens96d4e092016-11-18 14:22:38 -05005980 RValue<Float4> Float4::operator=(float x)
John Bauman89401822014-05-06 15:04:28 -04005981 {
5982 return *this = Float4(x, x, x, x);
5983 }
5984
Nicolas Capens96d4e092016-11-18 14:22:38 -05005985 RValue<Float4> Float4::operator=(RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005986 {
John Bauman66b8ab22014-05-06 15:57:45 -04005987 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005988
5989 return rhs;
5990 }
5991
Nicolas Capens96d4e092016-11-18 14:22:38 -05005992 RValue<Float4> Float4::operator=(const Float4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04005993 {
John Bauman66b8ab22014-05-06 15:57:45 -04005994 Value *value = rhs.loadValue();
5995 storeValue(value);
5996
5997 return RValue<Float4>(value);
5998 }
5999
Nicolas Capens96d4e092016-11-18 14:22:38 -05006000 RValue<Float4> Float4::operator=(const Reference<Float4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04006001 {
6002 Value *value = rhs.loadValue();
6003 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04006004
6005 return RValue<Float4>(value);
6006 }
6007
Nicolas Capens96d4e092016-11-18 14:22:38 -05006008 RValue<Float4> Float4::operator=(RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006009 {
6010 return *this = Float4(rhs);
6011 }
6012
Nicolas Capens96d4e092016-11-18 14:22:38 -05006013 RValue<Float4> Float4::operator=(const Float &rhs)
John Bauman89401822014-05-06 15:04:28 -04006014 {
6015 return *this = Float4(rhs);
6016 }
6017
Nicolas Capens96d4e092016-11-18 14:22:38 -05006018 RValue<Float4> Float4::operator=(const Reference<Float> &rhs)
John Bauman89401822014-05-06 15:04:28 -04006019 {
John Bauman66b8ab22014-05-06 15:57:45 -04006020 return *this = Float4(rhs);
John Bauman89401822014-05-06 15:04:28 -04006021 }
6022
John Bauman19bac1e2014-05-06 15:23:49 -04006023 RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006024 {
6025 return RValue<Float4>(Nucleus::createFAdd(lhs.value, rhs.value));
6026 }
6027
John Bauman19bac1e2014-05-06 15:23:49 -04006028 RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006029 {
6030 return RValue<Float4>(Nucleus::createFSub(lhs.value, rhs.value));
6031 }
6032
John Bauman19bac1e2014-05-06 15:23:49 -04006033 RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006034 {
6035 return RValue<Float4>(Nucleus::createFMul(lhs.value, rhs.value));
6036 }
6037
John Bauman19bac1e2014-05-06 15:23:49 -04006038 RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006039 {
6040 return RValue<Float4>(Nucleus::createFDiv(lhs.value, rhs.value));
6041 }
6042
John Bauman19bac1e2014-05-06 15:23:49 -04006043 RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006044 {
6045 return RValue<Float4>(Nucleus::createFRem(lhs.value, rhs.value));
6046 }
6047
Nicolas Capens96d4e092016-11-18 14:22:38 -05006048 RValue<Float4> operator+=(Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006049 {
6050 return lhs = lhs + rhs;
6051 }
6052
Nicolas Capens96d4e092016-11-18 14:22:38 -05006053 RValue<Float4> operator-=(Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006054 {
6055 return lhs = lhs - rhs;
6056 }
6057
Nicolas Capens96d4e092016-11-18 14:22:38 -05006058 RValue<Float4> operator*=(Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006059 {
6060 return lhs = lhs * rhs;
6061 }
6062
Nicolas Capens96d4e092016-11-18 14:22:38 -05006063 RValue<Float4> operator/=(Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006064 {
6065 return lhs = lhs / rhs;
6066 }
6067
Nicolas Capens96d4e092016-11-18 14:22:38 -05006068 RValue<Float4> operator%=(Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006069 {
6070 return lhs = lhs % rhs;
6071 }
6072
John Bauman19bac1e2014-05-06 15:23:49 -04006073 RValue<Float4> operator+(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006074 {
6075 return val;
6076 }
6077
John Bauman19bac1e2014-05-06 15:23:49 -04006078 RValue<Float4> operator-(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006079 {
6080 return RValue<Float4>(Nucleus::createFNeg(val.value));
6081 }
6082
John Bauman19bac1e2014-05-06 15:23:49 -04006083 RValue<Float4> Abs(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006084 {
6085 Value *vector = Nucleus::createBitCast(x.value, Int4::getType());
Nicolas Capens13ac2322016-10-13 14:52:12 -04006086 int64_t constantVector[4] = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF};
6087 Value *result = Nucleus::createAnd(vector, V(Nucleus::createConstantVector(constantVector, Int4::getType())));
John Bauman89401822014-05-06 15:04:28 -04006088
6089 return RValue<Float4>(Nucleus::createBitCast(result, Float4::getType()));
6090 }
6091
John Bauman19bac1e2014-05-06 15:23:49 -04006092 RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006093 {
6094 return x86::maxps(x, y);
6095 }
6096
John Bauman19bac1e2014-05-06 15:23:49 -04006097 RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006098 {
6099 return x86::minps(x, y);
6100 }
6101
Nicolas Capens05b3d662016-02-25 23:58:33 -05006102 RValue<Float4> Rcp_pp(RValue<Float4> x, bool exactAtPow2)
John Bauman89401822014-05-06 15:04:28 -04006103 {
Nicolas Capens05b3d662016-02-25 23:58:33 -05006104 if(exactAtPow2)
6105 {
6106 // rcpps uses a piecewise-linear approximation which minimizes the relative error
6107 // but is not exact at power-of-two values. Rectify by multiplying by the inverse.
6108 return x86::rcpps(x) * Float4(1.0f / _mm_cvtss_f32(_mm_rcp_ss(_mm_set_ps1(1.0f))));
6109 }
6110 else
6111 {
6112 return x86::rcpps(x);
6113 }
John Bauman89401822014-05-06 15:04:28 -04006114 }
John Bauman66b8ab22014-05-06 15:57:45 -04006115
John Bauman19bac1e2014-05-06 15:23:49 -04006116 RValue<Float4> RcpSqrt_pp(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006117 {
6118 return x86::rsqrtps(x);
6119 }
6120
John Bauman19bac1e2014-05-06 15:23:49 -04006121 RValue<Float4> Sqrt(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006122 {
6123 return x86::sqrtps(x);
6124 }
6125
Nicolas Capensc94ab742016-11-08 15:15:31 -05006126 RValue<Float4> Insert(RValue<Float4> val, RValue<Float> element, int i)
John Bauman89401822014-05-06 15:04:28 -04006127 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05006128 return RValue<Float4>(Nucleus::createInsertElement(val.value, element.value, i));
John Bauman89401822014-05-06 15:04:28 -04006129 }
6130
John Bauman19bac1e2014-05-06 15:23:49 -04006131 RValue<Float> Extract(RValue<Float4> x, int i)
John Bauman89401822014-05-06 15:04:28 -04006132 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006133 return RValue<Float>(Nucleus::createExtractElement(x.value, Float::getType(), i));
John Bauman89401822014-05-06 15:04:28 -04006134 }
6135
John Bauman19bac1e2014-05-06 15:23:49 -04006136 RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04006137 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006138 return RValue<Float4>(createSwizzle4(x.value, select));
John Bauman89401822014-05-06 15:04:28 -04006139 }
6140
John Bauman19bac1e2014-05-06 15:23:49 -04006141 RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006142 {
Nicolas Capense89cd582016-09-30 14:23:47 -04006143 int shuffle[4] =
6144 {
6145 ((imm >> 0) & 0x03) + 0,
6146 ((imm >> 2) & 0x03) + 0,
6147 ((imm >> 4) & 0x03) + 4,
6148 ((imm >> 6) & 0x03) + 4,
6149 };
John Bauman89401822014-05-06 15:04:28 -04006150
Nicolas Capense89cd582016-09-30 14:23:47 -04006151 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
John Bauman89401822014-05-06 15:04:28 -04006152 }
6153
John Bauman19bac1e2014-05-06 15:23:49 -04006154 RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006155 {
Nicolas Capense89cd582016-09-30 14:23:47 -04006156 int shuffle[4] = {0, 4, 1, 5};
6157 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
John Bauman89401822014-05-06 15:04:28 -04006158 }
6159
John Bauman19bac1e2014-05-06 15:23:49 -04006160 RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006161 {
Nicolas Capense89cd582016-09-30 14:23:47 -04006162 int shuffle[4] = {2, 6, 3, 7};
6163 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
John Bauman89401822014-05-06 15:04:28 -04006164 }
John Bauman66b8ab22014-05-06 15:57:45 -04006165
John Bauman19bac1e2014-05-06 15:23:49 -04006166 RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04006167 {
John Bauman66b8ab22014-05-06 15:57:45 -04006168 Value *vector = lhs.loadValue();
Nicolas Capense95d5342016-09-30 11:37:28 -04006169 Value *shuffle = createMask4(vector, rhs.value, select);
John Bauman66b8ab22014-05-06 15:57:45 -04006170 lhs.storeValue(shuffle);
John Bauman89401822014-05-06 15:04:28 -04006171
6172 return RValue<Float4>(shuffle);
6173 }
6174
John Bauman19bac1e2014-05-06 15:23:49 -04006175 RValue<Int> SignMask(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006176 {
6177 return x86::movmskps(x);
6178 }
6179
John Bauman19bac1e2014-05-06 15:23:49 -04006180 RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006181 {
6182 // return As<Int4>(x86::cmpeqps(x, y));
6183 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOEQ(x.value, y.value), Int4::getType()));
6184 }
6185
John Bauman19bac1e2014-05-06 15:23:49 -04006186 RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006187 {
6188 // return As<Int4>(x86::cmpltps(x, y));
6189 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOLT(x.value, y.value), Int4::getType()));
6190 }
6191
John Bauman19bac1e2014-05-06 15:23:49 -04006192 RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006193 {
6194 // return As<Int4>(x86::cmpleps(x, y));
6195 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOLE(x.value, y.value), Int4::getType()));
6196 }
6197
John Bauman19bac1e2014-05-06 15:23:49 -04006198 RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006199 {
6200 // return As<Int4>(x86::cmpneqps(x, y));
6201 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpONE(x.value, y.value), Int4::getType()));
6202 }
6203
John Bauman19bac1e2014-05-06 15:23:49 -04006204 RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006205 {
6206 // return As<Int4>(x86::cmpnltps(x, y));
6207 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOGE(x.value, y.value), Int4::getType()));
6208 }
6209
John Bauman19bac1e2014-05-06 15:23:49 -04006210 RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006211 {
6212 // return As<Int4>(x86::cmpnleps(x, y));
6213 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOGT(x.value, y.value), Int4::getType()));
6214 }
6215
John Bauman19bac1e2014-05-06 15:23:49 -04006216 RValue<Float4> Round(RValue<Float4> x)
6217 {
6218 if(CPUID::supportsSSE4_1())
6219 {
6220 return x86::roundps(x, 0);
6221 }
6222 else
6223 {
6224 return Float4(RoundInt(x));
6225 }
6226 }
6227
6228 RValue<Float4> Trunc(RValue<Float4> x)
6229 {
6230 if(CPUID::supportsSSE4_1())
6231 {
6232 return x86::roundps(x, 3);
6233 }
6234 else
6235 {
6236 return Float4(Int4(x)); // Rounded toward zero
6237 }
6238 }
6239
6240 RValue<Float4> Frac(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006241 {
6242 if(CPUID::supportsSSE4_1())
6243 {
6244 return x - x86::floorps(x);
6245 }
6246 else
6247 {
John Bauman19bac1e2014-05-06 15:23:49 -04006248 Float4 frc = x - Float4(Int4(x)); // Signed fractional part
John Bauman89401822014-05-06 15:04:28 -04006249
John Bauman19bac1e2014-05-06 15:23:49 -04006250 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 -04006251 }
6252 }
6253
John Bauman19bac1e2014-05-06 15:23:49 -04006254 RValue<Float4> Floor(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006255 {
6256 if(CPUID::supportsSSE4_1())
6257 {
6258 return x86::floorps(x);
6259 }
6260 else
6261 {
John Bauman19bac1e2014-05-06 15:23:49 -04006262 return x - Frac(x);
John Bauman89401822014-05-06 15:04:28 -04006263 }
6264 }
6265
John Bauman19bac1e2014-05-06 15:23:49 -04006266 RValue<Float4> Ceil(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006267 {
John Bauman19bac1e2014-05-06 15:23:49 -04006268 if(CPUID::supportsSSE4_1())
6269 {
6270 return x86::ceilps(x);
6271 }
6272 else
6273 {
6274 return -Floor(-x);
6275 }
John Bauman89401822014-05-06 15:04:28 -04006276 }
6277
John Bauman19bac1e2014-05-06 15:23:49 -04006278 Type *Float4::getType()
John Bauman89401822014-05-06 15:04:28 -04006279 {
Nicolas Capensac230122016-09-20 14:30:06 -04006280 return T(VectorType::get(Float::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04006281 }
6282
Nicolas Capens81f18302016-01-14 09:32:35 -05006283 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006284 {
Nicolas Capens6d738712016-09-30 04:15:22 -04006285 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), V(Nucleus::createConstantInt(offset))));
John Bauman89401822014-05-06 15:04:28 -04006286 }
6287
Nicolas Capens81f18302016-01-14 09:32:35 -05006288 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006289 {
Nicolas Capens6d738712016-09-30 04:15:22 -04006290 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value));
John Bauman89401822014-05-06 15:04:28 -04006291 }
6292
Nicolas Capens81f18302016-01-14 09:32:35 -05006293 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006294 {
Nicolas Capens6d738712016-09-30 04:15:22 -04006295 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value));
John Bauman89401822014-05-06 15:04:28 -04006296 }
6297
Nicolas Capens96d4e092016-11-18 14:22:38 -05006298 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006299 {
6300 return lhs = lhs + offset;
6301 }
6302
Nicolas Capens96d4e092016-11-18 14:22:38 -05006303 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006304 {
6305 return lhs = lhs + offset;
6306 }
6307
Nicolas Capens96d4e092016-11-18 14:22:38 -05006308 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006309 {
6310 return lhs = lhs + offset;
6311 }
6312
Nicolas Capens81f18302016-01-14 09:32:35 -05006313 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006314 {
6315 return lhs + -offset;
6316 }
6317
Nicolas Capens81f18302016-01-14 09:32:35 -05006318 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006319 {
6320 return lhs + -offset;
6321 }
6322
Nicolas Capens81f18302016-01-14 09:32:35 -05006323 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006324 {
6325 return lhs + -offset;
6326 }
6327
Nicolas Capens96d4e092016-11-18 14:22:38 -05006328 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006329 {
6330 return lhs = lhs - offset;
6331 }
6332
Nicolas Capens96d4e092016-11-18 14:22:38 -05006333 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006334 {
6335 return lhs = lhs - offset;
6336 }
6337
Nicolas Capens96d4e092016-11-18 14:22:38 -05006338 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006339 {
6340 return lhs = lhs - offset;
6341 }
6342
6343 void Return()
6344 {
John Bauman89401822014-05-06 15:04:28 -04006345 Nucleus::createRetVoid();
6346 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
John Bauman19bac1e2014-05-06 15:23:49 -04006347 Nucleus::createUnreachable();
6348 }
6349
Nicolas Capenseb253d02016-11-18 14:40:40 -05006350 void Return(RValue<Int> ret)
John Bauman19bac1e2014-05-06 15:23:49 -04006351 {
Nicolas Capenseb253d02016-11-18 14:40:40 -05006352 Nucleus::createRet(ret.value);
John Bauman89401822014-05-06 15:04:28 -04006353 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
John Bauman19bac1e2014-05-06 15:23:49 -04006354 Nucleus::createUnreachable();
John Bauman89401822014-05-06 15:04:28 -04006355 }
6356
John Bauman19bac1e2014-05-06 15:23:49 -04006357 bool branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB)
John Bauman89401822014-05-06 15:04:28 -04006358 {
6359 Nucleus::createCondBr(cmp.value, bodyBB, endBB);
John Bauman66b8ab22014-05-06 15:57:45 -04006360 Nucleus::setInsertBlock(bodyBB);
6361
John Bauman89401822014-05-06 15:04:28 -04006362 return true;
6363 }
6364
John Bauman89401822014-05-06 15:04:28 -04006365 RValue<Long> Ticks()
6366 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006367 llvm::Function *rdtsc = Intrinsic::getDeclaration(::module, Intrinsic::readcyclecounter);
John Bauman89401822014-05-06 15:04:28 -04006368
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006369 return RValue<Long>(V(::builder->CreateCall(rdtsc)));
John Bauman89401822014-05-06 15:04:28 -04006370 }
John Bauman89401822014-05-06 15:04:28 -04006371}
6372
6373namespace sw
6374{
6375 namespace x86
6376 {
John Bauman19bac1e2014-05-06 15:23:49 -04006377 RValue<Int> cvtss2si(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006378 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006379 llvm::Function *cvtss2si = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cvtss2si);
John Bauman66b8ab22014-05-06 15:57:45 -04006380
John Bauman89401822014-05-06 15:04:28 -04006381 Float4 vector;
6382 vector.x = val;
6383
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006384 return RValue<Int>(V(::builder->CreateCall(cvtss2si, RValue<Float4>(vector).value)));
John Bauman89401822014-05-06 15:04:28 -04006385 }
6386
John Bauman19bac1e2014-05-06 15:23:49 -04006387 RValue<Int2> cvtps2pi(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006388 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006389 llvm::Function *cvtps2pi = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cvtps2pi);
John Bauman89401822014-05-06 15:04:28 -04006390
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006391 return RValue<Int2>(V(::builder->CreateCall(cvtps2pi, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006392 }
6393
John Bauman19bac1e2014-05-06 15:23:49 -04006394 RValue<Int2> cvttps2pi(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006395 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006396 llvm::Function *cvttps2pi = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cvttps2pi);
John Bauman89401822014-05-06 15:04:28 -04006397
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006398 return RValue<Int2>(V(::builder->CreateCall(cvttps2pi, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006399 }
6400
John Bauman19bac1e2014-05-06 15:23:49 -04006401 RValue<Int4> cvtps2dq(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006402 {
6403 if(CPUID::supportsSSE2())
6404 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006405 llvm::Function *cvtps2dq = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_cvtps2dq);
John Bauman89401822014-05-06 15:04:28 -04006406
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006407 return RValue<Int4>(V(::builder->CreateCall(cvtps2dq, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006408 }
6409 else
6410 {
6411 Int2 lo = x86::cvtps2pi(val);
6412 Int2 hi = x86::cvtps2pi(Swizzle(val, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04006413
Nicolas Capens62abb552016-01-05 12:03:47 -05006414 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04006415 }
6416 }
6417
John Bauman19bac1e2014-05-06 15:23:49 -04006418 RValue<Float> rcpss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006419 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006420 llvm::Function *rcpss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rcp_ss);
John Bauman89401822014-05-06 15:04:28 -04006421
Nicolas Capens19336542016-09-26 10:32:29 -04006422 Value *vector = Nucleus::createInsertElement(V(UndefValue::get(Float4::getType())), val.value, 0);
John Bauman66b8ab22014-05-06 15:57:45 -04006423
Nicolas Capense95d5342016-09-30 11:37:28 -04006424 return RValue<Float>(Nucleus::createExtractElement(V(::builder->CreateCall(rcpss, vector)), Float::getType(), 0));
John Bauman89401822014-05-06 15:04:28 -04006425 }
6426
John Bauman19bac1e2014-05-06 15:23:49 -04006427 RValue<Float> sqrtss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006428 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006429 llvm::Function *sqrtss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_sqrt_ss);
John Bauman89401822014-05-06 15:04:28 -04006430
Nicolas Capens19336542016-09-26 10:32:29 -04006431 Value *vector = Nucleus::createInsertElement(V(UndefValue::get(Float4::getType())), val.value, 0);
John Bauman66b8ab22014-05-06 15:57:45 -04006432
Nicolas Capense95d5342016-09-30 11:37:28 -04006433 return RValue<Float>(Nucleus::createExtractElement(V(::builder->CreateCall(sqrtss, vector)), Float::getType(), 0));
John Bauman89401822014-05-06 15:04:28 -04006434 }
6435
John Bauman19bac1e2014-05-06 15:23:49 -04006436 RValue<Float> rsqrtss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006437 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006438 llvm::Function *rsqrtss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rsqrt_ss);
John Bauman66b8ab22014-05-06 15:57:45 -04006439
Nicolas Capens19336542016-09-26 10:32:29 -04006440 Value *vector = Nucleus::createInsertElement(V(UndefValue::get(Float4::getType())), val.value, 0);
John Bauman89401822014-05-06 15:04:28 -04006441
Nicolas Capense95d5342016-09-30 11:37:28 -04006442 return RValue<Float>(Nucleus::createExtractElement(V(::builder->CreateCall(rsqrtss, vector)), Float::getType(), 0));
John Bauman89401822014-05-06 15:04:28 -04006443 }
6444
John Bauman19bac1e2014-05-06 15:23:49 -04006445 RValue<Float4> rcpps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006446 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006447 llvm::Function *rcpps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rcp_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04006448
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006449 return RValue<Float4>(V(::builder->CreateCall(rcpps, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006450 }
6451
John Bauman19bac1e2014-05-06 15:23:49 -04006452 RValue<Float4> sqrtps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006453 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006454 llvm::Function *sqrtps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_sqrt_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04006455
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006456 return RValue<Float4>(V(::builder->CreateCall(sqrtps, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006457 }
6458
John Bauman19bac1e2014-05-06 15:23:49 -04006459 RValue<Float4> rsqrtps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006460 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006461 llvm::Function *rsqrtps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rsqrt_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04006462
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006463 return RValue<Float4>(V(::builder->CreateCall(rsqrtps, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006464 }
6465
John Bauman19bac1e2014-05-06 15:23:49 -04006466 RValue<Float4> maxps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006467 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006468 llvm::Function *maxps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_max_ps);
John Bauman89401822014-05-06 15:04:28 -04006469
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006470 return RValue<Float4>(V(::builder->CreateCall2(maxps, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04006471 }
6472
John Bauman19bac1e2014-05-06 15:23:49 -04006473 RValue<Float4> minps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006474 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006475 llvm::Function *minps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_min_ps);
John Bauman89401822014-05-06 15:04:28 -04006476
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006477 return RValue<Float4>(V(::builder->CreateCall2(minps, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04006478 }
6479
John Bauman19bac1e2014-05-06 15:23:49 -04006480 RValue<Float> roundss(RValue<Float> val, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006481 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006482 llvm::Function *roundss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_round_ss);
John Bauman89401822014-05-06 15:04:28 -04006483
Nicolas Capens19336542016-09-26 10:32:29 -04006484 Value *undef = V(UndefValue::get(Float4::getType()));
John Bauman89401822014-05-06 15:04:28 -04006485 Value *vector = Nucleus::createInsertElement(undef, val.value, 0);
6486
Nicolas Capense95d5342016-09-30 11:37:28 -04006487 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 -04006488 }
6489
John Bauman19bac1e2014-05-06 15:23:49 -04006490 RValue<Float> floorss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006491 {
6492 return roundss(val, 1);
6493 }
6494
John Bauman19bac1e2014-05-06 15:23:49 -04006495 RValue<Float> ceilss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006496 {
6497 return roundss(val, 2);
6498 }
6499
John Bauman19bac1e2014-05-06 15:23:49 -04006500 RValue<Float4> roundps(RValue<Float4> val, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006501 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006502 llvm::Function *roundps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_round_ps);
John Bauman89401822014-05-06 15:04:28 -04006503
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006504 return RValue<Float4>(V(::builder->CreateCall2(roundps, val.value, V(Nucleus::createConstantInt(imm)))));
John Bauman89401822014-05-06 15:04:28 -04006505 }
6506
John Bauman19bac1e2014-05-06 15:23:49 -04006507 RValue<Float4> floorps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006508 {
6509 return roundps(val, 1);
6510 }
6511
John Bauman19bac1e2014-05-06 15:23:49 -04006512 RValue<Float4> ceilps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006513 {
6514 return roundps(val, 2);
6515 }
6516
John Bauman19bac1e2014-05-06 15:23:49 -04006517 RValue<Float4> cmpps(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006518 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006519 llvm::Function *cmpps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cmp_ps);
John Bauman89401822014-05-06 15:04:28 -04006520
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006521 return RValue<Float4>(V(::builder->CreateCall3(cmpps, x.value, y.value, V(Nucleus::createConstantByte(imm)))));
John Bauman89401822014-05-06 15:04:28 -04006522 }
6523
John Bauman19bac1e2014-05-06 15:23:49 -04006524 RValue<Float4> cmpeqps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006525 {
6526 return cmpps(x, y, 0);
6527 }
6528
John Bauman19bac1e2014-05-06 15:23:49 -04006529 RValue<Float4> cmpltps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006530 {
6531 return cmpps(x, y, 1);
6532 }
6533
John Bauman19bac1e2014-05-06 15:23:49 -04006534 RValue<Float4> cmpleps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006535 {
6536 return cmpps(x, y, 2);
6537 }
6538
John Bauman19bac1e2014-05-06 15:23:49 -04006539 RValue<Float4> cmpunordps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006540 {
6541 return cmpps(x, y, 3);
6542 }
6543
John Bauman19bac1e2014-05-06 15:23:49 -04006544 RValue<Float4> cmpneqps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006545 {
6546 return cmpps(x, y, 4);
6547 }
6548
John Bauman19bac1e2014-05-06 15:23:49 -04006549 RValue<Float4> cmpnltps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006550 {
6551 return cmpps(x, y, 5);
6552 }
6553
John Bauman19bac1e2014-05-06 15:23:49 -04006554 RValue<Float4> cmpnleps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006555 {
6556 return cmpps(x, y, 6);
6557 }
6558
John Bauman19bac1e2014-05-06 15:23:49 -04006559 RValue<Float4> cmpordps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006560 {
6561 return cmpps(x, y, 7);
6562 }
6563
John Bauman19bac1e2014-05-06 15:23:49 -04006564 RValue<Float> cmpss(RValue<Float> x, RValue<Float> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006565 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006566 llvm::Function *cmpss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cmp_ss);
John Bauman89401822014-05-06 15:04:28 -04006567
Nicolas Capens19336542016-09-26 10:32:29 -04006568 Value *vector1 = Nucleus::createInsertElement(V(UndefValue::get(Float4::getType())), x.value, 0);
6569 Value *vector2 = Nucleus::createInsertElement(V(UndefValue::get(Float4::getType())), y.value, 0);
John Bauman89401822014-05-06 15:04:28 -04006570
Nicolas Capense95d5342016-09-30 11:37:28 -04006571 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 -04006572 }
6573
John Bauman19bac1e2014-05-06 15:23:49 -04006574 RValue<Float> cmpeqss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006575 {
6576 return cmpss(x, y, 0);
6577 }
6578
John Bauman19bac1e2014-05-06 15:23:49 -04006579 RValue<Float> cmpltss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006580 {
6581 return cmpss(x, y, 1);
6582 }
6583
John Bauman19bac1e2014-05-06 15:23:49 -04006584 RValue<Float> cmpless(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006585 {
6586 return cmpss(x, y, 2);
6587 }
6588
John Bauman19bac1e2014-05-06 15:23:49 -04006589 RValue<Float> cmpunordss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006590 {
6591 return cmpss(x, y, 3);
6592 }
6593
John Bauman19bac1e2014-05-06 15:23:49 -04006594 RValue<Float> cmpneqss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006595 {
6596 return cmpss(x, y, 4);
6597 }
6598
John Bauman19bac1e2014-05-06 15:23:49 -04006599 RValue<Float> cmpnltss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006600 {
6601 return cmpss(x, y, 5);
6602 }
6603
John Bauman19bac1e2014-05-06 15:23:49 -04006604 RValue<Float> cmpnless(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006605 {
6606 return cmpss(x, y, 6);
6607 }
6608
John Bauman19bac1e2014-05-06 15:23:49 -04006609 RValue<Float> cmpordss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006610 {
6611 return cmpss(x, y, 7);
6612 }
6613
Alexis Hetu0f448072016-03-18 10:56:08 -04006614 RValue<Int4> pabsd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04006615 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006616 llvm::Function *pabsd = Intrinsic::getDeclaration(::module, Intrinsic::x86_ssse3_pabs_d_128);
John Bauman89401822014-05-06 15:04:28 -04006617
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006618 return RValue<Int4>(V(::builder->CreateCall(pabsd, x.value)));
John Bauman89401822014-05-06 15:04:28 -04006619 }
6620
John Bauman19bac1e2014-05-06 15:23:49 -04006621 RValue<Short4> paddsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006622 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006623 llvm::Function *paddsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padds_w);
John Bauman89401822014-05-06 15:04:28 -04006624
Nicolas Capens70dfff42016-10-27 10:20:28 -04006625 return As<Short4>(V(::builder->CreateCall2(paddsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006626 }
John Bauman66b8ab22014-05-06 15:57:45 -04006627
John Bauman19bac1e2014-05-06 15:23:49 -04006628 RValue<Short4> psubsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006629 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006630 llvm::Function *psubsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubs_w);
John Bauman89401822014-05-06 15:04:28 -04006631
Nicolas Capens70dfff42016-10-27 10:20:28 -04006632 return As<Short4>(V(::builder->CreateCall2(psubsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006633 }
6634
John Bauman19bac1e2014-05-06 15:23:49 -04006635 RValue<UShort4> paddusw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04006636 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006637 llvm::Function *paddusw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_paddus_w);
John Bauman89401822014-05-06 15:04:28 -04006638
Nicolas Capens70dfff42016-10-27 10:20:28 -04006639 return As<UShort4>(V(::builder->CreateCall2(paddusw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006640 }
John Bauman66b8ab22014-05-06 15:57:45 -04006641
John Bauman19bac1e2014-05-06 15:23:49 -04006642 RValue<UShort4> psubusw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04006643 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006644 llvm::Function *psubusw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubus_w);
John Bauman89401822014-05-06 15:04:28 -04006645
Nicolas Capens70dfff42016-10-27 10:20:28 -04006646 return As<UShort4>(V(::builder->CreateCall2(psubusw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006647 }
6648
John Bauman19bac1e2014-05-06 15:23:49 -04006649 RValue<SByte8> paddsb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04006650 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006651 llvm::Function *paddsb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padds_b);
John Bauman89401822014-05-06 15:04:28 -04006652
Nicolas Capens70dfff42016-10-27 10:20:28 -04006653 return As<SByte8>(V(::builder->CreateCall2(paddsb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006654 }
John Bauman66b8ab22014-05-06 15:57:45 -04006655
John Bauman19bac1e2014-05-06 15:23:49 -04006656 RValue<SByte8> psubsb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04006657 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006658 llvm::Function *psubsb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubs_b);
John Bauman89401822014-05-06 15:04:28 -04006659
Nicolas Capens70dfff42016-10-27 10:20:28 -04006660 return As<SByte8>(V(::builder->CreateCall2(psubsb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006661 }
John Bauman66b8ab22014-05-06 15:57:45 -04006662
John Bauman19bac1e2014-05-06 15:23:49 -04006663 RValue<Byte8> paddusb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04006664 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006665 llvm::Function *paddusb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_paddus_b);
John Bauman89401822014-05-06 15:04:28 -04006666
Nicolas Capens70dfff42016-10-27 10:20:28 -04006667 return As<Byte8>(V(::builder->CreateCall2(paddusb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006668 }
John Bauman66b8ab22014-05-06 15:57:45 -04006669
John Bauman19bac1e2014-05-06 15:23:49 -04006670 RValue<Byte8> psubusb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04006671 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006672 llvm::Function *psubusb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubus_b);
John Bauman89401822014-05-06 15:04:28 -04006673
Nicolas Capens70dfff42016-10-27 10:20:28 -04006674 return As<Byte8>(V(::builder->CreateCall2(psubusb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006675 }
6676
John Bauman19bac1e2014-05-06 15:23:49 -04006677 RValue<Short4> paddw(RValue<Short4> x, RValue<Short4> y)
6678 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006679 llvm::Function *paddw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padd_w);
John Bauman19bac1e2014-05-06 15:23:49 -04006680
Nicolas Capens70dfff42016-10-27 10:20:28 -04006681 return As<Short4>(V(::builder->CreateCall2(paddw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006682 }
6683
6684 RValue<Short4> psubw(RValue<Short4> x, RValue<Short4> y)
6685 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006686 llvm::Function *psubw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psub_w);
John Bauman19bac1e2014-05-06 15:23:49 -04006687
Nicolas Capens70dfff42016-10-27 10:20:28 -04006688 return As<Short4>(V(::builder->CreateCall2(psubw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006689 }
6690
6691 RValue<Short4> pmullw(RValue<Short4> x, RValue<Short4> y)
6692 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006693 llvm::Function *pmullw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmull_w);
John Bauman19bac1e2014-05-06 15:23:49 -04006694
Nicolas Capens70dfff42016-10-27 10:20:28 -04006695 return As<Short4>(V(::builder->CreateCall2(pmullw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006696 }
6697
6698 RValue<Short4> pand(RValue<Short4> x, RValue<Short4> y)
6699 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006700 llvm::Function *pand = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pand);
John Bauman19bac1e2014-05-06 15:23:49 -04006701
Nicolas Capens70dfff42016-10-27 10:20:28 -04006702 return As<Short4>(V(::builder->CreateCall2(pand, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006703 }
6704
6705 RValue<Short4> por(RValue<Short4> x, RValue<Short4> y)
6706 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006707 llvm::Function *por = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_por);
John Bauman19bac1e2014-05-06 15:23:49 -04006708
Nicolas Capens70dfff42016-10-27 10:20:28 -04006709 return As<Short4>(V(::builder->CreateCall2(por, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006710 }
6711
6712 RValue<Short4> pxor(RValue<Short4> x, RValue<Short4> y)
6713 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006714 llvm::Function *pxor = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pxor);
John Bauman19bac1e2014-05-06 15:23:49 -04006715
Nicolas Capens70dfff42016-10-27 10:20:28 -04006716 return As<Short4>(V(::builder->CreateCall2(pxor, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006717 }
6718
6719 RValue<Short4> pshufw(RValue<Short4> x, unsigned char y)
6720 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006721 llvm::Function *pshufw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_pshuf_w);
John Bauman19bac1e2014-05-06 15:23:49 -04006722
Nicolas Capens70dfff42016-10-27 10:20:28 -04006723 return As<Short4>(V(::builder->CreateCall2(pshufw, As<MMX>(x).value, V(Nucleus::createConstantByte(y)))));
John Bauman19bac1e2014-05-06 15:23:49 -04006724 }
6725
6726 RValue<Int2> punpcklwd(RValue<Short4> x, RValue<Short4> y)
6727 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006728 llvm::Function *punpcklwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpcklwd);
John Bauman19bac1e2014-05-06 15:23:49 -04006729
Nicolas Capens70dfff42016-10-27 10:20:28 -04006730 return As<Int2>(V(::builder->CreateCall2(punpcklwd, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006731 }
6732
6733 RValue<Int2> punpckhwd(RValue<Short4> x, RValue<Short4> y)
6734 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006735 llvm::Function *punpckhwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckhwd);
John Bauman19bac1e2014-05-06 15:23:49 -04006736
Nicolas Capens70dfff42016-10-27 10:20:28 -04006737 return As<Int2>(V(::builder->CreateCall2(punpckhwd, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006738 }
6739
6740 RValue<Short4> pinsrw(RValue<Short4> x, RValue<Int> y, unsigned int i)
6741 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006742 llvm::Function *pinsrw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pinsr_w);
John Bauman19bac1e2014-05-06 15:23:49 -04006743
Nicolas Capens70dfff42016-10-27 10:20:28 -04006744 return As<Short4>(V(::builder->CreateCall3(pinsrw, As<MMX>(x).value, y.value, V(Nucleus::createConstantInt(i)))));
John Bauman19bac1e2014-05-06 15:23:49 -04006745 }
6746
6747 RValue<Int> pextrw(RValue<Short4> x, unsigned int i)
6748 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006749 llvm::Function *pextrw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pextr_w);
John Bauman19bac1e2014-05-06 15:23:49 -04006750
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006751 return RValue<Int>(V(::builder->CreateCall2(pextrw, As<MMX>(x).value, V(Nucleus::createConstantInt(i)))));
John Bauman19bac1e2014-05-06 15:23:49 -04006752 }
6753
Nicolas Capens45f187a2016-12-02 15:30:56 -05006754 RValue<Short4> punpckldq(RValue<Int2> x, RValue<Int2> y)
John Bauman19bac1e2014-05-06 15:23:49 -04006755 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006756 llvm::Function *punpckldq = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckldq);
John Bauman19bac1e2014-05-06 15:23:49 -04006757
Nicolas Capens45f187a2016-12-02 15:30:56 -05006758 return As<Short4>(V(::builder->CreateCall2(punpckldq, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006759 }
6760
Nicolas Capens45f187a2016-12-02 15:30:56 -05006761 RValue<Short4> punpckhdq(RValue<Int2> x, RValue<Int2> y)
John Bauman19bac1e2014-05-06 15:23:49 -04006762 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006763 llvm::Function *punpckhdq = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckhdq);
John Bauman19bac1e2014-05-06 15:23:49 -04006764
Nicolas Capens45f187a2016-12-02 15:30:56 -05006765 return As<Short4>(V(::builder->CreateCall2(punpckhdq, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006766 }
6767
6768 RValue<Short4> punpcklbw(RValue<Byte8> x, RValue<Byte8> y)
6769 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006770 llvm::Function *punpcklbw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpcklbw);
John Bauman19bac1e2014-05-06 15:23:49 -04006771
Nicolas Capens70dfff42016-10-27 10:20:28 -04006772 return As<Short4>(V(::builder->CreateCall2(punpcklbw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006773 }
6774
6775 RValue<Short4> punpckhbw(RValue<Byte8> x, RValue<Byte8> y)
6776 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006777 llvm::Function *punpckhbw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckhbw);
John Bauman19bac1e2014-05-06 15:23:49 -04006778
Nicolas Capens70dfff42016-10-27 10:20:28 -04006779 return As<Short4>(V(::builder->CreateCall2(punpckhbw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006780 }
6781
6782 RValue<Byte8> paddb(RValue<Byte8> x, RValue<Byte8> y)
6783 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006784 llvm::Function *paddb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padd_b);
John Bauman19bac1e2014-05-06 15:23:49 -04006785
Nicolas Capens70dfff42016-10-27 10:20:28 -04006786 return As<Byte8>(V(::builder->CreateCall2(paddb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006787 }
6788
6789 RValue<Byte8> psubb(RValue<Byte8> x, RValue<Byte8> y)
6790 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006791 llvm::Function *psubb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psub_b);
John Bauman19bac1e2014-05-06 15:23:49 -04006792
Nicolas Capens70dfff42016-10-27 10:20:28 -04006793 return As<Byte8>(V(::builder->CreateCall2(psubb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006794 }
6795
6796 RValue<Int2> paddd(RValue<Int2> x, RValue<Int2> y)
6797 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006798 llvm::Function *paddd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padd_d);
John Bauman19bac1e2014-05-06 15:23:49 -04006799
Nicolas Capens70dfff42016-10-27 10:20:28 -04006800 return As<Int2>(V(::builder->CreateCall2(paddd, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006801 }
6802
6803 RValue<Int2> psubd(RValue<Int2> x, RValue<Int2> y)
6804 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006805 llvm::Function *psubd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psub_d);
John Bauman19bac1e2014-05-06 15:23:49 -04006806
Nicolas Capens70dfff42016-10-27 10:20:28 -04006807 return As<Int2>(V(::builder->CreateCall2(psubd, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006808 }
6809
6810 RValue<UShort4> pavgw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04006811 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006812 llvm::Function *pavgw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pavg_w);
John Bauman89401822014-05-06 15:04:28 -04006813
Nicolas Capens70dfff42016-10-27 10:20:28 -04006814 return As<UShort4>(V(::builder->CreateCall2(pavgw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006815 }
6816
John Bauman19bac1e2014-05-06 15:23:49 -04006817 RValue<Short4> pmaxsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006818 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006819 llvm::Function *pmaxsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmaxs_w);
John Bauman89401822014-05-06 15:04:28 -04006820
Nicolas Capens70dfff42016-10-27 10:20:28 -04006821 return As<Short4>(V(::builder->CreateCall2(pmaxsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006822 }
6823
John Bauman19bac1e2014-05-06 15:23:49 -04006824 RValue<Short4> pminsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006825 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006826 llvm::Function *pminsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmins_w);
John Bauman89401822014-05-06 15:04:28 -04006827
Nicolas Capens70dfff42016-10-27 10:20:28 -04006828 return As<Short4>(V(::builder->CreateCall2(pminsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006829 }
6830
John Bauman19bac1e2014-05-06 15:23:49 -04006831 RValue<Short4> pcmpgtw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006832 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006833 llvm::Function *pcmpgtw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpgt_w);
John Bauman89401822014-05-06 15:04:28 -04006834
Nicolas Capens70dfff42016-10-27 10:20:28 -04006835 return As<Short4>(V(::builder->CreateCall2(pcmpgtw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006836 }
6837
John Bauman19bac1e2014-05-06 15:23:49 -04006838 RValue<Short4> pcmpeqw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006839 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006840 llvm::Function *pcmpeqw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpeq_w);
John Bauman89401822014-05-06 15:04:28 -04006841
Nicolas Capens70dfff42016-10-27 10:20:28 -04006842 return As<Short4>(V(::builder->CreateCall2(pcmpeqw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006843 }
6844
John Bauman19bac1e2014-05-06 15:23:49 -04006845 RValue<Byte8> pcmpgtb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04006846 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006847 llvm::Function *pcmpgtb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpgt_b);
John Bauman89401822014-05-06 15:04:28 -04006848
Nicolas Capens70dfff42016-10-27 10:20:28 -04006849 return As<Byte8>(V(::builder->CreateCall2(pcmpgtb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006850 }
6851
John Bauman19bac1e2014-05-06 15:23:49 -04006852 RValue<Byte8> pcmpeqb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04006853 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006854 llvm::Function *pcmpeqb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpeq_b);
John Bauman89401822014-05-06 15:04:28 -04006855
Nicolas Capens70dfff42016-10-27 10:20:28 -04006856 return As<Byte8>(V(::builder->CreateCall2(pcmpeqb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006857 }
6858
John Bauman19bac1e2014-05-06 15:23:49 -04006859 RValue<Short4> packssdw(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04006860 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006861 llvm::Function *packssdw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_packssdw);
John Bauman89401822014-05-06 15:04:28 -04006862
Nicolas Capens70dfff42016-10-27 10:20:28 -04006863 return As<Short4>(V(::builder->CreateCall2(packssdw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006864 }
6865
John Bauman19bac1e2014-05-06 15:23:49 -04006866 RValue<Short8> packssdw(RValue<Int4> x, RValue<Int4> y)
John Bauman89401822014-05-06 15:04:28 -04006867 {
6868 if(CPUID::supportsSSE2())
6869 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006870 llvm::Function *packssdw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_packssdw_128);
John Bauman89401822014-05-06 15:04:28 -04006871
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006872 return RValue<Short8>(V(::builder->CreateCall2(packssdw, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04006873 }
6874 else
6875 {
6876 Int2 loX = Int2(x);
6877 Int2 hiX = Int2(Swizzle(x, 0xEE));
6878
6879 Int2 loY = Int2(y);
6880 Int2 hiY = Int2(Swizzle(y, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04006881
John Bauman89401822014-05-06 15:04:28 -04006882 Short4 lo = x86::packssdw(loX, hiX);
6883 Short4 hi = x86::packssdw(loY, hiY);
John Bauman66b8ab22014-05-06 15:57:45 -04006884
Nicolas Capens62abb552016-01-05 12:03:47 -05006885 return Short8(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04006886 }
6887 }
6888
John Bauman19bac1e2014-05-06 15:23:49 -04006889 RValue<SByte8> packsswb(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006890 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006891 llvm::Function *packsswb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_packsswb);
John Bauman89401822014-05-06 15:04:28 -04006892
Nicolas Capens70dfff42016-10-27 10:20:28 -04006893 return As<SByte8>(V(::builder->CreateCall2(packsswb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006894 }
6895
John Bauman19bac1e2014-05-06 15:23:49 -04006896 RValue<Byte8> packuswb(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04006897 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006898 llvm::Function *packuswb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_packuswb);
John Bauman89401822014-05-06 15:04:28 -04006899
Nicolas Capens70dfff42016-10-27 10:20:28 -04006900 return As<Byte8>(V(::builder->CreateCall2(packuswb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006901 }
6902
Nicolas Capens3e7062b2017-01-17 14:01:33 -05006903 RValue<UShort8> packusdw(RValue<Int4> x, RValue<Int4> y)
John Bauman89401822014-05-06 15:04:28 -04006904 {
6905 if(CPUID::supportsSSE4_1())
6906 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006907 llvm::Function *packusdw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_packusdw);
John Bauman66b8ab22014-05-06 15:57:45 -04006908
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006909 return RValue<UShort8>(V(::builder->CreateCall2(packusdw, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04006910 }
6911 else
6912 {
Nicolas Capens3e7062b2017-01-17 14:01:33 -05006913 RValue<Int4> bx = (x & ~(x >> 31)) - Int4(0x8000);
6914 RValue<Int4> by = (y & ~(y >> 31)) - Int4(0x8000);
6915
6916 return As<UShort8>(packssdw(bx, by) + Short8(0x8000u));
John Bauman89401822014-05-06 15:04:28 -04006917 }
6918 }
6919
John Bauman19bac1e2014-05-06 15:23:49 -04006920 RValue<UShort4> psrlw(RValue<UShort4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006921 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006922 llvm::Function *psrlw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrli_w);
John Bauman89401822014-05-06 15:04:28 -04006923
Nicolas Capens70dfff42016-10-27 10:20:28 -04006924 return As<UShort4>(V(::builder->CreateCall2(psrlw, As<MMX>(x).value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006925 }
6926
John Bauman19bac1e2014-05-06 15:23:49 -04006927 RValue<UShort8> psrlw(RValue<UShort8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006928 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006929 llvm::Function *psrlw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrli_w);
John Bauman89401822014-05-06 15:04:28 -04006930
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006931 return RValue<UShort8>(V(::builder->CreateCall2(psrlw, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006932 }
6933
John Bauman19bac1e2014-05-06 15:23:49 -04006934 RValue<Short4> psraw(RValue<Short4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006935 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006936 llvm::Function *psraw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrai_w);
John Bauman89401822014-05-06 15:04:28 -04006937
Nicolas Capens70dfff42016-10-27 10:20:28 -04006938 return As<Short4>(V(::builder->CreateCall2(psraw, As<MMX>(x).value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006939 }
6940
John Bauman19bac1e2014-05-06 15:23:49 -04006941 RValue<Short8> psraw(RValue<Short8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006942 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006943 llvm::Function *psraw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrai_w);
John Bauman89401822014-05-06 15:04:28 -04006944
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006945 return RValue<Short8>(V(::builder->CreateCall2(psraw, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006946 }
6947
John Bauman19bac1e2014-05-06 15:23:49 -04006948 RValue<Short4> psllw(RValue<Short4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006949 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006950 llvm::Function *psllw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pslli_w);
John Bauman89401822014-05-06 15:04:28 -04006951
Nicolas Capens70dfff42016-10-27 10:20:28 -04006952 return As<Short4>(V(::builder->CreateCall2(psllw, As<MMX>(x).value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006953 }
6954
John Bauman19bac1e2014-05-06 15:23:49 -04006955 RValue<Short8> psllw(RValue<Short8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006956 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006957 llvm::Function *psllw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pslli_w);
John Bauman89401822014-05-06 15:04:28 -04006958
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006959 return RValue<Short8>(V(::builder->CreateCall2(psllw, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006960 }
6961
John Bauman19bac1e2014-05-06 15:23:49 -04006962 RValue<Int2> pslld(RValue<Int2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006963 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006964 llvm::Function *pslld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pslli_d);
John Bauman89401822014-05-06 15:04:28 -04006965
Nicolas Capens70dfff42016-10-27 10:20:28 -04006966 return As<Int2>(V(::builder->CreateCall2(pslld, As<MMX>(x).value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006967 }
6968
John Bauman19bac1e2014-05-06 15:23:49 -04006969 RValue<Int4> pslld(RValue<Int4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006970 {
6971 if(CPUID::supportsSSE2())
6972 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006973 llvm::Function *pslld = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pslli_d);
John Bauman89401822014-05-06 15:04:28 -04006974
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006975 return RValue<Int4>(V(::builder->CreateCall2(pslld, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006976 }
6977 else
6978 {
6979 Int2 lo = Int2(x);
6980 Int2 hi = Int2(Swizzle(x, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04006981
John Bauman89401822014-05-06 15:04:28 -04006982 lo = x86::pslld(lo, y);
6983 hi = x86::pslld(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04006984
Nicolas Capens62abb552016-01-05 12:03:47 -05006985 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04006986 }
6987 }
6988
John Bauman19bac1e2014-05-06 15:23:49 -04006989 RValue<Int2> psrad(RValue<Int2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006990 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006991 llvm::Function *psrad = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrai_d);
John Bauman89401822014-05-06 15:04:28 -04006992
Nicolas Capens70dfff42016-10-27 10:20:28 -04006993 return As<Int2>(V(::builder->CreateCall2(psrad, As<MMX>(x).value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006994 }
6995
John Bauman19bac1e2014-05-06 15:23:49 -04006996 RValue<Int4> psrad(RValue<Int4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006997 {
6998 if(CPUID::supportsSSE2())
6999 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007000 llvm::Function *psrad = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrai_d);
John Bauman89401822014-05-06 15:04:28 -04007001
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007002 return RValue<Int4>(V(::builder->CreateCall2(psrad, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007003 }
7004 else
7005 {
7006 Int2 lo = Int2(x);
7007 Int2 hi = Int2(Swizzle(x, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04007008
John Bauman89401822014-05-06 15:04:28 -04007009 lo = x86::psrad(lo, y);
7010 hi = x86::psrad(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04007011
Nicolas Capens62abb552016-01-05 12:03:47 -05007012 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007013 }
7014 }
7015
John Bauman19bac1e2014-05-06 15:23:49 -04007016 RValue<UInt2> psrld(RValue<UInt2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007017 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007018 llvm::Function *psrld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrli_d);
John Bauman89401822014-05-06 15:04:28 -04007019
Nicolas Capens70dfff42016-10-27 10:20:28 -04007020 return As<UInt2>(V(::builder->CreateCall2(psrld, As<MMX>(x).value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007021 }
7022
John Bauman19bac1e2014-05-06 15:23:49 -04007023 RValue<UInt4> psrld(RValue<UInt4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007024 {
7025 if(CPUID::supportsSSE2())
7026 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007027 llvm::Function *psrld = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrli_d);
John Bauman89401822014-05-06 15:04:28 -04007028
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007029 return RValue<UInt4>(V(::builder->CreateCall2(psrld, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007030 }
7031 else
7032 {
7033 UInt2 lo = As<UInt2>(Int2(As<Int4>(x)));
7034 UInt2 hi = As<UInt2>(Int2(Swizzle(As<Int4>(x), 0xEE)));
John Bauman66b8ab22014-05-06 15:57:45 -04007035
John Bauman89401822014-05-06 15:04:28 -04007036 lo = x86::psrld(lo, y);
7037 hi = x86::psrld(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04007038
Nicolas Capens62abb552016-01-05 12:03:47 -05007039 return UInt4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007040 }
7041 }
7042
John Bauman19bac1e2014-05-06 15:23:49 -04007043 RValue<Int4> pmaxsd(RValue<Int4> x, RValue<Int4> y)
7044 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007045 llvm::Function *pmaxsd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmaxsd);
John Bauman19bac1e2014-05-06 15:23:49 -04007046
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007047 return RValue<Int4>(V(::builder->CreateCall2(pmaxsd, x.value, y.value)));
John Bauman19bac1e2014-05-06 15:23:49 -04007048 }
7049
7050 RValue<Int4> pminsd(RValue<Int4> x, RValue<Int4> y)
7051 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007052 llvm::Function *pminsd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pminsd);
John Bauman19bac1e2014-05-06 15:23:49 -04007053
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007054 return RValue<Int4>(V(::builder->CreateCall2(pminsd, x.value, y.value)));
John Bauman19bac1e2014-05-06 15:23:49 -04007055 }
7056
7057 RValue<UInt4> pmaxud(RValue<UInt4> x, RValue<UInt4> y)
7058 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007059 llvm::Function *pmaxud = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmaxud);
John Bauman19bac1e2014-05-06 15:23:49 -04007060
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007061 return RValue<UInt4>(V(::builder->CreateCall2(pmaxud, x.value, y.value)));
John Bauman19bac1e2014-05-06 15:23:49 -04007062 }
7063
7064 RValue<UInt4> pminud(RValue<UInt4> x, RValue<UInt4> y)
7065 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007066 llvm::Function *pminud = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pminud);
John Bauman19bac1e2014-05-06 15:23:49 -04007067
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007068 return RValue<UInt4>(V(::builder->CreateCall2(pminud, x.value, y.value)));
John Bauman19bac1e2014-05-06 15:23:49 -04007069 }
7070
7071 RValue<Short4> pmulhw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007072 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007073 llvm::Function *pmulhw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmulh_w);
John Bauman89401822014-05-06 15:04:28 -04007074
Nicolas Capens70dfff42016-10-27 10:20:28 -04007075 return As<Short4>(V(::builder->CreateCall2(pmulhw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007076 }
7077
John Bauman19bac1e2014-05-06 15:23:49 -04007078 RValue<UShort4> pmulhuw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007079 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007080 llvm::Function *pmulhuw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmulhu_w);
John Bauman89401822014-05-06 15:04:28 -04007081
Nicolas Capens70dfff42016-10-27 10:20:28 -04007082 return As<UShort4>(V(::builder->CreateCall2(pmulhuw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007083 }
7084
John Bauman19bac1e2014-05-06 15:23:49 -04007085 RValue<Int2> pmaddwd(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007086 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007087 llvm::Function *pmaddwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmadd_wd);
John Bauman89401822014-05-06 15:04:28 -04007088
Nicolas Capens70dfff42016-10-27 10:20:28 -04007089 return As<Int2>(V(::builder->CreateCall2(pmaddwd, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007090 }
7091
John Bauman19bac1e2014-05-06 15:23:49 -04007092 RValue<Short8> pmulhw(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04007093 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007094 llvm::Function *pmulhw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pmulh_w);
John Bauman89401822014-05-06 15:04:28 -04007095
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007096 return RValue<Short8>(V(::builder->CreateCall2(pmulhw, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04007097 }
7098
John Bauman19bac1e2014-05-06 15:23:49 -04007099 RValue<UShort8> pmulhuw(RValue<UShort8> x, RValue<UShort8> y)
John Bauman89401822014-05-06 15:04:28 -04007100 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007101 llvm::Function *pmulhuw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pmulhu_w);
John Bauman89401822014-05-06 15:04:28 -04007102
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007103 return RValue<UShort8>(V(::builder->CreateCall2(pmulhuw, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04007104 }
7105
John Bauman19bac1e2014-05-06 15:23:49 -04007106 RValue<Int4> pmaddwd(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04007107 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007108 llvm::Function *pmaddwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pmadd_wd);
John Bauman89401822014-05-06 15:04:28 -04007109
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007110 return RValue<Int4>(V(::builder->CreateCall2(pmaddwd, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04007111 }
7112
John Bauman19bac1e2014-05-06 15:23:49 -04007113 RValue<Int> movmskps(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04007114 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007115 llvm::Function *movmskps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_movmsk_ps);
John Bauman89401822014-05-06 15:04:28 -04007116
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007117 return RValue<Int>(V(::builder->CreateCall(movmskps, x.value)));
John Bauman89401822014-05-06 15:04:28 -04007118 }
7119
John Bauman19bac1e2014-05-06 15:23:49 -04007120 RValue<Int> pmovmskb(RValue<Byte8> x)
John Bauman89401822014-05-06 15:04:28 -04007121 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007122 llvm::Function *pmovmskb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmovmskb);
John Bauman89401822014-05-06 15:04:28 -04007123
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007124 return RValue<Int>(V(::builder->CreateCall(pmovmskb, As<MMX>(x).value)));
John Bauman89401822014-05-06 15:04:28 -04007125 }
7126
Nicolas Capens81f18302016-01-14 09:32:35 -05007127 //RValue<Int2> movd(RValue<Pointer<Int>> x)
John Bauman89401822014-05-06 15:04:28 -04007128 //{
7129 // Value *element = Nucleus::createLoad(x.value);
7130
7131 //// Value *int2 = UndefValue::get(Int2::getType());
7132 //// int2 = Nucleus::createInsertElement(int2, element, ConstantInt::get(Int::getType(), 0));
7133
7134 // Value *int2 = Nucleus::createBitCast(Nucleus::createZExt(element, Long::getType()), Int2::getType());
7135
7136 // return RValue<Int2>(int2);
7137 //}
7138
John Bauman19bac1e2014-05-06 15:23:49 -04007139 //RValue<Int2> movdq2q(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007140 //{
Nicolas Capens22008782016-10-20 01:11:47 -04007141 // Value *long2 = Nucleus::createBitCast(x.value, T(VectorType::get(Long::getType(), 2)));
John Bauman89401822014-05-06 15:04:28 -04007142 // Value *element = Nucleus::createExtractElement(long2, ConstantInt::get(Int::getType(), 0));
7143
7144 // return RValue<Int2>(Nucleus::createBitCast(element, Int2::getType()));
7145 //}
7146
John Bauman19bac1e2014-05-06 15:23:49 -04007147 RValue<Int4> pmovzxbd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007148 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007149 llvm::Function *pmovzxbd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovzxbd);
John Bauman66b8ab22014-05-06 15:57:45 -04007150
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007151 return RValue<Int4>(V(::builder->CreateCall(pmovzxbd, Nucleus::createBitCast(x.value, Byte16::getType()))));
John Bauman89401822014-05-06 15:04:28 -04007152 }
7153
John Bauman19bac1e2014-05-06 15:23:49 -04007154 RValue<Int4> pmovsxbd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007155 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007156 llvm::Function *pmovsxbd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovsxbd);
John Bauman66b8ab22014-05-06 15:57:45 -04007157
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007158 return RValue<Int4>(V(::builder->CreateCall(pmovsxbd, Nucleus::createBitCast(x.value, SByte16::getType()))));
John Bauman89401822014-05-06 15:04:28 -04007159 }
7160
John Bauman19bac1e2014-05-06 15:23:49 -04007161 RValue<Int4> pmovzxwd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007162 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007163 llvm::Function *pmovzxwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovzxwd);
John Bauman66b8ab22014-05-06 15:57:45 -04007164
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007165 return RValue<Int4>(V(::builder->CreateCall(pmovzxwd, Nucleus::createBitCast(x.value, UShort8::getType()))));
John Bauman89401822014-05-06 15:04:28 -04007166 }
7167
John Bauman19bac1e2014-05-06 15:23:49 -04007168 RValue<Int4> pmovsxwd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007169 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007170 llvm::Function *pmovsxwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovsxwd);
John Bauman66b8ab22014-05-06 15:57:45 -04007171
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007172 return RValue<Int4>(V(::builder->CreateCall(pmovsxwd, Nucleus::createBitCast(x.value, Short8::getType()))));
John Bauman89401822014-05-06 15:04:28 -04007173 }
7174
7175 void emms()
7176 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007177 llvm::Function *emms = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_emms);
John Bauman89401822014-05-06 15:04:28 -04007178
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007179 V(::builder->CreateCall(emms));
John Bauman89401822014-05-06 15:04:28 -04007180 }
7181 }
7182}