blob: d8bda704104b684c62402467a5d843fb09e03a51 [file] [log] [blame]
Nicolas Capens0bac2852016-05-07 06:09:58 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
John Bauman89401822014-05-06 15:04:28 -04002//
Nicolas Capens0bac2852016-05-07 06:09:58 -04003// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
John Bauman89401822014-05-06 15:04:28 -04006//
Nicolas Capens0bac2852016-05-07 06:09:58 -04007// http://www.apache.org/licenses/LICENSE-2.0
John Bauman89401822014-05-06 15:04:28 -04008//
Nicolas Capens0bac2852016-05-07 06:09:58 -04009// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
John Bauman89401822014-05-06 15:04:28 -040014
15#include "Nucleus.hpp"
16
17#include "llvm/Support/IRBuilder.h"
18#include "llvm/Function.h"
19#include "llvm/GlobalVariable.h"
20#include "llvm/Module.h"
21#include "llvm/LLVMContext.h"
22#include "llvm/Constants.h"
23#include "llvm/Intrinsics.h"
John Bauman66b8ab22014-05-06 15:57:45 -040024#include "llvm/PassManager.h"
John Bauman89401822014-05-06 15:04:28 -040025#include "llvm/Analysis/LoopPass.h"
26#include "llvm/Transforms/Scalar.h"
27#include "llvm/Target/TargetData.h"
John Bauman89401822014-05-06 15:04:28 -040028#include "llvm/Target/TargetOptions.h"
John Bauman19bac1e2014-05-06 15:23:49 -040029#include "llvm/Support/TargetSelect.h"
John Bauman89401822014-05-06 15:04:28 -040030#include "../lib/ExecutionEngine/JIT/JIT.h"
John Bauman89401822014-05-06 15:04:28 -040031
Nicolas Capensdaa5d912016-09-28 16:56:36 -040032#include "LLVMRoutine.hpp"
33#include "LLVMRoutineManager.hpp"
John Bauman89401822014-05-06 15:04:28 -040034#include "x86.hpp"
35#include "CPUID.hpp"
36#include "Thread.hpp"
37#include "Memory.hpp"
Nicolas Capens3bbc5e12016-09-27 10:49:52 -040038#include "MutexLock.hpp"
John Bauman89401822014-05-06 15:04:28 -040039
40#include <fstream>
41
Nicolas Capens47dc8672017-04-25 12:54:39 -040042#if defined(__i386__) || defined(__x86_64__)
43#include <xmmintrin.h>
44#endif
45
Nicolas Capenscb122582014-05-06 23:34:44 -040046#if defined(__x86_64__) && defined(_WIN32)
John Bauman66b8ab22014-05-06 15:57:45 -040047extern "C" void X86CompilationCallback()
48{
49 assert(false); // UNIMPLEMENTED
50}
51#endif
52
John Bauman89401822014-05-06 15:04:28 -040053extern "C"
54{
55 bool (*CodeAnalystInitialize)() = 0;
56 void (*CodeAnalystCompleteJITLog)() = 0;
57 bool (*CodeAnalystLogJITCode)(const void *jitCodeStartAddr, unsigned int jitCodeSize, const wchar_t *functionName) = 0;
58}
59
60namespace llvm
61{
62 extern bool JITEmitDebugInfo;
63}
64
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -040065namespace
66{
Nicolas Capensdaa5d912016-09-28 16:56:36 -040067 sw::LLVMRoutineManager *routineManager = nullptr;
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -040068 llvm::ExecutionEngine *executionEngine = nullptr;
69 llvm::IRBuilder<> *builder = nullptr;
70 llvm::LLVMContext *context = nullptr;
71 llvm::Module *module = nullptr;
72 llvm::Function *function = nullptr;
Nicolas Capens3bbc5e12016-09-27 10:49:52 -040073
Jorge E. Moreiraf8faed62016-12-02 17:03:54 -080074 sw::MutexLock codegenMutex;
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -040075}
76
John Bauman89401822014-05-06 15:04:28 -040077namespace sw
78{
John Bauman89401822014-05-06 15:04:28 -040079 using namespace llvm;
John Bauman89401822014-05-06 15:04:28 -040080
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -040081 Optimization optimization[10] = {InstructionCombining, Disabled};
John Bauman89401822014-05-06 15:04:28 -040082
Nicolas Capensc8b67a42016-09-25 15:02:52 -040083 class Type : public llvm::Type {};
Nicolas Capens19336542016-09-26 10:32:29 -040084 class Value : public llvm::Value {};
Nicolas Capensb98fe5c2016-11-09 12:24:06 -050085 class SwitchCases : public llvm::SwitchInst {};
Nicolas Capensc8b67a42016-09-25 15:02:52 -040086 class BasicBlock : public llvm::BasicBlock {};
Nicolas Capensac230122016-09-20 14:30:06 -040087
88 inline Type *T(llvm::Type *t)
89 {
90 return reinterpret_cast<Type*>(t);
91 }
92
Nicolas Capens19336542016-09-26 10:32:29 -040093 inline Value *V(llvm::Value *t)
94 {
95 return reinterpret_cast<Value*>(t);
96 }
97
Nicolas Capensac230122016-09-20 14:30:06 -040098 inline std::vector<llvm::Type*> &T(std::vector<Type*> &t)
99 {
100 return reinterpret_cast<std::vector<llvm::Type*>&>(t);
101 }
102
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400103 inline BasicBlock *B(llvm::BasicBlock *t)
104 {
105 return reinterpret_cast<BasicBlock*>(t);
106 }
107
John Bauman89401822014-05-06 15:04:28 -0400108 Nucleus::Nucleus()
109 {
Nicolas Capens3bbc5e12016-09-27 10:49:52 -0400110 ::codegenMutex.lock(); // Reactor and LLVM are currently not thread safe
Nicolas Capensb7ea9842015-04-01 10:54:59 -0400111
John Bauman19bac1e2014-05-06 15:23:49 -0400112 InitializeNativeTarget();
John Bauman89401822014-05-06 15:04:28 -0400113 JITEmitDebugInfo = false;
114
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400115 if(!::context)
John Bauman89401822014-05-06 15:04:28 -0400116 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400117 ::context = new LLVMContext();
John Bauman89401822014-05-06 15:04:28 -0400118 }
119
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400120 ::module = new Module("", *::context);
Nicolas Capensdaa5d912016-09-28 16:56:36 -0400121 ::routineManager = new LLVMRoutineManager();
John Bauman66b8ab22014-05-06 15:57:45 -0400122
John Bauman89401822014-05-06 15:04:28 -0400123 #if defined(__x86_64__)
124 const char *architecture = "x86-64";
125 #else
126 const char *architecture = "x86";
127 #endif
128
129 SmallVector<std::string, 1> MAttrs;
130 MAttrs.push_back(CPUID::supportsMMX() ? "+mmx" : "-mmx");
131 MAttrs.push_back(CPUID::supportsCMOV() ? "+cmov" : "-cmov");
132 MAttrs.push_back(CPUID::supportsSSE() ? "+sse" : "-sse");
133 MAttrs.push_back(CPUID::supportsSSE2() ? "+sse2" : "-sse2");
134 MAttrs.push_back(CPUID::supportsSSE3() ? "+sse3" : "-sse3");
135 MAttrs.push_back(CPUID::supportsSSSE3() ? "+ssse3" : "-ssse3");
136 MAttrs.push_back(CPUID::supportsSSE4_1() ? "+sse41" : "-sse41");
137
John Bauman19bac1e2014-05-06 15:23:49 -0400138 std::string error;
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400139 TargetMachine *targetMachine = EngineBuilder::selectTarget(::module, architecture, "", MAttrs, Reloc::Default, CodeModel::JITDefault, &error);
140 ::executionEngine = JIT::createJIT(::module, 0, ::routineManager, CodeGenOpt::Aggressive, true, targetMachine);
John Bauman89401822014-05-06 15:04:28 -0400141
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400142 if(!::builder)
John Bauman89401822014-05-06 15:04:28 -0400143 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400144 ::builder = new IRBuilder<>(*::context);
John Bauman89401822014-05-06 15:04:28 -0400145
John Bauman66b8ab22014-05-06 15:57:45 -0400146 #if defined(_WIN32)
147 HMODULE CodeAnalyst = LoadLibrary("CAJitNtfyLib.dll");
148 if(CodeAnalyst)
149 {
150 CodeAnalystInitialize = (bool(*)())GetProcAddress(CodeAnalyst, "CAJIT_Initialize");
151 CodeAnalystCompleteJITLog = (void(*)())GetProcAddress(CodeAnalyst, "CAJIT_CompleteJITLog");
152 CodeAnalystLogJITCode = (bool(*)(const void*, unsigned int, const wchar_t*))GetProcAddress(CodeAnalyst, "CAJIT_LogJITCode");
153
154 CodeAnalystInitialize();
155 }
156 #endif
John Bauman89401822014-05-06 15:04:28 -0400157 }
158 }
159
160 Nucleus::~Nucleus()
161 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400162 delete ::executionEngine;
163 ::executionEngine = nullptr;
John Bauman89401822014-05-06 15:04:28 -0400164
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400165 ::routineManager = nullptr;
166 ::function = nullptr;
167 ::module = nullptr;
Nicolas Capensb7ea9842015-04-01 10:54:59 -0400168
Nicolas Capens3bbc5e12016-09-27 10:49:52 -0400169 ::codegenMutex.unlock();
John Bauman89401822014-05-06 15:04:28 -0400170 }
171
172 Routine *Nucleus::acquireRoutine(const wchar_t *name, bool runOptimizations)
173 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400174 if(::builder->GetInsertBlock()->empty() || !::builder->GetInsertBlock()->back().isTerminator())
John Bauman19bac1e2014-05-06 15:23:49 -0400175 {
Nicolas Capensac230122016-09-20 14:30:06 -0400176 llvm::Type *type = ::function->getReturnType();
John Bauman19bac1e2014-05-06 15:23:49 -0400177
178 if(type->isVoidTy())
179 {
180 createRetVoid();
181 }
182 else
183 {
Nicolas Capens19336542016-09-26 10:32:29 -0400184 createRet(V(UndefValue::get(type)));
John Bauman19bac1e2014-05-06 15:23:49 -0400185 }
186 }
John Bauman89401822014-05-06 15:04:28 -0400187
188 if(false)
189 {
John Bauman66b8ab22014-05-06 15:57:45 -0400190 std::string error;
191 raw_fd_ostream file("llvm-dump-unopt.txt", error);
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400192 ::module->print(file, 0);
John Bauman89401822014-05-06 15:04:28 -0400193 }
194
195 if(runOptimizations)
196 {
197 optimize();
198 }
199
200 if(false)
201 {
John Bauman66b8ab22014-05-06 15:57:45 -0400202 std::string error;
203 raw_fd_ostream file("llvm-dump-opt.txt", error);
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400204 ::module->print(file, 0);
John Bauman89401822014-05-06 15:04:28 -0400205 }
206
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400207 void *entry = ::executionEngine->getPointerToFunction(::function);
Nicolas Capensdaa5d912016-09-28 16:56:36 -0400208 LLVMRoutine *routine = ::routineManager->acquireRoutine(entry);
John Bauman89401822014-05-06 15:04:28 -0400209
210 if(CodeAnalystLogJITCode)
211 {
Nicolas Capensd946e0a2014-06-26 11:31:08 -0400212 CodeAnalystLogJITCode(routine->getEntry(), routine->getCodeSize(), name);
John Bauman89401822014-05-06 15:04:28 -0400213 }
214
215 return routine;
216 }
217
218 void Nucleus::optimize()
219 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400220 static PassManager *passManager = nullptr;
John Bauman66b8ab22014-05-06 15:57:45 -0400221
John Bauman89401822014-05-06 15:04:28 -0400222 if(!passManager)
223 {
224 passManager = new PassManager();
225
226 UnsafeFPMath = true;
227 // NoInfsFPMath = true;
228 // NoNaNsFPMath = true;
229
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400230 passManager->add(new TargetData(*::executionEngine->getTargetData()));
John Bauman89401822014-05-06 15:04:28 -0400231 passManager->add(createScalarReplAggregatesPass());
232
233 for(int pass = 0; pass < 10 && optimization[pass] != Disabled; pass++)
234 {
235 switch(optimization[pass])
236 {
237 case Disabled: break;
238 case CFGSimplification: passManager->add(createCFGSimplificationPass()); break;
239 case LICM: passManager->add(createLICMPass()); break;
240 case AggressiveDCE: passManager->add(createAggressiveDCEPass()); break;
241 case GVN: passManager->add(createGVNPass()); break;
242 case InstructionCombining: passManager->add(createInstructionCombiningPass()); break;
243 case Reassociate: passManager->add(createReassociatePass()); break;
244 case DeadStoreElimination: passManager->add(createDeadStoreEliminationPass()); break;
245 case SCCP: passManager->add(createSCCPPass()); break;
John Bauman19bac1e2014-05-06 15:23:49 -0400246 case ScalarReplAggregates: passManager->add(createScalarReplAggregatesPass()); break;
John Bauman89401822014-05-06 15:04:28 -0400247 default:
248 assert(false);
249 }
250 }
251 }
252
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400253 passManager->run(*::module);
John Bauman89401822014-05-06 15:04:28 -0400254 }
255
John Bauman19bac1e2014-05-06 15:23:49 -0400256 Value *Nucleus::allocateStackVariable(Type *type, int arraySize)
John Bauman89401822014-05-06 15:04:28 -0400257 {
258 // Need to allocate it in the entry block for mem2reg to work
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400259 llvm::BasicBlock &entryBlock = ::function->getEntryBlock();
John Bauman89401822014-05-06 15:04:28 -0400260
261 Instruction *declaration;
262
263 if(arraySize)
264 {
265 declaration = new AllocaInst(type, Nucleus::createConstantInt(arraySize));
266 }
267 else
268 {
269 declaration = new AllocaInst(type, (Value*)0);
270 }
271
272 entryBlock.getInstList().push_front(declaration);
273
Nicolas Capens19336542016-09-26 10:32:29 -0400274 return V(declaration);
John Bauman89401822014-05-06 15:04:28 -0400275 }
276
277 BasicBlock *Nucleus::createBasicBlock()
278 {
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400279 return B(BasicBlock::Create(*::context, "", ::function));
John Bauman89401822014-05-06 15:04:28 -0400280 }
281
282 BasicBlock *Nucleus::getInsertBlock()
283 {
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400284 return B(::builder->GetInsertBlock());
John Bauman89401822014-05-06 15:04:28 -0400285 }
286
287 void Nucleus::setInsertBlock(BasicBlock *basicBlock)
288 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400289 // assert(::builder->GetInsertBlock()->back().isTerminator());
290 return ::builder->SetInsertPoint(basicBlock);
John Bauman89401822014-05-06 15:04:28 -0400291 }
292
Nicolas Capensac230122016-09-20 14:30:06 -0400293 void Nucleus::createFunction(Type *ReturnType, std::vector<Type*> &Params)
John Bauman89401822014-05-06 15:04:28 -0400294 {
Nicolas Capensac230122016-09-20 14:30:06 -0400295 llvm::FunctionType *functionType = llvm::FunctionType::get(ReturnType, T(Params), false);
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400296 ::function = llvm::Function::Create(functionType, llvm::GlobalValue::InternalLinkage, "", ::module);
297 ::function->setCallingConv(llvm::CallingConv::C);
John Bauman89401822014-05-06 15:04:28 -0400298
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400299 ::builder->SetInsertPoint(BasicBlock::Create(*::context, "", ::function));
John Bauman89401822014-05-06 15:04:28 -0400300 }
301
Nicolas Capens19336542016-09-26 10:32:29 -0400302 Value *Nucleus::getArgument(unsigned int index)
John Bauman89401822014-05-06 15:04:28 -0400303 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400304 llvm::Function::arg_iterator args = ::function->arg_begin();
John Bauman89401822014-05-06 15:04:28 -0400305
306 while(index)
307 {
308 args++;
309 index--;
310 }
311
Nicolas Capens19336542016-09-26 10:32:29 -0400312 return V(&*args);
John Bauman89401822014-05-06 15:04:28 -0400313 }
314
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400315 void Nucleus::createRetVoid()
John Bauman89401822014-05-06 15:04:28 -0400316 {
John Bauman66b8ab22014-05-06 15:57:45 -0400317 x86::emms();
318
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400319 ::builder->CreateRetVoid();
John Bauman89401822014-05-06 15:04:28 -0400320 }
321
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400322 void Nucleus::createRet(Value *v)
John Bauman89401822014-05-06 15:04:28 -0400323 {
John Bauman66b8ab22014-05-06 15:57:45 -0400324 x86::emms();
325
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400326 ::builder->CreateRet(v);
John Bauman89401822014-05-06 15:04:28 -0400327 }
328
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400329 void Nucleus::createBr(BasicBlock *dest)
John Bauman89401822014-05-06 15:04:28 -0400330 {
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400331 ::builder->CreateBr(dest);
John Bauman89401822014-05-06 15:04:28 -0400332 }
333
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400334 void Nucleus::createCondBr(Value *cond, BasicBlock *ifTrue, BasicBlock *ifFalse)
John Bauman89401822014-05-06 15:04:28 -0400335 {
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400336 ::builder->CreateCondBr(cond, ifTrue, ifFalse);
John Bauman89401822014-05-06 15:04:28 -0400337 }
338
339 Value *Nucleus::createAdd(Value *lhs, Value *rhs)
340 {
Nicolas Capens19336542016-09-26 10:32:29 -0400341 return V(::builder->CreateAdd(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400342 }
343
344 Value *Nucleus::createSub(Value *lhs, Value *rhs)
345 {
Nicolas Capens19336542016-09-26 10:32:29 -0400346 return V(::builder->CreateSub(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400347 }
348
349 Value *Nucleus::createMul(Value *lhs, Value *rhs)
350 {
Nicolas Capens19336542016-09-26 10:32:29 -0400351 return V(::builder->CreateMul(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400352 }
353
354 Value *Nucleus::createUDiv(Value *lhs, Value *rhs)
355 {
Nicolas Capens19336542016-09-26 10:32:29 -0400356 return V(::builder->CreateUDiv(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400357 }
358
359 Value *Nucleus::createSDiv(Value *lhs, Value *rhs)
360 {
Nicolas Capens19336542016-09-26 10:32:29 -0400361 return V(::builder->CreateSDiv(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400362 }
363
364 Value *Nucleus::createFAdd(Value *lhs, Value *rhs)
365 {
Nicolas Capens19336542016-09-26 10:32:29 -0400366 return V(::builder->CreateFAdd(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400367 }
368
369 Value *Nucleus::createFSub(Value *lhs, Value *rhs)
370 {
Nicolas Capens19336542016-09-26 10:32:29 -0400371 return V(::builder->CreateFSub(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400372 }
373
374 Value *Nucleus::createFMul(Value *lhs, Value *rhs)
375 {
Nicolas Capens19336542016-09-26 10:32:29 -0400376 return V(::builder->CreateFMul(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400377 }
378
379 Value *Nucleus::createFDiv(Value *lhs, Value *rhs)
380 {
Nicolas Capens19336542016-09-26 10:32:29 -0400381 return V(::builder->CreateFDiv(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400382 }
383
384 Value *Nucleus::createURem(Value *lhs, Value *rhs)
385 {
Nicolas Capens19336542016-09-26 10:32:29 -0400386 return V(::builder->CreateURem(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400387 }
388
389 Value *Nucleus::createSRem(Value *lhs, Value *rhs)
390 {
Nicolas Capens19336542016-09-26 10:32:29 -0400391 return V(::builder->CreateSRem(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400392 }
393
394 Value *Nucleus::createFRem(Value *lhs, Value *rhs)
395 {
Nicolas Capens19336542016-09-26 10:32:29 -0400396 return V(::builder->CreateFRem(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400397 }
398
399 Value *Nucleus::createShl(Value *lhs, Value *rhs)
400 {
Nicolas Capens19336542016-09-26 10:32:29 -0400401 return V(::builder->CreateShl(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400402 }
403
404 Value *Nucleus::createLShr(Value *lhs, Value *rhs)
405 {
Nicolas Capens19336542016-09-26 10:32:29 -0400406 return V(::builder->CreateLShr(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400407 }
408
409 Value *Nucleus::createAShr(Value *lhs, Value *rhs)
410 {
Nicolas Capens19336542016-09-26 10:32:29 -0400411 return V(::builder->CreateAShr(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400412 }
413
414 Value *Nucleus::createAnd(Value *lhs, Value *rhs)
415 {
Nicolas Capens19336542016-09-26 10:32:29 -0400416 return V(::builder->CreateAnd(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400417 }
418
419 Value *Nucleus::createOr(Value *lhs, Value *rhs)
420 {
Nicolas Capens19336542016-09-26 10:32:29 -0400421 return V(::builder->CreateOr(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400422 }
423
424 Value *Nucleus::createXor(Value *lhs, Value *rhs)
425 {
Nicolas Capens19336542016-09-26 10:32:29 -0400426 return V(::builder->CreateXor(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400427 }
428
Nicolas Capens19336542016-09-26 10:32:29 -0400429 Value *Nucleus::createNeg(Value *v)
John Bauman89401822014-05-06 15:04:28 -0400430 {
Nicolas Capens19336542016-09-26 10:32:29 -0400431 return V(::builder->CreateNeg(v));
John Bauman89401822014-05-06 15:04:28 -0400432 }
433
Nicolas Capens19336542016-09-26 10:32:29 -0400434 Value *Nucleus::createFNeg(Value *v)
John Bauman89401822014-05-06 15:04:28 -0400435 {
Nicolas Capens19336542016-09-26 10:32:29 -0400436 return V(::builder->CreateFNeg(v));
John Bauman89401822014-05-06 15:04:28 -0400437 }
438
Nicolas Capens19336542016-09-26 10:32:29 -0400439 Value *Nucleus::createNot(Value *v)
John Bauman89401822014-05-06 15:04:28 -0400440 {
Nicolas Capens19336542016-09-26 10:32:29 -0400441 return V(::builder->CreateNot(v));
John Bauman89401822014-05-06 15:04:28 -0400442 }
443
Nicolas Capense12780d2016-09-27 14:18:07 -0400444 Value *Nucleus::createLoad(Value *ptr, Type *type, bool isVolatile, unsigned int align)
John Bauman89401822014-05-06 15:04:28 -0400445 {
Nicolas Capense12780d2016-09-27 14:18:07 -0400446 assert(ptr->getType()->getContainedType(0) == type);
Nicolas Capens19336542016-09-26 10:32:29 -0400447 return V(::builder->Insert(new LoadInst(ptr, "", isVolatile, align)));
John Bauman89401822014-05-06 15:04:28 -0400448 }
449
Nicolas Capens6d738712016-09-30 04:15:22 -0400450 Value *Nucleus::createStore(Value *value, Value *ptr, Type *type, bool isVolatile, unsigned int align)
John Bauman89401822014-05-06 15:04:28 -0400451 {
Nicolas Capens6d738712016-09-30 04:15:22 -0400452 assert(ptr->getType()->getContainedType(0) == type);
Nicolas Capensb955d5b2016-09-28 22:36:28 -0400453 ::builder->Insert(new StoreInst(value, ptr, isVolatile, align));
454 return value;
John Bauman89401822014-05-06 15:04:28 -0400455 }
456
Nicolas Capensd294def2017-01-26 17:44:37 -0800457 Value *Nucleus::createGEP(Value *ptr, Type *type, Value *index, bool unsignedIndex)
John Bauman89401822014-05-06 15:04:28 -0400458 {
Nicolas Capensd294def2017-01-26 17:44:37 -0800459 if(unsignedIndex && sizeof(void*) == 8)
460 {
461 index = createZExt(index, Long::getType());
462 }
463
Nicolas Capens6d738712016-09-30 04:15:22 -0400464 assert(ptr->getType()->getContainedType(0) == type);
Nicolas Capens19336542016-09-26 10:32:29 -0400465 return V(::builder->CreateGEP(ptr, index));
John Bauman89401822014-05-06 15:04:28 -0400466 }
467
John Bauman19bac1e2014-05-06 15:23:49 -0400468 Value *Nucleus::createAtomicAdd(Value *ptr, Value *value)
469 {
Nicolas Capens19336542016-09-26 10:32:29 -0400470 return V(::builder->CreateAtomicRMW(AtomicRMWInst::Add, ptr, value, SequentiallyConsistent));
John Bauman19bac1e2014-05-06 15:23:49 -0400471 }
472
Nicolas Capens19336542016-09-26 10:32:29 -0400473 Value *Nucleus::createTrunc(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400474 {
Nicolas Capens19336542016-09-26 10:32:29 -0400475 return V(::builder->CreateTrunc(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400476 }
477
Nicolas Capens19336542016-09-26 10:32:29 -0400478 Value *Nucleus::createZExt(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400479 {
Nicolas Capens19336542016-09-26 10:32:29 -0400480 return V(::builder->CreateZExt(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400481 }
482
Nicolas Capens19336542016-09-26 10:32:29 -0400483 Value *Nucleus::createSExt(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400484 {
Nicolas Capens19336542016-09-26 10:32:29 -0400485 return V(::builder->CreateSExt(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400486 }
487
Nicolas Capens19336542016-09-26 10:32:29 -0400488 Value *Nucleus::createFPToSI(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400489 {
Nicolas Capens19336542016-09-26 10:32:29 -0400490 return V(::builder->CreateFPToSI(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400491 }
492
Nicolas Capens19336542016-09-26 10:32:29 -0400493 Value *Nucleus::createSIToFP(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400494 {
Nicolas Capens19336542016-09-26 10:32:29 -0400495 return V(::builder->CreateSIToFP(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400496 }
497
Nicolas Capens19336542016-09-26 10:32:29 -0400498 Value *Nucleus::createFPTrunc(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400499 {
Nicolas Capens19336542016-09-26 10:32:29 -0400500 return V(::builder->CreateFPTrunc(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400501 }
502
Nicolas Capens19336542016-09-26 10:32:29 -0400503 Value *Nucleus::createFPExt(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400504 {
Nicolas Capens19336542016-09-26 10:32:29 -0400505 return V(::builder->CreateFPExt(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400506 }
507
Nicolas Capens19336542016-09-26 10:32:29 -0400508 Value *Nucleus::createBitCast(Value *v, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400509 {
Nicolas Capens19336542016-09-26 10:32:29 -0400510 return V(::builder->CreateBitCast(v, destType));
John Bauman89401822014-05-06 15:04:28 -0400511 }
512
John Bauman89401822014-05-06 15:04:28 -0400513 Value *Nucleus::createICmpEQ(Value *lhs, Value *rhs)
514 {
Nicolas Capens19336542016-09-26 10:32:29 -0400515 return V(::builder->CreateICmpEQ(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400516 }
517
518 Value *Nucleus::createICmpNE(Value *lhs, Value *rhs)
519 {
Nicolas Capens19336542016-09-26 10:32:29 -0400520 return V(::builder->CreateICmpNE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400521 }
522
523 Value *Nucleus::createICmpUGT(Value *lhs, Value *rhs)
524 {
Nicolas Capens19336542016-09-26 10:32:29 -0400525 return V(::builder->CreateICmpUGT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400526 }
527
528 Value *Nucleus::createICmpUGE(Value *lhs, Value *rhs)
529 {
Nicolas Capens19336542016-09-26 10:32:29 -0400530 return V(::builder->CreateICmpUGE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400531 }
532
533 Value *Nucleus::createICmpULT(Value *lhs, Value *rhs)
534 {
Nicolas Capens19336542016-09-26 10:32:29 -0400535 return V(::builder->CreateICmpULT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400536 }
537
538 Value *Nucleus::createICmpULE(Value *lhs, Value *rhs)
539 {
Nicolas Capens19336542016-09-26 10:32:29 -0400540 return V(::builder->CreateICmpULE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400541 }
542
543 Value *Nucleus::createICmpSGT(Value *lhs, Value *rhs)
544 {
Nicolas Capens19336542016-09-26 10:32:29 -0400545 return V(::builder->CreateICmpSGT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400546 }
547
548 Value *Nucleus::createICmpSGE(Value *lhs, Value *rhs)
549 {
Nicolas Capens19336542016-09-26 10:32:29 -0400550 return V(::builder->CreateICmpSGE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400551 }
552
553 Value *Nucleus::createICmpSLT(Value *lhs, Value *rhs)
554 {
Nicolas Capens19336542016-09-26 10:32:29 -0400555 return V(::builder->CreateICmpSLT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400556 }
557
558 Value *Nucleus::createICmpSLE(Value *lhs, Value *rhs)
559 {
Nicolas Capens19336542016-09-26 10:32:29 -0400560 return V(::builder->CreateICmpSLE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400561 }
562
563 Value *Nucleus::createFCmpOEQ(Value *lhs, Value *rhs)
564 {
Nicolas Capens19336542016-09-26 10:32:29 -0400565 return V(::builder->CreateFCmpOEQ(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400566 }
567
568 Value *Nucleus::createFCmpOGT(Value *lhs, Value *rhs)
569 {
Nicolas Capens19336542016-09-26 10:32:29 -0400570 return V(::builder->CreateFCmpOGT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400571 }
572
573 Value *Nucleus::createFCmpOGE(Value *lhs, Value *rhs)
574 {
Nicolas Capens19336542016-09-26 10:32:29 -0400575 return V(::builder->CreateFCmpOGE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400576 }
577
578 Value *Nucleus::createFCmpOLT(Value *lhs, Value *rhs)
579 {
Nicolas Capens19336542016-09-26 10:32:29 -0400580 return V(::builder->CreateFCmpOLT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400581 }
582
583 Value *Nucleus::createFCmpOLE(Value *lhs, Value *rhs)
584 {
Nicolas Capens19336542016-09-26 10:32:29 -0400585 return V(::builder->CreateFCmpOLE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400586 }
587
588 Value *Nucleus::createFCmpONE(Value *lhs, Value *rhs)
589 {
Nicolas Capens19336542016-09-26 10:32:29 -0400590 return V(::builder->CreateFCmpONE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400591 }
592
593 Value *Nucleus::createFCmpORD(Value *lhs, Value *rhs)
594 {
Nicolas Capens19336542016-09-26 10:32:29 -0400595 return V(::builder->CreateFCmpORD(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400596 }
597
598 Value *Nucleus::createFCmpUNO(Value *lhs, Value *rhs)
599 {
Nicolas Capens19336542016-09-26 10:32:29 -0400600 return V(::builder->CreateFCmpUNO(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400601 }
602
603 Value *Nucleus::createFCmpUEQ(Value *lhs, Value *rhs)
604 {
Nicolas Capens19336542016-09-26 10:32:29 -0400605 return V(::builder->CreateFCmpUEQ(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400606 }
607
608 Value *Nucleus::createFCmpUGT(Value *lhs, Value *rhs)
609 {
Nicolas Capens19336542016-09-26 10:32:29 -0400610 return V(::builder->CreateFCmpUGT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400611 }
612
613 Value *Nucleus::createFCmpUGE(Value *lhs, Value *rhs)
614 {
Nicolas Capens19336542016-09-26 10:32:29 -0400615 return V(::builder->CreateFCmpUGE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400616 }
617
618 Value *Nucleus::createFCmpULT(Value *lhs, Value *rhs)
619 {
Nicolas Capens19336542016-09-26 10:32:29 -0400620 return V(::builder->CreateFCmpULT(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400621 }
622
623 Value *Nucleus::createFCmpULE(Value *lhs, Value *rhs)
624 {
Nicolas Capens19336542016-09-26 10:32:29 -0400625 return V(::builder->CreateFCmpULE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400626 }
627
628 Value *Nucleus::createFCmpUNE(Value *lhs, Value *rhs)
629 {
Nicolas Capens19336542016-09-26 10:32:29 -0400630 return V(::builder->CreateFCmpULE(lhs, rhs));
John Bauman89401822014-05-06 15:04:28 -0400631 }
632
Nicolas Capense95d5342016-09-30 11:37:28 -0400633 Value *Nucleus::createExtractElement(Value *vector, Type *type, int index)
John Bauman89401822014-05-06 15:04:28 -0400634 {
Nicolas Capense95d5342016-09-30 11:37:28 -0400635 assert(vector->getType()->getContainedType(0) == type);
Nicolas Capens19336542016-09-26 10:32:29 -0400636 return V(::builder->CreateExtractElement(vector, createConstantInt(index)));
John Bauman89401822014-05-06 15:04:28 -0400637 }
638
639 Value *Nucleus::createInsertElement(Value *vector, Value *element, int index)
640 {
Nicolas Capens19336542016-09-26 10:32:29 -0400641 return V(::builder->CreateInsertElement(vector, element, createConstantInt(index)));
John Bauman89401822014-05-06 15:04:28 -0400642 }
643
Nicolas Capense89cd582016-09-30 14:23:47 -0400644 Value *Nucleus::createShuffleVector(Value *V1, Value *V2, const int *select)
John Bauman89401822014-05-06 15:04:28 -0400645 {
Nicolas Capense89cd582016-09-30 14:23:47 -0400646 int size = llvm::cast<llvm::VectorType>(V1->getType())->getNumElements();
647 const int maxSize = 16;
648 llvm::Constant *swizzle[maxSize];
649 assert(size <= maxSize);
650
651 for(int i = 0; i < size; i++)
652 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400653 swizzle[i] = llvm::ConstantInt::get(Type::getInt32Ty(*::context), select[i]);
Nicolas Capense89cd582016-09-30 14:23:47 -0400654 }
655
656 llvm::Value *shuffle = llvm::ConstantVector::get(llvm::ArrayRef<llvm::Constant*>(swizzle, size));
657
658 return V(::builder->CreateShuffleVector(V1, V2, shuffle));
John Bauman89401822014-05-06 15:04:28 -0400659 }
660
661 Value *Nucleus::createSelect(Value *C, Value *ifTrue, Value *ifFalse)
662 {
Nicolas Capens19336542016-09-26 10:32:29 -0400663 return V(::builder->CreateSelect(C, ifTrue, ifFalse));
John Bauman89401822014-05-06 15:04:28 -0400664 }
665
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500666 SwitchCases *Nucleus::createSwitch(Value *control, BasicBlock *defaultBranch, unsigned numCases)
John Bauman89401822014-05-06 15:04:28 -0400667 {
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500668 return reinterpret_cast<SwitchCases*>(::builder->CreateSwitch(control, defaultBranch, numCases));
John Bauman89401822014-05-06 15:04:28 -0400669 }
670
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500671 void Nucleus::addSwitchCase(SwitchCases *switchCases, int label, BasicBlock *branch)
John Bauman89401822014-05-06 15:04:28 -0400672 {
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500673 switchCases->addCase(llvm::ConstantInt::get(Type::getInt32Ty(*::context), label, true), branch);
John Bauman89401822014-05-06 15:04:28 -0400674 }
675
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400676 void Nucleus::createUnreachable()
John Bauman89401822014-05-06 15:04:28 -0400677 {
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400678 ::builder->CreateUnreachable();
John Bauman89401822014-05-06 15:04:28 -0400679 }
680
Nicolas Capense95d5342016-09-30 11:37:28 -0400681 static Value *createSwizzle4(Value *val, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -0400682 {
Nicolas Capense89cd582016-09-30 14:23:47 -0400683 int swizzle[4] =
684 {
685 (select >> 0) & 0x03,
686 (select >> 2) & 0x03,
687 (select >> 4) & 0x03,
688 (select >> 6) & 0x03,
689 };
John Bauman89401822014-05-06 15:04:28 -0400690
Nicolas Capense89cd582016-09-30 14:23:47 -0400691 return Nucleus::createShuffleVector(val, val, swizzle);
John Bauman89401822014-05-06 15:04:28 -0400692 }
693
Nicolas Capense95d5342016-09-30 11:37:28 -0400694 static Value *createMask4(Value *lhs, Value *rhs, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -0400695 {
696 bool mask[4] = {false, false, false, false};
697
698 mask[(select >> 0) & 0x03] = true;
699 mask[(select >> 2) & 0x03] = true;
700 mask[(select >> 4) & 0x03] = true;
701 mask[(select >> 6) & 0x03] = true;
702
Nicolas Capense89cd582016-09-30 14:23:47 -0400703 int swizzle[4] =
704 {
705 mask[0] ? 4 : 0,
706 mask[1] ? 5 : 1,
707 mask[2] ? 6 : 2,
708 mask[3] ? 7 : 3,
709 };
John Bauman89401822014-05-06 15:04:28 -0400710
Nicolas Capensa29d6532016-12-05 21:38:09 -0500711 return Nucleus::createShuffleVector(lhs, rhs, swizzle);
John Bauman89401822014-05-06 15:04:28 -0400712 }
713
Nicolas Capensac230122016-09-20 14:30:06 -0400714 Type *Nucleus::getPointerType(Type *ElementType)
John Bauman89401822014-05-06 15:04:28 -0400715 {
Nicolas Capensac230122016-09-20 14:30:06 -0400716 return T(llvm::PointerType::get(ElementType, 0));
John Bauman89401822014-05-06 15:04:28 -0400717 }
718
Nicolas Capens13ac2322016-10-13 14:52:12 -0400719 Value *Nucleus::createNullValue(Type *Ty)
John Bauman89401822014-05-06 15:04:28 -0400720 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400721 return V(llvm::Constant::getNullValue(Ty));
John Bauman89401822014-05-06 15:04:28 -0400722 }
723
Nicolas Capens13ac2322016-10-13 14:52:12 -0400724 Value *Nucleus::createConstantLong(int64_t i)
John Bauman89401822014-05-06 15:04:28 -0400725 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400726 return V(llvm::ConstantInt::get(Type::getInt64Ty(*::context), i, true));
John Bauman89401822014-05-06 15:04:28 -0400727 }
728
Nicolas Capens13ac2322016-10-13 14:52:12 -0400729 Value *Nucleus::createConstantInt(int i)
John Bauman89401822014-05-06 15:04:28 -0400730 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400731 return V(llvm::ConstantInt::get(Type::getInt32Ty(*::context), i, true));
John Bauman89401822014-05-06 15:04:28 -0400732 }
733
Nicolas Capens13ac2322016-10-13 14:52:12 -0400734 Value *Nucleus::createConstantInt(unsigned int i)
John Bauman89401822014-05-06 15:04:28 -0400735 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400736 return V(llvm::ConstantInt::get(Type::getInt32Ty(*::context), i, false));
John Bauman89401822014-05-06 15:04:28 -0400737 }
738
Nicolas Capens13ac2322016-10-13 14:52:12 -0400739 Value *Nucleus::createConstantBool(bool b)
John Bauman89401822014-05-06 15:04:28 -0400740 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400741 return V(llvm::ConstantInt::get(Type::getInt1Ty(*::context), b));
John Bauman89401822014-05-06 15:04:28 -0400742 }
743
Nicolas Capens13ac2322016-10-13 14:52:12 -0400744 Value *Nucleus::createConstantByte(signed char i)
John Bauman89401822014-05-06 15:04:28 -0400745 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400746 return V(llvm::ConstantInt::get(Type::getInt8Ty(*::context), i, true));
John Bauman89401822014-05-06 15:04:28 -0400747 }
748
Nicolas Capens13ac2322016-10-13 14:52:12 -0400749 Value *Nucleus::createConstantByte(unsigned char i)
John Bauman89401822014-05-06 15:04:28 -0400750 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400751 return V(llvm::ConstantInt::get(Type::getInt8Ty(*::context), i, false));
John Bauman89401822014-05-06 15:04:28 -0400752 }
753
Nicolas Capens13ac2322016-10-13 14:52:12 -0400754 Value *Nucleus::createConstantShort(short i)
John Bauman89401822014-05-06 15:04:28 -0400755 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400756 return V(llvm::ConstantInt::get(Type::getInt16Ty(*::context), i, true));
John Bauman89401822014-05-06 15:04:28 -0400757 }
758
Nicolas Capens13ac2322016-10-13 14:52:12 -0400759 Value *Nucleus::createConstantShort(unsigned short i)
John Bauman89401822014-05-06 15:04:28 -0400760 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400761 return V(llvm::ConstantInt::get(Type::getInt16Ty(*::context), i, false));
John Bauman89401822014-05-06 15:04:28 -0400762 }
763
Nicolas Capens13ac2322016-10-13 14:52:12 -0400764 Value *Nucleus::createConstantFloat(float x)
John Bauman89401822014-05-06 15:04:28 -0400765 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400766 return V(llvm::ConstantFP::get(Float::getType(), x));
John Bauman89401822014-05-06 15:04:28 -0400767 }
768
Nicolas Capens13ac2322016-10-13 14:52:12 -0400769 Value *Nucleus::createNullPointer(Type *Ty)
John Bauman89401822014-05-06 15:04:28 -0400770 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400771 return V(llvm::ConstantPointerNull::get(llvm::PointerType::get(Ty, 0)));
John Bauman89401822014-05-06 15:04:28 -0400772 }
773
Nicolas Capens13ac2322016-10-13 14:52:12 -0400774 Value *Nucleus::createConstantVector(const int64_t *constants, Type *type)
John Bauman89401822014-05-06 15:04:28 -0400775 {
Nicolas Capens13ac2322016-10-13 14:52:12 -0400776 assert(llvm::isa<VectorType>(type));
777 const int numConstants = llvm::cast<VectorType>(type)->getNumElements();
778 assert(numConstants <= 16);
779 llvm::Constant *constantVector[16];
780
781 for(int i = 0; i < numConstants; i++)
782 {
783 constantVector[i] = llvm::ConstantInt::get(type->getContainedType(0), constants[i]);
784 }
785
786 return V(llvm::ConstantVector::get(llvm::ArrayRef<llvm::Constant*>(constantVector, numConstants)));
787 }
788
789 Value *Nucleus::createConstantVector(const double *constants, Type *type)
790 {
791 assert(llvm::isa<VectorType>(type));
792 const int numConstants = llvm::cast<VectorType>(type)->getNumElements();
793 assert(numConstants <= 8);
794 llvm::Constant *constantVector[8];
795
796 for(int i = 0; i < numConstants; i++)
797 {
798 constantVector[i] = llvm::ConstantFP::get(type->getContainedType(0), constants[i]);
799 }
800
801 return V(llvm::ConstantVector::get(llvm::ArrayRef<llvm::Constant*>(constantVector, numConstants)));
John Bauman89401822014-05-06 15:04:28 -0400802 }
803
John Bauman19bac1e2014-05-06 15:23:49 -0400804 Type *Void::getType()
John Bauman89401822014-05-06 15:04:28 -0400805 {
Nicolas Capensac230122016-09-20 14:30:06 -0400806 return T(llvm::Type::getVoidTy(*::context));
John Bauman89401822014-05-06 15:04:28 -0400807 }
808
Nicolas Capens297d26e2016-11-18 12:52:17 -0500809 class MMX : public LValue<MMX>
Nicolas Capens4f738a12016-09-20 15:46:16 -0400810 {
811 public:
812 static Type *getType();
813 };
814
John Bauman19bac1e2014-05-06 15:23:49 -0400815 Type *MMX::getType()
816 {
Nicolas Capensac230122016-09-20 14:30:06 -0400817 return T(llvm::Type::getX86_MMXTy(*::context));
John Bauman19bac1e2014-05-06 15:23:49 -0400818 }
819
Nicolas Capens81f18302016-01-14 09:32:35 -0500820 Bool::Bool(Argument<Bool> argument)
John Bauman89401822014-05-06 15:04:28 -0400821 {
Nicolas Capens81f18302016-01-14 09:32:35 -0500822 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -0400823 }
824
John Bauman89401822014-05-06 15:04:28 -0400825 Bool::Bool(bool x)
826 {
John Bauman66b8ab22014-05-06 15:57:45 -0400827 storeValue(Nucleus::createConstantBool(x));
John Bauman89401822014-05-06 15:04:28 -0400828 }
829
John Bauman19bac1e2014-05-06 15:23:49 -0400830 Bool::Bool(RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400831 {
John Bauman66b8ab22014-05-06 15:57:45 -0400832 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400833 }
834
835 Bool::Bool(const Bool &rhs)
836 {
John Bauman66b8ab22014-05-06 15:57:45 -0400837 Value *value = rhs.loadValue();
838 storeValue(value);
839 }
John Bauman89401822014-05-06 15:04:28 -0400840
John Bauman66b8ab22014-05-06 15:57:45 -0400841 Bool::Bool(const Reference<Bool> &rhs)
842 {
843 Value *value = rhs.loadValue();
844 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400845 }
846
Nicolas Capens96d4e092016-11-18 14:22:38 -0500847 RValue<Bool> Bool::operator=(RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400848 {
John Bauman66b8ab22014-05-06 15:57:45 -0400849 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400850
851 return rhs;
852 }
853
Nicolas Capens96d4e092016-11-18 14:22:38 -0500854 RValue<Bool> Bool::operator=(const 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);
John Bauman89401822014-05-06 15:04:28 -0400858
859 return RValue<Bool>(value);
860 }
861
Nicolas Capens96d4e092016-11-18 14:22:38 -0500862 RValue<Bool> Bool::operator=(const Reference<Bool> &rhs)
John Bauman89401822014-05-06 15:04:28 -0400863 {
John Bauman66b8ab22014-05-06 15:57:45 -0400864 Value *value = rhs.loadValue();
865 storeValue(value);
866
867 return RValue<Bool>(value);
John Bauman89401822014-05-06 15:04:28 -0400868 }
869
John Bauman19bac1e2014-05-06 15:23:49 -0400870 RValue<Bool> operator!(RValue<Bool> val)
John Bauman89401822014-05-06 15:04:28 -0400871 {
872 return RValue<Bool>(Nucleus::createNot(val.value));
873 }
874
John Bauman19bac1e2014-05-06 15:23:49 -0400875 RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400876 {
877 return RValue<Bool>(Nucleus::createAnd(lhs.value, rhs.value));
878 }
879
John Bauman19bac1e2014-05-06 15:23:49 -0400880 RValue<Bool> operator||(RValue<Bool> lhs, RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400881 {
882 return RValue<Bool>(Nucleus::createOr(lhs.value, rhs.value));
883 }
884
John Bauman19bac1e2014-05-06 15:23:49 -0400885 Type *Bool::getType()
John Bauman89401822014-05-06 15:04:28 -0400886 {
Nicolas Capensac230122016-09-20 14:30:06 -0400887 return T(llvm::Type::getInt1Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -0400888 }
889
Nicolas Capens81f18302016-01-14 09:32:35 -0500890 Byte::Byte(Argument<Byte> argument)
John Bauman89401822014-05-06 15:04:28 -0400891 {
Nicolas Capens81f18302016-01-14 09:32:35 -0500892 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -0400893 }
894
John Bauman19bac1e2014-05-06 15:23:49 -0400895 Byte::Byte(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -0400896 {
John Bauman89401822014-05-06 15:04:28 -0400897 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
898
John Bauman66b8ab22014-05-06 15:57:45 -0400899 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -0400900 }
901
Alexis Hetu77dfab42015-11-23 13:31:22 -0500902 Byte::Byte(RValue<UInt> cast)
903 {
904 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
905
906 storeValue(integer);
907 }
908
909 Byte::Byte(RValue<UShort> cast)
910 {
911 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
912
913 storeValue(integer);
914 }
915
John Bauman89401822014-05-06 15:04:28 -0400916 Byte::Byte(int x)
917 {
John Bauman66b8ab22014-05-06 15:57:45 -0400918 storeValue(Nucleus::createConstantByte((unsigned char)x));
John Bauman89401822014-05-06 15:04:28 -0400919 }
920
921 Byte::Byte(unsigned char x)
922 {
John Bauman66b8ab22014-05-06 15:57:45 -0400923 storeValue(Nucleus::createConstantByte(x));
John Bauman89401822014-05-06 15:04:28 -0400924 }
925
John Bauman19bac1e2014-05-06 15:23:49 -0400926 Byte::Byte(RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400927 {
John Bauman66b8ab22014-05-06 15:57:45 -0400928 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400929 }
930
931 Byte::Byte(const Byte &rhs)
932 {
John Bauman66b8ab22014-05-06 15:57:45 -0400933 Value *value = rhs.loadValue();
934 storeValue(value);
935 }
John Bauman89401822014-05-06 15:04:28 -0400936
John Bauman66b8ab22014-05-06 15:57:45 -0400937 Byte::Byte(const Reference<Byte> &rhs)
938 {
939 Value *value = rhs.loadValue();
940 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400941 }
942
Nicolas Capens96d4e092016-11-18 14:22:38 -0500943 RValue<Byte> Byte::operator=(RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400944 {
John Bauman66b8ab22014-05-06 15:57:45 -0400945 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400946
947 return rhs;
948 }
949
Nicolas Capens96445fe2016-12-15 14:45:13 -0500950 RValue<Byte> Byte::operator=(const 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);
John Bauman89401822014-05-06 15:04:28 -0400954
955 return RValue<Byte>(value);
956 }
957
Nicolas Capens96d4e092016-11-18 14:22:38 -0500958 RValue<Byte> Byte::operator=(const Reference<Byte> &rhs)
John Bauman89401822014-05-06 15:04:28 -0400959 {
John Bauman66b8ab22014-05-06 15:57:45 -0400960 Value *value = rhs.loadValue();
961 storeValue(value);
962
963 return RValue<Byte>(value);
John Bauman89401822014-05-06 15:04:28 -0400964 }
965
John Bauman19bac1e2014-05-06 15:23:49 -0400966 RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400967 {
968 return RValue<Byte>(Nucleus::createAdd(lhs.value, rhs.value));
969 }
970
John Bauman19bac1e2014-05-06 15:23:49 -0400971 RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400972 {
973 return RValue<Byte>(Nucleus::createSub(lhs.value, rhs.value));
974 }
975
John Bauman19bac1e2014-05-06 15:23:49 -0400976 RValue<Byte> operator*(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400977 {
978 return RValue<Byte>(Nucleus::createMul(lhs.value, rhs.value));
979 }
980
John Bauman19bac1e2014-05-06 15:23:49 -0400981 RValue<Byte> operator/(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400982 {
983 return RValue<Byte>(Nucleus::createUDiv(lhs.value, rhs.value));
984 }
985
John Bauman19bac1e2014-05-06 15:23:49 -0400986 RValue<Byte> operator%(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400987 {
988 return RValue<Byte>(Nucleus::createURem(lhs.value, rhs.value));
989 }
990
John Bauman19bac1e2014-05-06 15:23:49 -0400991 RValue<Byte> operator&(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400992 {
993 return RValue<Byte>(Nucleus::createAnd(lhs.value, rhs.value));
994 }
995
John Bauman19bac1e2014-05-06 15:23:49 -0400996 RValue<Byte> operator|(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400997 {
998 return RValue<Byte>(Nucleus::createOr(lhs.value, rhs.value));
999 }
1000
John Bauman19bac1e2014-05-06 15:23:49 -04001001 RValue<Byte> operator^(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001002 {
1003 return RValue<Byte>(Nucleus::createXor(lhs.value, rhs.value));
1004 }
1005
John Bauman19bac1e2014-05-06 15:23:49 -04001006 RValue<Byte> operator<<(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001007 {
1008 return RValue<Byte>(Nucleus::createShl(lhs.value, rhs.value));
1009 }
1010
John Bauman19bac1e2014-05-06 15:23:49 -04001011 RValue<Byte> operator>>(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001012 {
1013 return RValue<Byte>(Nucleus::createLShr(lhs.value, rhs.value));
1014 }
1015
Nicolas Capens96d4e092016-11-18 14:22:38 -05001016 RValue<Byte> operator+=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001017 {
1018 return lhs = lhs + rhs;
1019 }
1020
Nicolas Capens96d4e092016-11-18 14:22:38 -05001021 RValue<Byte> operator-=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001022 {
1023 return lhs = lhs - rhs;
1024 }
1025
Nicolas Capens96d4e092016-11-18 14:22:38 -05001026 RValue<Byte> operator*=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001027 {
1028 return lhs = lhs * rhs;
1029 }
1030
Nicolas Capens96d4e092016-11-18 14:22:38 -05001031 RValue<Byte> operator/=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001032 {
1033 return lhs = lhs / rhs;
1034 }
1035
Nicolas Capens96d4e092016-11-18 14:22:38 -05001036 RValue<Byte> operator%=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001037 {
1038 return lhs = lhs % rhs;
1039 }
1040
Nicolas Capens96d4e092016-11-18 14:22:38 -05001041 RValue<Byte> operator&=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001042 {
1043 return lhs = lhs & rhs;
1044 }
1045
Nicolas Capens96d4e092016-11-18 14:22:38 -05001046 RValue<Byte> operator|=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001047 {
1048 return lhs = lhs | rhs;
1049 }
1050
Nicolas Capens96d4e092016-11-18 14:22:38 -05001051 RValue<Byte> operator^=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001052 {
1053 return lhs = lhs ^ rhs;
1054 }
1055
Nicolas Capens96d4e092016-11-18 14:22:38 -05001056 RValue<Byte> operator<<=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001057 {
1058 return lhs = lhs << rhs;
1059 }
1060
Nicolas Capens96d4e092016-11-18 14:22:38 -05001061 RValue<Byte> operator>>=(Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001062 {
1063 return lhs = lhs >> rhs;
1064 }
1065
John Bauman19bac1e2014-05-06 15:23:49 -04001066 RValue<Byte> operator+(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001067 {
1068 return val;
1069 }
1070
John Bauman19bac1e2014-05-06 15:23:49 -04001071 RValue<Byte> operator-(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001072 {
1073 return RValue<Byte>(Nucleus::createNeg(val.value));
1074 }
1075
John Bauman19bac1e2014-05-06 15:23:49 -04001076 RValue<Byte> operator~(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001077 {
1078 return RValue<Byte>(Nucleus::createNot(val.value));
1079 }
1080
Nicolas Capens96d4e092016-11-18 14:22:38 -05001081 RValue<Byte> operator++(Byte &val, int) // Post-increment
John Bauman89401822014-05-06 15:04:28 -04001082 {
1083 RValue<Byte> res = val;
1084
Nicolas Capens19336542016-09-26 10:32:29 -04001085 Value *inc = Nucleus::createAdd(res.value, 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 res;
1089 }
1090
Nicolas Capens96d4e092016-11-18 14:22:38 -05001091 const Byte &operator++(Byte &val) // Pre-increment
John Bauman89401822014-05-06 15:04:28 -04001092 {
Nicolas Capens19336542016-09-26 10:32:29 -04001093 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantByte((unsigned char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001094 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001095
1096 return val;
1097 }
1098
Nicolas Capens96d4e092016-11-18 14:22:38 -05001099 RValue<Byte> operator--(Byte &val, int) // Post-decrement
John Bauman89401822014-05-06 15:04:28 -04001100 {
1101 RValue<Byte> res = val;
1102
Nicolas Capens19336542016-09-26 10:32:29 -04001103 Value *inc = Nucleus::createSub(res.value, 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 res;
1107 }
1108
Nicolas Capens96d4e092016-11-18 14:22:38 -05001109 const Byte &operator--(Byte &val) // Pre-decrement
John Bauman89401822014-05-06 15:04:28 -04001110 {
Nicolas Capens19336542016-09-26 10:32:29 -04001111 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantByte((unsigned char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001112 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001113
1114 return val;
1115 }
1116
John Bauman19bac1e2014-05-06 15:23:49 -04001117 RValue<Bool> operator<(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001118 {
1119 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1120 }
1121
John Bauman19bac1e2014-05-06 15:23:49 -04001122 RValue<Bool> operator<=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001123 {
1124 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1125 }
1126
John Bauman19bac1e2014-05-06 15:23:49 -04001127 RValue<Bool> operator>(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001128 {
1129 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1130 }
1131
John Bauman19bac1e2014-05-06 15:23:49 -04001132 RValue<Bool> operator>=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001133 {
1134 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1135 }
1136
John Bauman19bac1e2014-05-06 15:23:49 -04001137 RValue<Bool> operator!=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001138 {
1139 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1140 }
1141
John Bauman19bac1e2014-05-06 15:23:49 -04001142 RValue<Bool> operator==(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001143 {
1144 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1145 }
1146
John Bauman19bac1e2014-05-06 15:23:49 -04001147 Type *Byte::getType()
John Bauman89401822014-05-06 15:04:28 -04001148 {
Nicolas Capensac230122016-09-20 14:30:06 -04001149 return T(llvm::Type::getInt8Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001150 }
1151
Nicolas Capens81f18302016-01-14 09:32:35 -05001152 SByte::SByte(Argument<SByte> argument)
John Bauman89401822014-05-06 15:04:28 -04001153 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001154 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001155 }
1156
Alexis Hetu77dfab42015-11-23 13:31:22 -05001157 SByte::SByte(RValue<Int> cast)
1158 {
1159 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1160
1161 storeValue(integer);
1162 }
1163
1164 SByte::SByte(RValue<Short> cast)
1165 {
1166 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1167
1168 storeValue(integer);
1169 }
1170
John Bauman89401822014-05-06 15:04:28 -04001171 SByte::SByte(signed char x)
1172 {
John Bauman66b8ab22014-05-06 15:57:45 -04001173 storeValue(Nucleus::createConstantByte(x));
John Bauman89401822014-05-06 15:04:28 -04001174 }
1175
John Bauman19bac1e2014-05-06 15:23:49 -04001176 SByte::SByte(RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001177 {
John Bauman66b8ab22014-05-06 15:57:45 -04001178 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001179 }
1180
1181 SByte::SByte(const SByte &rhs)
1182 {
John Bauman66b8ab22014-05-06 15:57:45 -04001183 Value *value = rhs.loadValue();
1184 storeValue(value);
1185 }
John Bauman89401822014-05-06 15:04:28 -04001186
John Bauman66b8ab22014-05-06 15:57:45 -04001187 SByte::SByte(const Reference<SByte> &rhs)
1188 {
1189 Value *value = rhs.loadValue();
1190 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001191 }
1192
Nicolas Capens96d4e092016-11-18 14:22:38 -05001193 RValue<SByte> SByte::operator=(RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001194 {
John Bauman66b8ab22014-05-06 15:57:45 -04001195 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001196
1197 return rhs;
1198 }
1199
Nicolas Capens96d4e092016-11-18 14:22:38 -05001200 RValue<SByte> SByte::operator=(const 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);
John Bauman89401822014-05-06 15:04:28 -04001204
1205 return RValue<SByte>(value);
1206 }
1207
Nicolas Capens96d4e092016-11-18 14:22:38 -05001208 RValue<SByte> SByte::operator=(const Reference<SByte> &rhs)
John Bauman89401822014-05-06 15:04:28 -04001209 {
John Bauman66b8ab22014-05-06 15:57:45 -04001210 Value *value = rhs.loadValue();
1211 storeValue(value);
1212
1213 return RValue<SByte>(value);
John Bauman89401822014-05-06 15:04:28 -04001214 }
1215
John Bauman19bac1e2014-05-06 15:23:49 -04001216 RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001217 {
1218 return RValue<SByte>(Nucleus::createAdd(lhs.value, rhs.value));
1219 }
1220
John Bauman19bac1e2014-05-06 15:23:49 -04001221 RValue<SByte> operator-(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001222 {
1223 return RValue<SByte>(Nucleus::createSub(lhs.value, rhs.value));
1224 }
1225
John Bauman19bac1e2014-05-06 15:23:49 -04001226 RValue<SByte> operator*(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001227 {
1228 return RValue<SByte>(Nucleus::createMul(lhs.value, rhs.value));
1229 }
1230
John Bauman19bac1e2014-05-06 15:23:49 -04001231 RValue<SByte> operator/(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001232 {
1233 return RValue<SByte>(Nucleus::createSDiv(lhs.value, rhs.value));
1234 }
1235
John Bauman19bac1e2014-05-06 15:23:49 -04001236 RValue<SByte> operator%(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001237 {
1238 return RValue<SByte>(Nucleus::createSRem(lhs.value, rhs.value));
1239 }
1240
John Bauman19bac1e2014-05-06 15:23:49 -04001241 RValue<SByte> operator&(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001242 {
1243 return RValue<SByte>(Nucleus::createAnd(lhs.value, rhs.value));
1244 }
1245
John Bauman19bac1e2014-05-06 15:23:49 -04001246 RValue<SByte> operator|(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001247 {
1248 return RValue<SByte>(Nucleus::createOr(lhs.value, rhs.value));
1249 }
1250
John Bauman19bac1e2014-05-06 15:23:49 -04001251 RValue<SByte> operator^(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001252 {
1253 return RValue<SByte>(Nucleus::createXor(lhs.value, rhs.value));
1254 }
1255
John Bauman19bac1e2014-05-06 15:23:49 -04001256 RValue<SByte> operator<<(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001257 {
1258 return RValue<SByte>(Nucleus::createShl(lhs.value, rhs.value));
1259 }
1260
John Bauman19bac1e2014-05-06 15:23:49 -04001261 RValue<SByte> operator>>(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001262 {
1263 return RValue<SByte>(Nucleus::createAShr(lhs.value, rhs.value));
1264 }
1265
Nicolas Capens96d4e092016-11-18 14:22:38 -05001266 RValue<SByte> operator+=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001267 {
1268 return lhs = lhs + rhs;
1269 }
1270
Nicolas Capens96d4e092016-11-18 14:22:38 -05001271 RValue<SByte> operator-=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001272 {
1273 return lhs = lhs - rhs;
1274 }
1275
Nicolas Capens96d4e092016-11-18 14:22:38 -05001276 RValue<SByte> operator*=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001277 {
1278 return lhs = lhs * rhs;
1279 }
1280
Nicolas Capens96d4e092016-11-18 14:22:38 -05001281 RValue<SByte> operator/=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001282 {
1283 return lhs = lhs / rhs;
1284 }
1285
Nicolas Capens96d4e092016-11-18 14:22:38 -05001286 RValue<SByte> operator%=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001287 {
1288 return lhs = lhs % rhs;
1289 }
1290
Nicolas Capens96d4e092016-11-18 14:22:38 -05001291 RValue<SByte> operator&=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001292 {
1293 return lhs = lhs & rhs;
1294 }
1295
Nicolas Capens96d4e092016-11-18 14:22:38 -05001296 RValue<SByte> operator|=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001297 {
1298 return lhs = lhs | rhs;
1299 }
1300
Nicolas Capens96d4e092016-11-18 14:22:38 -05001301 RValue<SByte> operator^=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001302 {
1303 return lhs = lhs ^ rhs;
1304 }
1305
Nicolas Capens96d4e092016-11-18 14:22:38 -05001306 RValue<SByte> operator<<=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001307 {
1308 return lhs = lhs << rhs;
1309 }
1310
Nicolas Capens96d4e092016-11-18 14:22:38 -05001311 RValue<SByte> operator>>=(SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001312 {
1313 return lhs = lhs >> rhs;
1314 }
1315
John Bauman19bac1e2014-05-06 15:23:49 -04001316 RValue<SByte> operator+(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001317 {
1318 return val;
1319 }
1320
John Bauman19bac1e2014-05-06 15:23:49 -04001321 RValue<SByte> operator-(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001322 {
1323 return RValue<SByte>(Nucleus::createNeg(val.value));
1324 }
1325
John Bauman19bac1e2014-05-06 15:23:49 -04001326 RValue<SByte> operator~(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001327 {
1328 return RValue<SByte>(Nucleus::createNot(val.value));
1329 }
1330
Nicolas Capens96d4e092016-11-18 14:22:38 -05001331 RValue<SByte> operator++(SByte &val, int) // Post-increment
John Bauman89401822014-05-06 15:04:28 -04001332 {
1333 RValue<SByte> res = val;
1334
Nicolas Capens19336542016-09-26 10:32:29 -04001335 Value *inc = Nucleus::createAdd(res.value, 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 res;
1339 }
1340
Nicolas Capens96d4e092016-11-18 14:22:38 -05001341 const SByte &operator++(SByte &val) // Pre-increment
John Bauman89401822014-05-06 15:04:28 -04001342 {
Nicolas Capens19336542016-09-26 10:32:29 -04001343 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantByte((signed char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001344 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001345
1346 return val;
1347 }
1348
Nicolas Capens96d4e092016-11-18 14:22:38 -05001349 RValue<SByte> operator--(SByte &val, int) // Post-decrement
John Bauman89401822014-05-06 15:04:28 -04001350 {
1351 RValue<SByte> res = val;
1352
Nicolas Capens19336542016-09-26 10:32:29 -04001353 Value *inc = Nucleus::createSub(res.value, 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 res;
1357 }
1358
Nicolas Capens96d4e092016-11-18 14:22:38 -05001359 const SByte &operator--(SByte &val) // Pre-decrement
John Bauman89401822014-05-06 15:04:28 -04001360 {
Nicolas Capens19336542016-09-26 10:32:29 -04001361 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantByte((signed char)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001362 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001363
1364 return val;
1365 }
1366
John Bauman19bac1e2014-05-06 15:23:49 -04001367 RValue<Bool> operator<(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001368 {
1369 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
1370 }
1371
John Bauman19bac1e2014-05-06 15:23:49 -04001372 RValue<Bool> operator<=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001373 {
1374 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
1375 }
1376
John Bauman19bac1e2014-05-06 15:23:49 -04001377 RValue<Bool> operator>(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001378 {
1379 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
1380 }
1381
John Bauman19bac1e2014-05-06 15:23:49 -04001382 RValue<Bool> operator>=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001383 {
1384 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
1385 }
1386
John Bauman19bac1e2014-05-06 15:23:49 -04001387 RValue<Bool> operator!=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001388 {
1389 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1390 }
1391
John Bauman19bac1e2014-05-06 15:23:49 -04001392 RValue<Bool> operator==(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001393 {
1394 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1395 }
1396
John Bauman19bac1e2014-05-06 15:23:49 -04001397 Type *SByte::getType()
John Bauman89401822014-05-06 15:04:28 -04001398 {
Nicolas Capensac230122016-09-20 14:30:06 -04001399 return T(llvm::Type::getInt8Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001400 }
1401
Nicolas Capens81f18302016-01-14 09:32:35 -05001402 Short::Short(Argument<Short> argument)
John Bauman89401822014-05-06 15:04:28 -04001403 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001404 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001405 }
1406
John Bauman19bac1e2014-05-06 15:23:49 -04001407 Short::Short(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04001408 {
John Bauman89401822014-05-06 15:04:28 -04001409 Value *integer = Nucleus::createTrunc(cast.value, Short::getType());
1410
John Bauman66b8ab22014-05-06 15:57:45 -04001411 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04001412 }
1413
John Bauman89401822014-05-06 15:04:28 -04001414 Short::Short(short x)
1415 {
John Bauman66b8ab22014-05-06 15:57:45 -04001416 storeValue(Nucleus::createConstantShort(x));
John Bauman89401822014-05-06 15:04:28 -04001417 }
1418
John Bauman19bac1e2014-05-06 15:23:49 -04001419 Short::Short(RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001420 {
John Bauman66b8ab22014-05-06 15:57:45 -04001421 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001422 }
1423
1424 Short::Short(const Short &rhs)
1425 {
John Bauman66b8ab22014-05-06 15:57:45 -04001426 Value *value = rhs.loadValue();
1427 storeValue(value);
1428 }
John Bauman89401822014-05-06 15:04:28 -04001429
John Bauman66b8ab22014-05-06 15:57:45 -04001430 Short::Short(const Reference<Short> &rhs)
1431 {
1432 Value *value = rhs.loadValue();
1433 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001434 }
1435
Nicolas Capens96d4e092016-11-18 14:22:38 -05001436 RValue<Short> Short::operator=(RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001437 {
John Bauman66b8ab22014-05-06 15:57:45 -04001438 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001439
1440 return rhs;
1441 }
1442
Nicolas Capens96d4e092016-11-18 14:22:38 -05001443 RValue<Short> Short::operator=(const 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);
John Bauman89401822014-05-06 15:04:28 -04001447
1448 return RValue<Short>(value);
1449 }
1450
Nicolas Capens96d4e092016-11-18 14:22:38 -05001451 RValue<Short> Short::operator=(const Reference<Short> &rhs)
John Bauman89401822014-05-06 15:04:28 -04001452 {
John Bauman66b8ab22014-05-06 15:57:45 -04001453 Value *value = rhs.loadValue();
1454 storeValue(value);
1455
1456 return RValue<Short>(value);
John Bauman89401822014-05-06 15:04:28 -04001457 }
1458
John Bauman19bac1e2014-05-06 15:23:49 -04001459 RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001460 {
1461 return RValue<Short>(Nucleus::createAdd(lhs.value, rhs.value));
1462 }
1463
John Bauman19bac1e2014-05-06 15:23:49 -04001464 RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001465 {
1466 return RValue<Short>(Nucleus::createSub(lhs.value, rhs.value));
1467 }
1468
John Bauman19bac1e2014-05-06 15:23:49 -04001469 RValue<Short> operator*(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001470 {
1471 return RValue<Short>(Nucleus::createMul(lhs.value, rhs.value));
1472 }
1473
John Bauman19bac1e2014-05-06 15:23:49 -04001474 RValue<Short> operator/(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001475 {
1476 return RValue<Short>(Nucleus::createSDiv(lhs.value, rhs.value));
1477 }
1478
John Bauman19bac1e2014-05-06 15:23:49 -04001479 RValue<Short> operator%(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001480 {
1481 return RValue<Short>(Nucleus::createSRem(lhs.value, rhs.value));
1482 }
1483
John Bauman19bac1e2014-05-06 15:23:49 -04001484 RValue<Short> operator&(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001485 {
1486 return RValue<Short>(Nucleus::createAnd(lhs.value, rhs.value));
1487 }
1488
John Bauman19bac1e2014-05-06 15:23:49 -04001489 RValue<Short> operator|(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001490 {
1491 return RValue<Short>(Nucleus::createOr(lhs.value, rhs.value));
1492 }
1493
John Bauman19bac1e2014-05-06 15:23:49 -04001494 RValue<Short> operator^(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001495 {
1496 return RValue<Short>(Nucleus::createXor(lhs.value, rhs.value));
1497 }
1498
John Bauman19bac1e2014-05-06 15:23:49 -04001499 RValue<Short> operator<<(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001500 {
1501 return RValue<Short>(Nucleus::createShl(lhs.value, rhs.value));
1502 }
1503
John Bauman19bac1e2014-05-06 15:23:49 -04001504 RValue<Short> operator>>(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001505 {
1506 return RValue<Short>(Nucleus::createAShr(lhs.value, rhs.value));
1507 }
1508
Nicolas Capens96d4e092016-11-18 14:22:38 -05001509 RValue<Short> operator+=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001510 {
1511 return lhs = lhs + rhs;
1512 }
1513
Nicolas Capens96d4e092016-11-18 14:22:38 -05001514 RValue<Short> operator-=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001515 {
1516 return lhs = lhs - rhs;
1517 }
1518
Nicolas Capens96d4e092016-11-18 14:22:38 -05001519 RValue<Short> operator*=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001520 {
1521 return lhs = lhs * rhs;
1522 }
1523
Nicolas Capens96d4e092016-11-18 14:22:38 -05001524 RValue<Short> operator/=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001525 {
1526 return lhs = lhs / rhs;
1527 }
1528
Nicolas Capens96d4e092016-11-18 14:22:38 -05001529 RValue<Short> operator%=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001530 {
1531 return lhs = lhs % rhs;
1532 }
1533
Nicolas Capens96d4e092016-11-18 14:22:38 -05001534 RValue<Short> operator&=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001535 {
1536 return lhs = lhs & rhs;
1537 }
1538
Nicolas Capens96d4e092016-11-18 14:22:38 -05001539 RValue<Short> operator|=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001540 {
1541 return lhs = lhs | rhs;
1542 }
1543
Nicolas Capens96d4e092016-11-18 14:22:38 -05001544 RValue<Short> operator^=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001545 {
1546 return lhs = lhs ^ rhs;
1547 }
1548
Nicolas Capens96d4e092016-11-18 14:22:38 -05001549 RValue<Short> operator<<=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001550 {
1551 return lhs = lhs << rhs;
1552 }
1553
Nicolas Capens96d4e092016-11-18 14:22:38 -05001554 RValue<Short> operator>>=(Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001555 {
1556 return lhs = lhs >> rhs;
1557 }
1558
John Bauman19bac1e2014-05-06 15:23:49 -04001559 RValue<Short> operator+(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001560 {
1561 return val;
1562 }
1563
John Bauman19bac1e2014-05-06 15:23:49 -04001564 RValue<Short> operator-(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001565 {
1566 return RValue<Short>(Nucleus::createNeg(val.value));
1567 }
1568
John Bauman19bac1e2014-05-06 15:23:49 -04001569 RValue<Short> operator~(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001570 {
1571 return RValue<Short>(Nucleus::createNot(val.value));
1572 }
1573
Nicolas Capens96d4e092016-11-18 14:22:38 -05001574 RValue<Short> operator++(Short &val, int) // Post-increment
John Bauman89401822014-05-06 15:04:28 -04001575 {
1576 RValue<Short> res = val;
1577
Nicolas Capens19336542016-09-26 10:32:29 -04001578 Value *inc = Nucleus::createAdd(res.value, 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 res;
1582 }
1583
Nicolas Capens96d4e092016-11-18 14:22:38 -05001584 const Short &operator++(Short &val) // Pre-increment
John Bauman89401822014-05-06 15:04:28 -04001585 {
Nicolas Capens19336542016-09-26 10:32:29 -04001586 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantShort((short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001587 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001588
1589 return val;
1590 }
1591
Nicolas Capens96d4e092016-11-18 14:22:38 -05001592 RValue<Short> operator--(Short &val, int) // Post-decrement
John Bauman89401822014-05-06 15:04:28 -04001593 {
1594 RValue<Short> res = val;
1595
Nicolas Capens19336542016-09-26 10:32:29 -04001596 Value *inc = Nucleus::createSub(res.value, 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 res;
1600 }
1601
Nicolas Capens96d4e092016-11-18 14:22:38 -05001602 const Short &operator--(Short &val) // Pre-decrement
John Bauman89401822014-05-06 15:04:28 -04001603 {
Nicolas Capens19336542016-09-26 10:32:29 -04001604 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantShort((short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001605 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001606
1607 return val;
1608 }
1609
John Bauman19bac1e2014-05-06 15:23:49 -04001610 RValue<Bool> operator<(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001611 {
1612 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
1613 }
1614
John Bauman19bac1e2014-05-06 15:23:49 -04001615 RValue<Bool> operator<=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001616 {
1617 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
1618 }
1619
John Bauman19bac1e2014-05-06 15:23:49 -04001620 RValue<Bool> operator>(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001621 {
1622 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
1623 }
1624
John Bauman19bac1e2014-05-06 15:23:49 -04001625 RValue<Bool> operator>=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001626 {
1627 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
1628 }
1629
John Bauman19bac1e2014-05-06 15:23:49 -04001630 RValue<Bool> operator!=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001631 {
1632 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1633 }
1634
John Bauman19bac1e2014-05-06 15:23:49 -04001635 RValue<Bool> operator==(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001636 {
1637 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1638 }
1639
John Bauman19bac1e2014-05-06 15:23:49 -04001640 Type *Short::getType()
John Bauman89401822014-05-06 15:04:28 -04001641 {
Nicolas Capensac230122016-09-20 14:30:06 -04001642 return T(llvm::Type::getInt16Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001643 }
1644
Nicolas Capens81f18302016-01-14 09:32:35 -05001645 UShort::UShort(Argument<UShort> argument)
John Bauman89401822014-05-06 15:04:28 -04001646 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001647 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001648 }
1649
Alexis Hetu77dfab42015-11-23 13:31:22 -05001650 UShort::UShort(RValue<UInt> cast)
1651 {
1652 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
1653
1654 storeValue(integer);
1655 }
1656
Alexis Hetu75b650f2015-11-19 17:40:15 -05001657 UShort::UShort(RValue<Int> cast)
1658 {
1659 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
1660
1661 storeValue(integer);
1662 }
1663
John Bauman89401822014-05-06 15:04:28 -04001664 UShort::UShort(unsigned short x)
1665 {
John Bauman66b8ab22014-05-06 15:57:45 -04001666 storeValue(Nucleus::createConstantShort(x));
John Bauman89401822014-05-06 15:04:28 -04001667 }
1668
John Bauman19bac1e2014-05-06 15:23:49 -04001669 UShort::UShort(RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001670 {
John Bauman66b8ab22014-05-06 15:57:45 -04001671 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001672 }
1673
1674 UShort::UShort(const UShort &rhs)
1675 {
John Bauman66b8ab22014-05-06 15:57:45 -04001676 Value *value = rhs.loadValue();
1677 storeValue(value);
1678 }
John Bauman89401822014-05-06 15:04:28 -04001679
John Bauman66b8ab22014-05-06 15:57:45 -04001680 UShort::UShort(const Reference<UShort> &rhs)
1681 {
1682 Value *value = rhs.loadValue();
1683 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001684 }
1685
Nicolas Capens96d4e092016-11-18 14:22:38 -05001686 RValue<UShort> UShort::operator=(RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001687 {
John Bauman66b8ab22014-05-06 15:57:45 -04001688 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001689
1690 return rhs;
1691 }
1692
Nicolas Capens96d4e092016-11-18 14:22:38 -05001693 RValue<UShort> UShort::operator=(const 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);
John Bauman89401822014-05-06 15:04:28 -04001697
1698 return RValue<UShort>(value);
1699 }
1700
Nicolas Capens96d4e092016-11-18 14:22:38 -05001701 RValue<UShort> UShort::operator=(const Reference<UShort> &rhs)
John Bauman89401822014-05-06 15:04:28 -04001702 {
John Bauman66b8ab22014-05-06 15:57:45 -04001703 Value *value = rhs.loadValue();
1704 storeValue(value);
1705
1706 return RValue<UShort>(value);
John Bauman89401822014-05-06 15:04:28 -04001707 }
1708
John Bauman19bac1e2014-05-06 15:23:49 -04001709 RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001710 {
1711 return RValue<UShort>(Nucleus::createAdd(lhs.value, rhs.value));
1712 }
1713
John Bauman19bac1e2014-05-06 15:23:49 -04001714 RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001715 {
1716 return RValue<UShort>(Nucleus::createSub(lhs.value, rhs.value));
1717 }
1718
John Bauman19bac1e2014-05-06 15:23:49 -04001719 RValue<UShort> operator*(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001720 {
1721 return RValue<UShort>(Nucleus::createMul(lhs.value, rhs.value));
1722 }
1723
John Bauman19bac1e2014-05-06 15:23:49 -04001724 RValue<UShort> operator/(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001725 {
1726 return RValue<UShort>(Nucleus::createUDiv(lhs.value, rhs.value));
1727 }
1728
John Bauman19bac1e2014-05-06 15:23:49 -04001729 RValue<UShort> operator%(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001730 {
1731 return RValue<UShort>(Nucleus::createURem(lhs.value, rhs.value));
1732 }
1733
John Bauman19bac1e2014-05-06 15:23:49 -04001734 RValue<UShort> operator&(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001735 {
1736 return RValue<UShort>(Nucleus::createAnd(lhs.value, rhs.value));
1737 }
1738
John Bauman19bac1e2014-05-06 15:23:49 -04001739 RValue<UShort> operator|(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001740 {
1741 return RValue<UShort>(Nucleus::createOr(lhs.value, rhs.value));
1742 }
1743
John Bauman19bac1e2014-05-06 15:23:49 -04001744 RValue<UShort> operator^(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001745 {
1746 return RValue<UShort>(Nucleus::createXor(lhs.value, rhs.value));
1747 }
1748
John Bauman19bac1e2014-05-06 15:23:49 -04001749 RValue<UShort> operator<<(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001750 {
1751 return RValue<UShort>(Nucleus::createShl(lhs.value, rhs.value));
1752 }
1753
John Bauman19bac1e2014-05-06 15:23:49 -04001754 RValue<UShort> operator>>(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001755 {
1756 return RValue<UShort>(Nucleus::createLShr(lhs.value, rhs.value));
1757 }
1758
Nicolas Capens96d4e092016-11-18 14:22:38 -05001759 RValue<UShort> operator+=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001760 {
1761 return lhs = lhs + rhs;
1762 }
1763
Nicolas Capens96d4e092016-11-18 14:22:38 -05001764 RValue<UShort> operator-=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001765 {
1766 return lhs = lhs - rhs;
1767 }
1768
Nicolas Capens96d4e092016-11-18 14:22:38 -05001769 RValue<UShort> operator*=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001770 {
1771 return lhs = lhs * rhs;
1772 }
1773
Nicolas Capens96d4e092016-11-18 14:22:38 -05001774 RValue<UShort> operator/=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001775 {
1776 return lhs = lhs / rhs;
1777 }
1778
Nicolas Capens96d4e092016-11-18 14:22:38 -05001779 RValue<UShort> operator%=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001780 {
1781 return lhs = lhs % rhs;
1782 }
1783
Nicolas Capens96d4e092016-11-18 14:22:38 -05001784 RValue<UShort> operator&=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001785 {
1786 return lhs = lhs & rhs;
1787 }
1788
Nicolas Capens96d4e092016-11-18 14:22:38 -05001789 RValue<UShort> operator|=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001790 {
1791 return lhs = lhs | rhs;
1792 }
1793
Nicolas Capens96d4e092016-11-18 14:22:38 -05001794 RValue<UShort> operator^=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001795 {
1796 return lhs = lhs ^ rhs;
1797 }
1798
Nicolas Capens96d4e092016-11-18 14:22:38 -05001799 RValue<UShort> operator<<=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001800 {
1801 return lhs = lhs << rhs;
1802 }
1803
Nicolas Capens96d4e092016-11-18 14:22:38 -05001804 RValue<UShort> operator>>=(UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001805 {
1806 return lhs = lhs >> rhs;
1807 }
1808
John Bauman19bac1e2014-05-06 15:23:49 -04001809 RValue<UShort> operator+(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001810 {
1811 return val;
1812 }
1813
John Bauman19bac1e2014-05-06 15:23:49 -04001814 RValue<UShort> operator-(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001815 {
1816 return RValue<UShort>(Nucleus::createNeg(val.value));
1817 }
1818
John Bauman19bac1e2014-05-06 15:23:49 -04001819 RValue<UShort> operator~(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001820 {
1821 return RValue<UShort>(Nucleus::createNot(val.value));
1822 }
1823
Nicolas Capens96d4e092016-11-18 14:22:38 -05001824 RValue<UShort> operator++(UShort &val, int) // Post-increment
John Bauman89401822014-05-06 15:04:28 -04001825 {
1826 RValue<UShort> res = val;
1827
Nicolas Capens19336542016-09-26 10:32:29 -04001828 Value *inc = Nucleus::createAdd(res.value, 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 res;
1832 }
1833
Nicolas Capens96d4e092016-11-18 14:22:38 -05001834 const UShort &operator++(UShort &val) // Pre-increment
John Bauman89401822014-05-06 15:04:28 -04001835 {
Nicolas Capens19336542016-09-26 10:32:29 -04001836 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantShort((unsigned short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001837 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001838
1839 return val;
1840 }
1841
Nicolas Capens96d4e092016-11-18 14:22:38 -05001842 RValue<UShort> operator--(UShort &val, int) // Post-decrement
John Bauman89401822014-05-06 15:04:28 -04001843 {
1844 RValue<UShort> res = val;
1845
Nicolas Capens19336542016-09-26 10:32:29 -04001846 Value *inc = Nucleus::createSub(res.value, 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 res;
1850 }
1851
Nicolas Capens96d4e092016-11-18 14:22:38 -05001852 const UShort &operator--(UShort &val) // Pre-decrement
John Bauman89401822014-05-06 15:04:28 -04001853 {
Nicolas Capens19336542016-09-26 10:32:29 -04001854 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantShort((unsigned short)1)));
John Bauman66b8ab22014-05-06 15:57:45 -04001855 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001856
1857 return val;
1858 }
1859
John Bauman19bac1e2014-05-06 15:23:49 -04001860 RValue<Bool> operator<(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001861 {
1862 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1863 }
1864
John Bauman19bac1e2014-05-06 15:23:49 -04001865 RValue<Bool> operator<=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001866 {
1867 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1868 }
1869
John Bauman19bac1e2014-05-06 15:23:49 -04001870 RValue<Bool> operator>(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001871 {
1872 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1873 }
1874
John Bauman19bac1e2014-05-06 15:23:49 -04001875 RValue<Bool> operator>=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001876 {
1877 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1878 }
1879
John Bauman19bac1e2014-05-06 15:23:49 -04001880 RValue<Bool> operator!=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001881 {
1882 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1883 }
1884
John Bauman19bac1e2014-05-06 15:23:49 -04001885 RValue<Bool> operator==(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001886 {
1887 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1888 }
1889
John Bauman19bac1e2014-05-06 15:23:49 -04001890 Type *UShort::getType()
John Bauman89401822014-05-06 15:04:28 -04001891 {
Nicolas Capensac230122016-09-20 14:30:06 -04001892 return T(llvm::Type::getInt16Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001893 }
1894
Nicolas Capens16b5f152016-10-13 13:39:01 -04001895 Byte4::Byte4(RValue<Byte8> cast)
1896 {
Nicolas Capens16b5f152016-10-13 13:39:01 -04001897 storeValue(Nucleus::createTrunc(Nucleus::createBitCast(cast.value, Long::getType()), Int::getType()));
1898 }
1899
1900 Byte4::Byte4(const Reference<Byte4> &rhs)
1901 {
Nicolas Capens16b5f152016-10-13 13:39:01 -04001902 Value *value = rhs.loadValue();
1903 storeValue(value);
1904 }
1905
John Bauman19bac1e2014-05-06 15:23:49 -04001906 Type *Byte4::getType()
John Bauman89401822014-05-06 15:04:28 -04001907 {
1908 #if 0
Nicolas Capensac230122016-09-20 14:30:06 -04001909 return T(VectorType::get(Byte::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04001910 #else
1911 return UInt::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
1912 #endif
1913 }
1914
John Bauman19bac1e2014-05-06 15:23:49 -04001915 Type *SByte4::getType()
John Bauman89401822014-05-06 15:04:28 -04001916 {
1917 #if 0
Nicolas Capensac230122016-09-20 14:30:06 -04001918 return T(VectorType::get(SByte::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04001919 #else
1920 return Int::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
1921 #endif
1922 }
1923
Nicolas Capens3bbc5e12016-09-27 10:49:52 -04001924 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 -04001925 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04001926 int64_t constantVector[8] = {x0, x1, x2, x3, x4, x5, x6, x7};
1927 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(Byte::getType(), 8))));
John Bauman89401822014-05-06 15:04:28 -04001928
John Bauman66b8ab22014-05-06 15:57:45 -04001929 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04001930 }
1931
John Bauman19bac1e2014-05-06 15:23:49 -04001932 Byte8::Byte8(RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04001933 {
John Bauman66b8ab22014-05-06 15:57:45 -04001934 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001935 }
1936
1937 Byte8::Byte8(const Byte8 &rhs)
1938 {
John Bauman66b8ab22014-05-06 15:57:45 -04001939 Value *value = rhs.loadValue();
1940 storeValue(value);
1941 }
1942
1943 Byte8::Byte8(const Reference<Byte8> &rhs)
1944 {
John Bauman66b8ab22014-05-06 15:57:45 -04001945 Value *value = rhs.loadValue();
1946 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001947 }
1948
Nicolas Capens96d4e092016-11-18 14:22:38 -05001949 RValue<Byte8> Byte8::operator=(RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04001950 {
John Bauman66b8ab22014-05-06 15:57:45 -04001951 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001952
1953 return rhs;
1954 }
1955
Nicolas Capens96d4e092016-11-18 14:22:38 -05001956 RValue<Byte8> Byte8::operator=(const Byte8 &rhs)
John Bauman89401822014-05-06 15:04:28 -04001957 {
John Bauman66b8ab22014-05-06 15:57:45 -04001958 Value *value = rhs.loadValue();
1959 storeValue(value);
1960
1961 return RValue<Byte8>(value);
1962 }
1963
Nicolas Capens96d4e092016-11-18 14:22:38 -05001964 RValue<Byte8> Byte8::operator=(const Reference<Byte8> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04001965 {
1966 Value *value = rhs.loadValue();
1967 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001968
1969 return RValue<Byte8>(value);
1970 }
1971
John Bauman19bac1e2014-05-06 15:23:49 -04001972 RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04001973 {
John Bauman19bac1e2014-05-06 15:23:49 -04001974 if(CPUID::supportsMMX2())
1975 {
1976 return x86::paddb(lhs, rhs);
1977 }
1978 else
1979 {
1980 return RValue<Byte8>(Nucleus::createAdd(lhs.value, rhs.value));
1981 }
John Bauman89401822014-05-06 15:04:28 -04001982 }
1983
John Bauman19bac1e2014-05-06 15:23:49 -04001984 RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04001985 {
John Bauman19bac1e2014-05-06 15:23:49 -04001986 if(CPUID::supportsMMX2())
1987 {
1988 return x86::psubb(lhs, rhs);
1989 }
1990 else
1991 {
1992 return RValue<Byte8>(Nucleus::createSub(lhs.value, rhs.value));
1993 }
John Bauman89401822014-05-06 15:04:28 -04001994 }
1995
John Bauman19bac1e2014-05-06 15:23:49 -04001996// RValue<Byte8> operator*(RValue<Byte8> lhs, RValue<Byte8> rhs)
1997// {
1998// return RValue<Byte8>(Nucleus::createMul(lhs.value, rhs.value));
1999// }
2000
2001// RValue<Byte8> operator/(RValue<Byte8> lhs, RValue<Byte8> rhs)
2002// {
2003// return RValue<Byte8>(Nucleus::createUDiv(lhs.value, rhs.value));
2004// }
2005
2006// RValue<Byte8> operator%(RValue<Byte8> lhs, RValue<Byte8> rhs)
2007// {
2008// return RValue<Byte8>(Nucleus::createURem(lhs.value, rhs.value));
2009// }
2010
2011 RValue<Byte8> operator&(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002012 {
John Bauman19bac1e2014-05-06 15:23:49 -04002013 if(CPUID::supportsMMX2())
2014 {
2015 return As<Byte8>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
2016 }
2017 else
2018 {
2019 return RValue<Byte8>(Nucleus::createAnd(lhs.value, rhs.value));
2020 }
John Bauman89401822014-05-06 15:04:28 -04002021 }
2022
John Bauman19bac1e2014-05-06 15:23:49 -04002023 RValue<Byte8> operator|(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002024 {
John Bauman19bac1e2014-05-06 15:23:49 -04002025 if(CPUID::supportsMMX2())
2026 {
2027 return As<Byte8>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
2028 }
2029 else
2030 {
2031 return RValue<Byte8>(Nucleus::createOr(lhs.value, rhs.value));
2032 }
John Bauman89401822014-05-06 15:04:28 -04002033 }
2034
John Bauman19bac1e2014-05-06 15:23:49 -04002035 RValue<Byte8> operator^(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002036 {
John Bauman19bac1e2014-05-06 15:23:49 -04002037 if(CPUID::supportsMMX2())
2038 {
2039 return As<Byte8>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
2040 }
2041 else
John Bauman66b8ab22014-05-06 15:57:45 -04002042 {
John Bauman19bac1e2014-05-06 15:23:49 -04002043 return RValue<Byte8>(Nucleus::createXor(lhs.value, rhs.value));
2044 }
John Bauman89401822014-05-06 15:04:28 -04002045 }
2046
John Bauman19bac1e2014-05-06 15:23:49 -04002047// RValue<Byte8> operator<<(RValue<Byte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002048// {
2049// return RValue<Byte8>(Nucleus::createShl(lhs.value, rhs.value));
2050// }
2051
John Bauman19bac1e2014-05-06 15:23:49 -04002052// RValue<Byte8> operator>>(RValue<Byte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002053// {
2054// return RValue<Byte8>(Nucleus::createLShr(lhs.value, rhs.value));
2055// }
2056
Nicolas Capens96d4e092016-11-18 14:22:38 -05002057 RValue<Byte8> operator+=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002058 {
2059 return lhs = lhs + rhs;
2060 }
2061
Nicolas Capens96d4e092016-11-18 14:22:38 -05002062 RValue<Byte8> operator-=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002063 {
2064 return lhs = lhs - rhs;
2065 }
2066
Nicolas Capens96d4e092016-11-18 14:22:38 -05002067// RValue<Byte8> operator*=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002068// {
2069// return lhs = lhs * rhs;
2070// }
John Bauman89401822014-05-06 15:04:28 -04002071
Nicolas Capens96d4e092016-11-18 14:22:38 -05002072// RValue<Byte8> operator/=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002073// {
2074// return lhs = lhs / rhs;
2075// }
John Bauman89401822014-05-06 15:04:28 -04002076
Nicolas Capens96d4e092016-11-18 14:22:38 -05002077// RValue<Byte8> operator%=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002078// {
2079// return lhs = lhs % rhs;
2080// }
John Bauman89401822014-05-06 15:04:28 -04002081
Nicolas Capens96d4e092016-11-18 14:22:38 -05002082 RValue<Byte8> operator&=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002083 {
2084 return lhs = lhs & rhs;
2085 }
2086
Nicolas Capens96d4e092016-11-18 14:22:38 -05002087 RValue<Byte8> operator|=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002088 {
2089 return lhs = lhs | rhs;
2090 }
2091
Nicolas Capens96d4e092016-11-18 14:22:38 -05002092 RValue<Byte8> operator^=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002093 {
2094 return lhs = lhs ^ rhs;
2095 }
2096
Nicolas Capens96d4e092016-11-18 14:22:38 -05002097// RValue<Byte8> operator<<=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002098// {
2099// return lhs = lhs << rhs;
2100// }
2101
Nicolas Capens96d4e092016-11-18 14:22:38 -05002102// RValue<Byte8> operator>>=(Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002103// {
2104// return lhs = lhs >> rhs;
2105// }
2106
John Bauman19bac1e2014-05-06 15:23:49 -04002107// RValue<Byte8> operator+(RValue<Byte8> val)
2108// {
2109// return val;
2110// }
2111
2112// RValue<Byte8> operator-(RValue<Byte8> val)
2113// {
2114// return RValue<Byte8>(Nucleus::createNeg(val.value));
2115// }
2116
2117 RValue<Byte8> operator~(RValue<Byte8> val)
John Bauman89401822014-05-06 15:04:28 -04002118 {
John Bauman19bac1e2014-05-06 15:23:49 -04002119 if(CPUID::supportsMMX2())
2120 {
Nicolas Capens16b5f152016-10-13 13:39:01 -04002121 return val ^ Byte8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
John Bauman19bac1e2014-05-06 15:23:49 -04002122 }
2123 else
2124 {
2125 return RValue<Byte8>(Nucleus::createNot(val.value));
2126 }
John Bauman89401822014-05-06 15:04:28 -04002127 }
2128
John Bauman19bac1e2014-05-06 15:23:49 -04002129 RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002130 {
2131 return x86::paddusb(x, y);
2132 }
John Bauman66b8ab22014-05-06 15:57:45 -04002133
John Bauman19bac1e2014-05-06 15:23:49 -04002134 RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002135 {
2136 return x86::psubusb(x, y);
2137 }
2138
John Bauman19bac1e2014-05-06 15:23:49 -04002139 RValue<Short4> Unpack(RValue<Byte4> x)
John Bauman89401822014-05-06 15:04:28 -04002140 {
Nicolas Capens19336542016-09-26 10:32:29 -04002141 Value *int2 = Nucleus::createInsertElement(V(UndefValue::get(VectorType::get(Int::getType(), 2))), x.value, 0);
John Bauman19bac1e2014-05-06 15:23:49 -04002142 Value *byte8 = Nucleus::createBitCast(int2, Byte8::getType());
John Bauman89401822014-05-06 15:04:28 -04002143
John Bauman19bac1e2014-05-06 15:23:49 -04002144 return UnpackLow(RValue<Byte8>(byte8), RValue<Byte8>(byte8));
2145 }
John Bauman89401822014-05-06 15:04:28 -04002146
Nicolas Capens411273e2017-01-26 15:13:36 -08002147 RValue<Short4> Unpack(RValue<Byte4> x, RValue<Byte4> y)
2148 {
2149 Value *xx = Nucleus::createInsertElement(V(UndefValue::get(VectorType::get(Int::getType(), 2))), x.value, 0);
2150 Value *yy = Nucleus::createInsertElement(V(UndefValue::get(VectorType::get(Int::getType(), 2))), y.value, 0);
2151
2152 return UnpackLow(As<Byte8>(xx), As<Byte8>(yy));
2153 }
2154
John Bauman19bac1e2014-05-06 15:23:49 -04002155 RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y)
2156 {
2157 if(CPUID::supportsMMX2())
2158 {
2159 return x86::punpcklbw(x, y);
2160 }
2161 else
2162 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002163 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11};
2164 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman19bac1e2014-05-06 15:23:49 -04002165
2166 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2167 }
John Bauman89401822014-05-06 15:04:28 -04002168 }
John Bauman66b8ab22014-05-06 15:57:45 -04002169
John Bauman19bac1e2014-05-06 15:23:49 -04002170 RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002171 {
John Bauman19bac1e2014-05-06 15:23:49 -04002172 if(CPUID::supportsMMX2())
2173 {
2174 return x86::punpckhbw(x, y);
2175 }
2176 else
2177 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002178 int shuffle[8] = {4, 12, 5, 13, 6, 14, 7, 15};
2179 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002180
John Bauman19bac1e2014-05-06 15:23:49 -04002181 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2182 }
John Bauman89401822014-05-06 15:04:28 -04002183 }
2184
John Bauman19bac1e2014-05-06 15:23:49 -04002185 RValue<Int> SignMask(RValue<Byte8> x)
John Bauman89401822014-05-06 15:04:28 -04002186 {
2187 return x86::pmovmskb(x);
2188 }
2189
John Bauman19bac1e2014-05-06 15:23:49 -04002190// RValue<Byte8> CmpGT(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002191// {
2192// return x86::pcmpgtb(x, y); // FIXME: Signedness
2193// }
John Bauman66b8ab22014-05-06 15:57:45 -04002194
John Bauman19bac1e2014-05-06 15:23:49 -04002195 RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002196 {
2197 return x86::pcmpeqb(x, y);
2198 }
2199
John Bauman19bac1e2014-05-06 15:23:49 -04002200 Type *Byte8::getType()
John Bauman89401822014-05-06 15:04:28 -04002201 {
John Bauman19bac1e2014-05-06 15:23:49 -04002202 if(CPUID::supportsMMX2())
2203 {
2204 return MMX::getType();
2205 }
2206 else
2207 {
Nicolas Capensac230122016-09-20 14:30:06 -04002208 return T(VectorType::get(Byte::getType(), 8));
John Bauman19bac1e2014-05-06 15:23:49 -04002209 }
John Bauman89401822014-05-06 15:04:28 -04002210 }
2211
Nicolas Capens3bbc5e12016-09-27 10:49:52 -04002212 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 -04002213 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04002214 int64_t constantVector[8] = {x0, x1, x2, x3, x4, x5, x6, x7};
2215 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(SByte::getType(), 8))));
John Bauman89401822014-05-06 15:04:28 -04002216
John Bauman66b8ab22014-05-06 15:57:45 -04002217 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04002218 }
2219
John Bauman19bac1e2014-05-06 15:23:49 -04002220 SByte8::SByte8(RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002221 {
John Bauman66b8ab22014-05-06 15:57:45 -04002222 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002223 }
2224
2225 SByte8::SByte8(const SByte8 &rhs)
2226 {
John Bauman66b8ab22014-05-06 15:57:45 -04002227 Value *value = rhs.loadValue();
2228 storeValue(value);
2229 }
2230
2231 SByte8::SByte8(const Reference<SByte8> &rhs)
2232 {
John Bauman66b8ab22014-05-06 15:57:45 -04002233 Value *value = rhs.loadValue();
2234 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002235 }
2236
Nicolas Capens96d4e092016-11-18 14:22:38 -05002237 RValue<SByte8> SByte8::operator=(RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002238 {
John Bauman66b8ab22014-05-06 15:57:45 -04002239 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002240
2241 return rhs;
2242 }
2243
Nicolas Capens96d4e092016-11-18 14:22:38 -05002244 RValue<SByte8> SByte8::operator=(const SByte8 &rhs)
John Bauman89401822014-05-06 15:04:28 -04002245 {
John Bauman66b8ab22014-05-06 15:57:45 -04002246 Value *value = rhs.loadValue();
2247 storeValue(value);
2248
2249 return RValue<SByte8>(value);
2250 }
2251
Nicolas Capens96d4e092016-11-18 14:22:38 -05002252 RValue<SByte8> SByte8::operator=(const Reference<SByte8> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04002253 {
2254 Value *value = rhs.loadValue();
2255 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002256
2257 return RValue<SByte8>(value);
2258 }
2259
John Bauman19bac1e2014-05-06 15:23:49 -04002260 RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002261 {
John Bauman19bac1e2014-05-06 15:23:49 -04002262 if(CPUID::supportsMMX2())
2263 {
2264 return As<SByte8>(x86::paddb(As<Byte8>(lhs), As<Byte8>(rhs)));
2265 }
2266 else
2267 {
2268 return RValue<SByte8>(Nucleus::createAdd(lhs.value, rhs.value));
2269 }
John Bauman89401822014-05-06 15:04:28 -04002270 }
2271
John Bauman19bac1e2014-05-06 15:23:49 -04002272 RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002273 {
John Bauman19bac1e2014-05-06 15:23:49 -04002274 if(CPUID::supportsMMX2())
2275 {
2276 return As<SByte8>(x86::psubb(As<Byte8>(lhs), As<Byte8>(rhs)));
2277 }
2278 else
2279 {
2280 return RValue<SByte8>(Nucleus::createSub(lhs.value, rhs.value));
2281 }
John Bauman89401822014-05-06 15:04:28 -04002282 }
2283
John Bauman19bac1e2014-05-06 15:23:49 -04002284// RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs)
2285// {
2286// return RValue<SByte8>(Nucleus::createMul(lhs.value, rhs.value));
2287// }
John Bauman89401822014-05-06 15:04:28 -04002288
John Bauman19bac1e2014-05-06 15:23:49 -04002289// RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs)
2290// {
2291// return RValue<SByte8>(Nucleus::createSDiv(lhs.value, rhs.value));
2292// }
John Bauman89401822014-05-06 15:04:28 -04002293
John Bauman19bac1e2014-05-06 15:23:49 -04002294// RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs)
2295// {
2296// return RValue<SByte8>(Nucleus::createSRem(lhs.value, rhs.value));
2297// }
John Bauman89401822014-05-06 15:04:28 -04002298
John Bauman19bac1e2014-05-06 15:23:49 -04002299 RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002300 {
2301 return RValue<SByte8>(Nucleus::createAnd(lhs.value, rhs.value));
2302 }
2303
John Bauman19bac1e2014-05-06 15:23:49 -04002304 RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002305 {
2306 return RValue<SByte8>(Nucleus::createOr(lhs.value, rhs.value));
2307 }
2308
John Bauman19bac1e2014-05-06 15:23:49 -04002309 RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002310 {
2311 return RValue<SByte8>(Nucleus::createXor(lhs.value, rhs.value));
2312 }
2313
John Bauman19bac1e2014-05-06 15:23:49 -04002314// RValue<SByte8> operator<<(RValue<SByte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002315// {
2316// return RValue<SByte8>(Nucleus::createShl(lhs.value, rhs.value));
2317// }
2318
John Bauman19bac1e2014-05-06 15:23:49 -04002319// RValue<SByte8> operator>>(RValue<SByte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002320// {
2321// return RValue<SByte8>(Nucleus::createAShr(lhs.value, rhs.value));
2322// }
2323
Nicolas Capens96d4e092016-11-18 14:22:38 -05002324 RValue<SByte8> operator+=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002325 {
2326 return lhs = lhs + rhs;
2327 }
2328
Nicolas Capens96d4e092016-11-18 14:22:38 -05002329 RValue<SByte8> operator-=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002330 {
2331 return lhs = lhs - rhs;
2332 }
2333
Nicolas Capens96d4e092016-11-18 14:22:38 -05002334// RValue<SByte8> operator*=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002335// {
2336// return lhs = lhs * rhs;
2337// }
John Bauman89401822014-05-06 15:04:28 -04002338
Nicolas Capens96d4e092016-11-18 14:22:38 -05002339// RValue<SByte8> operator/=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002340// {
2341// return lhs = lhs / rhs;
2342// }
John Bauman89401822014-05-06 15:04:28 -04002343
Nicolas Capens96d4e092016-11-18 14:22:38 -05002344// RValue<SByte8> operator%=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002345// {
2346// return lhs = lhs % rhs;
2347// }
John Bauman89401822014-05-06 15:04:28 -04002348
Nicolas Capens96d4e092016-11-18 14:22:38 -05002349 RValue<SByte8> operator&=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002350 {
2351 return lhs = lhs & rhs;
2352 }
2353
Nicolas Capens96d4e092016-11-18 14:22:38 -05002354 RValue<SByte8> operator|=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002355 {
2356 return lhs = lhs | rhs;
2357 }
2358
Nicolas Capens96d4e092016-11-18 14:22:38 -05002359 RValue<SByte8> operator^=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002360 {
2361 return lhs = lhs ^ rhs;
2362 }
2363
Nicolas Capens96d4e092016-11-18 14:22:38 -05002364// RValue<SByte8> operator<<=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002365// {
2366// return lhs = lhs << rhs;
2367// }
2368
Nicolas Capens96d4e092016-11-18 14:22:38 -05002369// RValue<SByte8> operator>>=(SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002370// {
2371// return lhs = lhs >> rhs;
2372// }
2373
John Bauman19bac1e2014-05-06 15:23:49 -04002374// RValue<SByte8> operator+(RValue<SByte8> val)
2375// {
2376// return val;
2377// }
2378
2379// RValue<SByte8> operator-(RValue<SByte8> val)
2380// {
2381// return RValue<SByte8>(Nucleus::createNeg(val.value));
2382// }
2383
2384 RValue<SByte8> operator~(RValue<SByte8> val)
John Bauman89401822014-05-06 15:04:28 -04002385 {
John Bauman19bac1e2014-05-06 15:23:49 -04002386 if(CPUID::supportsMMX2())
2387 {
Nicolas Capens16b5f152016-10-13 13:39:01 -04002388 return val ^ SByte8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
John Bauman19bac1e2014-05-06 15:23:49 -04002389 }
2390 else
2391 {
2392 return RValue<SByte8>(Nucleus::createNot(val.value));
2393 }
John Bauman89401822014-05-06 15:04:28 -04002394 }
2395
John Bauman19bac1e2014-05-06 15:23:49 -04002396 RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002397 {
2398 return x86::paddsb(x, y);
2399 }
John Bauman66b8ab22014-05-06 15:57:45 -04002400
John Bauman19bac1e2014-05-06 15:23:49 -04002401 RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002402 {
2403 return x86::psubsb(x, y);
2404 }
2405
John Bauman19bac1e2014-05-06 15:23:49 -04002406 RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002407 {
John Bauman19bac1e2014-05-06 15:23:49 -04002408 if(CPUID::supportsMMX2())
2409 {
2410 return As<Short4>(x86::punpcklbw(As<Byte8>(x), As<Byte8>(y)));
2411 }
2412 else
2413 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002414 int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11};
2415 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002416
John Bauman19bac1e2014-05-06 15:23:49 -04002417 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2418 }
John Bauman89401822014-05-06 15:04:28 -04002419 }
John Bauman66b8ab22014-05-06 15:57:45 -04002420
John Bauman19bac1e2014-05-06 15:23:49 -04002421 RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002422 {
John Bauman19bac1e2014-05-06 15:23:49 -04002423 if(CPUID::supportsMMX2())
2424 {
2425 return As<Short4>(x86::punpckhbw(As<Byte8>(x), As<Byte8>(y)));
2426 }
2427 else
2428 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002429 int shuffle[8] = {4, 12, 5, 13, 6, 14, 7, 15};
2430 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002431
John Bauman19bac1e2014-05-06 15:23:49 -04002432 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2433 }
John Bauman89401822014-05-06 15:04:28 -04002434 }
2435
John Bauman19bac1e2014-05-06 15:23:49 -04002436 RValue<Int> SignMask(RValue<SByte8> x)
John Bauman89401822014-05-06 15:04:28 -04002437 {
2438 return x86::pmovmskb(As<Byte8>(x));
2439 }
2440
John Bauman19bac1e2014-05-06 15:23:49 -04002441 RValue<Byte8> CmpGT(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002442 {
2443 return x86::pcmpgtb(x, y);
2444 }
John Bauman66b8ab22014-05-06 15:57:45 -04002445
John Bauman19bac1e2014-05-06 15:23:49 -04002446 RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002447 {
2448 return x86::pcmpeqb(As<Byte8>(x), As<Byte8>(y));
2449 }
2450
John Bauman19bac1e2014-05-06 15:23:49 -04002451 Type *SByte8::getType()
John Bauman89401822014-05-06 15:04:28 -04002452 {
John Bauman19bac1e2014-05-06 15:23:49 -04002453 if(CPUID::supportsMMX2())
2454 {
2455 return MMX::getType();
2456 }
2457 else
2458 {
Nicolas Capensac230122016-09-20 14:30:06 -04002459 return T(VectorType::get(SByte::getType(), 8));
John Bauman19bac1e2014-05-06 15:23:49 -04002460 }
John Bauman89401822014-05-06 15:04:28 -04002461 }
2462
John Bauman19bac1e2014-05-06 15:23:49 -04002463 Byte16::Byte16(RValue<Byte16> rhs)
John Bauman89401822014-05-06 15:04:28 -04002464 {
John Bauman66b8ab22014-05-06 15:57:45 -04002465 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002466 }
2467
2468 Byte16::Byte16(const Byte16 &rhs)
2469 {
John Bauman66b8ab22014-05-06 15:57:45 -04002470 Value *value = rhs.loadValue();
2471 storeValue(value);
2472 }
2473
2474 Byte16::Byte16(const Reference<Byte16> &rhs)
2475 {
John Bauman66b8ab22014-05-06 15:57:45 -04002476 Value *value = rhs.loadValue();
2477 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002478 }
2479
Nicolas Capens96d4e092016-11-18 14:22:38 -05002480 RValue<Byte16> Byte16::operator=(RValue<Byte16> rhs)
John Bauman89401822014-05-06 15:04:28 -04002481 {
John Bauman66b8ab22014-05-06 15:57:45 -04002482 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002483
2484 return rhs;
2485 }
2486
Nicolas Capens96d4e092016-11-18 14:22:38 -05002487 RValue<Byte16> Byte16::operator=(const Byte16 &rhs)
John Bauman89401822014-05-06 15:04:28 -04002488 {
John Bauman66b8ab22014-05-06 15:57:45 -04002489 Value *value = rhs.loadValue();
2490 storeValue(value);
2491
2492 return RValue<Byte16>(value);
2493 }
2494
Nicolas Capens96d4e092016-11-18 14:22:38 -05002495 RValue<Byte16> Byte16::operator=(const Reference<Byte16> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04002496 {
2497 Value *value = rhs.loadValue();
2498 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002499
2500 return RValue<Byte16>(value);
2501 }
2502
John Bauman19bac1e2014-05-06 15:23:49 -04002503 Type *Byte16::getType()
John Bauman89401822014-05-06 15:04:28 -04002504 {
Nicolas Capensac230122016-09-20 14:30:06 -04002505 return T(VectorType::get(Byte::getType(), 16));
John Bauman89401822014-05-06 15:04:28 -04002506 }
2507
John Bauman19bac1e2014-05-06 15:23:49 -04002508 Type *SByte16::getType()
John Bauman89401822014-05-06 15:04:28 -04002509 {
Nicolas Capensac230122016-09-20 14:30:06 -04002510 return T( VectorType::get(SByte::getType(), 16));
John Bauman89401822014-05-06 15:04:28 -04002511 }
2512
Nicolas Capens16b5f152016-10-13 13:39:01 -04002513 Short2::Short2(RValue<Short4> cast)
2514 {
2515 storeValue(Nucleus::createTrunc(Nucleus::createBitCast(cast.value, Long::getType()), UInt::getType()));
2516 }
2517
2518 Type *Short2::getType()
2519 {
2520 #if 0
2521 return T(VectorType::get(Short::getType(), 2));
2522 #else
2523 return UInt::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
2524 #endif
2525 }
2526
2527 UShort2::UShort2(RValue<UShort4> cast)
2528 {
2529 storeValue(Nucleus::createTrunc(Nucleus::createBitCast(cast.value, Long::getType()), UInt::getType()));
2530 }
2531
2532 Type *UShort2::getType()
2533 {
2534 #if 0
2535 return T(VectorType::get(UShort::getType(), 2));
2536 #else
2537 return UInt::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
2538 #endif
2539 }
2540
John Bauman19bac1e2014-05-06 15:23:49 -04002541 Short4::Short4(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04002542 {
John Bauman89401822014-05-06 15:04:28 -04002543 Value *extend = Nucleus::createZExt(cast.value, Long::getType());
John Bauman19bac1e2014-05-06 15:23:49 -04002544 Value *swizzle = Swizzle(RValue<Short4>(extend), 0x00).value;
John Bauman66b8ab22014-05-06 15:57:45 -04002545
2546 storeValue(swizzle);
John Bauman89401822014-05-06 15:04:28 -04002547 }
2548
John Bauman19bac1e2014-05-06 15:23:49 -04002549 Short4::Short4(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04002550 {
John Bauman89401822014-05-06 15:04:28 -04002551 Value *short8 = Nucleus::createBitCast(cast.value, Short8::getType());
2552
2553 #if 0 // FIXME: Check codegen (pshuflw phshufhw pshufd)
2554 Constant *pack[8];
2555 pack[0] = Nucleus::createConstantInt(0);
2556 pack[1] = Nucleus::createConstantInt(2);
2557 pack[2] = Nucleus::createConstantInt(4);
2558 pack[3] = Nucleus::createConstantInt(6);
2559
2560 Value *short4 = Nucleus::createShuffleVector(short8, short8, Nucleus::createConstantVector(pack, 4));
2561 #else
2562 Value *packed;
2563
2564 // FIXME: Use Swizzle<Short8>
2565 if(!CPUID::supportsSSSE3())
2566 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002567 int pshuflw[8] = {0, 2, 0, 2, 4, 5, 6, 7};
2568 int pshufhw[8] = {0, 1, 2, 3, 4, 6, 4, 6};
John Bauman89401822014-05-06 15:04:28 -04002569
Nicolas Capense89cd582016-09-30 14:23:47 -04002570 Value *shuffle1 = Nucleus::createShuffleVector(short8, short8, pshuflw);
2571 Value *shuffle2 = Nucleus::createShuffleVector(shuffle1, shuffle1, pshufhw);
John Bauman89401822014-05-06 15:04:28 -04002572 Value *int4 = Nucleus::createBitCast(shuffle2, Int4::getType());
Nicolas Capense95d5342016-09-30 11:37:28 -04002573 packed = createSwizzle4(int4, 0x88);
John Bauman89401822014-05-06 15:04:28 -04002574 }
2575 else
2576 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002577 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 -04002578 Value *byte16 = Nucleus::createBitCast(cast.value, Byte16::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04002579 packed = Nucleus::createShuffleVector(byte16, byte16, pshufb);
John Bauman89401822014-05-06 15:04:28 -04002580 }
2581
2582 #if 0 // FIXME: No optimal instruction selection
Nicolas Capens22008782016-10-20 01:11:47 -04002583 Value *qword2 = Nucleus::createBitCast(packed, T(VectorType::get(Long::getType(), 2)));
John Bauman89401822014-05-06 15:04:28 -04002584 Value *element = Nucleus::createExtractElement(qword2, 0);
2585 Value *short4 = Nucleus::createBitCast(element, Short4::getType());
2586 #else // FIXME: Requires SSE
2587 Value *int2 = RValue<Int2>(Int2(RValue<Int4>(packed))).value;
2588 Value *short4 = Nucleus::createBitCast(int2, Short4::getType());
2589 #endif
2590 #endif
2591
John Bauman66b8ab22014-05-06 15:57:45 -04002592 storeValue(short4);
John Bauman89401822014-05-06 15:04:28 -04002593 }
2594
John Bauman19bac1e2014-05-06 15:23:49 -04002595// Short4::Short4(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04002596// {
2597// }
2598
John Bauman19bac1e2014-05-06 15:23:49 -04002599 Short4::Short4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04002600 {
John Bauman89401822014-05-06 15:04:28 -04002601 Int4 v4i32 = Int4(cast);
2602 v4i32 = As<Int4>(x86::packssdw(v4i32, v4i32));
John Bauman66b8ab22014-05-06 15:57:45 -04002603
2604 storeValue(As<Short4>(Int2(v4i32)).value);
John Bauman89401822014-05-06 15:04:28 -04002605 }
2606
John Bauman19bac1e2014-05-06 15:23:49 -04002607 Short4::Short4(short xyzw)
2608 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04002609 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
2610 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(Short::getType(), 4))));
John Bauman19bac1e2014-05-06 15:23:49 -04002611
John Bauman66b8ab22014-05-06 15:57:45 -04002612 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman19bac1e2014-05-06 15:23:49 -04002613 }
2614
John Bauman89401822014-05-06 15:04:28 -04002615 Short4::Short4(short x, short y, short z, short w)
2616 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04002617 int64_t constantVector[4] = {x, y, z, w};
2618 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(Short::getType(), 4))));
John Bauman19bac1e2014-05-06 15:23:49 -04002619
John Bauman66b8ab22014-05-06 15:57:45 -04002620 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04002621 }
2622
John Bauman19bac1e2014-05-06 15:23:49 -04002623 Short4::Short4(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002624 {
John Bauman66b8ab22014-05-06 15:57:45 -04002625 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002626 }
2627
2628 Short4::Short4(const Short4 &rhs)
2629 {
John Bauman66b8ab22014-05-06 15:57:45 -04002630 Value *value = rhs.loadValue();
2631 storeValue(value);
2632 }
2633
2634 Short4::Short4(const Reference<Short4> &rhs)
2635 {
John Bauman66b8ab22014-05-06 15:57:45 -04002636 Value *value = rhs.loadValue();
2637 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002638 }
2639
John Bauman19bac1e2014-05-06 15:23:49 -04002640 Short4::Short4(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002641 {
John Bauman66b8ab22014-05-06 15:57:45 -04002642 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002643 }
2644
2645 Short4::Short4(const UShort4 &rhs)
2646 {
John Bauman66b8ab22014-05-06 15:57:45 -04002647 storeValue(rhs.loadValue());
2648 }
2649
2650 Short4::Short4(const Reference<UShort4> &rhs)
2651 {
John Bauman66b8ab22014-05-06 15:57:45 -04002652 storeValue(rhs.loadValue());
John Bauman89401822014-05-06 15:04:28 -04002653 }
2654
Nicolas Capens96d4e092016-11-18 14:22:38 -05002655 RValue<Short4> Short4::operator=(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002656 {
John Bauman66b8ab22014-05-06 15:57:45 -04002657 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002658
2659 return rhs;
2660 }
2661
Nicolas Capens96d4e092016-11-18 14:22:38 -05002662 RValue<Short4> Short4::operator=(const Short4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04002663 {
John Bauman66b8ab22014-05-06 15:57:45 -04002664 Value *value = rhs.loadValue();
2665 storeValue(value);
2666
2667 return RValue<Short4>(value);
2668 }
2669
Nicolas Capens96d4e092016-11-18 14:22:38 -05002670 RValue<Short4> Short4::operator=(const Reference<Short4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04002671 {
2672 Value *value = rhs.loadValue();
2673 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002674
2675 return RValue<Short4>(value);
2676 }
2677
Nicolas Capens96d4e092016-11-18 14:22:38 -05002678 RValue<Short4> Short4::operator=(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002679 {
John Bauman66b8ab22014-05-06 15:57:45 -04002680 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002681
John Bauman66b8ab22014-05-06 15:57:45 -04002682 return RValue<Short4>(rhs);
John Bauman89401822014-05-06 15:04:28 -04002683 }
2684
Nicolas Capens96d4e092016-11-18 14:22:38 -05002685 RValue<Short4> Short4::operator=(const UShort4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04002686 {
John Bauman66b8ab22014-05-06 15:57:45 -04002687 Value *value = rhs.loadValue();
2688 storeValue(value);
2689
2690 return RValue<Short4>(value);
2691 }
2692
Nicolas Capens96d4e092016-11-18 14:22:38 -05002693 RValue<Short4> Short4::operator=(const Reference<UShort4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04002694 {
2695 Value *value = rhs.loadValue();
2696 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002697
2698 return RValue<Short4>(value);
2699 }
2700
John Bauman19bac1e2014-05-06 15:23:49 -04002701 RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002702 {
John Bauman19bac1e2014-05-06 15:23:49 -04002703 if(CPUID::supportsMMX2())
2704 {
2705 return x86::paddw(lhs, rhs);
2706 }
2707 else
2708 {
2709 return RValue<Short4>(Nucleus::createAdd(lhs.value, rhs.value));
2710 }
John Bauman89401822014-05-06 15:04:28 -04002711 }
2712
John Bauman19bac1e2014-05-06 15:23:49 -04002713 RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002714 {
John Bauman19bac1e2014-05-06 15:23:49 -04002715 if(CPUID::supportsMMX2())
2716 {
2717 return x86::psubw(lhs, rhs);
2718 }
2719 else
2720 {
2721 return RValue<Short4>(Nucleus::createSub(lhs.value, rhs.value));
2722 }
John Bauman89401822014-05-06 15:04:28 -04002723 }
2724
John Bauman19bac1e2014-05-06 15:23:49 -04002725 RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002726 {
John Bauman19bac1e2014-05-06 15:23:49 -04002727 if(CPUID::supportsMMX2())
2728 {
2729 return x86::pmullw(lhs, rhs);
2730 }
2731 else
2732 {
2733 return RValue<Short4>(Nucleus::createMul(lhs.value, rhs.value));
2734 }
John Bauman89401822014-05-06 15:04:28 -04002735 }
2736
John Bauman19bac1e2014-05-06 15:23:49 -04002737// RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs)
2738// {
2739// return RValue<Short4>(Nucleus::createSDiv(lhs.value, rhs.value));
2740// }
2741
2742// RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs)
2743// {
2744// return RValue<Short4>(Nucleus::createSRem(lhs.value, rhs.value));
2745// }
2746
2747 RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002748 {
John Bauman19bac1e2014-05-06 15:23:49 -04002749 if(CPUID::supportsMMX2())
2750 {
2751 return x86::pand(lhs, rhs);
2752 }
2753 else
2754 {
2755 return RValue<Short4>(Nucleus::createAnd(lhs.value, rhs.value));
2756 }
John Bauman89401822014-05-06 15:04:28 -04002757 }
2758
John Bauman19bac1e2014-05-06 15:23:49 -04002759 RValue<Short4> operator|(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002760 {
John Bauman19bac1e2014-05-06 15:23:49 -04002761 if(CPUID::supportsMMX2())
2762 {
2763 return x86::por(lhs, rhs);
2764 }
2765 else
2766 {
2767 return RValue<Short4>(Nucleus::createOr(lhs.value, rhs.value));
2768 }
John Bauman89401822014-05-06 15:04:28 -04002769 }
2770
John Bauman19bac1e2014-05-06 15:23:49 -04002771 RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002772 {
John Bauman19bac1e2014-05-06 15:23:49 -04002773 if(CPUID::supportsMMX2())
2774 {
2775 return x86::pxor(lhs, rhs);
2776 }
2777 else
2778 {
2779 return RValue<Short4>(Nucleus::createXor(lhs.value, rhs.value));
2780 }
John Bauman89401822014-05-06 15:04:28 -04002781 }
2782
John Bauman19bac1e2014-05-06 15:23:49 -04002783 RValue<Short4> operator<<(RValue<Short4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002784 {
2785 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
2786
2787 return x86::psllw(lhs, rhs);
2788 }
2789
John Bauman19bac1e2014-05-06 15:23:49 -04002790 RValue<Short4> operator>>(RValue<Short4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002791 {
2792 // return RValue<Short4>(Nucleus::createAShr(lhs.value, rhs.value));
2793
2794 return x86::psraw(lhs, rhs);
2795 }
2796
Nicolas Capens96d4e092016-11-18 14:22:38 -05002797 RValue<Short4> operator+=(Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002798 {
2799 return lhs = lhs + rhs;
2800 }
2801
Nicolas Capens96d4e092016-11-18 14:22:38 -05002802 RValue<Short4> operator-=(Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002803 {
2804 return lhs = lhs - rhs;
2805 }
2806
Nicolas Capens96d4e092016-11-18 14:22:38 -05002807 RValue<Short4> operator*=(Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002808 {
2809 return lhs = lhs * rhs;
2810 }
2811
Nicolas Capens96d4e092016-11-18 14:22:38 -05002812// RValue<Short4> operator/=(Short4 &lhs, RValue<Short4> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002813// {
2814// return lhs = lhs / rhs;
2815// }
John Bauman89401822014-05-06 15:04:28 -04002816
Nicolas Capens96d4e092016-11-18 14:22:38 -05002817// RValue<Short4> operator%=(Short4 &lhs, RValue<Short4> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04002818// {
2819// return lhs = lhs % rhs;
2820// }
John Bauman89401822014-05-06 15:04:28 -04002821
Nicolas Capens96d4e092016-11-18 14:22:38 -05002822 RValue<Short4> operator&=(Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002823 {
2824 return lhs = lhs & rhs;
2825 }
2826
Nicolas Capens96d4e092016-11-18 14:22:38 -05002827 RValue<Short4> operator|=(Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002828 {
2829 return lhs = lhs | rhs;
2830 }
2831
Nicolas Capens96d4e092016-11-18 14:22:38 -05002832 RValue<Short4> operator^=(Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002833 {
2834 return lhs = lhs ^ rhs;
2835 }
2836
Nicolas Capens96d4e092016-11-18 14:22:38 -05002837 RValue<Short4> operator<<=(Short4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002838 {
2839 return lhs = lhs << rhs;
2840 }
2841
Nicolas Capens96d4e092016-11-18 14:22:38 -05002842 RValue<Short4> operator>>=(Short4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002843 {
2844 return lhs = lhs >> rhs;
2845 }
2846
John Bauman19bac1e2014-05-06 15:23:49 -04002847// RValue<Short4> operator+(RValue<Short4> val)
2848// {
2849// return val;
2850// }
2851
2852 RValue<Short4> operator-(RValue<Short4> val)
John Bauman89401822014-05-06 15:04:28 -04002853 {
John Bauman19bac1e2014-05-06 15:23:49 -04002854 if(CPUID::supportsMMX2())
2855 {
2856 return Short4(0, 0, 0, 0) - val;
2857 }
2858 else
2859 {
2860 return RValue<Short4>(Nucleus::createNeg(val.value));
2861 }
John Bauman89401822014-05-06 15:04:28 -04002862 }
2863
John Bauman19bac1e2014-05-06 15:23:49 -04002864 RValue<Short4> operator~(RValue<Short4> val)
John Bauman89401822014-05-06 15:04:28 -04002865 {
John Bauman19bac1e2014-05-06 15:23:49 -04002866 if(CPUID::supportsMMX2())
2867 {
2868 return val ^ Short4(0xFFFFu, 0xFFFFu, 0xFFFFu, 0xFFFFu);
2869 }
2870 else
2871 {
2872 return RValue<Short4>(Nucleus::createNot(val.value));
2873 }
John Bauman89401822014-05-06 15:04:28 -04002874 }
2875
John Bauman19bac1e2014-05-06 15:23:49 -04002876 RValue<Short4> RoundShort4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04002877 {
2878 RValue<Int4> v4i32 = x86::cvtps2dq(cast);
Nicolas Capens698633a2015-02-04 00:16:13 -05002879 RValue<Short8> v8i16 = x86::packssdw(v4i32, v4i32);
John Bauman66b8ab22014-05-06 15:57:45 -04002880
Nicolas Capens698633a2015-02-04 00:16:13 -05002881 return As<Short4>(Int2(As<Int4>(v8i16)));
John Bauman89401822014-05-06 15:04:28 -04002882 }
2883
John Bauman19bac1e2014-05-06 15:23:49 -04002884 RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002885 {
2886 return x86::pmaxsw(x, y);
2887 }
2888
John Bauman19bac1e2014-05-06 15:23:49 -04002889 RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002890 {
2891 return x86::pminsw(x, y);
2892 }
2893
John Bauman19bac1e2014-05-06 15:23:49 -04002894 RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002895 {
2896 return x86::paddsw(x, y);
2897 }
2898
John Bauman19bac1e2014-05-06 15:23:49 -04002899 RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002900 {
2901 return x86::psubsw(x, y);
2902 }
2903
John Bauman19bac1e2014-05-06 15:23:49 -04002904 RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002905 {
2906 return x86::pmulhw(x, y);
2907 }
2908
John Bauman19bac1e2014-05-06 15:23:49 -04002909 RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002910 {
2911 return x86::pmaddwd(x, y);
2912 }
2913
John Bauman19bac1e2014-05-06 15:23:49 -04002914 RValue<SByte8> Pack(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002915 {
2916 return x86::packsswb(x, y);
2917 }
2918
John Bauman19bac1e2014-05-06 15:23:49 -04002919 RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002920 {
John Bauman19bac1e2014-05-06 15:23:49 -04002921 if(CPUID::supportsMMX2())
2922 {
2923 return x86::punpcklwd(x, y);
2924 }
2925 else
2926 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002927 int shuffle[4] = {0, 4, 1, 5};
2928 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002929
John Bauman19bac1e2014-05-06 15:23:49 -04002930 return RValue<Int2>(Nucleus::createBitCast(packed, Int2::getType()));
2931 }
John Bauman89401822014-05-06 15:04:28 -04002932 }
2933
John Bauman19bac1e2014-05-06 15:23:49 -04002934 RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002935 {
John Bauman19bac1e2014-05-06 15:23:49 -04002936 if(CPUID::supportsMMX2())
2937 {
2938 return x86::punpckhwd(x, y);
2939 }
2940 else
2941 {
Nicolas Capense89cd582016-09-30 14:23:47 -04002942 int shuffle[4] = {2, 6, 3, 7};
2943 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04002944
John Bauman19bac1e2014-05-06 15:23:49 -04002945 return RValue<Int2>(Nucleus::createBitCast(packed, Int2::getType()));
2946 }
John Bauman89401822014-05-06 15:04:28 -04002947 }
2948
John Bauman19bac1e2014-05-06 15:23:49 -04002949 RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04002950 {
John Bauman19bac1e2014-05-06 15:23:49 -04002951 if(CPUID::supportsMMX2())
2952 {
2953 return x86::pshufw(x, select);
2954 }
2955 else
2956 {
Nicolas Capense95d5342016-09-30 11:37:28 -04002957 return RValue<Short4>(createSwizzle4(x.value, select));
John Bauman19bac1e2014-05-06 15:23:49 -04002958 }
John Bauman89401822014-05-06 15:04:28 -04002959 }
2960
John Bauman19bac1e2014-05-06 15:23:49 -04002961 RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i)
John Bauman89401822014-05-06 15:04:28 -04002962 {
John Bauman19bac1e2014-05-06 15:23:49 -04002963 if(CPUID::supportsMMX2())
2964 {
2965 return x86::pinsrw(val, Int(element), i);
2966 }
2967 else
2968 {
2969 return RValue<Short4>(Nucleus::createInsertElement(val.value, element.value, i));
2970 }
John Bauman89401822014-05-06 15:04:28 -04002971 }
2972
John Bauman19bac1e2014-05-06 15:23:49 -04002973 RValue<Short> Extract(RValue<Short4> val, int i)
John Bauman89401822014-05-06 15:04:28 -04002974 {
John Bauman19bac1e2014-05-06 15:23:49 -04002975 if(CPUID::supportsMMX2())
2976 {
2977 return Short(x86::pextrw(val, i));
2978 }
2979 else
2980 {
Nicolas Capense95d5342016-09-30 11:37:28 -04002981 return RValue<Short>(Nucleus::createExtractElement(val.value, Short::getType(), i));
John Bauman19bac1e2014-05-06 15:23:49 -04002982 }
John Bauman89401822014-05-06 15:04:28 -04002983 }
2984
John Bauman19bac1e2014-05-06 15:23:49 -04002985 RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002986 {
2987 return x86::pcmpgtw(x, y);
2988 }
2989
John Bauman19bac1e2014-05-06 15:23:49 -04002990 RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04002991 {
2992 return x86::pcmpeqw(x, y);
2993 }
2994
John Bauman19bac1e2014-05-06 15:23:49 -04002995 Type *Short4::getType()
John Bauman89401822014-05-06 15:04:28 -04002996 {
John Bauman19bac1e2014-05-06 15:23:49 -04002997 if(CPUID::supportsMMX2())
2998 {
2999 return MMX::getType();
3000 }
3001 else
3002 {
Nicolas Capensac230122016-09-20 14:30:06 -04003003 return T(VectorType::get(Short::getType(), 4));
John Bauman19bac1e2014-05-06 15:23:49 -04003004 }
John Bauman89401822014-05-06 15:04:28 -04003005 }
3006
John Bauman19bac1e2014-05-06 15:23:49 -04003007 UShort4::UShort4(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04003008 {
John Bauman89401822014-05-06 15:04:28 -04003009 *this = Short4(cast);
3010 }
3011
John Bauman19bac1e2014-05-06 15:23:49 -04003012 UShort4::UShort4(RValue<Float4> cast, bool saturate)
John Bauman89401822014-05-06 15:04:28 -04003013 {
John Bauman89401822014-05-06 15:04:28 -04003014 Float4 sat;
3015
3016 if(saturate)
3017 {
3018 if(CPUID::supportsSSE4_1())
3019 {
3020 sat = Min(cast, Float4(0xFFFF)); // packusdw takes care of 0x0000 saturation
3021 }
3022 else
3023 {
3024 sat = Max(Min(cast, Float4(0xFFFF)), Float4(0x0000));
3025 }
3026 }
3027 else
3028 {
3029 sat = cast;
3030 }
3031
3032 Int4 int4(sat);
3033
3034 if(!saturate || !CPUID::supportsSSE4_1())
3035 {
Nicolas Capens3e7062b2017-01-17 14:01:33 -05003036 *this = Short4(int4);
John Bauman89401822014-05-06 15:04:28 -04003037 }
3038 else
3039 {
Nicolas Capens3e7062b2017-01-17 14:01:33 -05003040 *this = As<Short4>(Int2(As<Int4>(x86::packusdw(int4, int4))));
John Bauman89401822014-05-06 15:04:28 -04003041 }
3042 }
3043
Alexis Hetu90c7ad62016-06-27 11:50:40 -04003044 UShort4::UShort4(unsigned short xyzw)
3045 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04003046 int64_t constantVector[4] = {xyzw, xyzw, xyzw, xyzw};
3047 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(UShort::getType(), 4))));
Alexis Hetu90c7ad62016-06-27 11:50:40 -04003048
3049 storeValue(Nucleus::createBitCast(vector, getType()));
3050 }
3051
John Bauman89401822014-05-06 15:04:28 -04003052 UShort4::UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w)
3053 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04003054 int64_t constantVector[4] = {x, y, z, w};
3055 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(UShort::getType(), 4))));
John Bauman89401822014-05-06 15:04:28 -04003056
John Bauman66b8ab22014-05-06 15:57:45 -04003057 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04003058 }
3059
John Bauman19bac1e2014-05-06 15:23:49 -04003060 UShort4::UShort4(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003061 {
John Bauman66b8ab22014-05-06 15:57:45 -04003062 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003063 }
3064
3065 UShort4::UShort4(const UShort4 &rhs)
3066 {
John Bauman66b8ab22014-05-06 15:57:45 -04003067 Value *value = rhs.loadValue();
3068 storeValue(value);
3069 }
3070
3071 UShort4::UShort4(const Reference<UShort4> &rhs)
3072 {
John Bauman66b8ab22014-05-06 15:57:45 -04003073 Value *value = rhs.loadValue();
3074 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003075 }
3076
John Bauman19bac1e2014-05-06 15:23:49 -04003077 UShort4::UShort4(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003078 {
John Bauman66b8ab22014-05-06 15:57:45 -04003079 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003080 }
3081
3082 UShort4::UShort4(const Short4 &rhs)
3083 {
John Bauman66b8ab22014-05-06 15:57:45 -04003084 Value *value = rhs.loadValue();
3085 storeValue(value);
3086 }
3087
3088 UShort4::UShort4(const Reference<Short4> &rhs)
3089 {
John Bauman66b8ab22014-05-06 15:57:45 -04003090 Value *value = rhs.loadValue();
3091 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003092 }
3093
Nicolas Capens96d4e092016-11-18 14:22:38 -05003094 RValue<UShort4> UShort4::operator=(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003095 {
John Bauman66b8ab22014-05-06 15:57:45 -04003096 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003097
3098 return rhs;
3099 }
3100
Nicolas Capens96d4e092016-11-18 14:22:38 -05003101 RValue<UShort4> UShort4::operator=(const UShort4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04003102 {
John Bauman66b8ab22014-05-06 15:57:45 -04003103 Value *value = rhs.loadValue();
3104 storeValue(value);
3105
3106 return RValue<UShort4>(value);
3107 }
3108
Nicolas Capens96d4e092016-11-18 14:22:38 -05003109 RValue<UShort4> UShort4::operator=(const Reference<UShort4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04003110 {
3111 Value *value = rhs.loadValue();
3112 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003113
3114 return RValue<UShort4>(value);
3115 }
3116
Nicolas Capens96d4e092016-11-18 14:22:38 -05003117 RValue<UShort4> UShort4::operator=(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003118 {
John Bauman66b8ab22014-05-06 15:57:45 -04003119 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003120
John Bauman66b8ab22014-05-06 15:57:45 -04003121 return RValue<UShort4>(rhs);
John Bauman89401822014-05-06 15:04:28 -04003122 }
3123
Nicolas Capens96d4e092016-11-18 14:22:38 -05003124 RValue<UShort4> UShort4::operator=(const Short4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04003125 {
John Bauman66b8ab22014-05-06 15:57:45 -04003126 Value *value = rhs.loadValue();
3127 storeValue(value);
3128
3129 return RValue<UShort4>(value);
3130 }
3131
Nicolas Capens96d4e092016-11-18 14:22:38 -05003132 RValue<UShort4> UShort4::operator=(const Reference<Short4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04003133 {
3134 Value *value = rhs.loadValue();
3135 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003136
3137 return RValue<UShort4>(value);
3138 }
3139
John Bauman19bac1e2014-05-06 15:23:49 -04003140 RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003141 {
John Bauman19bac1e2014-05-06 15:23:49 -04003142 if(CPUID::supportsMMX2())
3143 {
3144 return As<UShort4>(x86::paddw(As<Short4>(lhs), As<Short4>(rhs)));
3145 }
3146 else
3147 {
3148 return RValue<UShort4>(Nucleus::createAdd(lhs.value, rhs.value));
3149 }
John Bauman89401822014-05-06 15:04:28 -04003150 }
3151
John Bauman19bac1e2014-05-06 15:23:49 -04003152 RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003153 {
John Bauman19bac1e2014-05-06 15:23:49 -04003154 if(CPUID::supportsMMX2())
3155 {
3156 return As<UShort4>(x86::psubw(As<Short4>(lhs), As<Short4>(rhs)));
3157 }
3158 else
3159 {
3160 return RValue<UShort4>(Nucleus::createSub(lhs.value, rhs.value));
3161 }
John Bauman89401822014-05-06 15:04:28 -04003162 }
3163
John Bauman19bac1e2014-05-06 15:23:49 -04003164 RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003165 {
John Bauman19bac1e2014-05-06 15:23:49 -04003166 if(CPUID::supportsMMX2())
3167 {
3168 return As<UShort4>(x86::pmullw(As<Short4>(lhs), As<Short4>(rhs)));
3169 }
3170 else
3171 {
3172 return RValue<UShort4>(Nucleus::createMul(lhs.value, rhs.value));
3173 }
John Bauman89401822014-05-06 15:04:28 -04003174 }
3175
Nicolas Capens16b5f152016-10-13 13:39:01 -04003176 RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs)
3177 {
3178 if(CPUID::supportsMMX2())
3179 {
3180 return As<UShort4>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
3181 }
3182 else
3183 {
3184 return RValue<UShort4>(Nucleus::createAnd(lhs.value, rhs.value));
3185 }
3186 }
3187
3188 RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs)
3189 {
3190 if(CPUID::supportsMMX2())
3191 {
3192 return As<UShort4>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
3193 }
3194 else
3195 {
3196 return RValue<UShort4>(Nucleus::createOr(lhs.value, rhs.value));
3197 }
3198 }
3199
3200 RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs)
3201 {
3202 if(CPUID::supportsMMX2())
3203 {
3204 return As<UShort4>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
3205 }
3206 else
3207 {
3208 return RValue<UShort4>(Nucleus::createXor(lhs.value, rhs.value));
3209 }
3210 }
3211
John Bauman19bac1e2014-05-06 15:23:49 -04003212 RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003213 {
3214 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
3215
3216 return As<UShort4>(x86::psllw(As<Short4>(lhs), rhs));
3217 }
3218
John Bauman19bac1e2014-05-06 15:23:49 -04003219 RValue<UShort4> operator>>(RValue<UShort4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003220 {
3221 // return RValue<Short4>(Nucleus::createLShr(lhs.value, rhs.value));
3222
3223 return x86::psrlw(lhs, rhs);
3224 }
3225
Nicolas Capens96d4e092016-11-18 14:22:38 -05003226 RValue<UShort4> operator<<=(UShort4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003227 {
3228 return lhs = lhs << rhs;
3229 }
3230
Nicolas Capens96d4e092016-11-18 14:22:38 -05003231 RValue<UShort4> operator>>=(UShort4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003232 {
3233 return lhs = lhs >> rhs;
3234 }
3235
John Bauman19bac1e2014-05-06 15:23:49 -04003236 RValue<UShort4> operator~(RValue<UShort4> val)
John Bauman89401822014-05-06 15:04:28 -04003237 {
John Bauman19bac1e2014-05-06 15:23:49 -04003238 if(CPUID::supportsMMX2())
3239 {
3240 return As<UShort4>(As<Short4>(val) ^ Short4(0xFFFFu, 0xFFFFu, 0xFFFFu, 0xFFFFu));
3241 }
3242 else
3243 {
3244 return RValue<UShort4>(Nucleus::createNot(val.value));
3245 }
John Bauman89401822014-05-06 15:04:28 -04003246 }
3247
John Bauman19bac1e2014-05-06 15:23:49 -04003248 RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003249 {
John Bauman66b8ab22014-05-06 15:57:45 -04003250 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 -04003251 }
3252
John Bauman19bac1e2014-05-06 15:23:49 -04003253 RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003254 {
John Bauman66b8ab22014-05-06 15:57:45 -04003255 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 -04003256 }
3257
John Bauman19bac1e2014-05-06 15:23:49 -04003258 RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003259 {
3260 return x86::paddusw(x, y);
3261 }
3262
John Bauman19bac1e2014-05-06 15:23:49 -04003263 RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003264 {
3265 return x86::psubusw(x, y);
3266 }
3267
John Bauman19bac1e2014-05-06 15:23:49 -04003268 RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003269 {
3270 return x86::pmulhuw(x, y);
3271 }
3272
John Bauman19bac1e2014-05-06 15:23:49 -04003273 RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003274 {
3275 return x86::pavgw(x, y);
3276 }
3277
John Bauman19bac1e2014-05-06 15:23:49 -04003278 RValue<Byte8> Pack(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003279 {
3280 return x86::packuswb(x, y);
3281 }
3282
John Bauman19bac1e2014-05-06 15:23:49 -04003283 Type *UShort4::getType()
John Bauman89401822014-05-06 15:04:28 -04003284 {
John Bauman19bac1e2014-05-06 15:23:49 -04003285 if(CPUID::supportsMMX2())
3286 {
3287 return MMX::getType();
3288 }
3289 else
3290 {
Nicolas Capensac230122016-09-20 14:30:06 -04003291 return T(VectorType::get(UShort::getType(), 4));
John Bauman19bac1e2014-05-06 15:23:49 -04003292 }
John Bauman89401822014-05-06 15:04:28 -04003293 }
3294
Nicolas Capens3e7062b2017-01-17 14:01:33 -05003295 Short8::Short8(short c)
3296 {
3297 int64_t constantVector[8] = {c, c, c, c, c, c, c, c};
3298 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3299 }
3300
John Bauman89401822014-05-06 15:04:28 -04003301 Short8::Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7)
3302 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04003303 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
3304 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04003305 }
3306
John Bauman19bac1e2014-05-06 15:23:49 -04003307 Short8::Short8(RValue<Short8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003308 {
John Bauman66b8ab22014-05-06 15:57:45 -04003309 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003310 }
3311
Nicolas Capensef8cd662016-06-30 15:34:40 -04003312 Short8::Short8(const Reference<Short8> &rhs)
3313 {
Nicolas Capensef8cd662016-06-30 15:34:40 -04003314 Value *value = rhs.loadValue();
3315 storeValue(value);
3316 }
3317
Nicolas Capens62abb552016-01-05 12:03:47 -05003318 Short8::Short8(RValue<Short4> lo, RValue<Short4> hi)
3319 {
3320 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
3321 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
3322
Nicolas Capens22008782016-10-20 01:11:47 -04003323 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Nicolas Capens62abb552016-01-05 12:03:47 -05003324 long2 = Nucleus::createInsertElement(long2, loLong, 0);
3325 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
3326 Value *short8 = Nucleus::createBitCast(long2, Short8::getType());
3327
3328 storeValue(short8);
3329 }
3330
John Bauman19bac1e2014-05-06 15:23:49 -04003331 RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003332 {
3333 return RValue<Short8>(Nucleus::createAdd(lhs.value, rhs.value));
3334 }
3335
John Bauman19bac1e2014-05-06 15:23:49 -04003336 RValue<Short8> operator&(RValue<Short8> lhs, RValue<Short8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003337 {
3338 return RValue<Short8>(Nucleus::createAnd(lhs.value, rhs.value));
3339 }
3340
John Bauman19bac1e2014-05-06 15:23:49 -04003341 RValue<Short8> operator<<(RValue<Short8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003342 {
3343 return x86::psllw(lhs, rhs); // FIXME: Fallback required
3344 }
3345
John Bauman19bac1e2014-05-06 15:23:49 -04003346 RValue<Short8> operator>>(RValue<Short8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003347 {
3348 return x86::psraw(lhs, rhs); // FIXME: Fallback required
3349 }
3350
John Bauman19bac1e2014-05-06 15:23:49 -04003351 RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04003352 {
3353 return x86::pmaddwd(x, y); // FIXME: Fallback required
3354 }
3355
Alexis Hetu0f448072016-03-18 10:56:08 -04003356 RValue<Int4> Abs(RValue<Int4> x)
3357 {
3358 if(CPUID::supportsSSSE3())
3359 {
3360 return x86::pabsd(x);
3361 }
3362 else
3363 {
3364 Int4 mask = (x >> 31);
3365 return (mask ^ x) - mask;
3366 }
3367 }
3368
John Bauman19bac1e2014-05-06 15:23:49 -04003369 RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04003370 {
3371 return x86::pmulhw(x, y); // FIXME: Fallback required
3372 }
3373
John Bauman19bac1e2014-05-06 15:23:49 -04003374 Type *Short8::getType()
John Bauman89401822014-05-06 15:04:28 -04003375 {
Nicolas Capensac230122016-09-20 14:30:06 -04003376 return T(VectorType::get(Short::getType(), 8));
John Bauman89401822014-05-06 15:04:28 -04003377 }
3378
Nicolas Capens3e7062b2017-01-17 14:01:33 -05003379 UShort8::UShort8(unsigned short c)
3380 {
3381 int64_t constantVector[8] = {c, c, c, c, c, c, c, c};
3382 storeValue(Nucleus::createConstantVector(constantVector, getType()));
3383 }
3384
John Bauman89401822014-05-06 15:04:28 -04003385 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)
3386 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04003387 int64_t constantVector[8] = {c0, c1, c2, c3, c4, c5, c6, c7};
3388 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04003389 }
3390
John Bauman19bac1e2014-05-06 15:23:49 -04003391 UShort8::UShort8(RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003392 {
John Bauman66b8ab22014-05-06 15:57:45 -04003393 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003394 }
3395
Nicolas Capensef8cd662016-06-30 15:34:40 -04003396 UShort8::UShort8(const Reference<UShort8> &rhs)
3397 {
Nicolas Capensef8cd662016-06-30 15:34:40 -04003398 Value *value = rhs.loadValue();
3399 storeValue(value);
3400 }
3401
Nicolas Capens62abb552016-01-05 12:03:47 -05003402 UShort8::UShort8(RValue<UShort4> lo, RValue<UShort4> hi)
3403 {
3404 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
3405 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
3406
Nicolas Capens22008782016-10-20 01:11:47 -04003407 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Nicolas Capens62abb552016-01-05 12:03:47 -05003408 long2 = Nucleus::createInsertElement(long2, loLong, 0);
3409 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
3410 Value *short8 = Nucleus::createBitCast(long2, Short8::getType());
3411
3412 storeValue(short8);
3413 }
3414
Nicolas Capens96d4e092016-11-18 14:22:38 -05003415 RValue<UShort8> UShort8::operator=(RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003416 {
John Bauman66b8ab22014-05-06 15:57:45 -04003417 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003418
3419 return rhs;
3420 }
3421
Nicolas Capens96d4e092016-11-18 14:22:38 -05003422 RValue<UShort8> UShort8::operator=(const UShort8 &rhs)
John Bauman89401822014-05-06 15:04:28 -04003423 {
John Bauman66b8ab22014-05-06 15:57:45 -04003424 Value *value = rhs.loadValue();
3425 storeValue(value);
3426
3427 return RValue<UShort8>(value);
3428 }
3429
Nicolas Capens96d4e092016-11-18 14:22:38 -05003430 RValue<UShort8> UShort8::operator=(const Reference<UShort8> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04003431 {
3432 Value *value = rhs.loadValue();
3433 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003434
3435 return RValue<UShort8>(value);
3436 }
3437
John Bauman19bac1e2014-05-06 15:23:49 -04003438 RValue<UShort8> operator&(RValue<UShort8> lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003439 {
3440 return RValue<UShort8>(Nucleus::createAnd(lhs.value, rhs.value));
3441 }
3442
John Bauman19bac1e2014-05-06 15:23:49 -04003443 RValue<UShort8> operator<<(RValue<UShort8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003444 {
3445 return As<UShort8>(x86::psllw(As<Short8>(lhs), rhs)); // FIXME: Fallback required
3446 }
3447
John Bauman19bac1e2014-05-06 15:23:49 -04003448 RValue<UShort8> operator>>(RValue<UShort8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003449 {
3450 return x86::psrlw(lhs, rhs); // FIXME: Fallback required
3451 }
3452
John Bauman19bac1e2014-05-06 15:23:49 -04003453 RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003454 {
3455 return RValue<UShort8>(Nucleus::createAdd(lhs.value, rhs.value));
3456 }
3457
John Bauman19bac1e2014-05-06 15:23:49 -04003458 RValue<UShort8> operator*(RValue<UShort8> lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003459 {
3460 return RValue<UShort8>(Nucleus::createMul(lhs.value, rhs.value));
3461 }
3462
Nicolas Capens96d4e092016-11-18 14:22:38 -05003463 RValue<UShort8> operator+=(UShort8 &lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003464 {
3465 return lhs = lhs + rhs;
3466 }
3467
John Bauman19bac1e2014-05-06 15:23:49 -04003468 RValue<UShort8> operator~(RValue<UShort8> val)
John Bauman89401822014-05-06 15:04:28 -04003469 {
3470 return RValue<UShort8>(Nucleus::createNot(val.value));
3471 }
3472
John Bauman19bac1e2014-05-06 15:23:49 -04003473 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 -04003474 {
Nicolas Capense89cd582016-09-30 14:23:47 -04003475 int pshufb[16] =
3476 {
3477 select0 + 0,
3478 select0 + 1,
3479 select1 + 0,
3480 select1 + 1,
3481 select2 + 0,
3482 select2 + 1,
3483 select3 + 0,
3484 select3 + 1,
3485 select4 + 0,
3486 select4 + 1,
3487 select5 + 0,
3488 select5 + 1,
3489 select6 + 0,
3490 select6 + 1,
3491 select7 + 0,
3492 select7 + 1,
3493 };
John Bauman89401822014-05-06 15:04:28 -04003494
3495 Value *byte16 = Nucleus::createBitCast(x.value, Byte16::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04003496 Value *shuffle = Nucleus::createShuffleVector(byte16, byte16, pshufb);
John Bauman89401822014-05-06 15:04:28 -04003497 Value *short8 = Nucleus::createBitCast(shuffle, UShort8::getType());
3498
3499 return RValue<UShort8>(short8);
3500 }
3501
John Bauman19bac1e2014-05-06 15:23:49 -04003502 RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y)
John Bauman89401822014-05-06 15:04:28 -04003503 {
3504 return x86::pmulhuw(x, y); // FIXME: Fallback required
3505 }
3506
John Bauman19bac1e2014-05-06 15:23:49 -04003507 Type *UShort8::getType()
John Bauman89401822014-05-06 15:04:28 -04003508 {
Nicolas Capensac230122016-09-20 14:30:06 -04003509 return T(VectorType::get(UShort::getType(), 8));
John Bauman89401822014-05-06 15:04:28 -04003510 }
3511
Nicolas Capens81f18302016-01-14 09:32:35 -05003512 Int::Int(Argument<Int> argument)
John Bauman89401822014-05-06 15:04:28 -04003513 {
Nicolas Capens81f18302016-01-14 09:32:35 -05003514 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04003515 }
3516
John Bauman19bac1e2014-05-06 15:23:49 -04003517 Int::Int(RValue<Byte> cast)
John Bauman89401822014-05-06 15:04:28 -04003518 {
John Bauman89401822014-05-06 15:04:28 -04003519 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3520
John Bauman66b8ab22014-05-06 15:57:45 -04003521 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003522 }
3523
John Bauman19bac1e2014-05-06 15:23:49 -04003524 Int::Int(RValue<SByte> cast)
John Bauman89401822014-05-06 15:04:28 -04003525 {
John Bauman89401822014-05-06 15:04:28 -04003526 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3527
John Bauman66b8ab22014-05-06 15:57:45 -04003528 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003529 }
3530
John Bauman19bac1e2014-05-06 15:23:49 -04003531 Int::Int(RValue<Short> cast)
John Bauman89401822014-05-06 15:04:28 -04003532 {
John Bauman89401822014-05-06 15:04:28 -04003533 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3534
John Bauman66b8ab22014-05-06 15:57:45 -04003535 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003536 }
3537
John Bauman19bac1e2014-05-06 15:23:49 -04003538 Int::Int(RValue<UShort> cast)
John Bauman89401822014-05-06 15:04:28 -04003539 {
John Bauman89401822014-05-06 15:04:28 -04003540 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3541
John Bauman66b8ab22014-05-06 15:57:45 -04003542 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003543 }
3544
John Bauman19bac1e2014-05-06 15:23:49 -04003545 Int::Int(RValue<Int2> cast)
John Bauman89401822014-05-06 15:04:28 -04003546 {
John Bauman89401822014-05-06 15:04:28 -04003547 *this = Extract(cast, 0);
3548 }
3549
John Bauman19bac1e2014-05-06 15:23:49 -04003550 Int::Int(RValue<Long> cast)
John Bauman89401822014-05-06 15:04:28 -04003551 {
John Bauman89401822014-05-06 15:04:28 -04003552 Value *integer = Nucleus::createTrunc(cast.value, Int::getType());
3553
John Bauman66b8ab22014-05-06 15:57:45 -04003554 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003555 }
3556
John Bauman19bac1e2014-05-06 15:23:49 -04003557 Int::Int(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04003558 {
John Bauman89401822014-05-06 15:04:28 -04003559 Value *integer = Nucleus::createFPToSI(cast.value, Int::getType());
3560
John Bauman66b8ab22014-05-06 15:57:45 -04003561 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003562 }
3563
John Bauman89401822014-05-06 15:04:28 -04003564 Int::Int(int x)
3565 {
John Bauman66b8ab22014-05-06 15:57:45 -04003566 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04003567 }
3568
John Bauman19bac1e2014-05-06 15:23:49 -04003569 Int::Int(RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003570 {
John Bauman66b8ab22014-05-06 15:57:45 -04003571 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003572 }
3573
John Bauman19bac1e2014-05-06 15:23:49 -04003574 Int::Int(RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04003575 {
John Bauman66b8ab22014-05-06 15:57:45 -04003576 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003577 }
3578
3579 Int::Int(const Int &rhs)
3580 {
John Bauman66b8ab22014-05-06 15:57:45 -04003581 Value *value = rhs.loadValue();
3582 storeValue(value);
3583 }
John Bauman89401822014-05-06 15:04:28 -04003584
John Bauman66b8ab22014-05-06 15:57:45 -04003585 Int::Int(const Reference<Int> &rhs)
3586 {
3587 Value *value = rhs.loadValue();
3588 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003589 }
3590
3591 Int::Int(const UInt &rhs)
3592 {
John Bauman66b8ab22014-05-06 15:57:45 -04003593 Value *value = rhs.loadValue();
3594 storeValue(value);
3595 }
John Bauman89401822014-05-06 15:04:28 -04003596
John Bauman66b8ab22014-05-06 15:57:45 -04003597 Int::Int(const Reference<UInt> &rhs)
3598 {
3599 Value *value = rhs.loadValue();
3600 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003601 }
3602
Nicolas Capens96d4e092016-11-18 14:22:38 -05003603 RValue<Int> Int::operator=(int rhs)
John Bauman89401822014-05-06 15:04:28 -04003604 {
John Bauman66b8ab22014-05-06 15:57:45 -04003605 return RValue<Int>(storeValue(Nucleus::createConstantInt(rhs)));
John Bauman89401822014-05-06 15:04:28 -04003606 }
3607
Nicolas Capens96d4e092016-11-18 14:22:38 -05003608 RValue<Int> Int::operator=(RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003609 {
John Bauman66b8ab22014-05-06 15:57:45 -04003610 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003611
3612 return rhs;
3613 }
3614
Nicolas Capens96d4e092016-11-18 14:22:38 -05003615 RValue<Int> Int::operator=(RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04003616 {
John Bauman66b8ab22014-05-06 15:57:45 -04003617 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003618
John Bauman66b8ab22014-05-06 15:57:45 -04003619 return RValue<Int>(rhs);
John Bauman89401822014-05-06 15:04:28 -04003620 }
3621
Nicolas Capens96d4e092016-11-18 14:22:38 -05003622 RValue<Int> Int::operator=(const Int &rhs)
John Bauman89401822014-05-06 15:04:28 -04003623 {
John Bauman66b8ab22014-05-06 15:57:45 -04003624 Value *value = rhs.loadValue();
3625 storeValue(value);
3626
3627 return RValue<Int>(value);
3628 }
3629
Nicolas Capens96d4e092016-11-18 14:22:38 -05003630 RValue<Int> Int::operator=(const Reference<Int> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04003631 {
3632 Value *value = rhs.loadValue();
3633 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003634
3635 return RValue<Int>(value);
3636 }
3637
Nicolas Capens96d4e092016-11-18 14:22:38 -05003638 RValue<Int> Int::operator=(const UInt &rhs)
John Bauman89401822014-05-06 15:04:28 -04003639 {
John Bauman66b8ab22014-05-06 15:57:45 -04003640 Value *value = rhs.loadValue();
3641 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003642
3643 return RValue<Int>(value);
3644 }
3645
Nicolas Capens96d4e092016-11-18 14:22:38 -05003646 RValue<Int> Int::operator=(const Reference<UInt> &rhs)
John Bauman89401822014-05-06 15:04:28 -04003647 {
John Bauman66b8ab22014-05-06 15:57:45 -04003648 Value *value = rhs.loadValue();
3649 storeValue(value);
3650
3651 return RValue<Int>(value);
John Bauman89401822014-05-06 15:04:28 -04003652 }
3653
John Bauman19bac1e2014-05-06 15:23:49 -04003654 RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003655 {
3656 return RValue<Int>(Nucleus::createAdd(lhs.value, rhs.value));
3657 }
3658
John Bauman19bac1e2014-05-06 15:23:49 -04003659 RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003660 {
3661 return RValue<Int>(Nucleus::createSub(lhs.value, rhs.value));
3662 }
3663
John Bauman19bac1e2014-05-06 15:23:49 -04003664 RValue<Int> operator*(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003665 {
3666 return RValue<Int>(Nucleus::createMul(lhs.value, rhs.value));
3667 }
3668
John Bauman19bac1e2014-05-06 15:23:49 -04003669 RValue<Int> operator/(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003670 {
3671 return RValue<Int>(Nucleus::createSDiv(lhs.value, rhs.value));
3672 }
3673
John Bauman19bac1e2014-05-06 15:23:49 -04003674 RValue<Int> operator%(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003675 {
3676 return RValue<Int>(Nucleus::createSRem(lhs.value, rhs.value));
3677 }
3678
John Bauman19bac1e2014-05-06 15:23:49 -04003679 RValue<Int> operator&(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003680 {
3681 return RValue<Int>(Nucleus::createAnd(lhs.value, rhs.value));
3682 }
3683
John Bauman19bac1e2014-05-06 15:23:49 -04003684 RValue<Int> operator|(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003685 {
3686 return RValue<Int>(Nucleus::createOr(lhs.value, rhs.value));
3687 }
3688
John Bauman19bac1e2014-05-06 15:23:49 -04003689 RValue<Int> operator^(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003690 {
3691 return RValue<Int>(Nucleus::createXor(lhs.value, rhs.value));
3692 }
3693
John Bauman19bac1e2014-05-06 15:23:49 -04003694 RValue<Int> operator<<(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003695 {
3696 return RValue<Int>(Nucleus::createShl(lhs.value, rhs.value));
3697 }
3698
John Bauman19bac1e2014-05-06 15:23:49 -04003699 RValue<Int> operator>>(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003700 {
3701 return RValue<Int>(Nucleus::createAShr(lhs.value, rhs.value));
3702 }
3703
Nicolas Capens96d4e092016-11-18 14:22:38 -05003704 RValue<Int> operator+=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003705 {
3706 return lhs = lhs + rhs;
3707 }
3708
Nicolas Capens96d4e092016-11-18 14:22:38 -05003709 RValue<Int> operator-=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003710 {
3711 return lhs = lhs - rhs;
3712 }
3713
Nicolas Capens96d4e092016-11-18 14:22:38 -05003714 RValue<Int> operator*=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003715 {
3716 return lhs = lhs * rhs;
3717 }
3718
Nicolas Capens96d4e092016-11-18 14:22:38 -05003719 RValue<Int> operator/=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003720 {
3721 return lhs = lhs / rhs;
3722 }
3723
Nicolas Capens96d4e092016-11-18 14:22:38 -05003724 RValue<Int> operator%=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003725 {
3726 return lhs = lhs % rhs;
3727 }
3728
Nicolas Capens96d4e092016-11-18 14:22:38 -05003729 RValue<Int> operator&=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003730 {
3731 return lhs = lhs & rhs;
3732 }
3733
Nicolas Capens96d4e092016-11-18 14:22:38 -05003734 RValue<Int> operator|=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003735 {
3736 return lhs = lhs | rhs;
3737 }
3738
Nicolas Capens96d4e092016-11-18 14:22:38 -05003739 RValue<Int> operator^=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003740 {
3741 return lhs = lhs ^ rhs;
3742 }
3743
Nicolas Capens96d4e092016-11-18 14:22:38 -05003744 RValue<Int> operator<<=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003745 {
3746 return lhs = lhs << rhs;
3747 }
3748
Nicolas Capens96d4e092016-11-18 14:22:38 -05003749 RValue<Int> operator>>=(Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003750 {
3751 return lhs = lhs >> rhs;
3752 }
3753
John Bauman19bac1e2014-05-06 15:23:49 -04003754 RValue<Int> operator+(RValue<Int> val)
John Bauman89401822014-05-06 15:04:28 -04003755 {
3756 return val;
3757 }
3758
John Bauman19bac1e2014-05-06 15:23:49 -04003759 RValue<Int> operator-(RValue<Int> val)
John Bauman89401822014-05-06 15:04:28 -04003760 {
3761 return RValue<Int>(Nucleus::createNeg(val.value));
3762 }
3763
John Bauman19bac1e2014-05-06 15:23:49 -04003764 RValue<Int> operator~(RValue<Int> val)
John Bauman89401822014-05-06 15:04:28 -04003765 {
3766 return RValue<Int>(Nucleus::createNot(val.value));
3767 }
3768
Nicolas Capens96d4e092016-11-18 14:22:38 -05003769 RValue<Int> operator++(Int &val, int) // Post-increment
John Bauman89401822014-05-06 15:04:28 -04003770 {
3771 RValue<Int> res = val;
3772
Nicolas Capens19336542016-09-26 10:32:29 -04003773 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04003774 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04003775
3776 return res;
3777 }
3778
Nicolas Capens96d4e092016-11-18 14:22:38 -05003779 const Int &operator++(Int &val) // Pre-increment
John Bauman89401822014-05-06 15:04:28 -04003780 {
Nicolas Capens19336542016-09-26 10:32:29 -04003781 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04003782 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04003783
3784 return val;
3785 }
3786
Nicolas Capens96d4e092016-11-18 14:22:38 -05003787 RValue<Int> operator--(Int &val, int) // Post-decrement
John Bauman89401822014-05-06 15:04:28 -04003788 {
3789 RValue<Int> res = val;
3790
Nicolas Capens19336542016-09-26 10:32:29 -04003791 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04003792 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04003793
3794 return res;
3795 }
3796
Nicolas Capens96d4e092016-11-18 14:22:38 -05003797 const Int &operator--(Int &val) // Pre-decrement
John Bauman89401822014-05-06 15:04:28 -04003798 {
Nicolas Capens19336542016-09-26 10:32:29 -04003799 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04003800 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04003801
3802 return val;
3803 }
3804
John Bauman19bac1e2014-05-06 15:23:49 -04003805 RValue<Bool> operator<(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003806 {
3807 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
3808 }
3809
John Bauman19bac1e2014-05-06 15:23:49 -04003810 RValue<Bool> operator<=(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003811 {
3812 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
3813 }
3814
John Bauman19bac1e2014-05-06 15:23:49 -04003815 RValue<Bool> operator>(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003816 {
3817 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
3818 }
3819
John Bauman19bac1e2014-05-06 15:23:49 -04003820 RValue<Bool> operator>=(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003821 {
3822 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
3823 }
3824
John Bauman19bac1e2014-05-06 15:23:49 -04003825 RValue<Bool> operator!=(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003826 {
3827 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
3828 }
3829
John Bauman19bac1e2014-05-06 15:23:49 -04003830 RValue<Bool> operator==(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003831 {
3832 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
3833 }
3834
John Bauman19bac1e2014-05-06 15:23:49 -04003835 RValue<Int> Max(RValue<Int> x, RValue<Int> y)
3836 {
3837 return IfThenElse(x > y, x, y);
3838 }
3839
3840 RValue<Int> Min(RValue<Int> x, RValue<Int> y)
3841 {
3842 return IfThenElse(x < y, x, y);
3843 }
3844
3845 RValue<Int> Clamp(RValue<Int> x, RValue<Int> min, RValue<Int> max)
3846 {
3847 return Min(Max(x, min), max);
3848 }
3849
3850 RValue<Int> RoundInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04003851 {
3852 return x86::cvtss2si(cast);
3853
John Bauman66b8ab22014-05-06 15:57:45 -04003854 // return IfThenElse(val > 0.0f, Int(val + 0.5f), Int(val - 0.5f));
John Bauman89401822014-05-06 15:04:28 -04003855 }
3856
John Bauman19bac1e2014-05-06 15:23:49 -04003857 Type *Int::getType()
John Bauman89401822014-05-06 15:04:28 -04003858 {
Nicolas Capensac230122016-09-20 14:30:06 -04003859 return T(llvm::Type::getInt32Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04003860 }
3861
John Bauman19bac1e2014-05-06 15:23:49 -04003862 Long::Long(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04003863 {
John Bauman89401822014-05-06 15:04:28 -04003864 Value *integer = Nucleus::createSExt(cast.value, Long::getType());
3865
John Bauman66b8ab22014-05-06 15:57:45 -04003866 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003867 }
3868
John Bauman19bac1e2014-05-06 15:23:49 -04003869 Long::Long(RValue<UInt> cast)
John Bauman89401822014-05-06 15:04:28 -04003870 {
John Bauman89401822014-05-06 15:04:28 -04003871 Value *integer = Nucleus::createZExt(cast.value, Long::getType());
3872
John Bauman66b8ab22014-05-06 15:57:45 -04003873 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003874 }
3875
John Bauman19bac1e2014-05-06 15:23:49 -04003876 Long::Long(RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04003877 {
John Bauman66b8ab22014-05-06 15:57:45 -04003878 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003879 }
3880
Nicolas Capens96d4e092016-11-18 14:22:38 -05003881 RValue<Long> Long::operator=(int64_t rhs)
John Bauman89401822014-05-06 15:04:28 -04003882 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04003883 return RValue<Long>(storeValue(Nucleus::createConstantLong(rhs)));
John Bauman89401822014-05-06 15:04:28 -04003884 }
3885
Nicolas Capens96d4e092016-11-18 14:22:38 -05003886 RValue<Long> Long::operator=(RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04003887 {
John Bauman66b8ab22014-05-06 15:57:45 -04003888 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003889
3890 return rhs;
3891 }
3892
Nicolas Capens96d4e092016-11-18 14:22:38 -05003893 RValue<Long> Long::operator=(const Long &rhs)
John Bauman89401822014-05-06 15:04:28 -04003894 {
John Bauman66b8ab22014-05-06 15:57:45 -04003895 Value *value = rhs.loadValue();
3896 storeValue(value);
3897
3898 return RValue<Long>(value);
3899 }
3900
Nicolas Capens96d4e092016-11-18 14:22:38 -05003901 RValue<Long> Long::operator=(const Reference<Long> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04003902 {
3903 Value *value = rhs.loadValue();
3904 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003905
3906 return RValue<Long>(value);
3907 }
3908
John Bauman19bac1e2014-05-06 15:23:49 -04003909 RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04003910 {
3911 return RValue<Long>(Nucleus::createAdd(lhs.value, rhs.value));
3912 }
3913
John Bauman19bac1e2014-05-06 15:23:49 -04003914 RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04003915 {
3916 return RValue<Long>(Nucleus::createSub(lhs.value, rhs.value));
3917 }
3918
Nicolas Capens96d4e092016-11-18 14:22:38 -05003919 RValue<Long> operator+=(Long &lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04003920 {
3921 return lhs = lhs + rhs;
3922 }
3923
Nicolas Capens96d4e092016-11-18 14:22:38 -05003924 RValue<Long> operator-=(Long &lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04003925 {
3926 return lhs = lhs - rhs;
3927 }
3928
John Bauman66b8ab22014-05-06 15:57:45 -04003929 RValue<Long> AddAtomic(RValue<Pointer<Long> > x, RValue<Long> y)
John Bauman89401822014-05-06 15:04:28 -04003930 {
John Bauman19bac1e2014-05-06 15:23:49 -04003931 return RValue<Long>(Nucleus::createAtomicAdd(x.value, y.value));
John Bauman89401822014-05-06 15:04:28 -04003932 }
3933
John Bauman19bac1e2014-05-06 15:23:49 -04003934 Type *Long::getType()
John Bauman89401822014-05-06 15:04:28 -04003935 {
Nicolas Capensac230122016-09-20 14:30:06 -04003936 return T(llvm::Type::getInt64Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04003937 }
3938
Nicolas Capens81f18302016-01-14 09:32:35 -05003939 UInt::UInt(Argument<UInt> argument)
John Bauman89401822014-05-06 15:04:28 -04003940 {
Nicolas Capens81f18302016-01-14 09:32:35 -05003941 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04003942 }
3943
John Bauman19bac1e2014-05-06 15:23:49 -04003944 UInt::UInt(RValue<UShort> cast)
John Bauman89401822014-05-06 15:04:28 -04003945 {
John Bauman89401822014-05-06 15:04:28 -04003946 Value *integer = Nucleus::createZExt(cast.value, UInt::getType());
3947
John Bauman66b8ab22014-05-06 15:57:45 -04003948 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003949 }
3950
John Bauman19bac1e2014-05-06 15:23:49 -04003951 UInt::UInt(RValue<Long> cast)
John Bauman89401822014-05-06 15:04:28 -04003952 {
John Bauman89401822014-05-06 15:04:28 -04003953 Value *integer = Nucleus::createTrunc(cast.value, UInt::getType());
3954
John Bauman66b8ab22014-05-06 15:57:45 -04003955 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003956 }
3957
John Bauman19bac1e2014-05-06 15:23:49 -04003958 UInt::UInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04003959 {
Alexis Hetu764d1422016-09-28 08:44:22 -04003960 // Note: createFPToUI is broken, must perform conversion using createFPtoSI
3961 // Value *integer = Nucleus::createFPToUI(cast.value, UInt::getType());
John Bauman89401822014-05-06 15:04:28 -04003962
Alexis Hetu764d1422016-09-28 08:44:22 -04003963 // Smallest positive value representable in UInt, but not in Int
3964 const unsigned int ustart = 0x80000000u;
3965 const float ustartf = float(ustart);
3966
3967 // If the value is negative, store 0, otherwise store the result of the conversion
3968 storeValue((~(As<Int>(cast) >> 31) &
3969 // Check if the value can be represented as an Int
3970 IfThenElse(cast >= ustartf,
3971 // If the value is too large, subtract ustart and re-add it after conversion.
3972 As<Int>(As<UInt>(Int(cast - Float(ustartf))) + UInt(ustart)),
3973 // Otherwise, just convert normally
3974 Int(cast))).value);
John Bauman89401822014-05-06 15:04:28 -04003975 }
3976
John Bauman89401822014-05-06 15:04:28 -04003977 UInt::UInt(int x)
3978 {
John Bauman66b8ab22014-05-06 15:57:45 -04003979 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04003980 }
3981
3982 UInt::UInt(unsigned int x)
3983 {
John Bauman66b8ab22014-05-06 15:57:45 -04003984 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04003985 }
3986
John Bauman19bac1e2014-05-06 15:23:49 -04003987 UInt::UInt(RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04003988 {
John Bauman66b8ab22014-05-06 15:57:45 -04003989 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003990 }
3991
John Bauman19bac1e2014-05-06 15:23:49 -04003992 UInt::UInt(RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003993 {
John Bauman66b8ab22014-05-06 15:57:45 -04003994 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003995 }
3996
3997 UInt::UInt(const UInt &rhs)
3998 {
John Bauman66b8ab22014-05-06 15:57:45 -04003999 Value *value = rhs.loadValue();
4000 storeValue(value);
4001 }
John Bauman89401822014-05-06 15:04:28 -04004002
John Bauman66b8ab22014-05-06 15:57:45 -04004003 UInt::UInt(const Reference<UInt> &rhs)
4004 {
4005 Value *value = rhs.loadValue();
4006 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004007 }
4008
4009 UInt::UInt(const Int &rhs)
4010 {
John Bauman66b8ab22014-05-06 15:57:45 -04004011 Value *value = rhs.loadValue();
4012 storeValue(value);
4013 }
John Bauman89401822014-05-06 15:04:28 -04004014
John Bauman66b8ab22014-05-06 15:57:45 -04004015 UInt::UInt(const Reference<Int> &rhs)
4016 {
4017 Value *value = rhs.loadValue();
4018 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004019 }
4020
Nicolas Capens96d4e092016-11-18 14:22:38 -05004021 RValue<UInt> UInt::operator=(unsigned int rhs)
John Bauman89401822014-05-06 15:04:28 -04004022 {
John Bauman66b8ab22014-05-06 15:57:45 -04004023 return RValue<UInt>(storeValue(Nucleus::createConstantInt(rhs)));
John Bauman89401822014-05-06 15:04:28 -04004024 }
4025
Nicolas Capens96d4e092016-11-18 14:22:38 -05004026 RValue<UInt> UInt::operator=(RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004027 {
John Bauman66b8ab22014-05-06 15:57:45 -04004028 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004029
4030 return rhs;
4031 }
4032
Nicolas Capens96d4e092016-11-18 14:22:38 -05004033 RValue<UInt> UInt::operator=(RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004034 {
John Bauman66b8ab22014-05-06 15:57:45 -04004035 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004036
John Bauman66b8ab22014-05-06 15:57:45 -04004037 return RValue<UInt>(rhs);
John Bauman89401822014-05-06 15:04:28 -04004038 }
4039
Nicolas Capens96d4e092016-11-18 14:22:38 -05004040 RValue<UInt> UInt::operator=(const UInt &rhs)
John Bauman89401822014-05-06 15:04:28 -04004041 {
John Bauman66b8ab22014-05-06 15:57:45 -04004042 Value *value = rhs.loadValue();
4043 storeValue(value);
4044
4045 return RValue<UInt>(value);
4046 }
4047
Nicolas Capens96d4e092016-11-18 14:22:38 -05004048 RValue<UInt> UInt::operator=(const Reference<UInt> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04004049 {
4050 Value *value = rhs.loadValue();
4051 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004052
4053 return RValue<UInt>(value);
4054 }
4055
Nicolas Capens96d4e092016-11-18 14:22:38 -05004056 RValue<UInt> UInt::operator=(const Int &rhs)
John Bauman89401822014-05-06 15:04:28 -04004057 {
John Bauman66b8ab22014-05-06 15:57:45 -04004058 Value *value = rhs.loadValue();
4059 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004060
4061 return RValue<UInt>(value);
4062 }
4063
Nicolas Capens96d4e092016-11-18 14:22:38 -05004064 RValue<UInt> UInt::operator=(const Reference<Int> &rhs)
John Bauman89401822014-05-06 15:04:28 -04004065 {
John Bauman66b8ab22014-05-06 15:57:45 -04004066 Value *value = rhs.loadValue();
4067 storeValue(value);
4068
4069 return RValue<UInt>(value);
John Bauman89401822014-05-06 15:04:28 -04004070 }
4071
John Bauman19bac1e2014-05-06 15:23:49 -04004072 RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004073 {
4074 return RValue<UInt>(Nucleus::createAdd(lhs.value, rhs.value));
4075 }
4076
John Bauman19bac1e2014-05-06 15:23:49 -04004077 RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004078 {
4079 return RValue<UInt>(Nucleus::createSub(lhs.value, rhs.value));
4080 }
4081
John Bauman19bac1e2014-05-06 15:23:49 -04004082 RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004083 {
4084 return RValue<UInt>(Nucleus::createMul(lhs.value, rhs.value));
4085 }
4086
John Bauman19bac1e2014-05-06 15:23:49 -04004087 RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004088 {
4089 return RValue<UInt>(Nucleus::createUDiv(lhs.value, rhs.value));
4090 }
4091
John Bauman19bac1e2014-05-06 15:23:49 -04004092 RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004093 {
4094 return RValue<UInt>(Nucleus::createURem(lhs.value, rhs.value));
4095 }
4096
John Bauman19bac1e2014-05-06 15:23:49 -04004097 RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004098 {
4099 return RValue<UInt>(Nucleus::createAnd(lhs.value, rhs.value));
4100 }
4101
John Bauman19bac1e2014-05-06 15:23:49 -04004102 RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004103 {
4104 return RValue<UInt>(Nucleus::createOr(lhs.value, rhs.value));
4105 }
4106
John Bauman19bac1e2014-05-06 15:23:49 -04004107 RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004108 {
4109 return RValue<UInt>(Nucleus::createXor(lhs.value, rhs.value));
4110 }
4111
John Bauman19bac1e2014-05-06 15:23:49 -04004112 RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004113 {
4114 return RValue<UInt>(Nucleus::createShl(lhs.value, rhs.value));
4115 }
4116
John Bauman19bac1e2014-05-06 15:23:49 -04004117 RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004118 {
4119 return RValue<UInt>(Nucleus::createLShr(lhs.value, rhs.value));
4120 }
4121
Nicolas Capens96d4e092016-11-18 14:22:38 -05004122 RValue<UInt> operator+=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004123 {
4124 return lhs = lhs + rhs;
4125 }
4126
Nicolas Capens96d4e092016-11-18 14:22:38 -05004127 RValue<UInt> operator-=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004128 {
4129 return lhs = lhs - rhs;
4130 }
4131
Nicolas Capens96d4e092016-11-18 14:22:38 -05004132 RValue<UInt> operator*=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004133 {
4134 return lhs = lhs * rhs;
4135 }
4136
Nicolas Capens96d4e092016-11-18 14:22:38 -05004137 RValue<UInt> operator/=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004138 {
4139 return lhs = lhs / rhs;
4140 }
4141
Nicolas Capens96d4e092016-11-18 14:22:38 -05004142 RValue<UInt> operator%=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004143 {
4144 return lhs = lhs % rhs;
4145 }
4146
Nicolas Capens96d4e092016-11-18 14:22:38 -05004147 RValue<UInt> operator&=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004148 {
4149 return lhs = lhs & rhs;
4150 }
4151
Nicolas Capens96d4e092016-11-18 14:22:38 -05004152 RValue<UInt> operator|=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004153 {
4154 return lhs = lhs | rhs;
4155 }
4156
Nicolas Capens96d4e092016-11-18 14:22:38 -05004157 RValue<UInt> operator^=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004158 {
4159 return lhs = lhs ^ rhs;
4160 }
4161
Nicolas Capens96d4e092016-11-18 14:22:38 -05004162 RValue<UInt> operator<<=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004163 {
4164 return lhs = lhs << rhs;
4165 }
4166
Nicolas Capens96d4e092016-11-18 14:22:38 -05004167 RValue<UInt> operator>>=(UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004168 {
4169 return lhs = lhs >> rhs;
4170 }
4171
John Bauman19bac1e2014-05-06 15:23:49 -04004172 RValue<UInt> operator+(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004173 {
4174 return val;
4175 }
4176
John Bauman19bac1e2014-05-06 15:23:49 -04004177 RValue<UInt> operator-(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004178 {
4179 return RValue<UInt>(Nucleus::createNeg(val.value));
4180 }
4181
John Bauman19bac1e2014-05-06 15:23:49 -04004182 RValue<UInt> operator~(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004183 {
4184 return RValue<UInt>(Nucleus::createNot(val.value));
4185 }
4186
Nicolas Capens96d4e092016-11-18 14:22:38 -05004187 RValue<UInt> operator++(UInt &val, int) // Post-increment
John Bauman89401822014-05-06 15:04:28 -04004188 {
4189 RValue<UInt> res = val;
4190
Nicolas Capens19336542016-09-26 10:32:29 -04004191 Value *inc = Nucleus::createAdd(res.value, V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04004192 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004193
4194 return res;
4195 }
4196
Nicolas Capens96d4e092016-11-18 14:22:38 -05004197 const UInt &operator++(UInt &val) // Pre-increment
John Bauman89401822014-05-06 15:04:28 -04004198 {
Nicolas Capens19336542016-09-26 10:32:29 -04004199 Value *inc = Nucleus::createAdd(val.loadValue(), V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04004200 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004201
4202 return val;
4203 }
4204
Nicolas Capens96d4e092016-11-18 14:22:38 -05004205 RValue<UInt> operator--(UInt &val, int) // Post-decrement
John Bauman89401822014-05-06 15:04:28 -04004206 {
4207 RValue<UInt> res = val;
4208
Nicolas Capens19336542016-09-26 10:32:29 -04004209 Value *inc = Nucleus::createSub(res.value, V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04004210 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004211
4212 return res;
4213 }
4214
Nicolas Capens96d4e092016-11-18 14:22:38 -05004215 const UInt &operator--(UInt &val) // Pre-decrement
John Bauman89401822014-05-06 15:04:28 -04004216 {
Nicolas Capens19336542016-09-26 10:32:29 -04004217 Value *inc = Nucleus::createSub(val.loadValue(), V(Nucleus::createConstantInt(1)));
John Bauman66b8ab22014-05-06 15:57:45 -04004218 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004219
4220 return val;
4221 }
4222
John Bauman19bac1e2014-05-06 15:23:49 -04004223 RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y)
4224 {
4225 return IfThenElse(x > y, x, y);
4226 }
4227
4228 RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y)
4229 {
4230 return IfThenElse(x < y, x, y);
4231 }
4232
4233 RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max)
4234 {
4235 return Min(Max(x, min), max);
4236 }
4237
4238 RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004239 {
4240 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
4241 }
4242
John Bauman19bac1e2014-05-06 15:23:49 -04004243 RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004244 {
4245 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
4246 }
4247
John Bauman19bac1e2014-05-06 15:23:49 -04004248 RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004249 {
4250 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
4251 }
4252
John Bauman19bac1e2014-05-06 15:23:49 -04004253 RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004254 {
4255 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
4256 }
4257
John Bauman19bac1e2014-05-06 15:23:49 -04004258 RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004259 {
4260 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
4261 }
4262
John Bauman19bac1e2014-05-06 15:23:49 -04004263 RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004264 {
4265 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
4266 }
4267
John Bauman19bac1e2014-05-06 15:23:49 -04004268// RValue<UInt> RoundUInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04004269// {
4270// return x86::cvtss2si(val); // FIXME: Unsigned
4271//
John Bauman66b8ab22014-05-06 15:57:45 -04004272// // return IfThenElse(val > 0.0f, Int(val + 0.5f), Int(val - 0.5f));
John Bauman89401822014-05-06 15:04:28 -04004273// }
4274
John Bauman19bac1e2014-05-06 15:23:49 -04004275 Type *UInt::getType()
John Bauman89401822014-05-06 15:04:28 -04004276 {
Nicolas Capensac230122016-09-20 14:30:06 -04004277 return T(llvm::Type::getInt32Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04004278 }
4279
John Bauman19bac1e2014-05-06 15:23:49 -04004280// Int2::Int2(RValue<Int> cast)
4281// {
John Bauman19bac1e2014-05-06 15:23:49 -04004282// Value *extend = Nucleus::createZExt(cast.value, Long::getType());
4283// Value *vector = Nucleus::createBitCast(extend, Int2::getType());
John Bauman66b8ab22014-05-06 15:57:45 -04004284//
Nicolas Capense89cd582016-09-30 14:23:47 -04004285// int shuffle[2] = {0, 0};
4286// Value *replicate = Nucleus::createShuffleVector(vector, vector, shuffle);
John Bauman19bac1e2014-05-06 15:23:49 -04004287//
John Bauman66b8ab22014-05-06 15:57:45 -04004288// storeValue(replicate);
John Bauman19bac1e2014-05-06 15:23:49 -04004289// }
John Bauman89401822014-05-06 15:04:28 -04004290
John Bauman19bac1e2014-05-06 15:23:49 -04004291 Int2::Int2(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04004292 {
Nicolas Capens22008782016-10-20 01:11:47 -04004293 Value *long2 = Nucleus::createBitCast(cast.value, T(VectorType::get(Long::getType(), 2)));
Nicolas Capense95d5342016-09-30 11:37:28 -04004294 Value *element = Nucleus::createExtractElement(long2, Long::getType(), 0);
John Bauman89401822014-05-06 15:04:28 -04004295 Value *int2 = Nucleus::createBitCast(element, Int2::getType());
4296
John Bauman66b8ab22014-05-06 15:57:45 -04004297 storeValue(int2);
John Bauman89401822014-05-06 15:04:28 -04004298 }
4299
John Bauman89401822014-05-06 15:04:28 -04004300 Int2::Int2(int x, int y)
4301 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04004302 int64_t constantVector[2] = {x, y};
4303 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(Int::getType(), 2))));
John Bauman89401822014-05-06 15:04:28 -04004304
John Bauman66b8ab22014-05-06 15:57:45 -04004305 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04004306 }
4307
John Bauman19bac1e2014-05-06 15:23:49 -04004308 Int2::Int2(RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004309 {
John Bauman66b8ab22014-05-06 15:57:45 -04004310 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004311 }
4312
4313 Int2::Int2(const Int2 &rhs)
4314 {
John Bauman66b8ab22014-05-06 15:57:45 -04004315 Value *value = rhs.loadValue();
4316 storeValue(value);
4317 }
4318
4319 Int2::Int2(const Reference<Int2> &rhs)
4320 {
John Bauman66b8ab22014-05-06 15:57:45 -04004321 Value *value = rhs.loadValue();
4322 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004323 }
4324
Nicolas Capens62abb552016-01-05 12:03:47 -05004325 Int2::Int2(RValue<Int> lo, RValue<Int> hi)
4326 {
Nicolas Capensb40a2562016-01-05 00:08:45 -05004327 if(CPUID::supportsMMX2())
4328 {
4329 // movd mm0, lo
4330 // movd mm1, hi
4331 // punpckldq mm0, mm1
Nicolas Capens45f187a2016-12-02 15:30:56 -05004332
4333 Value *loLong = Nucleus::createInsertElement(V(UndefValue::get(VectorType::get(Int::getType(), 2))), lo.value, 0);
4334 loLong = Nucleus::createInsertElement(loLong, V(ConstantInt::get(Int::getType(), 0)), 1);
4335 Value *hiLong = Nucleus::createInsertElement(V(UndefValue::get(VectorType::get(Int::getType(), 2))), hi.value, 0);
4336 hiLong = Nucleus::createInsertElement(hiLong, V(ConstantInt::get(Int::getType(), 0)), 1);
4337
4338 storeValue(As<Int2>(UnpackLow(As<Int2>(loLong), As<Int2>(hiLong))).value);
Nicolas Capensb40a2562016-01-05 00:08:45 -05004339 }
4340 else
4341 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004342 int shuffle[2] = {0, 1};
4343 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 -05004344
Nicolas Capensb40a2562016-01-05 00:08:45 -05004345 storeValue(Nucleus::createBitCast(packed, Int2::getType()));
4346 }
Nicolas Capens62abb552016-01-05 12:03:47 -05004347 }
4348
Nicolas Capens96d4e092016-11-18 14:22:38 -05004349 RValue<Int2> Int2::operator=(RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004350 {
John Bauman66b8ab22014-05-06 15:57:45 -04004351 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004352
4353 return rhs;
4354 }
4355
Nicolas Capens96d4e092016-11-18 14:22:38 -05004356 RValue<Int2> Int2::operator=(const Int2 &rhs)
John Bauman89401822014-05-06 15:04:28 -04004357 {
John Bauman66b8ab22014-05-06 15:57:45 -04004358 Value *value = rhs.loadValue();
4359 storeValue(value);
4360
4361 return RValue<Int2>(value);
4362 }
4363
Nicolas Capens96d4e092016-11-18 14:22:38 -05004364 RValue<Int2> Int2::operator=(const Reference<Int2> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04004365 {
4366 Value *value = rhs.loadValue();
4367 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004368
4369 return RValue<Int2>(value);
4370 }
4371
John Bauman19bac1e2014-05-06 15:23:49 -04004372 RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004373 {
John Bauman19bac1e2014-05-06 15:23:49 -04004374 if(CPUID::supportsMMX2())
4375 {
4376 return x86::paddd(lhs, rhs);
4377 }
4378 else
4379 {
4380 return RValue<Int2>(Nucleus::createAdd(lhs.value, rhs.value));
4381 }
John Bauman89401822014-05-06 15:04:28 -04004382 }
4383
John Bauman19bac1e2014-05-06 15:23:49 -04004384 RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004385 {
John Bauman19bac1e2014-05-06 15:23:49 -04004386 if(CPUID::supportsMMX2())
4387 {
4388 return x86::psubd(lhs, rhs);
4389 }
4390 else
4391 {
4392 return RValue<Int2>(Nucleus::createSub(lhs.value, rhs.value));
4393 }
John Bauman89401822014-05-06 15:04:28 -04004394 }
4395
John Bauman19bac1e2014-05-06 15:23:49 -04004396// RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs)
4397// {
4398// return RValue<Int2>(Nucleus::createMul(lhs.value, rhs.value));
4399// }
4400
4401// RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs)
4402// {
4403// return RValue<Int2>(Nucleus::createSDiv(lhs.value, rhs.value));
4404// }
4405
4406// RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs)
4407// {
4408// return RValue<Int2>(Nucleus::createSRem(lhs.value, rhs.value));
4409// }
4410
4411 RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004412 {
John Bauman19bac1e2014-05-06 15:23:49 -04004413 if(CPUID::supportsMMX2())
4414 {
4415 return As<Int2>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
4416 }
4417 else
4418 {
4419 return RValue<Int2>(Nucleus::createAnd(lhs.value, rhs.value));
4420 }
John Bauman89401822014-05-06 15:04:28 -04004421 }
4422
John Bauman19bac1e2014-05-06 15:23:49 -04004423 RValue<Int2> operator|(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004424 {
John Bauman19bac1e2014-05-06 15:23:49 -04004425 if(CPUID::supportsMMX2())
4426 {
4427 return As<Int2>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
4428 }
4429 else
4430 {
4431 return RValue<Int2>(Nucleus::createOr(lhs.value, rhs.value));
4432 }
John Bauman89401822014-05-06 15:04:28 -04004433 }
4434
John Bauman19bac1e2014-05-06 15:23:49 -04004435 RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004436 {
John Bauman19bac1e2014-05-06 15:23:49 -04004437 if(CPUID::supportsMMX2())
4438 {
4439 return As<Int2>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
4440 }
4441 else
4442 {
4443 return RValue<Int2>(Nucleus::createXor(lhs.value, rhs.value));
4444 }
John Bauman89401822014-05-06 15:04:28 -04004445 }
4446
John Bauman19bac1e2014-05-06 15:23:49 -04004447 RValue<Int2> operator<<(RValue<Int2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004448 {
4449 // return RValue<Int2>(Nucleus::createShl(lhs.value, rhs.value));
4450
4451 return x86::pslld(lhs, rhs);
4452 }
4453
John Bauman19bac1e2014-05-06 15:23:49 -04004454 RValue<Int2> operator>>(RValue<Int2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004455 {
4456 // return RValue<Int2>(Nucleus::createAShr(lhs.value, rhs.value));
4457
4458 return x86::psrad(lhs, rhs);
4459 }
4460
Nicolas Capens96d4e092016-11-18 14:22:38 -05004461 RValue<Int2> operator+=(Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004462 {
4463 return lhs = lhs + rhs;
4464 }
4465
Nicolas Capens96d4e092016-11-18 14:22:38 -05004466 RValue<Int2> operator-=(Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004467 {
4468 return lhs = lhs - rhs;
4469 }
4470
Nicolas Capens96d4e092016-11-18 14:22:38 -05004471// RValue<Int2> operator*=(Int2 &lhs, RValue<Int2> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04004472// {
4473// return lhs = lhs * rhs;
4474// }
John Bauman89401822014-05-06 15:04:28 -04004475
Nicolas Capens96d4e092016-11-18 14:22:38 -05004476// RValue<Int2> operator/=(Int2 &lhs, RValue<Int2> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04004477// {
4478// return lhs = lhs / rhs;
4479// }
John Bauman89401822014-05-06 15:04:28 -04004480
Nicolas Capens96d4e092016-11-18 14:22:38 -05004481// RValue<Int2> operator%=(Int2 &lhs, RValue<Int2> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04004482// {
4483// return lhs = lhs % rhs;
4484// }
John Bauman89401822014-05-06 15:04:28 -04004485
Nicolas Capens96d4e092016-11-18 14:22:38 -05004486 RValue<Int2> operator&=(Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004487 {
4488 return lhs = lhs & rhs;
4489 }
4490
Nicolas Capens96d4e092016-11-18 14:22:38 -05004491 RValue<Int2> operator|=(Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004492 {
4493 return lhs = lhs | rhs;
4494 }
4495
Nicolas Capens96d4e092016-11-18 14:22:38 -05004496 RValue<Int2> operator^=(Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004497 {
4498 return lhs = lhs ^ rhs;
4499 }
4500
Nicolas Capens96d4e092016-11-18 14:22:38 -05004501 RValue<Int2> operator<<=(Int2 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004502 {
4503 return lhs = lhs << rhs;
4504 }
4505
Nicolas Capens96d4e092016-11-18 14:22:38 -05004506 RValue<Int2> operator>>=(Int2 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004507 {
4508 return lhs = lhs >> rhs;
4509 }
4510
John Bauman19bac1e2014-05-06 15:23:49 -04004511// RValue<Int2> operator+(RValue<Int2> val)
4512// {
4513// return val;
4514// }
4515
4516// RValue<Int2> operator-(RValue<Int2> val)
4517// {
4518// return RValue<Int2>(Nucleus::createNeg(val.value));
4519// }
4520
4521 RValue<Int2> operator~(RValue<Int2> val)
John Bauman89401822014-05-06 15:04:28 -04004522 {
John Bauman19bac1e2014-05-06 15:23:49 -04004523 if(CPUID::supportsMMX2())
4524 {
4525 return val ^ Int2(0xFFFFFFFF, 0xFFFFFFFF);
4526 }
4527 else
4528 {
4529 return RValue<Int2>(Nucleus::createNot(val.value));
4530 }
John Bauman89401822014-05-06 15:04:28 -04004531 }
4532
Nicolas Capens45f187a2016-12-02 15:30:56 -05004533 RValue<Short4> UnpackLow(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04004534 {
John Bauman19bac1e2014-05-06 15:23:49 -04004535 if(CPUID::supportsMMX2())
4536 {
4537 return x86::punpckldq(x, y);
4538 }
4539 else
4540 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004541 int shuffle[2] = {0, 2};
4542 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04004543
Nicolas Capens45f187a2016-12-02 15:30:56 -05004544 return As<Short4>(packed);
John Bauman19bac1e2014-05-06 15:23:49 -04004545 }
John Bauman89401822014-05-06 15:04:28 -04004546 }
John Bauman66b8ab22014-05-06 15:57:45 -04004547
Nicolas Capens45f187a2016-12-02 15:30:56 -05004548 RValue<Short4> UnpackHigh(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04004549 {
John Bauman19bac1e2014-05-06 15:23:49 -04004550 if(CPUID::supportsMMX2())
4551 {
4552 return x86::punpckhdq(x, y);
4553 }
4554 else
4555 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004556 int shuffle[2] = {1, 3};
4557 Value *packed = Nucleus::createShuffleVector(x.value, y.value, shuffle);
John Bauman89401822014-05-06 15:04:28 -04004558
Nicolas Capens45f187a2016-12-02 15:30:56 -05004559 return As<Short4>(packed);
John Bauman19bac1e2014-05-06 15:23:49 -04004560 }
John Bauman89401822014-05-06 15:04:28 -04004561 }
4562
John Bauman19bac1e2014-05-06 15:23:49 -04004563 RValue<Int> Extract(RValue<Int2> val, int i)
John Bauman89401822014-05-06 15:04:28 -04004564 {
4565 if(false) // FIXME: LLVM does not generate optimal code
4566 {
Nicolas Capense95d5342016-09-30 11:37:28 -04004567 return RValue<Int>(Nucleus::createExtractElement(val.value, Int::getType(), i));
John Bauman89401822014-05-06 15:04:28 -04004568 }
4569 else
4570 {
4571 if(i == 0)
4572 {
Nicolas Capense95d5342016-09-30 11:37:28 -04004573 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 -04004574 }
4575 else
4576 {
4577 Int2 val2 = As<Int2>(UnpackHigh(val, val));
4578
4579 return Extract(val2, 0);
4580 }
4581 }
4582 }
4583
Nicolas Capensfff3c9b2015-05-13 23:40:44 -04004584 RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i)
4585 {
Nicolas Capensac230122016-09-20 14:30:06 -04004586 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 -04004587 }
John Bauman89401822014-05-06 15:04:28 -04004588
John Bauman19bac1e2014-05-06 15:23:49 -04004589 Type *Int2::getType()
John Bauman89401822014-05-06 15:04:28 -04004590 {
John Bauman19bac1e2014-05-06 15:23:49 -04004591 if(CPUID::supportsMMX2())
4592 {
4593 return MMX::getType();
4594 }
4595 else
4596 {
Nicolas Capensac230122016-09-20 14:30:06 -04004597 return T(VectorType::get(Int::getType(), 2));
John Bauman19bac1e2014-05-06 15:23:49 -04004598 }
John Bauman89401822014-05-06 15:04:28 -04004599 }
4600
John Bauman89401822014-05-06 15:04:28 -04004601 UInt2::UInt2(unsigned int x, unsigned int y)
4602 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04004603 int64_t constantVector[2] = {x, y};
4604 Value *vector = V(Nucleus::createConstantVector(constantVector, T(VectorType::get(UInt::getType(), 2))));
John Bauman89401822014-05-06 15:04:28 -04004605
John Bauman66b8ab22014-05-06 15:57:45 -04004606 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04004607 }
4608
John Bauman19bac1e2014-05-06 15:23:49 -04004609 UInt2::UInt2(RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004610 {
John Bauman66b8ab22014-05-06 15:57:45 -04004611 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004612 }
4613
4614 UInt2::UInt2(const UInt2 &rhs)
4615 {
John Bauman66b8ab22014-05-06 15:57:45 -04004616 Value *value = rhs.loadValue();
4617 storeValue(value);
4618 }
4619
4620 UInt2::UInt2(const Reference<UInt2> &rhs)
4621 {
John Bauman66b8ab22014-05-06 15:57:45 -04004622 Value *value = rhs.loadValue();
4623 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004624 }
4625
Nicolas Capens96d4e092016-11-18 14:22:38 -05004626 RValue<UInt2> UInt2::operator=(RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004627 {
John Bauman66b8ab22014-05-06 15:57:45 -04004628 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004629
4630 return rhs;
4631 }
4632
Nicolas Capens96d4e092016-11-18 14:22:38 -05004633 RValue<UInt2> UInt2::operator=(const UInt2 &rhs)
John Bauman89401822014-05-06 15:04:28 -04004634 {
John Bauman66b8ab22014-05-06 15:57:45 -04004635 Value *value = rhs.loadValue();
4636 storeValue(value);
4637
4638 return RValue<UInt2>(value);
4639 }
4640
Nicolas Capens96d4e092016-11-18 14:22:38 -05004641 RValue<UInt2> UInt2::operator=(const Reference<UInt2> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04004642 {
4643 Value *value = rhs.loadValue();
4644 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004645
4646 return RValue<UInt2>(value);
4647 }
4648
John Bauman19bac1e2014-05-06 15:23:49 -04004649 RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004650 {
John Bauman19bac1e2014-05-06 15:23:49 -04004651 if(CPUID::supportsMMX2())
4652 {
4653 return As<UInt2>(x86::paddd(As<Int2>(lhs), As<Int2>(rhs)));
4654 }
4655 else
4656 {
4657 return RValue<UInt2>(Nucleus::createAdd(lhs.value, rhs.value));
4658 }
John Bauman89401822014-05-06 15:04:28 -04004659 }
4660
John Bauman19bac1e2014-05-06 15:23:49 -04004661 RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004662 {
John Bauman19bac1e2014-05-06 15:23:49 -04004663 if(CPUID::supportsMMX2())
4664 {
4665 return As<UInt2>(x86::psubd(As<Int2>(lhs), As<Int2>(rhs)));
4666 }
4667 else
4668 {
4669 return RValue<UInt2>(Nucleus::createSub(lhs.value, rhs.value));
4670 }
John Bauman89401822014-05-06 15:04:28 -04004671 }
4672
John Bauman19bac1e2014-05-06 15:23:49 -04004673// RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs)
4674// {
4675// return RValue<UInt2>(Nucleus::createMul(lhs.value, rhs.value));
4676// }
4677
4678// RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs)
4679// {
4680// return RValue<UInt2>(Nucleus::createUDiv(lhs.value, rhs.value));
4681// }
4682
4683// RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs)
4684// {
4685// return RValue<UInt2>(Nucleus::createURem(lhs.value, rhs.value));
4686// }
4687
4688 RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004689 {
John Bauman19bac1e2014-05-06 15:23:49 -04004690 if(CPUID::supportsMMX2())
4691 {
4692 return As<UInt2>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
4693 }
4694 else
4695 {
4696 return RValue<UInt2>(Nucleus::createAnd(lhs.value, rhs.value));
4697 }
John Bauman89401822014-05-06 15:04:28 -04004698 }
4699
John Bauman19bac1e2014-05-06 15:23:49 -04004700 RValue<UInt2> operator|(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004701 {
John Bauman19bac1e2014-05-06 15:23:49 -04004702 if(CPUID::supportsMMX2())
4703 {
4704 return As<UInt2>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
4705 }
4706 else
4707 {
4708 return RValue<UInt2>(Nucleus::createOr(lhs.value, rhs.value));
4709 }
John Bauman89401822014-05-06 15:04:28 -04004710 }
4711
John Bauman19bac1e2014-05-06 15:23:49 -04004712 RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004713 {
John Bauman19bac1e2014-05-06 15:23:49 -04004714 if(CPUID::supportsMMX2())
4715 {
4716 return As<UInt2>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
4717 }
4718 else
4719 {
4720 return RValue<UInt2>(Nucleus::createXor(lhs.value, rhs.value));
4721 }
John Bauman89401822014-05-06 15:04:28 -04004722 }
4723
John Bauman19bac1e2014-05-06 15:23:49 -04004724 RValue<UInt2> operator<<(RValue<UInt2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004725 {
4726 // return RValue<UInt2>(Nucleus::createShl(lhs.value, rhs.value));
4727
4728 return As<UInt2>(x86::pslld(As<Int2>(lhs), rhs));
4729 }
4730
John Bauman19bac1e2014-05-06 15:23:49 -04004731 RValue<UInt2> operator>>(RValue<UInt2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004732 {
4733 // return RValue<UInt2>(Nucleus::createLShr(lhs.value, rhs.value));
4734
4735 return x86::psrld(lhs, rhs);
4736 }
4737
Nicolas Capens96d4e092016-11-18 14:22:38 -05004738 RValue<UInt2> operator+=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004739 {
4740 return lhs = lhs + rhs;
4741 }
4742
Nicolas Capens96d4e092016-11-18 14:22:38 -05004743 RValue<UInt2> operator-=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004744 {
4745 return lhs = lhs - rhs;
4746 }
4747
Nicolas Capens96d4e092016-11-18 14:22:38 -05004748// RValue<UInt2> operator*=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04004749// {
4750// return lhs = lhs * rhs;
4751// }
John Bauman89401822014-05-06 15:04:28 -04004752
Nicolas Capens96d4e092016-11-18 14:22:38 -05004753// RValue<UInt2> operator/=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04004754// {
4755// return lhs = lhs / rhs;
4756// }
John Bauman89401822014-05-06 15:04:28 -04004757
Nicolas Capens96d4e092016-11-18 14:22:38 -05004758// RValue<UInt2> operator%=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04004759// {
4760// return lhs = lhs % rhs;
4761// }
John Bauman89401822014-05-06 15:04:28 -04004762
Nicolas Capens96d4e092016-11-18 14:22:38 -05004763 RValue<UInt2> operator&=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004764 {
4765 return lhs = lhs & rhs;
4766 }
4767
Nicolas Capens96d4e092016-11-18 14:22:38 -05004768 RValue<UInt2> operator|=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004769 {
4770 return lhs = lhs | rhs;
4771 }
4772
Nicolas Capens96d4e092016-11-18 14:22:38 -05004773 RValue<UInt2> operator^=(UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004774 {
4775 return lhs = lhs ^ rhs;
4776 }
4777
Nicolas Capens96d4e092016-11-18 14:22:38 -05004778 RValue<UInt2> operator<<=(UInt2 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004779 {
4780 return lhs = lhs << rhs;
4781 }
4782
Nicolas Capens96d4e092016-11-18 14:22:38 -05004783 RValue<UInt2> operator>>=(UInt2 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004784 {
4785 return lhs = lhs >> rhs;
4786 }
4787
John Bauman19bac1e2014-05-06 15:23:49 -04004788// RValue<UInt2> operator+(RValue<UInt2> val)
4789// {
4790// return val;
4791// }
4792
4793// RValue<UInt2> operator-(RValue<UInt2> val)
4794// {
4795// return RValue<UInt2>(Nucleus::createNeg(val.value));
4796// }
4797
4798 RValue<UInt2> operator~(RValue<UInt2> val)
John Bauman89401822014-05-06 15:04:28 -04004799 {
John Bauman19bac1e2014-05-06 15:23:49 -04004800 if(CPUID::supportsMMX2())
4801 {
4802 return val ^ UInt2(0xFFFFFFFF, 0xFFFFFFFF);
4803 }
4804 else
4805 {
4806 return RValue<UInt2>(Nucleus::createNot(val.value));
4807 }
John Bauman89401822014-05-06 15:04:28 -04004808 }
4809
John Bauman19bac1e2014-05-06 15:23:49 -04004810 Type *UInt2::getType()
John Bauman89401822014-05-06 15:04:28 -04004811 {
John Bauman19bac1e2014-05-06 15:23:49 -04004812 if(CPUID::supportsMMX2())
4813 {
4814 return MMX::getType();
4815 }
4816 else
4817 {
Nicolas Capensac230122016-09-20 14:30:06 -04004818 return T(VectorType::get(UInt::getType(), 2));
John Bauman19bac1e2014-05-06 15:23:49 -04004819 }
John Bauman89401822014-05-06 15:04:28 -04004820 }
4821
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004822 Int4::Int4(RValue<Byte4> cast)
4823 {
4824 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
Nicolas Capens19336542016-09-26 10:32:29 -04004825 Value *a = Nucleus::createInsertElement(V(UndefValue::get(Int4::getType())), x, 0);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004826
4827 Value *e;
4828
4829 if (CPUID::supportsSSE4_1())
4830 {
4831 e = x86::pmovzxbd(RValue<Int4>(a)).value;
4832 }
4833 else
4834 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004835 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 -04004836 Value *b = Nucleus::createBitCast(a, Byte16::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04004837 Value *c = Nucleus::createShuffleVector(b, V(Nucleus::createNullValue(Byte16::getType())), swizzle);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004838
Nicolas Capense89cd582016-09-30 14:23:47 -04004839 int swizzle2[8] = {0, 8, 1, 9, 2, 10, 3, 11};
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004840 Value *d = Nucleus::createBitCast(c, Short8::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04004841 e = Nucleus::createShuffleVector(d, V(Nucleus::createNullValue(Short8::getType())), swizzle2);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004842 }
4843
4844 Value *f = Nucleus::createBitCast(e, Int4::getType());
4845 storeValue(f);
4846 }
4847
4848 Int4::Int4(RValue<SByte4> cast)
4849 {
4850 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
Nicolas Capens19336542016-09-26 10:32:29 -04004851 Value *a = Nucleus::createInsertElement(V(UndefValue::get(Int4::getType())), x, 0);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004852
4853 Value *g;
4854
4855 if (CPUID::supportsSSE4_1())
4856 {
4857 g = x86::pmovsxbd(RValue<Int4>(a)).value;
4858 }
4859 else
4860 {
Nicolas Capense89cd582016-09-30 14:23:47 -04004861 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 -04004862 Value *b = Nucleus::createBitCast(a, Byte16::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04004863 Value *c = Nucleus::createShuffleVector(b, b, swizzle);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004864
Nicolas Capense89cd582016-09-30 14:23:47 -04004865 int swizzle2[8] = {0, 0, 1, 1, 2, 2, 3, 3};
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004866 Value *d = Nucleus::createBitCast(c, Short8::getType());
Nicolas Capense89cd582016-09-30 14:23:47 -04004867 Value *e = Nucleus::createShuffleVector(d, d, swizzle2);
Meng-Lin Wu601d0052016-06-10 14:18:41 -04004868
4869 Value *f = Nucleus::createBitCast(e, Int4::getType());
4870 // g = Nucleus::createAShr(f, Nucleus::createConstantInt(24));
4871 g = x86::psrad(RValue<Int4>(f), 24).value;
4872 }
4873
4874 storeValue(g);
4875 }
4876
John Bauman19bac1e2014-05-06 15:23:49 -04004877 Int4::Int4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04004878 {
John Bauman89401822014-05-06 15:04:28 -04004879 Value *xyzw = Nucleus::createFPToSI(cast.value, Int4::getType());
John Bauman89401822014-05-06 15:04:28 -04004880
John Bauman66b8ab22014-05-06 15:57:45 -04004881 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04004882 }
4883
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004884 Int4::Int4(RValue<Short4> cast)
4885 {
Nicolas Capens22008782016-10-20 01:11:47 -04004886 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004887 Value *element = Nucleus::createBitCast(cast.value, Long::getType());
4888 long2 = Nucleus::createInsertElement(long2, element, 0);
4889 RValue<Int4> vector = RValue<Int4>(Nucleus::createBitCast(long2, Int4::getType()));
Nicolas Capens05b3d662016-02-25 23:58:33 -05004890
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004891 if(CPUID::supportsSSE4_1())
4892 {
4893 storeValue(x86::pmovsxwd(vector).value);
4894 }
4895 else
4896 {
4897 Value *b = Nucleus::createBitCast(vector.value, Short8::getType());
4898
Nicolas Capense89cd582016-09-30 14:23:47 -04004899 int swizzle[8] = {0, 0, 1, 1, 2, 2, 3, 3};
4900 Value *c = Nucleus::createShuffleVector(b, b, swizzle);
Nicolas Capens6ce5c332015-10-28 01:58:18 -04004901 Value *d = Nucleus::createBitCast(c, Int4::getType());
4902 storeValue(d);
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004903
4904 // Each Short is packed into each Int in the (Short | Short) format.
4905 // Shifting by 16 will retrieve the original Short value.
Nicolas Capensf549e3b2017-01-24 08:53:47 -08004906 // Shifting an Int will propagate the sign bit, which will work
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004907 // for both positive and negative values of a Short.
4908 *this >>= 16;
4909 }
4910 }
4911
4912 Int4::Int4(RValue<UShort4> cast)
4913 {
Nicolas Capens22008782016-10-20 01:11:47 -04004914 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004915 Value *element = Nucleus::createBitCast(cast.value, Long::getType());
4916 long2 = Nucleus::createInsertElement(long2, element, 0);
4917 RValue<Int4> vector = RValue<Int4>(Nucleus::createBitCast(long2, Int4::getType()));
4918
4919 if(CPUID::supportsSSE4_1())
4920 {
4921 storeValue(x86::pmovzxwd(RValue<Int4>(vector)).value);
4922 }
4923 else
4924 {
4925 Value *b = Nucleus::createBitCast(vector.value, Short8::getType());
4926
Nicolas Capense89cd582016-09-30 14:23:47 -04004927 int swizzle[8] = {0, 8, 1, 9, 2, 10, 3, 11};
4928 Value *c = Nucleus::createShuffleVector(b, V(Nucleus::createNullValue(Short8::getType())), swizzle);
Nicolas Capens6ce5c332015-10-28 01:58:18 -04004929 Value *d = Nucleus::createBitCast(c, Int4::getType());
4930 storeValue(d);
Alexis Hetu2aa852f2015-10-14 16:32:39 -04004931 }
4932 }
4933
John Bauman89401822014-05-06 15:04:28 -04004934 Int4::Int4(int xyzw)
4935 {
4936 constant(xyzw, xyzw, xyzw, xyzw);
4937 }
4938
4939 Int4::Int4(int x, int yzw)
4940 {
4941 constant(x, yzw, yzw, yzw);
4942 }
4943
4944 Int4::Int4(int x, int y, int zw)
4945 {
4946 constant(x, y, zw, zw);
4947 }
4948
4949 Int4::Int4(int x, int y, int z, int w)
4950 {
4951 constant(x, y, z, w);
4952 }
4953
4954 void Int4::constant(int x, int y, int z, int w)
4955 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04004956 int64_t constantVector[4] = {x, y, z, w};
4957 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04004958 }
4959
John Bauman19bac1e2014-05-06 15:23:49 -04004960 Int4::Int4(RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04004961 {
John Bauman66b8ab22014-05-06 15:57:45 -04004962 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004963 }
4964
4965 Int4::Int4(const Int4 &rhs)
4966 {
John Bauman66b8ab22014-05-06 15:57:45 -04004967 Value *value = rhs.loadValue();
4968 storeValue(value);
4969 }
4970
4971 Int4::Int4(const Reference<Int4> &rhs)
4972 {
John Bauman66b8ab22014-05-06 15:57:45 -04004973 Value *value = rhs.loadValue();
4974 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004975 }
4976
John Bauman19bac1e2014-05-06 15:23:49 -04004977 Int4::Int4(RValue<UInt4> rhs)
4978 {
John Bauman66b8ab22014-05-06 15:57:45 -04004979 storeValue(rhs.value);
John Bauman19bac1e2014-05-06 15:23:49 -04004980 }
4981
4982 Int4::Int4(const UInt4 &rhs)
4983 {
John Bauman66b8ab22014-05-06 15:57:45 -04004984 Value *value = rhs.loadValue();
4985 storeValue(value);
4986 }
4987
4988 Int4::Int4(const Reference<UInt4> &rhs)
4989 {
John Bauman66b8ab22014-05-06 15:57:45 -04004990 Value *value = rhs.loadValue();
4991 storeValue(value);
John Bauman19bac1e2014-05-06 15:23:49 -04004992 }
4993
Nicolas Capens62abb552016-01-05 12:03:47 -05004994 Int4::Int4(RValue<Int2> lo, RValue<Int2> hi)
4995 {
4996 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
4997 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
4998
Nicolas Capens22008782016-10-20 01:11:47 -04004999 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Nicolas Capens62abb552016-01-05 12:03:47 -05005000 long2 = Nucleus::createInsertElement(long2, loLong, 0);
5001 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
5002 Value *int4 = Nucleus::createBitCast(long2, Int4::getType());
5003
5004 storeValue(int4);
5005 }
5006
Nicolas Capens24c8cf02016-08-15 15:33:14 -04005007 Int4::Int4(RValue<Int> rhs)
5008 {
Nicolas Capens24c8cf02016-08-15 15:33:14 -04005009 Value *vector = loadValue();
5010 Value *insert = Nucleus::createInsertElement(vector, rhs.value, 0);
5011
Nicolas Capense89cd582016-09-30 14:23:47 -04005012 int swizzle[4] = {0, 0, 0, 0};
5013 Value *replicate = Nucleus::createShuffleVector(insert, insert, swizzle);
Nicolas Capens24c8cf02016-08-15 15:33:14 -04005014
5015 storeValue(replicate);
5016 }
5017
5018 Int4::Int4(const Int &rhs)
5019 {
Nicolas Capens24c8cf02016-08-15 15:33:14 -04005020 *this = RValue<Int>(rhs.loadValue());
5021 }
5022
5023 Int4::Int4(const Reference<Int> &rhs)
5024 {
Nicolas Capens24c8cf02016-08-15 15:33:14 -04005025 *this = RValue<Int>(rhs.loadValue());
5026 }
5027
Nicolas Capens96d4e092016-11-18 14:22:38 -05005028 RValue<Int4> Int4::operator=(RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005029 {
John Bauman66b8ab22014-05-06 15:57:45 -04005030 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005031
5032 return rhs;
5033 }
5034
Nicolas Capens96d4e092016-11-18 14:22:38 -05005035 RValue<Int4> Int4::operator=(const Int4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04005036 {
John Bauman66b8ab22014-05-06 15:57:45 -04005037 Value *value = rhs.loadValue();
5038 storeValue(value);
5039
5040 return RValue<Int4>(value);
5041 }
5042
Nicolas Capens96d4e092016-11-18 14:22:38 -05005043 RValue<Int4> Int4::operator=(const Reference<Int4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04005044 {
5045 Value *value = rhs.loadValue();
5046 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005047
5048 return RValue<Int4>(value);
5049 }
5050
John Bauman19bac1e2014-05-06 15:23:49 -04005051 RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005052 {
5053 return RValue<Int4>(Nucleus::createAdd(lhs.value, rhs.value));
5054 }
5055
John Bauman19bac1e2014-05-06 15:23:49 -04005056 RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005057 {
5058 return RValue<Int4>(Nucleus::createSub(lhs.value, rhs.value));
5059 }
5060
John Bauman19bac1e2014-05-06 15:23:49 -04005061 RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005062 {
5063 return RValue<Int4>(Nucleus::createMul(lhs.value, rhs.value));
5064 }
5065
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005066 RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs)
5067 {
5068 return RValue<Int4>(Nucleus::createSDiv(lhs.value, rhs.value));
5069 }
John Bauman89401822014-05-06 15:04:28 -04005070
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005071 RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs)
5072 {
5073 return RValue<Int4>(Nucleus::createSRem(lhs.value, rhs.value));
5074 }
John Bauman89401822014-05-06 15:04:28 -04005075
John Bauman19bac1e2014-05-06 15:23:49 -04005076 RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005077 {
5078 return RValue<Int4>(Nucleus::createAnd(lhs.value, rhs.value));
5079 }
5080
John Bauman19bac1e2014-05-06 15:23:49 -04005081 RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005082 {
5083 return RValue<Int4>(Nucleus::createOr(lhs.value, rhs.value));
5084 }
5085
John Bauman19bac1e2014-05-06 15:23:49 -04005086 RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005087 {
5088 return RValue<Int4>(Nucleus::createXor(lhs.value, rhs.value));
5089 }
5090
John Bauman19bac1e2014-05-06 15:23:49 -04005091 RValue<Int4> operator<<(RValue<Int4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005092 {
John Bauman89401822014-05-06 15:04:28 -04005093 return x86::pslld(lhs, rhs);
5094 }
5095
John Bauman19bac1e2014-05-06 15:23:49 -04005096 RValue<Int4> operator>>(RValue<Int4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005097 {
John Bauman89401822014-05-06 15:04:28 -04005098 return x86::psrad(lhs, rhs);
5099 }
5100
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005101 RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs)
5102 {
5103 return RValue<Int4>(Nucleus::createShl(lhs.value, rhs.value));
5104 }
5105
5106 RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs)
5107 {
5108 return RValue<Int4>(Nucleus::createAShr(lhs.value, rhs.value));
5109 }
5110
Nicolas Capens96d4e092016-11-18 14:22:38 -05005111 RValue<Int4> operator+=(Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005112 {
5113 return lhs = lhs + rhs;
5114 }
5115
Nicolas Capens96d4e092016-11-18 14:22:38 -05005116 RValue<Int4> operator-=(Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005117 {
5118 return lhs = lhs - rhs;
5119 }
5120
Nicolas Capens96d4e092016-11-18 14:22:38 -05005121 RValue<Int4> operator*=(Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005122 {
5123 return lhs = lhs * rhs;
5124 }
5125
Nicolas Capens96d4e092016-11-18 14:22:38 -05005126// RValue<Int4> operator/=(Int4 &lhs, RValue<Int4> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04005127// {
5128// return lhs = lhs / rhs;
5129// }
John Bauman89401822014-05-06 15:04:28 -04005130
Nicolas Capens96d4e092016-11-18 14:22:38 -05005131// RValue<Int4> operator%=(Int4 &lhs, RValue<Int4> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04005132// {
5133// return lhs = lhs % rhs;
5134// }
John Bauman89401822014-05-06 15:04:28 -04005135
Nicolas Capens96d4e092016-11-18 14:22:38 -05005136 RValue<Int4> operator&=(Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005137 {
5138 return lhs = lhs & rhs;
5139 }
5140
Nicolas Capens96d4e092016-11-18 14:22:38 -05005141 RValue<Int4> operator|=(Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005142 {
5143 return lhs = lhs | rhs;
5144 }
5145
Nicolas Capens96d4e092016-11-18 14:22:38 -05005146 RValue<Int4> operator^=(Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005147 {
5148 return lhs = lhs ^ rhs;
5149 }
5150
Nicolas Capens96d4e092016-11-18 14:22:38 -05005151 RValue<Int4> operator<<=(Int4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005152 {
5153 return lhs = lhs << rhs;
5154 }
5155
Nicolas Capens96d4e092016-11-18 14:22:38 -05005156 RValue<Int4> operator>>=(Int4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005157 {
5158 return lhs = lhs >> rhs;
5159 }
5160
John Bauman19bac1e2014-05-06 15:23:49 -04005161 RValue<Int4> operator+(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005162 {
5163 return val;
5164 }
5165
John Bauman19bac1e2014-05-06 15:23:49 -04005166 RValue<Int4> operator-(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005167 {
5168 return RValue<Int4>(Nucleus::createNeg(val.value));
5169 }
5170
John Bauman19bac1e2014-05-06 15:23:49 -04005171 RValue<Int4> operator~(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005172 {
5173 return RValue<Int4>(Nucleus::createNot(val.value));
5174 }
5175
John Bauman19bac1e2014-05-06 15:23:49 -04005176 RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y)
5177 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005178 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
Alexis Hetufb603992016-04-26 11:50:40 -04005179 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5180 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
5181 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005182 }
5183
5184 RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y)
5185 {
5186 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLT(x.value, y.value), Int4::getType()));
5187 }
5188
5189 RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y)
5190 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005191 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5192 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5193 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLE(x.value, y.value), Int4::getType()));
5194 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGT(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005195 }
5196
5197 RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y)
5198 {
5199 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
5200 }
5201
5202 RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y)
5203 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005204 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5205 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5206 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGE(x.value, y.value), Int4::getType()));
5207 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLT(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005208 }
5209
5210 RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y)
5211 {
5212 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGT(x.value, y.value), Int4::getType()));
5213 }
5214
5215 RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y)
5216 {
5217 if(CPUID::supportsSSE4_1())
5218 {
5219 return x86::pmaxsd(x, y);
5220 }
5221 else
5222 {
5223 RValue<Int4> greater = CmpNLE(x, y);
Tom Anderson69bc6e82017-03-20 11:54:29 -07005224 return (x & greater) | (y & ~greater);
John Bauman19bac1e2014-05-06 15:23:49 -04005225 }
5226 }
5227
5228 RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y)
5229 {
5230 if(CPUID::supportsSSE4_1())
5231 {
5232 return x86::pminsd(x, y);
5233 }
5234 else
5235 {
5236 RValue<Int4> less = CmpLT(x, y);
Tom Anderson69bc6e82017-03-20 11:54:29 -07005237 return (x & less) | (y & ~less);
John Bauman19bac1e2014-05-06 15:23:49 -04005238 }
5239 }
5240
5241 RValue<Int4> RoundInt(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005242 {
5243 return x86::cvtps2dq(cast);
5244 }
5245
John Bauman19bac1e2014-05-06 15:23:49 -04005246 RValue<Short8> Pack(RValue<Int4> x, RValue<Int4> y)
John Bauman89401822014-05-06 15:04:28 -04005247 {
5248 return x86::packssdw(x, y);
5249 }
5250
John Bauman19bac1e2014-05-06 15:23:49 -04005251 RValue<Int> Extract(RValue<Int4> x, int i)
John Bauman89401822014-05-06 15:04:28 -04005252 {
Nicolas Capense95d5342016-09-30 11:37:28 -04005253 return RValue<Int>(Nucleus::createExtractElement(x.value, Int::getType(), i));
John Bauman89401822014-05-06 15:04:28 -04005254 }
5255
John Bauman19bac1e2014-05-06 15:23:49 -04005256 RValue<Int4> Insert(RValue<Int4> x, RValue<Int> element, int i)
John Bauman89401822014-05-06 15:04:28 -04005257 {
5258 return RValue<Int4>(Nucleus::createInsertElement(x.value, element.value, i));
5259 }
5260
John Bauman19bac1e2014-05-06 15:23:49 -04005261 RValue<Int> SignMask(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04005262 {
5263 return x86::movmskps(As<Float4>(x));
5264 }
5265
John Bauman19bac1e2014-05-06 15:23:49 -04005266 RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04005267 {
Nicolas Capense95d5342016-09-30 11:37:28 -04005268 return RValue<Int4>(createSwizzle4(x.value, select));
John Bauman89401822014-05-06 15:04:28 -04005269 }
5270
John Bauman19bac1e2014-05-06 15:23:49 -04005271 Type *Int4::getType()
John Bauman89401822014-05-06 15:04:28 -04005272 {
Nicolas Capensac230122016-09-20 14:30:06 -04005273 return T(VectorType::get(Int::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04005274 }
5275
John Bauman19bac1e2014-05-06 15:23:49 -04005276 UInt4::UInt4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005277 {
Alexis Hetu764d1422016-09-28 08:44:22 -04005278 // Note: createFPToUI is broken, must perform conversion using createFPtoSI
5279 // Value *xyzw = Nucleus::createFPToUI(cast.value, UInt4::getType());
John Bauman89401822014-05-06 15:04:28 -04005280
Alexis Hetu764d1422016-09-28 08:44:22 -04005281 // Smallest positive value representable in UInt, but not in Int
5282 const unsigned int ustart = 0x80000000u;
5283 const float ustartf = float(ustart);
5284
5285 // Check if the value can be represented as an Int
5286 Int4 uiValue = CmpNLT(cast, Float4(ustartf));
5287 // If the value is too large, subtract ustart and re-add it after conversion.
5288 uiValue = (uiValue & As<Int4>(As<UInt4>(Int4(cast - Float4(ustartf))) + UInt4(ustart))) |
5289 // Otherwise, just convert normally
5290 (~uiValue & Int4(cast));
5291 // If the value is negative, store 0, otherwise store the result of the conversion
5292 storeValue((~(As<Int4>(cast) >> 31) & uiValue).value);
John Bauman89401822014-05-06 15:04:28 -04005293 }
5294
John Bauman19bac1e2014-05-06 15:23:49 -04005295 UInt4::UInt4(int xyzw)
5296 {
5297 constant(xyzw, xyzw, xyzw, xyzw);
5298 }
5299
5300 UInt4::UInt4(int x, int yzw)
5301 {
5302 constant(x, yzw, yzw, yzw);
5303 }
5304
5305 UInt4::UInt4(int x, int y, int zw)
5306 {
5307 constant(x, y, zw, zw);
5308 }
5309
5310 UInt4::UInt4(int x, int y, int z, int w)
5311 {
5312 constant(x, y, z, w);
5313 }
5314
5315 void UInt4::constant(int x, int y, int z, int w)
John Bauman89401822014-05-06 15:04:28 -04005316 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04005317 int64_t constantVector[4] = {x, y, z, w};
5318 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04005319 }
5320
John Bauman19bac1e2014-05-06 15:23:49 -04005321 UInt4::UInt4(RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005322 {
John Bauman66b8ab22014-05-06 15:57:45 -04005323 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005324 }
5325
5326 UInt4::UInt4(const UInt4 &rhs)
5327 {
John Bauman66b8ab22014-05-06 15:57:45 -04005328 Value *value = rhs.loadValue();
5329 storeValue(value);
5330 }
5331
5332 UInt4::UInt4(const Reference<UInt4> &rhs)
5333 {
John Bauman66b8ab22014-05-06 15:57:45 -04005334 Value *value = rhs.loadValue();
5335 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005336 }
5337
John Bauman19bac1e2014-05-06 15:23:49 -04005338 UInt4::UInt4(RValue<Int4> rhs)
5339 {
John Bauman66b8ab22014-05-06 15:57:45 -04005340 storeValue(rhs.value);
John Bauman19bac1e2014-05-06 15:23:49 -04005341 }
5342
5343 UInt4::UInt4(const Int4 &rhs)
5344 {
John Bauman66b8ab22014-05-06 15:57:45 -04005345 Value *value = rhs.loadValue();
5346 storeValue(value);
5347 }
5348
5349 UInt4::UInt4(const Reference<Int4> &rhs)
5350 {
John Bauman66b8ab22014-05-06 15:57:45 -04005351 Value *value = rhs.loadValue();
5352 storeValue(value);
John Bauman19bac1e2014-05-06 15:23:49 -04005353 }
5354
Nicolas Capens62abb552016-01-05 12:03:47 -05005355 UInt4::UInt4(RValue<UInt2> lo, RValue<UInt2> hi)
5356 {
5357 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
5358 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
5359
Nicolas Capens22008782016-10-20 01:11:47 -04005360 Value *long2 = V(UndefValue::get(VectorType::get(Long::getType(), 2)));
Nicolas Capens62abb552016-01-05 12:03:47 -05005361 long2 = Nucleus::createInsertElement(long2, loLong, 0);
5362 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
5363 Value *uint4 = Nucleus::createBitCast(long2, Int4::getType());
5364
5365 storeValue(uint4);
5366 }
5367
Nicolas Capens96d4e092016-11-18 14:22:38 -05005368 RValue<UInt4> UInt4::operator=(RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005369 {
John Bauman66b8ab22014-05-06 15:57:45 -04005370 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005371
5372 return rhs;
5373 }
5374
Nicolas Capens96d4e092016-11-18 14:22:38 -05005375 RValue<UInt4> UInt4::operator=(const UInt4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04005376 {
John Bauman66b8ab22014-05-06 15:57:45 -04005377 Value *value = rhs.loadValue();
5378 storeValue(value);
5379
5380 return RValue<UInt4>(value);
5381 }
5382
Nicolas Capens96d4e092016-11-18 14:22:38 -05005383 RValue<UInt4> UInt4::operator=(const Reference<UInt4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04005384 {
5385 Value *value = rhs.loadValue();
5386 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005387
5388 return RValue<UInt4>(value);
5389 }
5390
John Bauman19bac1e2014-05-06 15:23:49 -04005391 RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005392 {
5393 return RValue<UInt4>(Nucleus::createAdd(lhs.value, rhs.value));
5394 }
5395
John Bauman19bac1e2014-05-06 15:23:49 -04005396 RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005397 {
5398 return RValue<UInt4>(Nucleus::createSub(lhs.value, rhs.value));
5399 }
5400
John Bauman19bac1e2014-05-06 15:23:49 -04005401 RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005402 {
5403 return RValue<UInt4>(Nucleus::createMul(lhs.value, rhs.value));
5404 }
5405
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005406 RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs)
5407 {
5408 return RValue<UInt4>(Nucleus::createUDiv(lhs.value, rhs.value));
5409 }
John Bauman89401822014-05-06 15:04:28 -04005410
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005411 RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs)
5412 {
5413 return RValue<UInt4>(Nucleus::createURem(lhs.value, rhs.value));
5414 }
John Bauman89401822014-05-06 15:04:28 -04005415
John Bauman19bac1e2014-05-06 15:23:49 -04005416 RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005417 {
5418 return RValue<UInt4>(Nucleus::createAnd(lhs.value, rhs.value));
5419 }
5420
John Bauman19bac1e2014-05-06 15:23:49 -04005421 RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005422 {
5423 return RValue<UInt4>(Nucleus::createOr(lhs.value, rhs.value));
5424 }
5425
John Bauman19bac1e2014-05-06 15:23:49 -04005426 RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005427 {
5428 return RValue<UInt4>(Nucleus::createXor(lhs.value, rhs.value));
5429 }
5430
John Bauman19bac1e2014-05-06 15:23:49 -04005431 RValue<UInt4> operator<<(RValue<UInt4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005432 {
John Bauman89401822014-05-06 15:04:28 -04005433 return As<UInt4>(x86::pslld(As<Int4>(lhs), rhs));
5434 }
5435
John Bauman19bac1e2014-05-06 15:23:49 -04005436 RValue<UInt4> operator>>(RValue<UInt4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005437 {
John Bauman89401822014-05-06 15:04:28 -04005438 return x86::psrld(lhs, rhs);
5439 }
5440
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005441 RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs)
5442 {
5443 return RValue<UInt4>(Nucleus::createShl(lhs.value, rhs.value));
5444 }
5445
5446 RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs)
5447 {
5448 return RValue<UInt4>(Nucleus::createLShr(lhs.value, rhs.value));
5449 }
5450
Nicolas Capens96d4e092016-11-18 14:22:38 -05005451 RValue<UInt4> operator+=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005452 {
5453 return lhs = lhs + rhs;
5454 }
5455
Nicolas Capens96d4e092016-11-18 14:22:38 -05005456 RValue<UInt4> operator-=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005457 {
5458 return lhs = lhs - rhs;
5459 }
5460
Nicolas Capens96d4e092016-11-18 14:22:38 -05005461 RValue<UInt4> operator*=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005462 {
5463 return lhs = lhs * rhs;
5464 }
5465
Nicolas Capens96d4e092016-11-18 14:22:38 -05005466// RValue<UInt4> operator/=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04005467// {
5468// return lhs = lhs / rhs;
5469// }
John Bauman89401822014-05-06 15:04:28 -04005470
Nicolas Capens96d4e092016-11-18 14:22:38 -05005471// RValue<UInt4> operator%=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman19bac1e2014-05-06 15:23:49 -04005472// {
5473// return lhs = lhs % rhs;
5474// }
John Bauman89401822014-05-06 15:04:28 -04005475
Nicolas Capens96d4e092016-11-18 14:22:38 -05005476 RValue<UInt4> operator&=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005477 {
5478 return lhs = lhs & rhs;
5479 }
5480
Nicolas Capens96d4e092016-11-18 14:22:38 -05005481 RValue<UInt4> operator|=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005482 {
5483 return lhs = lhs | rhs;
5484 }
5485
Nicolas Capens96d4e092016-11-18 14:22:38 -05005486 RValue<UInt4> operator^=(UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005487 {
5488 return lhs = lhs ^ rhs;
5489 }
5490
Nicolas Capens96d4e092016-11-18 14:22:38 -05005491 RValue<UInt4> operator<<=(UInt4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005492 {
5493 return lhs = lhs << rhs;
5494 }
5495
Nicolas Capens96d4e092016-11-18 14:22:38 -05005496 RValue<UInt4> operator>>=(UInt4 &lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005497 {
5498 return lhs = lhs >> rhs;
5499 }
5500
John Bauman19bac1e2014-05-06 15:23:49 -04005501 RValue<UInt4> operator+(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04005502 {
5503 return val;
5504 }
5505
John Bauman19bac1e2014-05-06 15:23:49 -04005506 RValue<UInt4> operator-(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04005507 {
5508 return RValue<UInt4>(Nucleus::createNeg(val.value));
5509 }
5510
John Bauman19bac1e2014-05-06 15:23:49 -04005511 RValue<UInt4> operator~(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04005512 {
5513 return RValue<UInt4>(Nucleus::createNot(val.value));
5514 }
5515
John Bauman19bac1e2014-05-06 15:23:49 -04005516 RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y)
5517 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005518 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
Alexis Hetufb603992016-04-26 11:50:40 -04005519 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5520 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
5521 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005522 }
5523
5524 RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y)
5525 {
5526 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULT(x.value, y.value), Int4::getType()));
5527 }
5528
5529 RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y)
5530 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005531 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5532 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5533 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULE(x.value, y.value), Int4::getType()));
5534 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGT(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005535 }
5536
5537 RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y)
5538 {
5539 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
5540 }
5541
5542 RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y)
5543 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005544 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5545 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5546 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGE(x.value, y.value), Int4::getType()));
5547 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULT(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005548 }
5549
5550 RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y)
5551 {
5552 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGT(x.value, y.value), Int4::getType()));
5553 }
5554
5555 RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y)
5556 {
5557 if(CPUID::supportsSSE4_1())
5558 {
5559 return x86::pmaxud(x, y);
5560 }
5561 else
5562 {
5563 RValue<UInt4> greater = CmpNLE(x, y);
Tom Anderson69bc6e82017-03-20 11:54:29 -07005564 return (x & greater) | (y & ~greater);
John Bauman19bac1e2014-05-06 15:23:49 -04005565 }
5566 }
5567
5568 RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y)
5569 {
5570 if(CPUID::supportsSSE4_1())
5571 {
5572 return x86::pminud(x, y);
5573 }
5574 else
5575 {
5576 RValue<UInt4> less = CmpLT(x, y);
Tom Anderson69bc6e82017-03-20 11:54:29 -07005577 return (x & less) | (y & ~less);
John Bauman19bac1e2014-05-06 15:23:49 -04005578 }
5579 }
5580
5581 RValue<UShort8> Pack(RValue<UInt4> x, RValue<UInt4> y)
John Bauman89401822014-05-06 15:04:28 -04005582 {
Nicolas Capens3e7062b2017-01-17 14:01:33 -05005583 return x86::packusdw(As<Int4>(x), As<Int4>(y));
John Bauman89401822014-05-06 15:04:28 -04005584 }
5585
John Bauman19bac1e2014-05-06 15:23:49 -04005586 Type *UInt4::getType()
John Bauman89401822014-05-06 15:04:28 -04005587 {
Nicolas Capensac230122016-09-20 14:30:06 -04005588 return T(VectorType::get(UInt::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04005589 }
5590
John Bauman19bac1e2014-05-06 15:23:49 -04005591 Float::Float(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04005592 {
John Bauman89401822014-05-06 15:04:28 -04005593 Value *integer = Nucleus::createSIToFP(cast.value, Float::getType());
5594
John Bauman66b8ab22014-05-06 15:57:45 -04005595 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04005596 }
5597
John Bauman89401822014-05-06 15:04:28 -04005598 Float::Float(float x)
5599 {
John Bauman66b8ab22014-05-06 15:57:45 -04005600 storeValue(Nucleus::createConstantFloat(x));
John Bauman89401822014-05-06 15:04:28 -04005601 }
5602
John Bauman19bac1e2014-05-06 15:23:49 -04005603 Float::Float(RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005604 {
John Bauman66b8ab22014-05-06 15:57:45 -04005605 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005606 }
5607
5608 Float::Float(const Float &rhs)
5609 {
John Bauman66b8ab22014-05-06 15:57:45 -04005610 Value *value = rhs.loadValue();
5611 storeValue(value);
5612 }
John Bauman89401822014-05-06 15:04:28 -04005613
John Bauman66b8ab22014-05-06 15:57:45 -04005614 Float::Float(const Reference<Float> &rhs)
5615 {
5616 Value *value = rhs.loadValue();
5617 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005618 }
5619
Nicolas Capens96d4e092016-11-18 14:22:38 -05005620 RValue<Float> Float::operator=(RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005621 {
John Bauman66b8ab22014-05-06 15:57:45 -04005622 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005623
5624 return rhs;
5625 }
5626
Nicolas Capens96d4e092016-11-18 14:22:38 -05005627 RValue<Float> Float::operator=(const Float &rhs)
John Bauman89401822014-05-06 15:04:28 -04005628 {
John Bauman66b8ab22014-05-06 15:57:45 -04005629 Value *value = rhs.loadValue();
5630 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005631
5632 return RValue<Float>(value);
5633 }
5634
Nicolas Capens96d4e092016-11-18 14:22:38 -05005635 RValue<Float> Float::operator=(const Reference<Float> &rhs)
John Bauman89401822014-05-06 15:04:28 -04005636 {
John Bauman66b8ab22014-05-06 15:57:45 -04005637 Value *value = rhs.loadValue();
5638 storeValue(value);
5639
5640 return RValue<Float>(value);
John Bauman89401822014-05-06 15:04:28 -04005641 }
5642
John Bauman19bac1e2014-05-06 15:23:49 -04005643 RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005644 {
5645 return RValue<Float>(Nucleus::createFAdd(lhs.value, rhs.value));
5646 }
5647
John Bauman19bac1e2014-05-06 15:23:49 -04005648 RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005649 {
5650 return RValue<Float>(Nucleus::createFSub(lhs.value, rhs.value));
5651 }
5652
John Bauman19bac1e2014-05-06 15:23:49 -04005653 RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005654 {
5655 return RValue<Float>(Nucleus::createFMul(lhs.value, rhs.value));
5656 }
5657
John Bauman19bac1e2014-05-06 15:23:49 -04005658 RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005659 {
5660 return RValue<Float>(Nucleus::createFDiv(lhs.value, rhs.value));
5661 }
5662
Nicolas Capens96d4e092016-11-18 14:22:38 -05005663 RValue<Float> operator+=(Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005664 {
5665 return lhs = lhs + rhs;
5666 }
5667
Nicolas Capens96d4e092016-11-18 14:22:38 -05005668 RValue<Float> operator-=(Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005669 {
5670 return lhs = lhs - rhs;
5671 }
5672
Nicolas Capens96d4e092016-11-18 14:22:38 -05005673 RValue<Float> operator*=(Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005674 {
5675 return lhs = lhs * rhs;
5676 }
5677
Nicolas Capens96d4e092016-11-18 14:22:38 -05005678 RValue<Float> operator/=(Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005679 {
5680 return lhs = lhs / rhs;
5681 }
5682
John Bauman19bac1e2014-05-06 15:23:49 -04005683 RValue<Float> operator+(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04005684 {
5685 return val;
5686 }
5687
John Bauman19bac1e2014-05-06 15:23:49 -04005688 RValue<Float> operator-(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04005689 {
5690 return RValue<Float>(Nucleus::createFNeg(val.value));
5691 }
5692
John Bauman19bac1e2014-05-06 15:23:49 -04005693 RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005694 {
5695 return RValue<Bool>(Nucleus::createFCmpOLT(lhs.value, rhs.value));
5696 }
5697
John Bauman19bac1e2014-05-06 15:23:49 -04005698 RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005699 {
5700 return RValue<Bool>(Nucleus::createFCmpOLE(lhs.value, rhs.value));
5701 }
5702
John Bauman19bac1e2014-05-06 15:23:49 -04005703 RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005704 {
5705 return RValue<Bool>(Nucleus::createFCmpOGT(lhs.value, rhs.value));
5706 }
5707
John Bauman19bac1e2014-05-06 15:23:49 -04005708 RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005709 {
5710 return RValue<Bool>(Nucleus::createFCmpOGE(lhs.value, rhs.value));
5711 }
5712
John Bauman19bac1e2014-05-06 15:23:49 -04005713 RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005714 {
5715 return RValue<Bool>(Nucleus::createFCmpONE(lhs.value, rhs.value));
5716 }
5717
John Bauman19bac1e2014-05-06 15:23:49 -04005718 RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04005719 {
5720 return RValue<Bool>(Nucleus::createFCmpOEQ(lhs.value, rhs.value));
5721 }
5722
John Bauman19bac1e2014-05-06 15:23:49 -04005723 RValue<Float> Abs(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04005724 {
John Bauman66b8ab22014-05-06 15:57:45 -04005725 return IfThenElse(x > 0.0f, x, -x);
John Bauman89401822014-05-06 15:04:28 -04005726 }
5727
John Bauman19bac1e2014-05-06 15:23:49 -04005728 RValue<Float> Max(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04005729 {
5730 return IfThenElse(x > y, x, y);
5731 }
5732
John Bauman19bac1e2014-05-06 15:23:49 -04005733 RValue<Float> Min(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04005734 {
5735 return IfThenElse(x < y, x, y);
5736 }
5737
Nicolas Capens05b3d662016-02-25 23:58:33 -05005738 RValue<Float> Rcp_pp(RValue<Float> x, bool exactAtPow2)
John Bauman89401822014-05-06 15:04:28 -04005739 {
Nicolas Capens47dc8672017-04-25 12:54:39 -04005740 #if defined(__i386__) || defined(__x86_64__)
5741 if(exactAtPow2)
5742 {
5743 // rcpss uses a piecewise-linear approximation which minimizes the relative error
5744 // but is not exact at power-of-two values. Rectify by multiplying by the inverse.
5745 return x86::rcpss(x) * Float(1.0f / _mm_cvtss_f32(_mm_rcp_ss(_mm_set_ps1(1.0f))));
5746 }
5747 #endif
5748
5749 return x86::rcpss(x);
John Bauman89401822014-05-06 15:04:28 -04005750 }
John Bauman66b8ab22014-05-06 15:57:45 -04005751
John Bauman19bac1e2014-05-06 15:23:49 -04005752 RValue<Float> RcpSqrt_pp(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04005753 {
5754 return x86::rsqrtss(x);
5755 }
5756
John Bauman19bac1e2014-05-06 15:23:49 -04005757 RValue<Float> Sqrt(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04005758 {
5759 return x86::sqrtss(x);
5760 }
5761
John Bauman19bac1e2014-05-06 15:23:49 -04005762 RValue<Float> Round(RValue<Float> x)
5763 {
5764 if(CPUID::supportsSSE4_1())
5765 {
5766 return x86::roundss(x, 0);
5767 }
5768 else
5769 {
5770 return Float4(Round(Float4(x))).x;
5771 }
5772 }
5773
5774 RValue<Float> Trunc(RValue<Float> x)
5775 {
5776 if(CPUID::supportsSSE4_1())
5777 {
5778 return x86::roundss(x, 3);
5779 }
5780 else
5781 {
5782 return Float(Int(x)); // Rounded toward zero
5783 }
5784 }
5785
5786 RValue<Float> Frac(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04005787 {
5788 if(CPUID::supportsSSE4_1())
5789 {
5790 return x - x86::floorss(x);
5791 }
5792 else
5793 {
John Bauman19bac1e2014-05-06 15:23:49 -04005794 return Float4(Frac(Float4(x))).x;
John Bauman89401822014-05-06 15:04:28 -04005795 }
5796 }
5797
John Bauman19bac1e2014-05-06 15:23:49 -04005798 RValue<Float> Floor(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04005799 {
5800 if(CPUID::supportsSSE4_1())
5801 {
5802 return x86::floorss(x);
5803 }
5804 else
5805 {
5806 return Float4(Floor(Float4(x))).x;
5807 }
5808 }
5809
John Bauman19bac1e2014-05-06 15:23:49 -04005810 RValue<Float> Ceil(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04005811 {
John Bauman19bac1e2014-05-06 15:23:49 -04005812 if(CPUID::supportsSSE4_1())
5813 {
5814 return x86::ceilss(x);
5815 }
5816 else
5817 {
5818 return Float4(Ceil(Float4(x))).x;
5819 }
John Bauman89401822014-05-06 15:04:28 -04005820 }
5821
John Bauman19bac1e2014-05-06 15:23:49 -04005822 Type *Float::getType()
John Bauman89401822014-05-06 15:04:28 -04005823 {
Nicolas Capensac230122016-09-20 14:30:06 -04005824 return T(llvm::Type::getFloatTy(*::context));
John Bauman89401822014-05-06 15:04:28 -04005825 }
5826
John Bauman19bac1e2014-05-06 15:23:49 -04005827 Float2::Float2(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005828 {
Nicolas Capens22008782016-10-20 01:11:47 -04005829 Value *int64x2 = Nucleus::createBitCast(cast.value, T(VectorType::get(Long::getType(), 2)));
Nicolas Capense95d5342016-09-30 11:37:28 -04005830 Value *int64 = Nucleus::createExtractElement(int64x2, Long::getType(), 0);
John Bauman89401822014-05-06 15:04:28 -04005831 Value *float2 = Nucleus::createBitCast(int64, Float2::getType());
5832
John Bauman66b8ab22014-05-06 15:57:45 -04005833 storeValue(float2);
John Bauman89401822014-05-06 15:04:28 -04005834 }
5835
John Bauman19bac1e2014-05-06 15:23:49 -04005836 Type *Float2::getType()
John Bauman89401822014-05-06 15:04:28 -04005837 {
Nicolas Capensac230122016-09-20 14:30:06 -04005838 return T(VectorType::get(Float::getType(), 2));
John Bauman89401822014-05-06 15:04:28 -04005839 }
5840
Nicolas Capensa25311a2017-01-16 17:19:00 -05005841 Float4::Float4(RValue<Byte4> cast) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005842 {
John Bauman89401822014-05-06 15:04:28 -04005843 #if 0
5844 Value *xyzw = Nucleus::createUIToFP(cast.value, Float4::getType()); // FIXME: Crashes
5845 #elif 0
John Bauman66b8ab22014-05-06 15:57:45 -04005846 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04005847
5848 Value *i8x = Nucleus::createExtractElement(cast.value, 0);
5849 Value *f32x = Nucleus::createUIToFP(i8x, Float::getType());
5850 Value *x = Nucleus::createInsertElement(vector, f32x, 0);
5851
Nicolas Capens19336542016-09-26 10:32:29 -04005852 Value *i8y = Nucleus::createExtractElement(cast.value, V(Nucleus::createConstantInt(1)));
John Bauman89401822014-05-06 15:04:28 -04005853 Value *f32y = Nucleus::createUIToFP(i8y, Float::getType());
Nicolas Capens19336542016-09-26 10:32:29 -04005854 Value *xy = Nucleus::createInsertElement(x, f32y, V(Nucleus::createConstantInt(1)));
John Bauman89401822014-05-06 15:04:28 -04005855
5856 Value *i8z = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(2));
5857 Value *f32z = Nucleus::createUIToFP(i8z, Float::getType());
5858 Value *xyz = Nucleus::createInsertElement(xy, f32z, Nucleus::createConstantInt(2));
5859
5860 Value *i8w = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(3));
5861 Value *f32w = Nucleus::createUIToFP(i8w, Float::getType());
5862 Value *xyzw = Nucleus::createInsertElement(xyz, f32w, Nucleus::createConstantInt(3));
5863 #else
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005864 Value *a = Int4(cast).loadValue();
5865 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04005866 #endif
John Bauman66b8ab22014-05-06 15:57:45 -04005867
5868 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04005869 }
5870
Nicolas Capensa25311a2017-01-16 17:19:00 -05005871 Float4::Float4(RValue<SByte4> cast) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005872 {
John Bauman89401822014-05-06 15:04:28 -04005873 #if 0
5874 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType()); // FIXME: Crashes
5875 #elif 0
John Bauman66b8ab22014-05-06 15:57:45 -04005876 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04005877
5878 Value *i8x = Nucleus::createExtractElement(cast.value, 0);
5879 Value *f32x = Nucleus::createSIToFP(i8x, Float::getType());
5880 Value *x = Nucleus::createInsertElement(vector, f32x, 0);
5881
Nicolas Capens19336542016-09-26 10:32:29 -04005882 Value *i8y = Nucleus::createExtractElement(cast.value, V(Nucleus::createConstantInt(1)));
John Bauman89401822014-05-06 15:04:28 -04005883 Value *f32y = Nucleus::createSIToFP(i8y, Float::getType());
Nicolas Capens19336542016-09-26 10:32:29 -04005884 Value *xy = Nucleus::createInsertElement(x, f32y, V(Nucleus::createConstantInt(1)));
John Bauman89401822014-05-06 15:04:28 -04005885
5886 Value *i8z = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(2));
5887 Value *f32z = Nucleus::createSIToFP(i8z, Float::getType());
5888 Value *xyz = Nucleus::createInsertElement(xy, f32z, Nucleus::createConstantInt(2));
5889
5890 Value *i8w = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(3));
5891 Value *f32w = Nucleus::createSIToFP(i8w, Float::getType());
5892 Value *xyzw = Nucleus::createInsertElement(xyz, f32w, Nucleus::createConstantInt(3));
5893 #else
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005894 Value *a = Int4(cast).loadValue();
5895 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04005896 #endif
John Bauman66b8ab22014-05-06 15:57:45 -04005897
5898 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04005899 }
5900
Nicolas Capensa25311a2017-01-16 17:19:00 -05005901 Float4::Float4(RValue<Short4> cast) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005902 {
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005903 Int4 c(cast);
5904 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
John Bauman89401822014-05-06 15:04:28 -04005905 }
5906
Nicolas Capensa25311a2017-01-16 17:19:00 -05005907 Float4::Float4(RValue<UShort4> cast) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005908 {
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005909 Int4 c(cast);
5910 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
John Bauman89401822014-05-06 15:04:28 -04005911 }
5912
Nicolas Capensa25311a2017-01-16 17:19:00 -05005913 Float4::Float4(RValue<Int4> cast) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005914 {
John Bauman89401822014-05-06 15:04:28 -04005915 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04005916
John Bauman66b8ab22014-05-06 15:57:45 -04005917 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04005918 }
5919
Nicolas Capensa25311a2017-01-16 17:19:00 -05005920 Float4::Float4(RValue<UInt4> cast) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005921 {
Nicolas Capens96445fe2016-12-15 14:45:13 -05005922 RValue<Float4> result = Float4(Int4(cast & UInt4(0x7FFFFFFF))) +
5923 As<Float4>((As<Int4>(cast) >> 31) & As<Int4>(Float4(0x80000000u)));
John Bauman89401822014-05-06 15:04:28 -04005924
Nicolas Capens96445fe2016-12-15 14:45:13 -05005925 storeValue(result.value);
John Bauman89401822014-05-06 15:04:28 -04005926 }
5927
Nicolas Capensa25311a2017-01-16 17:19:00 -05005928 Float4::Float4() : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005929 {
John Bauman89401822014-05-06 15:04:28 -04005930 }
John Bauman66b8ab22014-05-06 15:57:45 -04005931
Nicolas Capensa25311a2017-01-16 17:19:00 -05005932 Float4::Float4(float xyzw) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005933 {
5934 constant(xyzw, xyzw, xyzw, xyzw);
5935 }
5936
Nicolas Capensa25311a2017-01-16 17:19:00 -05005937 Float4::Float4(float x, float yzw) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005938 {
5939 constant(x, yzw, yzw, yzw);
5940 }
5941
Nicolas Capensa25311a2017-01-16 17:19:00 -05005942 Float4::Float4(float x, float y, float zw) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005943 {
5944 constant(x, y, zw, zw);
5945 }
5946
Nicolas Capensa25311a2017-01-16 17:19:00 -05005947 Float4::Float4(float x, float y, float z, float w) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005948 {
5949 constant(x, y, z, w);
5950 }
5951
5952 void Float4::constant(float x, float y, float z, float w)
5953 {
Nicolas Capens13ac2322016-10-13 14:52:12 -04005954 double constantVector[4] = {x, y, z, w};
5955 storeValue(Nucleus::createConstantVector(constantVector, getType()));
John Bauman89401822014-05-06 15:04:28 -04005956 }
5957
Nicolas Capensa25311a2017-01-16 17:19:00 -05005958 Float4::Float4(RValue<Float4> rhs) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005959 {
John Bauman66b8ab22014-05-06 15:57:45 -04005960 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005961 }
5962
Nicolas Capensa25311a2017-01-16 17:19:00 -05005963 Float4::Float4(const Float4 &rhs) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005964 {
John Bauman66b8ab22014-05-06 15:57:45 -04005965 Value *value = rhs.loadValue();
5966 storeValue(value);
5967 }
5968
Nicolas Capensa25311a2017-01-16 17:19:00 -05005969 Float4::Float4(const Reference<Float4> &rhs) : FloatXYZW(this)
John Bauman66b8ab22014-05-06 15:57:45 -04005970 {
John Bauman66b8ab22014-05-06 15:57:45 -04005971 Value *value = rhs.loadValue();
5972 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005973 }
5974
Nicolas Capensa25311a2017-01-16 17:19:00 -05005975 Float4::Float4(RValue<Float> rhs) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005976 {
John Bauman66b8ab22014-05-06 15:57:45 -04005977 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04005978 Value *insert = Nucleus::createInsertElement(vector, rhs.value, 0);
5979
Nicolas Capense89cd582016-09-30 14:23:47 -04005980 int swizzle[4] = {0, 0, 0, 0};
5981 Value *replicate = Nucleus::createShuffleVector(insert, insert, swizzle);
John Bauman89401822014-05-06 15:04:28 -04005982
John Bauman66b8ab22014-05-06 15:57:45 -04005983 storeValue(replicate);
John Bauman89401822014-05-06 15:04:28 -04005984 }
5985
Nicolas Capensa25311a2017-01-16 17:19:00 -05005986 Float4::Float4(const Float &rhs) : FloatXYZW(this)
John Bauman89401822014-05-06 15:04:28 -04005987 {
John Bauman66b8ab22014-05-06 15:57:45 -04005988 *this = RValue<Float>(rhs.loadValue());
5989 }
John Bauman89401822014-05-06 15:04:28 -04005990
Nicolas Capensa25311a2017-01-16 17:19:00 -05005991 Float4::Float4(const Reference<Float> &rhs) : FloatXYZW(this)
John Bauman66b8ab22014-05-06 15:57:45 -04005992 {
John Bauman66b8ab22014-05-06 15:57:45 -04005993 *this = RValue<Float>(rhs.loadValue());
John Bauman89401822014-05-06 15:04:28 -04005994 }
5995
Nicolas Capens96d4e092016-11-18 14:22:38 -05005996 RValue<Float4> Float4::operator=(float x)
John Bauman89401822014-05-06 15:04:28 -04005997 {
5998 return *this = Float4(x, x, x, x);
5999 }
6000
Nicolas Capens96d4e092016-11-18 14:22:38 -05006001 RValue<Float4> Float4::operator=(RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006002 {
John Bauman66b8ab22014-05-06 15:57:45 -04006003 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04006004
6005 return rhs;
6006 }
6007
Nicolas Capens96d4e092016-11-18 14:22:38 -05006008 RValue<Float4> Float4::operator=(const Float4 &rhs)
John Bauman89401822014-05-06 15:04:28 -04006009 {
John Bauman66b8ab22014-05-06 15:57:45 -04006010 Value *value = rhs.loadValue();
6011 storeValue(value);
6012
6013 return RValue<Float4>(value);
6014 }
6015
Nicolas Capens96d4e092016-11-18 14:22:38 -05006016 RValue<Float4> Float4::operator=(const Reference<Float4> &rhs)
John Bauman66b8ab22014-05-06 15:57:45 -04006017 {
6018 Value *value = rhs.loadValue();
6019 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04006020
6021 return RValue<Float4>(value);
6022 }
6023
Nicolas Capens96d4e092016-11-18 14:22:38 -05006024 RValue<Float4> Float4::operator=(RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006025 {
6026 return *this = Float4(rhs);
6027 }
6028
Nicolas Capens96d4e092016-11-18 14:22:38 -05006029 RValue<Float4> Float4::operator=(const Float &rhs)
John Bauman89401822014-05-06 15:04:28 -04006030 {
6031 return *this = Float4(rhs);
6032 }
6033
Nicolas Capens96d4e092016-11-18 14:22:38 -05006034 RValue<Float4> Float4::operator=(const Reference<Float> &rhs)
John Bauman89401822014-05-06 15:04:28 -04006035 {
John Bauman66b8ab22014-05-06 15:57:45 -04006036 return *this = Float4(rhs);
John Bauman89401822014-05-06 15:04:28 -04006037 }
6038
John Bauman19bac1e2014-05-06 15:23:49 -04006039 RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006040 {
6041 return RValue<Float4>(Nucleus::createFAdd(lhs.value, rhs.value));
6042 }
6043
John Bauman19bac1e2014-05-06 15:23:49 -04006044 RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006045 {
6046 return RValue<Float4>(Nucleus::createFSub(lhs.value, rhs.value));
6047 }
6048
John Bauman19bac1e2014-05-06 15:23:49 -04006049 RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006050 {
6051 return RValue<Float4>(Nucleus::createFMul(lhs.value, rhs.value));
6052 }
6053
John Bauman19bac1e2014-05-06 15:23:49 -04006054 RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006055 {
6056 return RValue<Float4>(Nucleus::createFDiv(lhs.value, rhs.value));
6057 }
6058
John Bauman19bac1e2014-05-06 15:23:49 -04006059 RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006060 {
6061 return RValue<Float4>(Nucleus::createFRem(lhs.value, rhs.value));
6062 }
6063
Nicolas Capens96d4e092016-11-18 14:22:38 -05006064 RValue<Float4> operator+=(Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006065 {
6066 return lhs = lhs + rhs;
6067 }
6068
Nicolas Capens96d4e092016-11-18 14:22:38 -05006069 RValue<Float4> operator-=(Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006070 {
6071 return lhs = lhs - rhs;
6072 }
6073
Nicolas Capens96d4e092016-11-18 14:22:38 -05006074 RValue<Float4> operator*=(Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006075 {
6076 return lhs = lhs * rhs;
6077 }
6078
Nicolas Capens96d4e092016-11-18 14:22:38 -05006079 RValue<Float4> operator/=(Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006080 {
6081 return lhs = lhs / rhs;
6082 }
6083
Nicolas Capens96d4e092016-11-18 14:22:38 -05006084 RValue<Float4> operator%=(Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006085 {
6086 return lhs = lhs % rhs;
6087 }
6088
John Bauman19bac1e2014-05-06 15:23:49 -04006089 RValue<Float4> operator+(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006090 {
6091 return val;
6092 }
6093
John Bauman19bac1e2014-05-06 15:23:49 -04006094 RValue<Float4> operator-(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006095 {
6096 return RValue<Float4>(Nucleus::createFNeg(val.value));
6097 }
6098
John Bauman19bac1e2014-05-06 15:23:49 -04006099 RValue<Float4> Abs(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006100 {
6101 Value *vector = Nucleus::createBitCast(x.value, Int4::getType());
Nicolas Capens13ac2322016-10-13 14:52:12 -04006102 int64_t constantVector[4] = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF};
6103 Value *result = Nucleus::createAnd(vector, V(Nucleus::createConstantVector(constantVector, Int4::getType())));
John Bauman89401822014-05-06 15:04:28 -04006104
6105 return RValue<Float4>(Nucleus::createBitCast(result, Float4::getType()));
6106 }
6107
John Bauman19bac1e2014-05-06 15:23:49 -04006108 RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006109 {
6110 return x86::maxps(x, y);
6111 }
6112
John Bauman19bac1e2014-05-06 15:23:49 -04006113 RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006114 {
6115 return x86::minps(x, y);
6116 }
6117
Nicolas Capens05b3d662016-02-25 23:58:33 -05006118 RValue<Float4> Rcp_pp(RValue<Float4> x, bool exactAtPow2)
John Bauman89401822014-05-06 15:04:28 -04006119 {
Nicolas Capens47dc8672017-04-25 12:54:39 -04006120 #if defined(__i386__) || defined(__x86_64__)
6121 if(exactAtPow2)
6122 {
6123 // rcpps uses a piecewise-linear approximation which minimizes the relative error
6124 // but is not exact at power-of-two values. Rectify by multiplying by the inverse.
6125 return x86::rcpps(x) * Float4(1.0f / _mm_cvtss_f32(_mm_rcp_ss(_mm_set_ps1(1.0f))));
6126 }
6127 #endif
6128
6129 return x86::rcpps(x);
John Bauman89401822014-05-06 15:04:28 -04006130 }
John Bauman66b8ab22014-05-06 15:57:45 -04006131
John Bauman19bac1e2014-05-06 15:23:49 -04006132 RValue<Float4> RcpSqrt_pp(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006133 {
6134 return x86::rsqrtps(x);
6135 }
6136
John Bauman19bac1e2014-05-06 15:23:49 -04006137 RValue<Float4> Sqrt(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006138 {
6139 return x86::sqrtps(x);
6140 }
6141
Nicolas Capensc94ab742016-11-08 15:15:31 -05006142 RValue<Float4> Insert(RValue<Float4> val, RValue<Float> element, int i)
John Bauman89401822014-05-06 15:04:28 -04006143 {
Nicolas Capensc94ab742016-11-08 15:15:31 -05006144 return RValue<Float4>(Nucleus::createInsertElement(val.value, element.value, i));
John Bauman89401822014-05-06 15:04:28 -04006145 }
6146
John Bauman19bac1e2014-05-06 15:23:49 -04006147 RValue<Float> Extract(RValue<Float4> x, int i)
John Bauman89401822014-05-06 15:04:28 -04006148 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006149 return RValue<Float>(Nucleus::createExtractElement(x.value, Float::getType(), i));
John Bauman89401822014-05-06 15:04:28 -04006150 }
6151
John Bauman19bac1e2014-05-06 15:23:49 -04006152 RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04006153 {
Nicolas Capense95d5342016-09-30 11:37:28 -04006154 return RValue<Float4>(createSwizzle4(x.value, select));
John Bauman89401822014-05-06 15:04:28 -04006155 }
6156
John Bauman19bac1e2014-05-06 15:23:49 -04006157 RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006158 {
Nicolas Capense89cd582016-09-30 14:23:47 -04006159 int shuffle[4] =
6160 {
6161 ((imm >> 0) & 0x03) + 0,
6162 ((imm >> 2) & 0x03) + 0,
6163 ((imm >> 4) & 0x03) + 4,
6164 ((imm >> 6) & 0x03) + 4,
6165 };
John Bauman89401822014-05-06 15:04:28 -04006166
Nicolas Capense89cd582016-09-30 14:23:47 -04006167 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
John Bauman89401822014-05-06 15:04:28 -04006168 }
6169
John Bauman19bac1e2014-05-06 15:23:49 -04006170 RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006171 {
Nicolas Capense89cd582016-09-30 14:23:47 -04006172 int shuffle[4] = {0, 4, 1, 5};
6173 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
John Bauman89401822014-05-06 15:04:28 -04006174 }
6175
John Bauman19bac1e2014-05-06 15:23:49 -04006176 RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006177 {
Nicolas Capense89cd582016-09-30 14:23:47 -04006178 int shuffle[4] = {2, 6, 3, 7};
6179 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
John Bauman89401822014-05-06 15:04:28 -04006180 }
John Bauman66b8ab22014-05-06 15:57:45 -04006181
John Bauman19bac1e2014-05-06 15:23:49 -04006182 RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04006183 {
John Bauman66b8ab22014-05-06 15:57:45 -04006184 Value *vector = lhs.loadValue();
Nicolas Capense95d5342016-09-30 11:37:28 -04006185 Value *shuffle = createMask4(vector, rhs.value, select);
John Bauman66b8ab22014-05-06 15:57:45 -04006186 lhs.storeValue(shuffle);
John Bauman89401822014-05-06 15:04:28 -04006187
6188 return RValue<Float4>(shuffle);
6189 }
6190
John Bauman19bac1e2014-05-06 15:23:49 -04006191 RValue<Int> SignMask(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006192 {
6193 return x86::movmskps(x);
6194 }
6195
John Bauman19bac1e2014-05-06 15:23:49 -04006196 RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006197 {
6198 // return As<Int4>(x86::cmpeqps(x, y));
6199 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOEQ(x.value, y.value), Int4::getType()));
6200 }
6201
John Bauman19bac1e2014-05-06 15:23:49 -04006202 RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006203 {
6204 // return As<Int4>(x86::cmpltps(x, y));
6205 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOLT(x.value, y.value), Int4::getType()));
6206 }
6207
John Bauman19bac1e2014-05-06 15:23:49 -04006208 RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006209 {
6210 // return As<Int4>(x86::cmpleps(x, y));
6211 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOLE(x.value, y.value), Int4::getType()));
6212 }
6213
John Bauman19bac1e2014-05-06 15:23:49 -04006214 RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006215 {
6216 // return As<Int4>(x86::cmpneqps(x, y));
6217 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpONE(x.value, y.value), Int4::getType()));
6218 }
6219
John Bauman19bac1e2014-05-06 15:23:49 -04006220 RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006221 {
6222 // return As<Int4>(x86::cmpnltps(x, y));
6223 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOGE(x.value, y.value), Int4::getType()));
6224 }
6225
John Bauman19bac1e2014-05-06 15:23:49 -04006226 RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006227 {
6228 // return As<Int4>(x86::cmpnleps(x, y));
6229 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOGT(x.value, y.value), Int4::getType()));
6230 }
6231
John Bauman19bac1e2014-05-06 15:23:49 -04006232 RValue<Float4> Round(RValue<Float4> x)
6233 {
6234 if(CPUID::supportsSSE4_1())
6235 {
6236 return x86::roundps(x, 0);
6237 }
6238 else
6239 {
6240 return Float4(RoundInt(x));
6241 }
6242 }
6243
6244 RValue<Float4> Trunc(RValue<Float4> x)
6245 {
6246 if(CPUID::supportsSSE4_1())
6247 {
6248 return x86::roundps(x, 3);
6249 }
6250 else
6251 {
6252 return Float4(Int4(x)); // Rounded toward zero
6253 }
6254 }
6255
6256 RValue<Float4> Frac(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006257 {
Nicolas Capensb9230422017-07-17 10:27:33 -04006258 Float4 frc;
6259
John Bauman89401822014-05-06 15:04:28 -04006260 if(CPUID::supportsSSE4_1())
6261 {
Nicolas Capensb9230422017-07-17 10:27:33 -04006262 frc = x - x86::floorps(x);
John Bauman89401822014-05-06 15:04:28 -04006263 }
6264 else
6265 {
Nicolas Capensb9230422017-07-17 10:27:33 -04006266 frc = x - Float4(Int4(x)); // Signed fractional part.
John Bauman89401822014-05-06 15:04:28 -04006267
Nicolas Capensb9230422017-07-17 10:27:33 -04006268 frc += As<Float4>(As<Int4>(CmpNLE(Float4(0.0f), frc)) & As<Int4>(Float4(1.0f))); // Add 1.0 if negative.
John Bauman89401822014-05-06 15:04:28 -04006269 }
Nicolas Capensb9230422017-07-17 10:27:33 -04006270
6271 // x - floor(x) can be 1.0 for very small negative x.
6272 // Clamp against the value just below 1.0.
6273 return Min(frc, As<Float4>(Int4(0x3F7FFFFF)));
John Bauman89401822014-05-06 15:04:28 -04006274 }
6275
John Bauman19bac1e2014-05-06 15:23:49 -04006276 RValue<Float4> Floor(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006277 {
6278 if(CPUID::supportsSSE4_1())
6279 {
6280 return x86::floorps(x);
6281 }
6282 else
6283 {
John Bauman19bac1e2014-05-06 15:23:49 -04006284 return x - Frac(x);
John Bauman89401822014-05-06 15:04:28 -04006285 }
6286 }
6287
John Bauman19bac1e2014-05-06 15:23:49 -04006288 RValue<Float4> Ceil(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006289 {
John Bauman19bac1e2014-05-06 15:23:49 -04006290 if(CPUID::supportsSSE4_1())
6291 {
6292 return x86::ceilps(x);
6293 }
6294 else
6295 {
6296 return -Floor(-x);
6297 }
John Bauman89401822014-05-06 15:04:28 -04006298 }
6299
John Bauman19bac1e2014-05-06 15:23:49 -04006300 Type *Float4::getType()
John Bauman89401822014-05-06 15:04:28 -04006301 {
Nicolas Capensac230122016-09-20 14:30:06 -04006302 return T(VectorType::get(Float::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04006303 }
6304
Nicolas Capens81f18302016-01-14 09:32:35 -05006305 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006306 {
Nicolas Capensd294def2017-01-26 17:44:37 -08006307 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), V(Nucleus::createConstantInt(offset)), false));
John Bauman89401822014-05-06 15:04:28 -04006308 }
6309
Nicolas Capens81f18302016-01-14 09:32:35 -05006310 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006311 {
Nicolas Capensd294def2017-01-26 17:44:37 -08006312 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value, false));
John Bauman89401822014-05-06 15:04:28 -04006313 }
6314
Nicolas Capens81f18302016-01-14 09:32:35 -05006315 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006316 {
Nicolas Capensd294def2017-01-26 17:44:37 -08006317 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value, true));
John Bauman89401822014-05-06 15:04:28 -04006318 }
6319
Nicolas Capens96d4e092016-11-18 14:22:38 -05006320 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006321 {
6322 return lhs = lhs + offset;
6323 }
6324
Nicolas Capens96d4e092016-11-18 14:22:38 -05006325 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006326 {
6327 return lhs = lhs + offset;
6328 }
6329
Nicolas Capens96d4e092016-11-18 14:22:38 -05006330 RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006331 {
6332 return lhs = lhs + offset;
6333 }
6334
Nicolas Capens81f18302016-01-14 09:32:35 -05006335 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006336 {
6337 return lhs + -offset;
6338 }
6339
Nicolas Capens81f18302016-01-14 09:32:35 -05006340 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006341 {
6342 return lhs + -offset;
6343 }
6344
Nicolas Capens81f18302016-01-14 09:32:35 -05006345 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006346 {
6347 return lhs + -offset;
6348 }
6349
Nicolas Capens96d4e092016-11-18 14:22:38 -05006350 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006351 {
6352 return lhs = lhs - offset;
6353 }
6354
Nicolas Capens96d4e092016-11-18 14:22:38 -05006355 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006356 {
6357 return lhs = lhs - offset;
6358 }
6359
Nicolas Capens96d4e092016-11-18 14:22:38 -05006360 RValue<Pointer<Byte>> operator-=(Pointer<Byte> &lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006361 {
6362 return lhs = lhs - offset;
6363 }
6364
6365 void Return()
6366 {
John Bauman89401822014-05-06 15:04:28 -04006367 Nucleus::createRetVoid();
6368 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
John Bauman19bac1e2014-05-06 15:23:49 -04006369 Nucleus::createUnreachable();
6370 }
6371
Nicolas Capenseb253d02016-11-18 14:40:40 -05006372 void Return(RValue<Int> ret)
John Bauman19bac1e2014-05-06 15:23:49 -04006373 {
Nicolas Capenseb253d02016-11-18 14:40:40 -05006374 Nucleus::createRet(ret.value);
John Bauman89401822014-05-06 15:04:28 -04006375 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
John Bauman19bac1e2014-05-06 15:23:49 -04006376 Nucleus::createUnreachable();
John Bauman89401822014-05-06 15:04:28 -04006377 }
6378
Nicolas Capensf4eec2f2017-05-24 15:46:48 -04006379 void branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB)
John Bauman89401822014-05-06 15:04:28 -04006380 {
6381 Nucleus::createCondBr(cmp.value, bodyBB, endBB);
John Bauman66b8ab22014-05-06 15:57:45 -04006382 Nucleus::setInsertBlock(bodyBB);
John Bauman89401822014-05-06 15:04:28 -04006383 }
6384
John Bauman89401822014-05-06 15:04:28 -04006385 RValue<Long> Ticks()
6386 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006387 llvm::Function *rdtsc = Intrinsic::getDeclaration(::module, Intrinsic::readcyclecounter);
John Bauman89401822014-05-06 15:04:28 -04006388
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006389 return RValue<Long>(V(::builder->CreateCall(rdtsc)));
John Bauman89401822014-05-06 15:04:28 -04006390 }
John Bauman89401822014-05-06 15:04:28 -04006391}
6392
6393namespace sw
6394{
6395 namespace x86
6396 {
John Bauman19bac1e2014-05-06 15:23:49 -04006397 RValue<Int> cvtss2si(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006398 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006399 llvm::Function *cvtss2si = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cvtss2si);
John Bauman66b8ab22014-05-06 15:57:45 -04006400
John Bauman89401822014-05-06 15:04:28 -04006401 Float4 vector;
6402 vector.x = val;
6403
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006404 return RValue<Int>(V(::builder->CreateCall(cvtss2si, RValue<Float4>(vector).value)));
John Bauman89401822014-05-06 15:04:28 -04006405 }
6406
John Bauman19bac1e2014-05-06 15:23:49 -04006407 RValue<Int2> cvtps2pi(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006408 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006409 llvm::Function *cvtps2pi = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cvtps2pi);
John Bauman89401822014-05-06 15:04:28 -04006410
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006411 return RValue<Int2>(V(::builder->CreateCall(cvtps2pi, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006412 }
6413
John Bauman19bac1e2014-05-06 15:23:49 -04006414 RValue<Int2> cvttps2pi(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006415 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006416 llvm::Function *cvttps2pi = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cvttps2pi);
John Bauman89401822014-05-06 15:04:28 -04006417
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006418 return RValue<Int2>(V(::builder->CreateCall(cvttps2pi, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006419 }
6420
John Bauman19bac1e2014-05-06 15:23:49 -04006421 RValue<Int4> cvtps2dq(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006422 {
6423 if(CPUID::supportsSSE2())
6424 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006425 llvm::Function *cvtps2dq = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_cvtps2dq);
John Bauman89401822014-05-06 15:04:28 -04006426
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006427 return RValue<Int4>(V(::builder->CreateCall(cvtps2dq, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006428 }
6429 else
6430 {
6431 Int2 lo = x86::cvtps2pi(val);
6432 Int2 hi = x86::cvtps2pi(Swizzle(val, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04006433
Nicolas Capens62abb552016-01-05 12:03:47 -05006434 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04006435 }
6436 }
6437
John Bauman19bac1e2014-05-06 15:23:49 -04006438 RValue<Float> rcpss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006439 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006440 llvm::Function *rcpss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rcp_ss);
John Bauman89401822014-05-06 15:04:28 -04006441
Nicolas Capens19336542016-09-26 10:32:29 -04006442 Value *vector = Nucleus::createInsertElement(V(UndefValue::get(Float4::getType())), val.value, 0);
John Bauman66b8ab22014-05-06 15:57:45 -04006443
Nicolas Capense95d5342016-09-30 11:37:28 -04006444 return RValue<Float>(Nucleus::createExtractElement(V(::builder->CreateCall(rcpss, vector)), Float::getType(), 0));
John Bauman89401822014-05-06 15:04:28 -04006445 }
6446
John Bauman19bac1e2014-05-06 15:23:49 -04006447 RValue<Float> sqrtss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006448 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006449 llvm::Function *sqrtss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_sqrt_ss);
John Bauman89401822014-05-06 15:04:28 -04006450
Nicolas Capens19336542016-09-26 10:32:29 -04006451 Value *vector = Nucleus::createInsertElement(V(UndefValue::get(Float4::getType())), val.value, 0);
John Bauman66b8ab22014-05-06 15:57:45 -04006452
Nicolas Capense95d5342016-09-30 11:37:28 -04006453 return RValue<Float>(Nucleus::createExtractElement(V(::builder->CreateCall(sqrtss, vector)), Float::getType(), 0));
John Bauman89401822014-05-06 15:04:28 -04006454 }
6455
John Bauman19bac1e2014-05-06 15:23:49 -04006456 RValue<Float> rsqrtss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006457 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006458 llvm::Function *rsqrtss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rsqrt_ss);
John Bauman66b8ab22014-05-06 15:57:45 -04006459
Nicolas Capens19336542016-09-26 10:32:29 -04006460 Value *vector = Nucleus::createInsertElement(V(UndefValue::get(Float4::getType())), val.value, 0);
John Bauman89401822014-05-06 15:04:28 -04006461
Nicolas Capense95d5342016-09-30 11:37:28 -04006462 return RValue<Float>(Nucleus::createExtractElement(V(::builder->CreateCall(rsqrtss, vector)), Float::getType(), 0));
John Bauman89401822014-05-06 15:04:28 -04006463 }
6464
John Bauman19bac1e2014-05-06 15:23:49 -04006465 RValue<Float4> rcpps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006466 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006467 llvm::Function *rcpps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rcp_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04006468
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006469 return RValue<Float4>(V(::builder->CreateCall(rcpps, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006470 }
6471
John Bauman19bac1e2014-05-06 15:23:49 -04006472 RValue<Float4> sqrtps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006473 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006474 llvm::Function *sqrtps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_sqrt_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04006475
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006476 return RValue<Float4>(V(::builder->CreateCall(sqrtps, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006477 }
6478
John Bauman19bac1e2014-05-06 15:23:49 -04006479 RValue<Float4> rsqrtps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006480 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006481 llvm::Function *rsqrtps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rsqrt_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04006482
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006483 return RValue<Float4>(V(::builder->CreateCall(rsqrtps, val.value)));
John Bauman89401822014-05-06 15:04:28 -04006484 }
6485
John Bauman19bac1e2014-05-06 15:23:49 -04006486 RValue<Float4> maxps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006487 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006488 llvm::Function *maxps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_max_ps);
John Bauman89401822014-05-06 15:04:28 -04006489
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006490 return RValue<Float4>(V(::builder->CreateCall2(maxps, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04006491 }
6492
John Bauman19bac1e2014-05-06 15:23:49 -04006493 RValue<Float4> minps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006494 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006495 llvm::Function *minps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_min_ps);
John Bauman89401822014-05-06 15:04:28 -04006496
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006497 return RValue<Float4>(V(::builder->CreateCall2(minps, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04006498 }
6499
John Bauman19bac1e2014-05-06 15:23:49 -04006500 RValue<Float> roundss(RValue<Float> val, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006501 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006502 llvm::Function *roundss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_round_ss);
John Bauman89401822014-05-06 15:04:28 -04006503
Nicolas Capens19336542016-09-26 10:32:29 -04006504 Value *undef = V(UndefValue::get(Float4::getType()));
John Bauman89401822014-05-06 15:04:28 -04006505 Value *vector = Nucleus::createInsertElement(undef, val.value, 0);
6506
Nicolas Capense95d5342016-09-30 11:37:28 -04006507 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 -04006508 }
6509
John Bauman19bac1e2014-05-06 15:23:49 -04006510 RValue<Float> floorss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006511 {
6512 return roundss(val, 1);
6513 }
6514
John Bauman19bac1e2014-05-06 15:23:49 -04006515 RValue<Float> ceilss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006516 {
6517 return roundss(val, 2);
6518 }
6519
John Bauman19bac1e2014-05-06 15:23:49 -04006520 RValue<Float4> roundps(RValue<Float4> val, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006521 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006522 llvm::Function *roundps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_round_ps);
John Bauman89401822014-05-06 15:04:28 -04006523
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006524 return RValue<Float4>(V(::builder->CreateCall2(roundps, val.value, V(Nucleus::createConstantInt(imm)))));
John Bauman89401822014-05-06 15:04:28 -04006525 }
6526
John Bauman19bac1e2014-05-06 15:23:49 -04006527 RValue<Float4> floorps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006528 {
6529 return roundps(val, 1);
6530 }
6531
John Bauman19bac1e2014-05-06 15:23:49 -04006532 RValue<Float4> ceilps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006533 {
6534 return roundps(val, 2);
6535 }
6536
John Bauman19bac1e2014-05-06 15:23:49 -04006537 RValue<Float4> cmpps(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006538 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006539 llvm::Function *cmpps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cmp_ps);
John Bauman89401822014-05-06 15:04:28 -04006540
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006541 return RValue<Float4>(V(::builder->CreateCall3(cmpps, x.value, y.value, V(Nucleus::createConstantByte(imm)))));
John Bauman89401822014-05-06 15:04:28 -04006542 }
6543
John Bauman19bac1e2014-05-06 15:23:49 -04006544 RValue<Float4> cmpeqps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006545 {
6546 return cmpps(x, y, 0);
6547 }
6548
John Bauman19bac1e2014-05-06 15:23:49 -04006549 RValue<Float4> cmpltps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006550 {
6551 return cmpps(x, y, 1);
6552 }
6553
John Bauman19bac1e2014-05-06 15:23:49 -04006554 RValue<Float4> cmpleps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006555 {
6556 return cmpps(x, y, 2);
6557 }
6558
John Bauman19bac1e2014-05-06 15:23:49 -04006559 RValue<Float4> cmpunordps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006560 {
6561 return cmpps(x, y, 3);
6562 }
6563
John Bauman19bac1e2014-05-06 15:23:49 -04006564 RValue<Float4> cmpneqps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006565 {
6566 return cmpps(x, y, 4);
6567 }
6568
John Bauman19bac1e2014-05-06 15:23:49 -04006569 RValue<Float4> cmpnltps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006570 {
6571 return cmpps(x, y, 5);
6572 }
6573
John Bauman19bac1e2014-05-06 15:23:49 -04006574 RValue<Float4> cmpnleps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006575 {
6576 return cmpps(x, y, 6);
6577 }
6578
John Bauman19bac1e2014-05-06 15:23:49 -04006579 RValue<Float4> cmpordps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006580 {
6581 return cmpps(x, y, 7);
6582 }
6583
John Bauman19bac1e2014-05-06 15:23:49 -04006584 RValue<Float> cmpss(RValue<Float> x, RValue<Float> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006585 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006586 llvm::Function *cmpss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cmp_ss);
John Bauman89401822014-05-06 15:04:28 -04006587
Nicolas Capens19336542016-09-26 10:32:29 -04006588 Value *vector1 = Nucleus::createInsertElement(V(UndefValue::get(Float4::getType())), x.value, 0);
6589 Value *vector2 = Nucleus::createInsertElement(V(UndefValue::get(Float4::getType())), y.value, 0);
John Bauman89401822014-05-06 15:04:28 -04006590
Nicolas Capense95d5342016-09-30 11:37:28 -04006591 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 -04006592 }
6593
John Bauman19bac1e2014-05-06 15:23:49 -04006594 RValue<Float> cmpeqss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006595 {
6596 return cmpss(x, y, 0);
6597 }
6598
John Bauman19bac1e2014-05-06 15:23:49 -04006599 RValue<Float> cmpltss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006600 {
6601 return cmpss(x, y, 1);
6602 }
6603
John Bauman19bac1e2014-05-06 15:23:49 -04006604 RValue<Float> cmpless(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006605 {
6606 return cmpss(x, y, 2);
6607 }
6608
John Bauman19bac1e2014-05-06 15:23:49 -04006609 RValue<Float> cmpunordss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006610 {
6611 return cmpss(x, y, 3);
6612 }
6613
John Bauman19bac1e2014-05-06 15:23:49 -04006614 RValue<Float> cmpneqss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006615 {
6616 return cmpss(x, y, 4);
6617 }
6618
John Bauman19bac1e2014-05-06 15:23:49 -04006619 RValue<Float> cmpnltss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006620 {
6621 return cmpss(x, y, 5);
6622 }
6623
John Bauman19bac1e2014-05-06 15:23:49 -04006624 RValue<Float> cmpnless(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006625 {
6626 return cmpss(x, y, 6);
6627 }
6628
John Bauman19bac1e2014-05-06 15:23:49 -04006629 RValue<Float> cmpordss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006630 {
6631 return cmpss(x, y, 7);
6632 }
6633
Alexis Hetu0f448072016-03-18 10:56:08 -04006634 RValue<Int4> pabsd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04006635 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006636 llvm::Function *pabsd = Intrinsic::getDeclaration(::module, Intrinsic::x86_ssse3_pabs_d_128);
John Bauman89401822014-05-06 15:04:28 -04006637
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006638 return RValue<Int4>(V(::builder->CreateCall(pabsd, x.value)));
John Bauman89401822014-05-06 15:04:28 -04006639 }
6640
John Bauman19bac1e2014-05-06 15:23:49 -04006641 RValue<Short4> paddsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006642 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006643 llvm::Function *paddsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padds_w);
John Bauman89401822014-05-06 15:04:28 -04006644
Nicolas Capens70dfff42016-10-27 10:20:28 -04006645 return As<Short4>(V(::builder->CreateCall2(paddsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006646 }
John Bauman66b8ab22014-05-06 15:57:45 -04006647
John Bauman19bac1e2014-05-06 15:23:49 -04006648 RValue<Short4> psubsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006649 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006650 llvm::Function *psubsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubs_w);
John Bauman89401822014-05-06 15:04:28 -04006651
Nicolas Capens70dfff42016-10-27 10:20:28 -04006652 return As<Short4>(V(::builder->CreateCall2(psubsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006653 }
6654
John Bauman19bac1e2014-05-06 15:23:49 -04006655 RValue<UShort4> paddusw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04006656 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006657 llvm::Function *paddusw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_paddus_w);
John Bauman89401822014-05-06 15:04:28 -04006658
Nicolas Capens70dfff42016-10-27 10:20:28 -04006659 return As<UShort4>(V(::builder->CreateCall2(paddusw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006660 }
John Bauman66b8ab22014-05-06 15:57:45 -04006661
John Bauman19bac1e2014-05-06 15:23:49 -04006662 RValue<UShort4> psubusw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04006663 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006664 llvm::Function *psubusw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubus_w);
John Bauman89401822014-05-06 15:04:28 -04006665
Nicolas Capens70dfff42016-10-27 10:20:28 -04006666 return As<UShort4>(V(::builder->CreateCall2(psubusw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006667 }
6668
John Bauman19bac1e2014-05-06 15:23:49 -04006669 RValue<SByte8> paddsb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04006670 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006671 llvm::Function *paddsb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padds_b);
John Bauman89401822014-05-06 15:04:28 -04006672
Nicolas Capens70dfff42016-10-27 10:20:28 -04006673 return As<SByte8>(V(::builder->CreateCall2(paddsb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006674 }
John Bauman66b8ab22014-05-06 15:57:45 -04006675
John Bauman19bac1e2014-05-06 15:23:49 -04006676 RValue<SByte8> psubsb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04006677 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006678 llvm::Function *psubsb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubs_b);
John Bauman89401822014-05-06 15:04:28 -04006679
Nicolas Capens70dfff42016-10-27 10:20:28 -04006680 return As<SByte8>(V(::builder->CreateCall2(psubsb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006681 }
John Bauman66b8ab22014-05-06 15:57:45 -04006682
John Bauman19bac1e2014-05-06 15:23:49 -04006683 RValue<Byte8> paddusb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04006684 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006685 llvm::Function *paddusb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_paddus_b);
John Bauman89401822014-05-06 15:04:28 -04006686
Nicolas Capens70dfff42016-10-27 10:20:28 -04006687 return As<Byte8>(V(::builder->CreateCall2(paddusb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006688 }
John Bauman66b8ab22014-05-06 15:57:45 -04006689
John Bauman19bac1e2014-05-06 15:23:49 -04006690 RValue<Byte8> psubusb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04006691 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006692 llvm::Function *psubusb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubus_b);
John Bauman89401822014-05-06 15:04:28 -04006693
Nicolas Capens70dfff42016-10-27 10:20:28 -04006694 return As<Byte8>(V(::builder->CreateCall2(psubusb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006695 }
6696
John Bauman19bac1e2014-05-06 15:23:49 -04006697 RValue<Short4> paddw(RValue<Short4> x, RValue<Short4> y)
6698 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006699 llvm::Function *paddw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padd_w);
John Bauman19bac1e2014-05-06 15:23:49 -04006700
Nicolas Capens70dfff42016-10-27 10:20:28 -04006701 return As<Short4>(V(::builder->CreateCall2(paddw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006702 }
6703
6704 RValue<Short4> psubw(RValue<Short4> x, RValue<Short4> y)
6705 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006706 llvm::Function *psubw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psub_w);
John Bauman19bac1e2014-05-06 15:23:49 -04006707
Nicolas Capens70dfff42016-10-27 10:20:28 -04006708 return As<Short4>(V(::builder->CreateCall2(psubw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006709 }
6710
6711 RValue<Short4> pmullw(RValue<Short4> x, RValue<Short4> y)
6712 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006713 llvm::Function *pmullw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmull_w);
John Bauman19bac1e2014-05-06 15:23:49 -04006714
Nicolas Capens70dfff42016-10-27 10:20:28 -04006715 return As<Short4>(V(::builder->CreateCall2(pmullw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006716 }
6717
6718 RValue<Short4> pand(RValue<Short4> x, RValue<Short4> y)
6719 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006720 llvm::Function *pand = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pand);
John Bauman19bac1e2014-05-06 15:23:49 -04006721
Nicolas Capens70dfff42016-10-27 10:20:28 -04006722 return As<Short4>(V(::builder->CreateCall2(pand, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006723 }
6724
6725 RValue<Short4> por(RValue<Short4> x, RValue<Short4> y)
6726 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006727 llvm::Function *por = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_por);
John Bauman19bac1e2014-05-06 15:23:49 -04006728
Nicolas Capens70dfff42016-10-27 10:20:28 -04006729 return As<Short4>(V(::builder->CreateCall2(por, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006730 }
6731
6732 RValue<Short4> pxor(RValue<Short4> x, RValue<Short4> y)
6733 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006734 llvm::Function *pxor = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pxor);
John Bauman19bac1e2014-05-06 15:23:49 -04006735
Nicolas Capens70dfff42016-10-27 10:20:28 -04006736 return As<Short4>(V(::builder->CreateCall2(pxor, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006737 }
6738
6739 RValue<Short4> pshufw(RValue<Short4> x, unsigned char y)
6740 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006741 llvm::Function *pshufw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_pshuf_w);
John Bauman19bac1e2014-05-06 15:23:49 -04006742
Nicolas Capens70dfff42016-10-27 10:20:28 -04006743 return As<Short4>(V(::builder->CreateCall2(pshufw, As<MMX>(x).value, V(Nucleus::createConstantByte(y)))));
John Bauman19bac1e2014-05-06 15:23:49 -04006744 }
6745
6746 RValue<Int2> punpcklwd(RValue<Short4> x, RValue<Short4> y)
6747 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006748 llvm::Function *punpcklwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpcklwd);
John Bauman19bac1e2014-05-06 15:23:49 -04006749
Nicolas Capens70dfff42016-10-27 10:20:28 -04006750 return As<Int2>(V(::builder->CreateCall2(punpcklwd, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006751 }
6752
6753 RValue<Int2> punpckhwd(RValue<Short4> x, RValue<Short4> y)
6754 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006755 llvm::Function *punpckhwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckhwd);
John Bauman19bac1e2014-05-06 15:23:49 -04006756
Nicolas Capens70dfff42016-10-27 10:20:28 -04006757 return As<Int2>(V(::builder->CreateCall2(punpckhwd, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006758 }
6759
6760 RValue<Short4> pinsrw(RValue<Short4> x, RValue<Int> y, unsigned int i)
6761 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006762 llvm::Function *pinsrw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pinsr_w);
John Bauman19bac1e2014-05-06 15:23:49 -04006763
Nicolas Capens70dfff42016-10-27 10:20:28 -04006764 return As<Short4>(V(::builder->CreateCall3(pinsrw, As<MMX>(x).value, y.value, V(Nucleus::createConstantInt(i)))));
John Bauman19bac1e2014-05-06 15:23:49 -04006765 }
6766
6767 RValue<Int> pextrw(RValue<Short4> x, unsigned int i)
6768 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006769 llvm::Function *pextrw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pextr_w);
John Bauman19bac1e2014-05-06 15:23:49 -04006770
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006771 return RValue<Int>(V(::builder->CreateCall2(pextrw, As<MMX>(x).value, V(Nucleus::createConstantInt(i)))));
John Bauman19bac1e2014-05-06 15:23:49 -04006772 }
6773
Nicolas Capens45f187a2016-12-02 15:30:56 -05006774 RValue<Short4> punpckldq(RValue<Int2> x, RValue<Int2> y)
John Bauman19bac1e2014-05-06 15:23:49 -04006775 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006776 llvm::Function *punpckldq = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckldq);
John Bauman19bac1e2014-05-06 15:23:49 -04006777
Nicolas Capens45f187a2016-12-02 15:30:56 -05006778 return As<Short4>(V(::builder->CreateCall2(punpckldq, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006779 }
6780
Nicolas Capens45f187a2016-12-02 15:30:56 -05006781 RValue<Short4> punpckhdq(RValue<Int2> x, RValue<Int2> y)
John Bauman19bac1e2014-05-06 15:23:49 -04006782 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006783 llvm::Function *punpckhdq = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckhdq);
John Bauman19bac1e2014-05-06 15:23:49 -04006784
Nicolas Capens45f187a2016-12-02 15:30:56 -05006785 return As<Short4>(V(::builder->CreateCall2(punpckhdq, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006786 }
6787
6788 RValue<Short4> punpcklbw(RValue<Byte8> x, RValue<Byte8> y)
6789 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006790 llvm::Function *punpcklbw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpcklbw);
John Bauman19bac1e2014-05-06 15:23:49 -04006791
Nicolas Capens70dfff42016-10-27 10:20:28 -04006792 return As<Short4>(V(::builder->CreateCall2(punpcklbw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006793 }
6794
6795 RValue<Short4> punpckhbw(RValue<Byte8> x, RValue<Byte8> y)
6796 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006797 llvm::Function *punpckhbw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckhbw);
John Bauman19bac1e2014-05-06 15:23:49 -04006798
Nicolas Capens70dfff42016-10-27 10:20:28 -04006799 return As<Short4>(V(::builder->CreateCall2(punpckhbw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006800 }
6801
6802 RValue<Byte8> paddb(RValue<Byte8> x, RValue<Byte8> y)
6803 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006804 llvm::Function *paddb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padd_b);
John Bauman19bac1e2014-05-06 15:23:49 -04006805
Nicolas Capens70dfff42016-10-27 10:20:28 -04006806 return As<Byte8>(V(::builder->CreateCall2(paddb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006807 }
6808
6809 RValue<Byte8> psubb(RValue<Byte8> x, RValue<Byte8> y)
6810 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006811 llvm::Function *psubb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psub_b);
John Bauman19bac1e2014-05-06 15:23:49 -04006812
Nicolas Capens70dfff42016-10-27 10:20:28 -04006813 return As<Byte8>(V(::builder->CreateCall2(psubb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006814 }
6815
6816 RValue<Int2> paddd(RValue<Int2> x, RValue<Int2> y)
6817 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006818 llvm::Function *paddd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padd_d);
John Bauman19bac1e2014-05-06 15:23:49 -04006819
Nicolas Capens70dfff42016-10-27 10:20:28 -04006820 return As<Int2>(V(::builder->CreateCall2(paddd, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006821 }
6822
6823 RValue<Int2> psubd(RValue<Int2> x, RValue<Int2> y)
6824 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006825 llvm::Function *psubd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psub_d);
John Bauman19bac1e2014-05-06 15:23:49 -04006826
Nicolas Capens70dfff42016-10-27 10:20:28 -04006827 return As<Int2>(V(::builder->CreateCall2(psubd, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman19bac1e2014-05-06 15:23:49 -04006828 }
6829
6830 RValue<UShort4> pavgw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04006831 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006832 llvm::Function *pavgw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pavg_w);
John Bauman89401822014-05-06 15:04:28 -04006833
Nicolas Capens70dfff42016-10-27 10:20:28 -04006834 return As<UShort4>(V(::builder->CreateCall2(pavgw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006835 }
6836
John Bauman19bac1e2014-05-06 15:23:49 -04006837 RValue<Short4> pmaxsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006838 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006839 llvm::Function *pmaxsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmaxs_w);
John Bauman89401822014-05-06 15:04:28 -04006840
Nicolas Capens70dfff42016-10-27 10:20:28 -04006841 return As<Short4>(V(::builder->CreateCall2(pmaxsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006842 }
6843
John Bauman19bac1e2014-05-06 15:23:49 -04006844 RValue<Short4> pminsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006845 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006846 llvm::Function *pminsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmins_w);
John Bauman89401822014-05-06 15:04:28 -04006847
Nicolas Capens70dfff42016-10-27 10:20:28 -04006848 return As<Short4>(V(::builder->CreateCall2(pminsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006849 }
6850
John Bauman19bac1e2014-05-06 15:23:49 -04006851 RValue<Short4> pcmpgtw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006852 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006853 llvm::Function *pcmpgtw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpgt_w);
John Bauman89401822014-05-06 15:04:28 -04006854
Nicolas Capens70dfff42016-10-27 10:20:28 -04006855 return As<Short4>(V(::builder->CreateCall2(pcmpgtw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006856 }
6857
John Bauman19bac1e2014-05-06 15:23:49 -04006858 RValue<Short4> pcmpeqw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006859 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006860 llvm::Function *pcmpeqw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpeq_w);
John Bauman89401822014-05-06 15:04:28 -04006861
Nicolas Capens70dfff42016-10-27 10:20:28 -04006862 return As<Short4>(V(::builder->CreateCall2(pcmpeqw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006863 }
6864
John Bauman19bac1e2014-05-06 15:23:49 -04006865 RValue<Byte8> pcmpgtb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04006866 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006867 llvm::Function *pcmpgtb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpgt_b);
John Bauman89401822014-05-06 15:04:28 -04006868
Nicolas Capens70dfff42016-10-27 10:20:28 -04006869 return As<Byte8>(V(::builder->CreateCall2(pcmpgtb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006870 }
6871
John Bauman19bac1e2014-05-06 15:23:49 -04006872 RValue<Byte8> pcmpeqb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04006873 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006874 llvm::Function *pcmpeqb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpeq_b);
John Bauman89401822014-05-06 15:04:28 -04006875
Nicolas Capens70dfff42016-10-27 10:20:28 -04006876 return As<Byte8>(V(::builder->CreateCall2(pcmpeqb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006877 }
6878
John Bauman19bac1e2014-05-06 15:23:49 -04006879 RValue<Short4> packssdw(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04006880 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006881 llvm::Function *packssdw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_packssdw);
John Bauman89401822014-05-06 15:04:28 -04006882
Nicolas Capens70dfff42016-10-27 10:20:28 -04006883 return As<Short4>(V(::builder->CreateCall2(packssdw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006884 }
6885
John Bauman19bac1e2014-05-06 15:23:49 -04006886 RValue<Short8> packssdw(RValue<Int4> x, RValue<Int4> y)
John Bauman89401822014-05-06 15:04:28 -04006887 {
6888 if(CPUID::supportsSSE2())
6889 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006890 llvm::Function *packssdw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_packssdw_128);
John Bauman89401822014-05-06 15:04:28 -04006891
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006892 return RValue<Short8>(V(::builder->CreateCall2(packssdw, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04006893 }
6894 else
6895 {
6896 Int2 loX = Int2(x);
6897 Int2 hiX = Int2(Swizzle(x, 0xEE));
6898
6899 Int2 loY = Int2(y);
6900 Int2 hiY = Int2(Swizzle(y, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04006901
John Bauman89401822014-05-06 15:04:28 -04006902 Short4 lo = x86::packssdw(loX, hiX);
6903 Short4 hi = x86::packssdw(loY, hiY);
John Bauman66b8ab22014-05-06 15:57:45 -04006904
Nicolas Capens62abb552016-01-05 12:03:47 -05006905 return Short8(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04006906 }
6907 }
6908
John Bauman19bac1e2014-05-06 15:23:49 -04006909 RValue<SByte8> packsswb(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04006910 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006911 llvm::Function *packsswb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_packsswb);
John Bauman89401822014-05-06 15:04:28 -04006912
Nicolas Capens70dfff42016-10-27 10:20:28 -04006913 return As<SByte8>(V(::builder->CreateCall2(packsswb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006914 }
6915
John Bauman19bac1e2014-05-06 15:23:49 -04006916 RValue<Byte8> packuswb(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04006917 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006918 llvm::Function *packuswb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_packuswb);
John Bauman89401822014-05-06 15:04:28 -04006919
Nicolas Capens70dfff42016-10-27 10:20:28 -04006920 return As<Byte8>(V(::builder->CreateCall2(packuswb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04006921 }
6922
Nicolas Capens3e7062b2017-01-17 14:01:33 -05006923 RValue<UShort8> packusdw(RValue<Int4> x, RValue<Int4> y)
John Bauman89401822014-05-06 15:04:28 -04006924 {
6925 if(CPUID::supportsSSE4_1())
6926 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006927 llvm::Function *packusdw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_packusdw);
John Bauman66b8ab22014-05-06 15:57:45 -04006928
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006929 return RValue<UShort8>(V(::builder->CreateCall2(packusdw, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04006930 }
6931 else
6932 {
Nicolas Capens3e7062b2017-01-17 14:01:33 -05006933 RValue<Int4> bx = (x & ~(x >> 31)) - Int4(0x8000);
6934 RValue<Int4> by = (y & ~(y >> 31)) - Int4(0x8000);
6935
6936 return As<UShort8>(packssdw(bx, by) + Short8(0x8000u));
John Bauman89401822014-05-06 15:04:28 -04006937 }
6938 }
6939
John Bauman19bac1e2014-05-06 15:23:49 -04006940 RValue<UShort4> psrlw(RValue<UShort4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006941 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006942 llvm::Function *psrlw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrli_w);
John Bauman89401822014-05-06 15:04:28 -04006943
Nicolas Capens70dfff42016-10-27 10:20:28 -04006944 return As<UShort4>(V(::builder->CreateCall2(psrlw, As<MMX>(x).value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006945 }
6946
John Bauman19bac1e2014-05-06 15:23:49 -04006947 RValue<UShort8> psrlw(RValue<UShort8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006948 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006949 llvm::Function *psrlw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrli_w);
John Bauman89401822014-05-06 15:04:28 -04006950
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006951 return RValue<UShort8>(V(::builder->CreateCall2(psrlw, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006952 }
6953
John Bauman19bac1e2014-05-06 15:23:49 -04006954 RValue<Short4> psraw(RValue<Short4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006955 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006956 llvm::Function *psraw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrai_w);
John Bauman89401822014-05-06 15:04:28 -04006957
Nicolas Capens70dfff42016-10-27 10:20:28 -04006958 return As<Short4>(V(::builder->CreateCall2(psraw, As<MMX>(x).value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006959 }
6960
John Bauman19bac1e2014-05-06 15:23:49 -04006961 RValue<Short8> psraw(RValue<Short8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006962 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006963 llvm::Function *psraw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrai_w);
John Bauman89401822014-05-06 15:04:28 -04006964
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006965 return RValue<Short8>(V(::builder->CreateCall2(psraw, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006966 }
6967
John Bauman19bac1e2014-05-06 15:23:49 -04006968 RValue<Short4> psllw(RValue<Short4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006969 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006970 llvm::Function *psllw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pslli_w);
John Bauman89401822014-05-06 15:04:28 -04006971
Nicolas Capens70dfff42016-10-27 10:20:28 -04006972 return As<Short4>(V(::builder->CreateCall2(psllw, As<MMX>(x).value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006973 }
6974
John Bauman19bac1e2014-05-06 15:23:49 -04006975 RValue<Short8> psllw(RValue<Short8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006976 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006977 llvm::Function *psllw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pslli_w);
John Bauman89401822014-05-06 15:04:28 -04006978
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006979 return RValue<Short8>(V(::builder->CreateCall2(psllw, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006980 }
6981
John Bauman19bac1e2014-05-06 15:23:49 -04006982 RValue<Int2> pslld(RValue<Int2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006983 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006984 llvm::Function *pslld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pslli_d);
John Bauman89401822014-05-06 15:04:28 -04006985
Nicolas Capens70dfff42016-10-27 10:20:28 -04006986 return As<Int2>(V(::builder->CreateCall2(pslld, As<MMX>(x).value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006987 }
6988
John Bauman19bac1e2014-05-06 15:23:49 -04006989 RValue<Int4> pslld(RValue<Int4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04006990 {
6991 if(CPUID::supportsSSE2())
6992 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04006993 llvm::Function *pslld = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pslli_d);
John Bauman89401822014-05-06 15:04:28 -04006994
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04006995 return RValue<Int4>(V(::builder->CreateCall2(pslld, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04006996 }
6997 else
6998 {
6999 Int2 lo = Int2(x);
7000 Int2 hi = Int2(Swizzle(x, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04007001
John Bauman89401822014-05-06 15:04:28 -04007002 lo = x86::pslld(lo, y);
7003 hi = x86::pslld(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04007004
Nicolas Capens62abb552016-01-05 12:03:47 -05007005 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007006 }
7007 }
7008
John Bauman19bac1e2014-05-06 15:23:49 -04007009 RValue<Int2> psrad(RValue<Int2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007010 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007011 llvm::Function *psrad = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrai_d);
John Bauman89401822014-05-06 15:04:28 -04007012
Nicolas Capens70dfff42016-10-27 10:20:28 -04007013 return As<Int2>(V(::builder->CreateCall2(psrad, As<MMX>(x).value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007014 }
7015
John Bauman19bac1e2014-05-06 15:23:49 -04007016 RValue<Int4> psrad(RValue<Int4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007017 {
7018 if(CPUID::supportsSSE2())
7019 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007020 llvm::Function *psrad = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrai_d);
John Bauman89401822014-05-06 15:04:28 -04007021
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007022 return RValue<Int4>(V(::builder->CreateCall2(psrad, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007023 }
7024 else
7025 {
7026 Int2 lo = Int2(x);
7027 Int2 hi = Int2(Swizzle(x, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04007028
John Bauman89401822014-05-06 15:04:28 -04007029 lo = x86::psrad(lo, y);
7030 hi = x86::psrad(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04007031
Nicolas Capens62abb552016-01-05 12:03:47 -05007032 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007033 }
7034 }
7035
John Bauman19bac1e2014-05-06 15:23:49 -04007036 RValue<UInt2> psrld(RValue<UInt2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007037 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007038 llvm::Function *psrld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrli_d);
John Bauman89401822014-05-06 15:04:28 -04007039
Nicolas Capens70dfff42016-10-27 10:20:28 -04007040 return As<UInt2>(V(::builder->CreateCall2(psrld, As<MMX>(x).value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007041 }
7042
John Bauman19bac1e2014-05-06 15:23:49 -04007043 RValue<UInt4> psrld(RValue<UInt4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007044 {
7045 if(CPUID::supportsSSE2())
7046 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007047 llvm::Function *psrld = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrli_d);
John Bauman89401822014-05-06 15:04:28 -04007048
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007049 return RValue<UInt4>(V(::builder->CreateCall2(psrld, x.value, V(Nucleus::createConstantInt(y)))));
John Bauman89401822014-05-06 15:04:28 -04007050 }
7051 else
7052 {
7053 UInt2 lo = As<UInt2>(Int2(As<Int4>(x)));
7054 UInt2 hi = As<UInt2>(Int2(Swizzle(As<Int4>(x), 0xEE)));
John Bauman66b8ab22014-05-06 15:57:45 -04007055
John Bauman89401822014-05-06 15:04:28 -04007056 lo = x86::psrld(lo, y);
7057 hi = x86::psrld(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04007058
Nicolas Capens62abb552016-01-05 12:03:47 -05007059 return UInt4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007060 }
7061 }
7062
John Bauman19bac1e2014-05-06 15:23:49 -04007063 RValue<Int4> pmaxsd(RValue<Int4> x, RValue<Int4> y)
7064 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007065 llvm::Function *pmaxsd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmaxsd);
John Bauman19bac1e2014-05-06 15:23:49 -04007066
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007067 return RValue<Int4>(V(::builder->CreateCall2(pmaxsd, x.value, y.value)));
John Bauman19bac1e2014-05-06 15:23:49 -04007068 }
7069
7070 RValue<Int4> pminsd(RValue<Int4> x, RValue<Int4> y)
7071 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007072 llvm::Function *pminsd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pminsd);
John Bauman19bac1e2014-05-06 15:23:49 -04007073
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007074 return RValue<Int4>(V(::builder->CreateCall2(pminsd, x.value, y.value)));
John Bauman19bac1e2014-05-06 15:23:49 -04007075 }
7076
7077 RValue<UInt4> pmaxud(RValue<UInt4> x, RValue<UInt4> y)
7078 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007079 llvm::Function *pmaxud = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmaxud);
John Bauman19bac1e2014-05-06 15:23:49 -04007080
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007081 return RValue<UInt4>(V(::builder->CreateCall2(pmaxud, x.value, y.value)));
John Bauman19bac1e2014-05-06 15:23:49 -04007082 }
7083
7084 RValue<UInt4> pminud(RValue<UInt4> x, RValue<UInt4> y)
7085 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007086 llvm::Function *pminud = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pminud);
John Bauman19bac1e2014-05-06 15:23:49 -04007087
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007088 return RValue<UInt4>(V(::builder->CreateCall2(pminud, x.value, y.value)));
John Bauman19bac1e2014-05-06 15:23:49 -04007089 }
7090
7091 RValue<Short4> pmulhw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007092 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007093 llvm::Function *pmulhw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmulh_w);
John Bauman89401822014-05-06 15:04:28 -04007094
Nicolas Capens70dfff42016-10-27 10:20:28 -04007095 return As<Short4>(V(::builder->CreateCall2(pmulhw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007096 }
7097
John Bauman19bac1e2014-05-06 15:23:49 -04007098 RValue<UShort4> pmulhuw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007099 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007100 llvm::Function *pmulhuw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmulhu_w);
John Bauman89401822014-05-06 15:04:28 -04007101
Nicolas Capens70dfff42016-10-27 10:20:28 -04007102 return As<UShort4>(V(::builder->CreateCall2(pmulhuw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007103 }
7104
John Bauman19bac1e2014-05-06 15:23:49 -04007105 RValue<Int2> pmaddwd(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007106 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007107 llvm::Function *pmaddwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmadd_wd);
John Bauman89401822014-05-06 15:04:28 -04007108
Nicolas Capens70dfff42016-10-27 10:20:28 -04007109 return As<Int2>(V(::builder->CreateCall2(pmaddwd, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007110 }
7111
John Bauman19bac1e2014-05-06 15:23:49 -04007112 RValue<Short8> pmulhw(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04007113 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007114 llvm::Function *pmulhw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pmulh_w);
John Bauman89401822014-05-06 15:04:28 -04007115
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007116 return RValue<Short8>(V(::builder->CreateCall2(pmulhw, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04007117 }
7118
John Bauman19bac1e2014-05-06 15:23:49 -04007119 RValue<UShort8> pmulhuw(RValue<UShort8> x, RValue<UShort8> y)
John Bauman89401822014-05-06 15:04:28 -04007120 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007121 llvm::Function *pmulhuw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pmulhu_w);
John Bauman89401822014-05-06 15:04:28 -04007122
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007123 return RValue<UShort8>(V(::builder->CreateCall2(pmulhuw, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04007124 }
7125
John Bauman19bac1e2014-05-06 15:23:49 -04007126 RValue<Int4> pmaddwd(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04007127 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007128 llvm::Function *pmaddwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pmadd_wd);
John Bauman89401822014-05-06 15:04:28 -04007129
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007130 return RValue<Int4>(V(::builder->CreateCall2(pmaddwd, x.value, y.value)));
John Bauman89401822014-05-06 15:04:28 -04007131 }
7132
John Bauman19bac1e2014-05-06 15:23:49 -04007133 RValue<Int> movmskps(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04007134 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007135 llvm::Function *movmskps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_movmsk_ps);
John Bauman89401822014-05-06 15:04:28 -04007136
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007137 return RValue<Int>(V(::builder->CreateCall(movmskps, x.value)));
John Bauman89401822014-05-06 15:04:28 -04007138 }
7139
John Bauman19bac1e2014-05-06 15:23:49 -04007140 RValue<Int> pmovmskb(RValue<Byte8> x)
John Bauman89401822014-05-06 15:04:28 -04007141 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007142 llvm::Function *pmovmskb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmovmskb);
John Bauman89401822014-05-06 15:04:28 -04007143
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007144 return RValue<Int>(V(::builder->CreateCall(pmovmskb, As<MMX>(x).value)));
John Bauman89401822014-05-06 15:04:28 -04007145 }
7146
Nicolas Capens81f18302016-01-14 09:32:35 -05007147 //RValue<Int2> movd(RValue<Pointer<Int>> x)
John Bauman89401822014-05-06 15:04:28 -04007148 //{
7149 // Value *element = Nucleus::createLoad(x.value);
7150
7151 //// Value *int2 = UndefValue::get(Int2::getType());
7152 //// int2 = Nucleus::createInsertElement(int2, element, ConstantInt::get(Int::getType(), 0));
7153
7154 // Value *int2 = Nucleus::createBitCast(Nucleus::createZExt(element, Long::getType()), Int2::getType());
7155
7156 // return RValue<Int2>(int2);
7157 //}
7158
John Bauman19bac1e2014-05-06 15:23:49 -04007159 //RValue<Int2> movdq2q(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007160 //{
Nicolas Capens22008782016-10-20 01:11:47 -04007161 // Value *long2 = Nucleus::createBitCast(x.value, T(VectorType::get(Long::getType(), 2)));
John Bauman89401822014-05-06 15:04:28 -04007162 // Value *element = Nucleus::createExtractElement(long2, ConstantInt::get(Int::getType(), 0));
7163
7164 // return RValue<Int2>(Nucleus::createBitCast(element, Int2::getType()));
7165 //}
7166
John Bauman19bac1e2014-05-06 15:23:49 -04007167 RValue<Int4> pmovzxbd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007168 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007169 llvm::Function *pmovzxbd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovzxbd);
John Bauman66b8ab22014-05-06 15:57:45 -04007170
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007171 return RValue<Int4>(V(::builder->CreateCall(pmovzxbd, Nucleus::createBitCast(x.value, Byte16::getType()))));
John Bauman89401822014-05-06 15:04:28 -04007172 }
7173
John Bauman19bac1e2014-05-06 15:23:49 -04007174 RValue<Int4> pmovsxbd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007175 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007176 llvm::Function *pmovsxbd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovsxbd);
John Bauman66b8ab22014-05-06 15:57:45 -04007177
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007178 return RValue<Int4>(V(::builder->CreateCall(pmovsxbd, Nucleus::createBitCast(x.value, SByte16::getType()))));
John Bauman89401822014-05-06 15:04:28 -04007179 }
7180
John Bauman19bac1e2014-05-06 15:23:49 -04007181 RValue<Int4> pmovzxwd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007182 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007183 llvm::Function *pmovzxwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovzxwd);
John Bauman66b8ab22014-05-06 15:57:45 -04007184
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007185 return RValue<Int4>(V(::builder->CreateCall(pmovzxwd, Nucleus::createBitCast(x.value, UShort8::getType()))));
John Bauman89401822014-05-06 15:04:28 -04007186 }
7187
John Bauman19bac1e2014-05-06 15:23:49 -04007188 RValue<Int4> pmovsxwd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007189 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007190 llvm::Function *pmovsxwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovsxwd);
John Bauman66b8ab22014-05-06 15:57:45 -04007191
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007192 return RValue<Int4>(V(::builder->CreateCall(pmovsxwd, Nucleus::createBitCast(x.value, Short8::getType()))));
John Bauman89401822014-05-06 15:04:28 -04007193 }
7194
7195 void emms()
7196 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007197 llvm::Function *emms = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_emms);
John Bauman89401822014-05-06 15:04:28 -04007198
Nicolas Capens2ab69ee2016-09-26 11:45:17 -04007199 V(::builder->CreateCall(emms));
John Bauman89401822014-05-06 15:04:28 -04007200 }
7201 }
7202}