blob: b1c1ac6c32c60288a5752440cda10a17d5d08c2e [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 Capensd946e0a2014-06-26 11:31:08 -040032#include "Routine.hpp"
Nicolas Capens2fb41102014-06-26 10:11:50 -040033#include "RoutineManager.hpp"
John Bauman89401822014-05-06 15:04:28 -040034#include "x86.hpp"
35#include "CPUID.hpp"
36#include "Thread.hpp"
37#include "Memory.hpp"
38
Nicolas Capens05b3d662016-02-25 23:58:33 -050039#include <xmmintrin.h>
John Bauman89401822014-05-06 15:04:28 -040040#include <fstream>
41
Nicolas Capenscb122582014-05-06 23:34:44 -040042#if defined(__x86_64__) && defined(_WIN32)
John Bauman66b8ab22014-05-06 15:57:45 -040043extern "C" void X86CompilationCallback()
44{
45 assert(false); // UNIMPLEMENTED
46}
47#endif
48
John Bauman89401822014-05-06 15:04:28 -040049extern "C"
50{
51 bool (*CodeAnalystInitialize)() = 0;
52 void (*CodeAnalystCompleteJITLog)() = 0;
53 bool (*CodeAnalystLogJITCode)(const void *jitCodeStartAddr, unsigned int jitCodeSize, const wchar_t *functionName) = 0;
54}
55
56namespace llvm
57{
58 extern bool JITEmitDebugInfo;
59}
60
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -040061namespace
62{
63 sw::RoutineManager *routineManager = nullptr;
64 llvm::ExecutionEngine *executionEngine = nullptr;
65 llvm::IRBuilder<> *builder = nullptr;
66 llvm::LLVMContext *context = nullptr;
67 llvm::Module *module = nullptr;
68 llvm::Function *function = nullptr;
69}
70
John Bauman89401822014-05-06 15:04:28 -040071namespace sw
72{
John Bauman89401822014-05-06 15:04:28 -040073 using namespace llvm;
Nicolas Capensb7ea9842015-04-01 10:54:59 -040074 BackoffLock Nucleus::codegenMutex;
John Bauman89401822014-05-06 15:04:28 -040075
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -040076 Optimization optimization[10] = {InstructionCombining, Disabled};
John Bauman89401822014-05-06 15:04:28 -040077
Nicolas Capensc8b67a42016-09-25 15:02:52 -040078 class Type : public llvm::Type {};
79 class BasicBlock : public llvm::BasicBlock {};
Nicolas Capensac230122016-09-20 14:30:06 -040080
81 inline Type *T(llvm::Type *t)
82 {
83 return reinterpret_cast<Type*>(t);
84 }
85
86 inline std::vector<llvm::Type*> &T(std::vector<Type*> &t)
87 {
88 return reinterpret_cast<std::vector<llvm::Type*>&>(t);
89 }
90
Nicolas Capensc8b67a42016-09-25 15:02:52 -040091 inline BasicBlock *B(llvm::BasicBlock *t)
92 {
93 return reinterpret_cast<BasicBlock*>(t);
94 }
95
John Bauman89401822014-05-06 15:04:28 -040096 Nucleus::Nucleus()
97 {
Nicolas Capensb7ea9842015-04-01 10:54:59 -040098 codegenMutex.lock(); // Reactor and LLVM are currently not thread safe
99
John Bauman19bac1e2014-05-06 15:23:49 -0400100 InitializeNativeTarget();
John Bauman89401822014-05-06 15:04:28 -0400101 JITEmitDebugInfo = false;
102
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400103 if(!::context)
John Bauman89401822014-05-06 15:04:28 -0400104 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400105 ::context = new LLVMContext();
John Bauman89401822014-05-06 15:04:28 -0400106 }
107
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400108 ::module = new Module("", *::context);
109 ::routineManager = new RoutineManager();
John Bauman66b8ab22014-05-06 15:57:45 -0400110
John Bauman89401822014-05-06 15:04:28 -0400111 #if defined(__x86_64__)
112 const char *architecture = "x86-64";
113 #else
114 const char *architecture = "x86";
115 #endif
116
117 SmallVector<std::string, 1> MAttrs;
118 MAttrs.push_back(CPUID::supportsMMX() ? "+mmx" : "-mmx");
119 MAttrs.push_back(CPUID::supportsCMOV() ? "+cmov" : "-cmov");
120 MAttrs.push_back(CPUID::supportsSSE() ? "+sse" : "-sse");
121 MAttrs.push_back(CPUID::supportsSSE2() ? "+sse2" : "-sse2");
122 MAttrs.push_back(CPUID::supportsSSE3() ? "+sse3" : "-sse3");
123 MAttrs.push_back(CPUID::supportsSSSE3() ? "+ssse3" : "-ssse3");
124 MAttrs.push_back(CPUID::supportsSSE4_1() ? "+sse41" : "-sse41");
125
John Bauman19bac1e2014-05-06 15:23:49 -0400126 std::string error;
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400127 TargetMachine *targetMachine = EngineBuilder::selectTarget(::module, architecture, "", MAttrs, Reloc::Default, CodeModel::JITDefault, &error);
128 ::executionEngine = JIT::createJIT(::module, 0, ::routineManager, CodeGenOpt::Aggressive, true, targetMachine);
John Bauman89401822014-05-06 15:04:28 -0400129
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400130 if(!::builder)
John Bauman89401822014-05-06 15:04:28 -0400131 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400132 ::builder = new IRBuilder<>(*::context);
John Bauman89401822014-05-06 15:04:28 -0400133
John Bauman66b8ab22014-05-06 15:57:45 -0400134 #if defined(_WIN32)
135 HMODULE CodeAnalyst = LoadLibrary("CAJitNtfyLib.dll");
136 if(CodeAnalyst)
137 {
138 CodeAnalystInitialize = (bool(*)())GetProcAddress(CodeAnalyst, "CAJIT_Initialize");
139 CodeAnalystCompleteJITLog = (void(*)())GetProcAddress(CodeAnalyst, "CAJIT_CompleteJITLog");
140 CodeAnalystLogJITCode = (bool(*)(const void*, unsigned int, const wchar_t*))GetProcAddress(CodeAnalyst, "CAJIT_LogJITCode");
141
142 CodeAnalystInitialize();
143 }
144 #endif
John Bauman89401822014-05-06 15:04:28 -0400145 }
146 }
147
148 Nucleus::~Nucleus()
149 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400150 delete ::executionEngine;
151 ::executionEngine = nullptr;
John Bauman89401822014-05-06 15:04:28 -0400152
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400153 ::routineManager = nullptr;
154 ::function = nullptr;
155 ::module = nullptr;
Nicolas Capensb7ea9842015-04-01 10:54:59 -0400156
157 codegenMutex.unlock();
John Bauman89401822014-05-06 15:04:28 -0400158 }
159
160 Routine *Nucleus::acquireRoutine(const wchar_t *name, bool runOptimizations)
161 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400162 if(::builder->GetInsertBlock()->empty() || !::builder->GetInsertBlock()->back().isTerminator())
John Bauman19bac1e2014-05-06 15:23:49 -0400163 {
Nicolas Capensac230122016-09-20 14:30:06 -0400164 llvm::Type *type = ::function->getReturnType();
John Bauman19bac1e2014-05-06 15:23:49 -0400165
166 if(type->isVoidTy())
167 {
168 createRetVoid();
169 }
170 else
171 {
172 createRet(UndefValue::get(type));
173 }
174 }
John Bauman89401822014-05-06 15:04:28 -0400175
176 if(false)
177 {
John Bauman66b8ab22014-05-06 15:57:45 -0400178 std::string error;
179 raw_fd_ostream file("llvm-dump-unopt.txt", error);
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400180 ::module->print(file, 0);
John Bauman89401822014-05-06 15:04:28 -0400181 }
182
183 if(runOptimizations)
184 {
185 optimize();
186 }
187
188 if(false)
189 {
John Bauman66b8ab22014-05-06 15:57:45 -0400190 std::string error;
191 raw_fd_ostream file("llvm-dump-opt.txt", error);
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400192 ::module->print(file, 0);
John Bauman89401822014-05-06 15:04:28 -0400193 }
194
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400195 void *entry = ::executionEngine->getPointerToFunction(::function);
196 Routine *routine = ::routineManager->acquireRoutine(entry);
John Bauman89401822014-05-06 15:04:28 -0400197
198 if(CodeAnalystLogJITCode)
199 {
Nicolas Capensd946e0a2014-06-26 11:31:08 -0400200 CodeAnalystLogJITCode(routine->getEntry(), routine->getCodeSize(), name);
John Bauman89401822014-05-06 15:04:28 -0400201 }
202
203 return routine;
204 }
205
206 void Nucleus::optimize()
207 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400208 static PassManager *passManager = nullptr;
John Bauman66b8ab22014-05-06 15:57:45 -0400209
John Bauman89401822014-05-06 15:04:28 -0400210 if(!passManager)
211 {
212 passManager = new PassManager();
213
214 UnsafeFPMath = true;
215 // NoInfsFPMath = true;
216 // NoNaNsFPMath = true;
217
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400218 passManager->add(new TargetData(*::executionEngine->getTargetData()));
John Bauman89401822014-05-06 15:04:28 -0400219 passManager->add(createScalarReplAggregatesPass());
220
221 for(int pass = 0; pass < 10 && optimization[pass] != Disabled; pass++)
222 {
223 switch(optimization[pass])
224 {
225 case Disabled: break;
226 case CFGSimplification: passManager->add(createCFGSimplificationPass()); break;
227 case LICM: passManager->add(createLICMPass()); break;
228 case AggressiveDCE: passManager->add(createAggressiveDCEPass()); break;
229 case GVN: passManager->add(createGVNPass()); break;
230 case InstructionCombining: passManager->add(createInstructionCombiningPass()); break;
231 case Reassociate: passManager->add(createReassociatePass()); break;
232 case DeadStoreElimination: passManager->add(createDeadStoreEliminationPass()); break;
233 case SCCP: passManager->add(createSCCPPass()); break;
John Bauman19bac1e2014-05-06 15:23:49 -0400234 case ScalarReplAggregates: passManager->add(createScalarReplAggregatesPass()); break;
John Bauman89401822014-05-06 15:04:28 -0400235 default:
236 assert(false);
237 }
238 }
239 }
240
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400241 passManager->run(*::module);
John Bauman89401822014-05-06 15:04:28 -0400242 }
243
John Bauman19bac1e2014-05-06 15:23:49 -0400244 Value *Nucleus::allocateStackVariable(Type *type, int arraySize)
John Bauman89401822014-05-06 15:04:28 -0400245 {
246 // Need to allocate it in the entry block for mem2reg to work
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400247 llvm::BasicBlock &entryBlock = ::function->getEntryBlock();
John Bauman89401822014-05-06 15:04:28 -0400248
249 Instruction *declaration;
250
251 if(arraySize)
252 {
253 declaration = new AllocaInst(type, Nucleus::createConstantInt(arraySize));
254 }
255 else
256 {
257 declaration = new AllocaInst(type, (Value*)0);
258 }
259
260 entryBlock.getInstList().push_front(declaration);
261
262 return declaration;
263 }
264
265 BasicBlock *Nucleus::createBasicBlock()
266 {
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400267 return B(BasicBlock::Create(*::context, "", ::function));
John Bauman89401822014-05-06 15:04:28 -0400268 }
269
270 BasicBlock *Nucleus::getInsertBlock()
271 {
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400272 return B(::builder->GetInsertBlock());
John Bauman89401822014-05-06 15:04:28 -0400273 }
274
275 void Nucleus::setInsertBlock(BasicBlock *basicBlock)
276 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400277 // assert(::builder->GetInsertBlock()->back().isTerminator());
278 return ::builder->SetInsertPoint(basicBlock);
John Bauman89401822014-05-06 15:04:28 -0400279 }
280
281 BasicBlock *Nucleus::getPredecessor(BasicBlock *basicBlock)
282 {
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400283 return B(*pred_begin(basicBlock));
John Bauman89401822014-05-06 15:04:28 -0400284 }
285
Nicolas Capensac230122016-09-20 14:30:06 -0400286 void Nucleus::createFunction(Type *ReturnType, std::vector<Type*> &Params)
John Bauman89401822014-05-06 15:04:28 -0400287 {
Nicolas Capensac230122016-09-20 14:30:06 -0400288 llvm::FunctionType *functionType = llvm::FunctionType::get(ReturnType, T(Params), false);
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400289 ::function = llvm::Function::Create(functionType, llvm::GlobalValue::InternalLinkage, "", ::module);
290 ::function->setCallingConv(llvm::CallingConv::C);
John Bauman89401822014-05-06 15:04:28 -0400291
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400292 ::builder->SetInsertPoint(BasicBlock::Create(*::context, "", ::function));
John Bauman89401822014-05-06 15:04:28 -0400293 }
294
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400295 llvm::Value *Nucleus::getArgument(unsigned int index)
John Bauman89401822014-05-06 15:04:28 -0400296 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400297 llvm::Function::arg_iterator args = ::function->arg_begin();
John Bauman89401822014-05-06 15:04:28 -0400298
299 while(index)
300 {
301 args++;
302 index--;
303 }
304
305 return &*args;
306 }
307
308 Value *Nucleus::createRetVoid()
309 {
John Bauman66b8ab22014-05-06 15:57:45 -0400310 x86::emms();
311
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400312 return ::builder->CreateRetVoid();
John Bauman89401822014-05-06 15:04:28 -0400313 }
314
315 Value *Nucleus::createRet(Value *V)
316 {
John Bauman66b8ab22014-05-06 15:57:45 -0400317 x86::emms();
318
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400319 return ::builder->CreateRet(V);
John Bauman89401822014-05-06 15:04:28 -0400320 }
321
322 Value *Nucleus::createBr(BasicBlock *dest)
323 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400324 return ::builder->CreateBr(dest);
John Bauman89401822014-05-06 15:04:28 -0400325 }
326
327 Value *Nucleus::createCondBr(Value *cond, BasicBlock *ifTrue, BasicBlock *ifFalse)
328 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400329 return ::builder->CreateCondBr(cond, ifTrue, ifFalse);
John Bauman89401822014-05-06 15:04:28 -0400330 }
331
332 Value *Nucleus::createAdd(Value *lhs, Value *rhs)
333 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400334 return ::builder->CreateAdd(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400335 }
336
337 Value *Nucleus::createSub(Value *lhs, Value *rhs)
338 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400339 return ::builder->CreateSub(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400340 }
341
342 Value *Nucleus::createMul(Value *lhs, Value *rhs)
343 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400344 return ::builder->CreateMul(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400345 }
346
347 Value *Nucleus::createUDiv(Value *lhs, Value *rhs)
348 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400349 return ::builder->CreateUDiv(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400350 }
351
352 Value *Nucleus::createSDiv(Value *lhs, Value *rhs)
353 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400354 return ::builder->CreateSDiv(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400355 }
356
357 Value *Nucleus::createFAdd(Value *lhs, Value *rhs)
358 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400359 return ::builder->CreateFAdd(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400360 }
361
362 Value *Nucleus::createFSub(Value *lhs, Value *rhs)
363 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400364 return ::builder->CreateFSub(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400365 }
366
367 Value *Nucleus::createFMul(Value *lhs, Value *rhs)
368 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400369 return ::builder->CreateFMul(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400370 }
371
372 Value *Nucleus::createFDiv(Value *lhs, Value *rhs)
373 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400374 return ::builder->CreateFDiv(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400375 }
376
377 Value *Nucleus::createURem(Value *lhs, Value *rhs)
378 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400379 return ::builder->CreateURem(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400380 }
381
382 Value *Nucleus::createSRem(Value *lhs, Value *rhs)
383 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400384 return ::builder->CreateSRem(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400385 }
386
387 Value *Nucleus::createFRem(Value *lhs, Value *rhs)
388 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400389 return ::builder->CreateFRem(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400390 }
391
392 Value *Nucleus::createShl(Value *lhs, Value *rhs)
393 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400394 return ::builder->CreateShl(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400395 }
396
397 Value *Nucleus::createLShr(Value *lhs, Value *rhs)
398 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400399 return ::builder->CreateLShr(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400400 }
401
402 Value *Nucleus::createAShr(Value *lhs, Value *rhs)
403 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400404 return ::builder->CreateAShr(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400405 }
406
407 Value *Nucleus::createAnd(Value *lhs, Value *rhs)
408 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400409 return ::builder->CreateAnd(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400410 }
411
412 Value *Nucleus::createOr(Value *lhs, Value *rhs)
413 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400414 return ::builder->CreateOr(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400415 }
416
417 Value *Nucleus::createXor(Value *lhs, Value *rhs)
418 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400419 return ::builder->CreateXor(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400420 }
421
422 Value *Nucleus::createNeg(Value *V)
423 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400424 return ::builder->CreateNeg(V);
John Bauman89401822014-05-06 15:04:28 -0400425 }
426
427 Value *Nucleus::createFNeg(Value *V)
428 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400429 return ::builder->CreateFNeg(V);
John Bauman89401822014-05-06 15:04:28 -0400430 }
431
432 Value *Nucleus::createNot(Value *V)
433 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400434 return ::builder->CreateNot(V);
John Bauman89401822014-05-06 15:04:28 -0400435 }
436
437 Value *Nucleus::createLoad(Value *ptr, bool isVolatile, unsigned int align)
438 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400439 return ::builder->Insert(new LoadInst(ptr, "", isVolatile, align));
John Bauman89401822014-05-06 15:04:28 -0400440 }
441
442 Value *Nucleus::createStore(Value *value, Value *ptr, bool isVolatile, unsigned int align)
443 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400444 return ::builder->Insert(new StoreInst(value, ptr, isVolatile, align));
John Bauman89401822014-05-06 15:04:28 -0400445 }
446
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400447 Value *Nucleus::createStore(Constant *constant, Value *ptr, bool isVolatile, unsigned int align)
448 {
449 return ::builder->Insert(new StoreInst(constant, ptr, isVolatile, align));
450 }
451
John Bauman89401822014-05-06 15:04:28 -0400452 Value *Nucleus::createGEP(Value *ptr, Value *index)
453 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400454 return ::builder->CreateGEP(ptr, index);
John Bauman89401822014-05-06 15:04:28 -0400455 }
456
John Bauman19bac1e2014-05-06 15:23:49 -0400457 Value *Nucleus::createAtomicAdd(Value *ptr, Value *value)
458 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400459 return ::builder->CreateAtomicRMW(AtomicRMWInst::Add, ptr, value, SequentiallyConsistent);
John Bauman19bac1e2014-05-06 15:23:49 -0400460 }
461
462 Value *Nucleus::createTrunc(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400463 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400464 return ::builder->CreateTrunc(V, destType);
John Bauman89401822014-05-06 15:04:28 -0400465 }
466
John Bauman19bac1e2014-05-06 15:23:49 -0400467 Value *Nucleus::createZExt(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400468 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400469 return ::builder->CreateZExt(V, destType);
John Bauman89401822014-05-06 15:04:28 -0400470 }
471
John Bauman19bac1e2014-05-06 15:23:49 -0400472 Value *Nucleus::createSExt(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400473 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400474 return ::builder->CreateSExt(V, destType);
John Bauman89401822014-05-06 15:04:28 -0400475 }
476
John Bauman19bac1e2014-05-06 15:23:49 -0400477 Value *Nucleus::createFPToSI(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400478 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400479 return ::builder->CreateFPToSI(V, destType);
John Bauman89401822014-05-06 15:04:28 -0400480 }
481
John Bauman19bac1e2014-05-06 15:23:49 -0400482 Value *Nucleus::createUIToFP(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400483 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400484 return ::builder->CreateUIToFP(V, destType);
John Bauman89401822014-05-06 15:04:28 -0400485 }
486
John Bauman19bac1e2014-05-06 15:23:49 -0400487 Value *Nucleus::createSIToFP(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400488 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400489 return ::builder->CreateSIToFP(V, destType);
John Bauman89401822014-05-06 15:04:28 -0400490 }
491
John Bauman19bac1e2014-05-06 15:23:49 -0400492 Value *Nucleus::createFPTrunc(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400493 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400494 return ::builder->CreateFPTrunc(V, destType);
John Bauman89401822014-05-06 15:04:28 -0400495 }
496
John Bauman19bac1e2014-05-06 15:23:49 -0400497 Value *Nucleus::createFPExt(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400498 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400499 return ::builder->CreateFPExt(V, destType);
John Bauman89401822014-05-06 15:04:28 -0400500 }
501
John Bauman19bac1e2014-05-06 15:23:49 -0400502 Value *Nucleus::createPtrToInt(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400503 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400504 return ::builder->CreatePtrToInt(V, destType);
John Bauman89401822014-05-06 15:04:28 -0400505 }
506
John Bauman19bac1e2014-05-06 15:23:49 -0400507 Value *Nucleus::createIntToPtr(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400508 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400509 return ::builder->CreateIntToPtr(V, destType);
John Bauman89401822014-05-06 15:04:28 -0400510 }
511
John Bauman19bac1e2014-05-06 15:23:49 -0400512 Value *Nucleus::createBitCast(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400513 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400514 return ::builder->CreateBitCast(V, destType);
John Bauman89401822014-05-06 15:04:28 -0400515 }
516
John Bauman19bac1e2014-05-06 15:23:49 -0400517 Value *Nucleus::createIntCast(Value *V, Type *destType, bool isSigned)
John Bauman89401822014-05-06 15:04:28 -0400518 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400519 return ::builder->CreateIntCast(V, destType, isSigned);
John Bauman89401822014-05-06 15:04:28 -0400520 }
521
522 Value *Nucleus::createICmpEQ(Value *lhs, Value *rhs)
523 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400524 return ::builder->CreateICmpEQ(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400525 }
526
527 Value *Nucleus::createICmpNE(Value *lhs, Value *rhs)
528 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400529 return ::builder->CreateICmpNE(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400530 }
531
532 Value *Nucleus::createICmpUGT(Value *lhs, Value *rhs)
533 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400534 return ::builder->CreateICmpUGT(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400535 }
536
537 Value *Nucleus::createICmpUGE(Value *lhs, Value *rhs)
538 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400539 return ::builder->CreateICmpUGE(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400540 }
541
542 Value *Nucleus::createICmpULT(Value *lhs, Value *rhs)
543 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400544 return ::builder->CreateICmpULT(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400545 }
546
547 Value *Nucleus::createICmpULE(Value *lhs, Value *rhs)
548 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400549 return ::builder->CreateICmpULE(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400550 }
551
552 Value *Nucleus::createICmpSGT(Value *lhs, Value *rhs)
553 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400554 return ::builder->CreateICmpSGT(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400555 }
556
557 Value *Nucleus::createICmpSGE(Value *lhs, Value *rhs)
558 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400559 return ::builder->CreateICmpSGE(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400560 }
561
562 Value *Nucleus::createICmpSLT(Value *lhs, Value *rhs)
563 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400564 return ::builder->CreateICmpSLT(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400565 }
566
567 Value *Nucleus::createICmpSLE(Value *lhs, Value *rhs)
568 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400569 return ::builder->CreateICmpSLE(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400570 }
571
572 Value *Nucleus::createFCmpOEQ(Value *lhs, Value *rhs)
573 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400574 return ::builder->CreateFCmpOEQ(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400575 }
576
577 Value *Nucleus::createFCmpOGT(Value *lhs, Value *rhs)
578 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400579 return ::builder->CreateFCmpOGT(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400580 }
581
582 Value *Nucleus::createFCmpOGE(Value *lhs, Value *rhs)
583 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400584 return ::builder->CreateFCmpOGE(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400585 }
586
587 Value *Nucleus::createFCmpOLT(Value *lhs, Value *rhs)
588 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400589 return ::builder->CreateFCmpOLT(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400590 }
591
592 Value *Nucleus::createFCmpOLE(Value *lhs, Value *rhs)
593 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400594 return ::builder->CreateFCmpOLE(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400595 }
596
597 Value *Nucleus::createFCmpONE(Value *lhs, Value *rhs)
598 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400599 return ::builder->CreateFCmpONE(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400600 }
601
602 Value *Nucleus::createFCmpORD(Value *lhs, Value *rhs)
603 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400604 return ::builder->CreateFCmpORD(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400605 }
606
607 Value *Nucleus::createFCmpUNO(Value *lhs, Value *rhs)
608 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400609 return ::builder->CreateFCmpUNO(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400610 }
611
612 Value *Nucleus::createFCmpUEQ(Value *lhs, Value *rhs)
613 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400614 return ::builder->CreateFCmpUEQ(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400615 }
616
617 Value *Nucleus::createFCmpUGT(Value *lhs, Value *rhs)
618 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400619 return ::builder->CreateFCmpUGT(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400620 }
621
622 Value *Nucleus::createFCmpUGE(Value *lhs, Value *rhs)
623 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400624 return ::builder->CreateFCmpUGE(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400625 }
626
627 Value *Nucleus::createFCmpULT(Value *lhs, Value *rhs)
628 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400629 return ::builder->CreateFCmpULT(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400630 }
631
632 Value *Nucleus::createFCmpULE(Value *lhs, Value *rhs)
633 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400634 return ::builder->CreateFCmpULE(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400635 }
636
637 Value *Nucleus::createFCmpUNE(Value *lhs, Value *rhs)
638 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400639 return ::builder->CreateFCmpULE(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400640 }
641
642 Value *Nucleus::createCall(Value *callee)
643 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400644 return ::builder->CreateCall(callee);
John Bauman89401822014-05-06 15:04:28 -0400645 }
646
647 Value *Nucleus::createCall(Value *callee, Value *arg)
648 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400649 return ::builder->CreateCall(callee, arg);
John Bauman89401822014-05-06 15:04:28 -0400650 }
651
652 Value *Nucleus::createCall(Value *callee, Value *arg1, Value *arg2)
653 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400654 return ::builder->CreateCall2(callee, arg1, arg2);
John Bauman89401822014-05-06 15:04:28 -0400655 }
656
657 Value *Nucleus::createCall(Value *callee, Value *arg1, Value *arg2, Value *arg3)
658 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400659 return ::builder->CreateCall3(callee, arg1, arg2, arg3);
John Bauman89401822014-05-06 15:04:28 -0400660 }
661
662 Value *Nucleus::createCall(Value *callee, Value *arg1, Value *arg2, Value *arg3, Value *arg4)
663 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400664 return ::builder->CreateCall4(callee, arg1, arg2, arg3, arg4);
John Bauman89401822014-05-06 15:04:28 -0400665 }
666
667 Value *Nucleus::createExtractElement(Value *vector, int index)
668 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400669 return ::builder->CreateExtractElement(vector, createConstantInt(index));
John Bauman89401822014-05-06 15:04:28 -0400670 }
671
672 Value *Nucleus::createInsertElement(Value *vector, Value *element, int index)
673 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400674 return ::builder->CreateInsertElement(vector, element, createConstantInt(index));
John Bauman89401822014-05-06 15:04:28 -0400675 }
676
677 Value *Nucleus::createShuffleVector(Value *V1, Value *V2, Value *mask)
678 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400679 return ::builder->CreateShuffleVector(V1, V2, mask);
John Bauman89401822014-05-06 15:04:28 -0400680 }
681
682 Value *Nucleus::createSelect(Value *C, Value *ifTrue, Value *ifFalse)
683 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400684 return ::builder->CreateSelect(C, ifTrue, ifFalse);
John Bauman89401822014-05-06 15:04:28 -0400685 }
686
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400687 Value *Nucleus::createSwitch(llvm::Value *V, BasicBlock *Dest, unsigned NumCases)
John Bauman89401822014-05-06 15:04:28 -0400688 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400689 return ::builder->CreateSwitch(V, Dest, NumCases);
John Bauman89401822014-05-06 15:04:28 -0400690 }
691
Nicolas Capensc8b67a42016-09-25 15:02:52 -0400692 void Nucleus::addSwitchCase(llvm::Value *Switch, int Case, BasicBlock *Branch)
John Bauman89401822014-05-06 15:04:28 -0400693 {
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400694 static_cast<SwitchInst*>(Switch)->addCase(llvm::ConstantInt::get(Type::getInt32Ty(*::context), Case, true), Branch);
John Bauman89401822014-05-06 15:04:28 -0400695 }
696
697 Value *Nucleus::createUnreachable()
698 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400699 return ::builder->CreateUnreachable();
John Bauman89401822014-05-06 15:04:28 -0400700 }
701
702 Value *Nucleus::createSwizzle(Value *val, unsigned char select)
703 {
704 Constant *swizzle[4];
705 swizzle[0] = Nucleus::createConstantInt((select >> 0) & 0x03);
706 swizzle[1] = Nucleus::createConstantInt((select >> 2) & 0x03);
707 swizzle[2] = Nucleus::createConstantInt((select >> 4) & 0x03);
708 swizzle[3] = Nucleus::createConstantInt((select >> 6) & 0x03);
709
710 Value *shuffle = Nucleus::createShuffleVector(val, UndefValue::get(val->getType()), Nucleus::createConstantVector(swizzle, 4));
711
712 return shuffle;
713 }
714
715 Value *Nucleus::createMask(Value *lhs, Value *rhs, unsigned char select)
716 {
717 bool mask[4] = {false, false, false, false};
718
719 mask[(select >> 0) & 0x03] = true;
720 mask[(select >> 2) & 0x03] = true;
721 mask[(select >> 4) & 0x03] = true;
722 mask[(select >> 6) & 0x03] = true;
723
724 Constant *swizzle[4];
725 swizzle[0] = Nucleus::createConstantInt(mask[0] ? 4 : 0);
726 swizzle[1] = Nucleus::createConstantInt(mask[1] ? 5 : 1);
727 swizzle[2] = Nucleus::createConstantInt(mask[2] ? 6 : 2);
728 swizzle[3] = Nucleus::createConstantInt(mask[3] ? 7 : 3);
729
730 Value *shuffle = Nucleus::createShuffleVector(lhs, rhs, Nucleus::createConstantVector(swizzle, 4));
731
732 return shuffle;
733 }
734
Nicolas Capensac230122016-09-20 14:30:06 -0400735 llvm::Constant *Nucleus::createConstantPointer(const void *address, Type *Ty, bool isConstant, unsigned int Align)
John Bauman89401822014-05-06 15:04:28 -0400736 {
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400737 const GlobalValue *existingGlobal = ::executionEngine->getGlobalValueAtAddress(const_cast<void*>(address)); // FIXME: Const
John Bauman89401822014-05-06 15:04:28 -0400738
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400739 if(existingGlobal)
740 {
741 return (llvm::Constant*)existingGlobal;
742 }
John Bauman89401822014-05-06 15:04:28 -0400743
Nicolas Capensac230122016-09-20 14:30:06 -0400744 llvm::GlobalValue *global = new llvm::GlobalVariable(*::module, Ty, isConstant, llvm::GlobalValue::ExternalLinkage, 0, "");
745
John Bauman89401822014-05-06 15:04:28 -0400746 global->setAlignment(Align);
747
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400748 ::executionEngine->addGlobalMapping(global, const_cast<void*>(address));
749
John Bauman89401822014-05-06 15:04:28 -0400750 return global;
751 }
752
Nicolas Capensac230122016-09-20 14:30:06 -0400753 Type *Nucleus::getPointerType(Type *ElementType)
John Bauman89401822014-05-06 15:04:28 -0400754 {
Nicolas Capensac230122016-09-20 14:30:06 -0400755 return T(llvm::PointerType::get(ElementType, 0));
John Bauman89401822014-05-06 15:04:28 -0400756 }
757
Nicolas Capensac230122016-09-20 14:30:06 -0400758 llvm::Constant *Nucleus::createNullValue(Type *Ty)
John Bauman89401822014-05-06 15:04:28 -0400759 {
760 return llvm::Constant::getNullValue(Ty);
761 }
762
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400763 llvm::Constant *Nucleus::createConstantInt(int64_t i)
John Bauman89401822014-05-06 15:04:28 -0400764 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400765 return llvm::ConstantInt::get(Type::getInt64Ty(*::context), i, true);
John Bauman89401822014-05-06 15:04:28 -0400766 }
767
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400768 llvm::Constant *Nucleus::createConstantInt(int i)
John Bauman89401822014-05-06 15:04:28 -0400769 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400770 return llvm::ConstantInt::get(Type::getInt32Ty(*::context), i, true);
John Bauman89401822014-05-06 15:04:28 -0400771 }
772
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400773 llvm::Constant *Nucleus::createConstantInt(unsigned int i)
John Bauman89401822014-05-06 15:04:28 -0400774 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400775 return llvm::ConstantInt::get(Type::getInt32Ty(*::context), i, false);
John Bauman89401822014-05-06 15:04:28 -0400776 }
777
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400778 llvm::Constant *Nucleus::createConstantBool(bool b)
John Bauman89401822014-05-06 15:04:28 -0400779 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400780 return llvm::ConstantInt::get(Type::getInt1Ty(*::context), b);
John Bauman89401822014-05-06 15:04:28 -0400781 }
782
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400783 llvm::Constant *Nucleus::createConstantByte(signed char i)
John Bauman89401822014-05-06 15:04:28 -0400784 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400785 return llvm::ConstantInt::get(Type::getInt8Ty(*::context), i, true);
John Bauman89401822014-05-06 15:04:28 -0400786 }
787
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400788 llvm::Constant *Nucleus::createConstantByte(unsigned char i)
John Bauman89401822014-05-06 15:04:28 -0400789 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400790 return llvm::ConstantInt::get(Type::getInt8Ty(*::context), i, false);
John Bauman89401822014-05-06 15:04:28 -0400791 }
792
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400793 llvm::Constant *Nucleus::createConstantShort(short i)
John Bauman89401822014-05-06 15:04:28 -0400794 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400795 return llvm::ConstantInt::get(Type::getInt16Ty(*::context), i, true);
John Bauman89401822014-05-06 15:04:28 -0400796 }
797
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400798 llvm::Constant *Nucleus::createConstantShort(unsigned short i)
John Bauman89401822014-05-06 15:04:28 -0400799 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400800 return llvm::ConstantInt::get(Type::getInt16Ty(*::context), i, false);
John Bauman89401822014-05-06 15:04:28 -0400801 }
802
803 llvm::Constant *Nucleus::createConstantFloat(float x)
804 {
805 return ConstantFP::get(Float::getType(), x);
806 }
807
Nicolas Capensac230122016-09-20 14:30:06 -0400808 llvm::Value *Nucleus::createNullPointer(Type *Ty)
John Bauman89401822014-05-06 15:04:28 -0400809 {
810 return llvm::ConstantPointerNull::get(llvm::PointerType::get(Ty, 0));
811 }
812
John Bauman19bac1e2014-05-06 15:23:49 -0400813 llvm::Value *Nucleus::createConstantVector(llvm::Constant *const *Vals, unsigned NumVals)
John Bauman89401822014-05-06 15:04:28 -0400814 {
John Bauman19bac1e2014-05-06 15:23:49 -0400815 return llvm::ConstantVector::get(llvm::ArrayRef<llvm::Constant*>(Vals, NumVals));
John Bauman89401822014-05-06 15:04:28 -0400816 }
817
John Bauman19bac1e2014-05-06 15:23:49 -0400818 Type *Void::getType()
John Bauman89401822014-05-06 15:04:28 -0400819 {
Nicolas Capensac230122016-09-20 14:30:06 -0400820 return T(llvm::Type::getVoidTy(*::context));
John Bauman89401822014-05-06 15:04:28 -0400821 }
822
Nicolas Capensac230122016-09-20 14:30:06 -0400823 LValue::LValue(Type *type, int arraySize)
John Bauman66b8ab22014-05-06 15:57:45 -0400824 {
825 address = Nucleus::allocateStackVariable(type, arraySize);
826 }
827
828 llvm::Value *LValue::loadValue(unsigned int alignment) const
829 {
830 return Nucleus::createLoad(address, false, alignment);
831 }
832
833 llvm::Value *LValue::storeValue(llvm::Value *value, unsigned int alignment) const
834 {
835 return Nucleus::createStore(value, address, false, alignment);
836 }
837
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400838 llvm::Value *LValue::storeValue(llvm::Constant *constant, unsigned int alignment) const
839 {
840 return Nucleus::createStore(constant, address, false, alignment);
841 }
842
John Bauman66b8ab22014-05-06 15:57:45 -0400843 llvm::Value *LValue::getAddress(llvm::Value *index) const
844 {
845 return Nucleus::createGEP(address, index);
846 }
847
Nicolas Capens4f738a12016-09-20 15:46:16 -0400848 class MMX : public Variable<MMX>
849 {
850 public:
851 static Type *getType();
852 };
853
John Bauman19bac1e2014-05-06 15:23:49 -0400854 Type *MMX::getType()
855 {
Nicolas Capensac230122016-09-20 14:30:06 -0400856 return T(llvm::Type::getX86_MMXTy(*::context));
John Bauman19bac1e2014-05-06 15:23:49 -0400857 }
858
Nicolas Capens81f18302016-01-14 09:32:35 -0500859 Bool::Bool(Argument<Bool> argument)
John Bauman89401822014-05-06 15:04:28 -0400860 {
Nicolas Capens81f18302016-01-14 09:32:35 -0500861 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -0400862 }
863
864 Bool::Bool()
865 {
John Bauman89401822014-05-06 15:04:28 -0400866 }
867
868 Bool::Bool(bool x)
869 {
John Bauman66b8ab22014-05-06 15:57:45 -0400870 storeValue(Nucleus::createConstantBool(x));
John Bauman89401822014-05-06 15:04:28 -0400871 }
872
John Bauman19bac1e2014-05-06 15:23:49 -0400873 Bool::Bool(RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400874 {
John Bauman66b8ab22014-05-06 15:57:45 -0400875 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400876 }
877
878 Bool::Bool(const Bool &rhs)
879 {
John Bauman66b8ab22014-05-06 15:57:45 -0400880 Value *value = rhs.loadValue();
881 storeValue(value);
882 }
John Bauman89401822014-05-06 15:04:28 -0400883
John Bauman66b8ab22014-05-06 15:57:45 -0400884 Bool::Bool(const Reference<Bool> &rhs)
885 {
886 Value *value = rhs.loadValue();
887 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400888 }
889
John Bauman19bac1e2014-05-06 15:23:49 -0400890 RValue<Bool> Bool::operator=(RValue<Bool> rhs) const
John Bauman89401822014-05-06 15:04:28 -0400891 {
John Bauman66b8ab22014-05-06 15:57:45 -0400892 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400893
894 return rhs;
895 }
896
897 RValue<Bool> Bool::operator=(const Bool &rhs) const
898 {
John Bauman66b8ab22014-05-06 15:57:45 -0400899 Value *value = rhs.loadValue();
900 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400901
902 return RValue<Bool>(value);
903 }
904
John Bauman66b8ab22014-05-06 15:57:45 -0400905 RValue<Bool> Bool::operator=(const Reference<Bool> &rhs) const
John Bauman89401822014-05-06 15:04:28 -0400906 {
John Bauman66b8ab22014-05-06 15:57:45 -0400907 Value *value = rhs.loadValue();
908 storeValue(value);
909
910 return RValue<Bool>(value);
John Bauman89401822014-05-06 15:04:28 -0400911 }
912
John Bauman19bac1e2014-05-06 15:23:49 -0400913 RValue<Bool> operator!(RValue<Bool> val)
John Bauman89401822014-05-06 15:04:28 -0400914 {
915 return RValue<Bool>(Nucleus::createNot(val.value));
916 }
917
John Bauman19bac1e2014-05-06 15:23:49 -0400918 RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400919 {
920 return RValue<Bool>(Nucleus::createAnd(lhs.value, rhs.value));
921 }
922
John Bauman19bac1e2014-05-06 15:23:49 -0400923 RValue<Bool> operator||(RValue<Bool> lhs, RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400924 {
925 return RValue<Bool>(Nucleus::createOr(lhs.value, rhs.value));
926 }
927
John Bauman19bac1e2014-05-06 15:23:49 -0400928 Type *Bool::getType()
John Bauman89401822014-05-06 15:04:28 -0400929 {
Nicolas Capensac230122016-09-20 14:30:06 -0400930 return T(llvm::Type::getInt1Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -0400931 }
932
Nicolas Capens81f18302016-01-14 09:32:35 -0500933 Byte::Byte(Argument<Byte> argument)
John Bauman89401822014-05-06 15:04:28 -0400934 {
Nicolas Capens81f18302016-01-14 09:32:35 -0500935 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -0400936 }
937
John Bauman19bac1e2014-05-06 15:23:49 -0400938 Byte::Byte(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -0400939 {
John Bauman89401822014-05-06 15:04:28 -0400940 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
941
John Bauman66b8ab22014-05-06 15:57:45 -0400942 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -0400943 }
944
Alexis Hetu77dfab42015-11-23 13:31:22 -0500945 Byte::Byte(RValue<UInt> cast)
946 {
947 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
948
949 storeValue(integer);
950 }
951
952 Byte::Byte(RValue<UShort> cast)
953 {
954 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
955
956 storeValue(integer);
957 }
958
John Bauman89401822014-05-06 15:04:28 -0400959 Byte::Byte()
960 {
John Bauman89401822014-05-06 15:04:28 -0400961 }
962
963 Byte::Byte(int x)
964 {
John Bauman66b8ab22014-05-06 15:57:45 -0400965 storeValue(Nucleus::createConstantByte((unsigned char)x));
John Bauman89401822014-05-06 15:04:28 -0400966 }
967
968 Byte::Byte(unsigned char x)
969 {
John Bauman66b8ab22014-05-06 15:57:45 -0400970 storeValue(Nucleus::createConstantByte(x));
John Bauman89401822014-05-06 15:04:28 -0400971 }
972
John Bauman19bac1e2014-05-06 15:23:49 -0400973 Byte::Byte(RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400974 {
John Bauman66b8ab22014-05-06 15:57:45 -0400975 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400976 }
977
978 Byte::Byte(const Byte &rhs)
979 {
John Bauman66b8ab22014-05-06 15:57:45 -0400980 Value *value = rhs.loadValue();
981 storeValue(value);
982 }
John Bauman89401822014-05-06 15:04:28 -0400983
John Bauman66b8ab22014-05-06 15:57:45 -0400984 Byte::Byte(const Reference<Byte> &rhs)
985 {
986 Value *value = rhs.loadValue();
987 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400988 }
989
John Bauman19bac1e2014-05-06 15:23:49 -0400990 RValue<Byte> Byte::operator=(RValue<Byte> rhs) const
John Bauman89401822014-05-06 15:04:28 -0400991 {
John Bauman66b8ab22014-05-06 15:57:45 -0400992 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400993
994 return rhs;
995 }
996
997 RValue<Byte> Byte::operator=(const Byte &rhs) const
998 {
John Bauman66b8ab22014-05-06 15:57:45 -0400999 Value *value = rhs.loadValue();
1000 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001001
1002 return RValue<Byte>(value);
1003 }
1004
John Bauman66b8ab22014-05-06 15:57:45 -04001005 RValue<Byte> Byte::operator=(const Reference<Byte> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04001006 {
John Bauman66b8ab22014-05-06 15:57:45 -04001007 Value *value = rhs.loadValue();
1008 storeValue(value);
1009
1010 return RValue<Byte>(value);
John Bauman89401822014-05-06 15:04:28 -04001011 }
1012
John Bauman19bac1e2014-05-06 15:23:49 -04001013 RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001014 {
1015 return RValue<Byte>(Nucleus::createAdd(lhs.value, rhs.value));
1016 }
1017
John Bauman19bac1e2014-05-06 15:23:49 -04001018 RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001019 {
1020 return RValue<Byte>(Nucleus::createSub(lhs.value, rhs.value));
1021 }
1022
John Bauman19bac1e2014-05-06 15:23:49 -04001023 RValue<Byte> operator*(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001024 {
1025 return RValue<Byte>(Nucleus::createMul(lhs.value, rhs.value));
1026 }
1027
John Bauman19bac1e2014-05-06 15:23:49 -04001028 RValue<Byte> operator/(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001029 {
1030 return RValue<Byte>(Nucleus::createUDiv(lhs.value, rhs.value));
1031 }
1032
John Bauman19bac1e2014-05-06 15:23:49 -04001033 RValue<Byte> operator%(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001034 {
1035 return RValue<Byte>(Nucleus::createURem(lhs.value, rhs.value));
1036 }
1037
John Bauman19bac1e2014-05-06 15:23:49 -04001038 RValue<Byte> operator&(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001039 {
1040 return RValue<Byte>(Nucleus::createAnd(lhs.value, rhs.value));
1041 }
1042
John Bauman19bac1e2014-05-06 15:23:49 -04001043 RValue<Byte> operator|(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001044 {
1045 return RValue<Byte>(Nucleus::createOr(lhs.value, rhs.value));
1046 }
1047
John Bauman19bac1e2014-05-06 15:23:49 -04001048 RValue<Byte> operator^(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001049 {
1050 return RValue<Byte>(Nucleus::createXor(lhs.value, rhs.value));
1051 }
1052
John Bauman19bac1e2014-05-06 15:23:49 -04001053 RValue<Byte> operator<<(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001054 {
1055 return RValue<Byte>(Nucleus::createShl(lhs.value, rhs.value));
1056 }
1057
John Bauman19bac1e2014-05-06 15:23:49 -04001058 RValue<Byte> operator>>(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001059 {
1060 return RValue<Byte>(Nucleus::createLShr(lhs.value, rhs.value));
1061 }
1062
John Bauman19bac1e2014-05-06 15:23:49 -04001063 RValue<Byte> operator+=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001064 {
1065 return lhs = lhs + rhs;
1066 }
1067
John Bauman19bac1e2014-05-06 15:23:49 -04001068 RValue<Byte> operator-=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001069 {
1070 return lhs = lhs - rhs;
1071 }
1072
John Bauman19bac1e2014-05-06 15:23:49 -04001073 RValue<Byte> operator*=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001074 {
1075 return lhs = lhs * rhs;
1076 }
1077
John Bauman19bac1e2014-05-06 15:23:49 -04001078 RValue<Byte> operator/=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001079 {
1080 return lhs = lhs / rhs;
1081 }
1082
John Bauman19bac1e2014-05-06 15:23:49 -04001083 RValue<Byte> operator%=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001084 {
1085 return lhs = lhs % rhs;
1086 }
1087
John Bauman19bac1e2014-05-06 15:23:49 -04001088 RValue<Byte> operator&=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001089 {
1090 return lhs = lhs & rhs;
1091 }
1092
John Bauman19bac1e2014-05-06 15:23:49 -04001093 RValue<Byte> operator|=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001094 {
1095 return lhs = lhs | rhs;
1096 }
1097
John Bauman19bac1e2014-05-06 15:23:49 -04001098 RValue<Byte> operator^=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001099 {
1100 return lhs = lhs ^ rhs;
1101 }
1102
John Bauman19bac1e2014-05-06 15:23:49 -04001103 RValue<Byte> operator<<=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001104 {
1105 return lhs = lhs << rhs;
1106 }
1107
John Bauman19bac1e2014-05-06 15:23:49 -04001108 RValue<Byte> operator>>=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001109 {
1110 return lhs = lhs >> rhs;
1111 }
1112
John Bauman19bac1e2014-05-06 15:23:49 -04001113 RValue<Byte> operator+(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001114 {
1115 return val;
1116 }
1117
John Bauman19bac1e2014-05-06 15:23:49 -04001118 RValue<Byte> operator-(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001119 {
1120 return RValue<Byte>(Nucleus::createNeg(val.value));
1121 }
1122
John Bauman19bac1e2014-05-06 15:23:49 -04001123 RValue<Byte> operator~(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001124 {
1125 return RValue<Byte>(Nucleus::createNot(val.value));
1126 }
1127
1128 RValue<Byte> operator++(const Byte &val, int) // Post-increment
1129 {
1130 RValue<Byte> res = val;
1131
1132 Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantByte((unsigned char)1));
John Bauman66b8ab22014-05-06 15:57:45 -04001133 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001134
1135 return res;
1136 }
1137
1138 const Byte &operator++(const Byte &val) // Pre-increment
1139 {
John Bauman66b8ab22014-05-06 15:57:45 -04001140 Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantByte((unsigned char)1));
1141 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001142
1143 return val;
1144 }
1145
1146 RValue<Byte> operator--(const Byte &val, int) // Post-decrement
1147 {
1148 RValue<Byte> res = val;
1149
1150 Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantByte((unsigned char)1));
John Bauman66b8ab22014-05-06 15:57:45 -04001151 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001152
1153 return res;
1154 }
1155
1156 const Byte &operator--(const Byte &val) // Pre-decrement
1157 {
John Bauman66b8ab22014-05-06 15:57:45 -04001158 Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantByte((unsigned char)1));
1159 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001160
1161 return val;
1162 }
1163
John Bauman19bac1e2014-05-06 15:23:49 -04001164 RValue<Bool> operator<(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001165 {
1166 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1167 }
1168
John Bauman19bac1e2014-05-06 15:23:49 -04001169 RValue<Bool> operator<=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001170 {
1171 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1172 }
1173
John Bauman19bac1e2014-05-06 15:23:49 -04001174 RValue<Bool> operator>(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001175 {
1176 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1177 }
1178
John Bauman19bac1e2014-05-06 15:23:49 -04001179 RValue<Bool> operator>=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001180 {
1181 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1182 }
1183
John Bauman19bac1e2014-05-06 15:23:49 -04001184 RValue<Bool> operator!=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001185 {
1186 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1187 }
1188
John Bauman19bac1e2014-05-06 15:23:49 -04001189 RValue<Bool> operator==(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001190 {
1191 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1192 }
1193
John Bauman19bac1e2014-05-06 15:23:49 -04001194 Type *Byte::getType()
John Bauman89401822014-05-06 15:04:28 -04001195 {
Nicolas Capensac230122016-09-20 14:30:06 -04001196 return T(llvm::Type::getInt8Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001197 }
1198
Nicolas Capens81f18302016-01-14 09:32:35 -05001199 SByte::SByte(Argument<SByte> argument)
John Bauman89401822014-05-06 15:04:28 -04001200 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001201 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001202 }
1203
Alexis Hetu77dfab42015-11-23 13:31:22 -05001204 SByte::SByte(RValue<Int> cast)
1205 {
1206 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1207
1208 storeValue(integer);
1209 }
1210
1211 SByte::SByte(RValue<Short> cast)
1212 {
1213 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1214
1215 storeValue(integer);
1216 }
1217
John Bauman89401822014-05-06 15:04:28 -04001218 SByte::SByte()
1219 {
John Bauman89401822014-05-06 15:04:28 -04001220 }
1221
1222 SByte::SByte(signed char x)
1223 {
John Bauman66b8ab22014-05-06 15:57:45 -04001224 storeValue(Nucleus::createConstantByte(x));
John Bauman89401822014-05-06 15:04:28 -04001225 }
1226
John Bauman19bac1e2014-05-06 15:23:49 -04001227 SByte::SByte(RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001228 {
John Bauman66b8ab22014-05-06 15:57:45 -04001229 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001230 }
1231
1232 SByte::SByte(const SByte &rhs)
1233 {
John Bauman66b8ab22014-05-06 15:57:45 -04001234 Value *value = rhs.loadValue();
1235 storeValue(value);
1236 }
John Bauman89401822014-05-06 15:04:28 -04001237
John Bauman66b8ab22014-05-06 15:57:45 -04001238 SByte::SByte(const Reference<SByte> &rhs)
1239 {
1240 Value *value = rhs.loadValue();
1241 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001242 }
1243
John Bauman19bac1e2014-05-06 15:23:49 -04001244 RValue<SByte> SByte::operator=(RValue<SByte> rhs) const
John Bauman89401822014-05-06 15:04:28 -04001245 {
John Bauman66b8ab22014-05-06 15:57:45 -04001246 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001247
1248 return rhs;
1249 }
1250
1251 RValue<SByte> SByte::operator=(const SByte &rhs) const
1252 {
John Bauman66b8ab22014-05-06 15:57:45 -04001253 Value *value = rhs.loadValue();
1254 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001255
1256 return RValue<SByte>(value);
1257 }
1258
John Bauman66b8ab22014-05-06 15:57:45 -04001259 RValue<SByte> SByte::operator=(const Reference<SByte> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04001260 {
John Bauman66b8ab22014-05-06 15:57:45 -04001261 Value *value = rhs.loadValue();
1262 storeValue(value);
1263
1264 return RValue<SByte>(value);
John Bauman89401822014-05-06 15:04:28 -04001265 }
1266
John Bauman19bac1e2014-05-06 15:23:49 -04001267 RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001268 {
1269 return RValue<SByte>(Nucleus::createAdd(lhs.value, rhs.value));
1270 }
1271
John Bauman19bac1e2014-05-06 15:23:49 -04001272 RValue<SByte> operator-(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001273 {
1274 return RValue<SByte>(Nucleus::createSub(lhs.value, rhs.value));
1275 }
1276
John Bauman19bac1e2014-05-06 15:23:49 -04001277 RValue<SByte> operator*(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001278 {
1279 return RValue<SByte>(Nucleus::createMul(lhs.value, rhs.value));
1280 }
1281
John Bauman19bac1e2014-05-06 15:23:49 -04001282 RValue<SByte> operator/(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001283 {
1284 return RValue<SByte>(Nucleus::createSDiv(lhs.value, rhs.value));
1285 }
1286
John Bauman19bac1e2014-05-06 15:23:49 -04001287 RValue<SByte> operator%(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001288 {
1289 return RValue<SByte>(Nucleus::createSRem(lhs.value, rhs.value));
1290 }
1291
John Bauman19bac1e2014-05-06 15:23:49 -04001292 RValue<SByte> operator&(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001293 {
1294 return RValue<SByte>(Nucleus::createAnd(lhs.value, rhs.value));
1295 }
1296
John Bauman19bac1e2014-05-06 15:23:49 -04001297 RValue<SByte> operator|(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001298 {
1299 return RValue<SByte>(Nucleus::createOr(lhs.value, rhs.value));
1300 }
1301
John Bauman19bac1e2014-05-06 15:23:49 -04001302 RValue<SByte> operator^(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001303 {
1304 return RValue<SByte>(Nucleus::createXor(lhs.value, rhs.value));
1305 }
1306
John Bauman19bac1e2014-05-06 15:23:49 -04001307 RValue<SByte> operator<<(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001308 {
1309 return RValue<SByte>(Nucleus::createShl(lhs.value, rhs.value));
1310 }
1311
John Bauman19bac1e2014-05-06 15:23:49 -04001312 RValue<SByte> operator>>(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001313 {
1314 return RValue<SByte>(Nucleus::createAShr(lhs.value, rhs.value));
1315 }
1316
John Bauman19bac1e2014-05-06 15:23:49 -04001317 RValue<SByte> operator+=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001318 {
1319 return lhs = lhs + rhs;
1320 }
1321
John Bauman19bac1e2014-05-06 15:23:49 -04001322 RValue<SByte> operator-=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001323 {
1324 return lhs = lhs - rhs;
1325 }
1326
John Bauman19bac1e2014-05-06 15:23:49 -04001327 RValue<SByte> operator*=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001328 {
1329 return lhs = lhs * rhs;
1330 }
1331
John Bauman19bac1e2014-05-06 15:23:49 -04001332 RValue<SByte> operator/=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001333 {
1334 return lhs = lhs / rhs;
1335 }
1336
John Bauman19bac1e2014-05-06 15:23:49 -04001337 RValue<SByte> operator%=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001338 {
1339 return lhs = lhs % rhs;
1340 }
1341
John Bauman19bac1e2014-05-06 15:23:49 -04001342 RValue<SByte> operator&=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001343 {
1344 return lhs = lhs & rhs;
1345 }
1346
John Bauman19bac1e2014-05-06 15:23:49 -04001347 RValue<SByte> operator|=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001348 {
1349 return lhs = lhs | rhs;
1350 }
1351
John Bauman19bac1e2014-05-06 15:23:49 -04001352 RValue<SByte> operator^=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001353 {
1354 return lhs = lhs ^ rhs;
1355 }
1356
John Bauman19bac1e2014-05-06 15:23:49 -04001357 RValue<SByte> operator<<=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001358 {
1359 return lhs = lhs << rhs;
1360 }
1361
John Bauman19bac1e2014-05-06 15:23:49 -04001362 RValue<SByte> operator>>=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001363 {
1364 return lhs = lhs >> rhs;
1365 }
1366
John Bauman19bac1e2014-05-06 15:23:49 -04001367 RValue<SByte> operator+(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001368 {
1369 return val;
1370 }
1371
John Bauman19bac1e2014-05-06 15:23:49 -04001372 RValue<SByte> operator-(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001373 {
1374 return RValue<SByte>(Nucleus::createNeg(val.value));
1375 }
1376
John Bauman19bac1e2014-05-06 15:23:49 -04001377 RValue<SByte> operator~(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001378 {
1379 return RValue<SByte>(Nucleus::createNot(val.value));
1380 }
1381
1382 RValue<SByte> operator++(const SByte &val, int) // Post-increment
1383 {
1384 RValue<SByte> res = val;
1385
1386 Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantByte((signed char)1));
John Bauman66b8ab22014-05-06 15:57:45 -04001387 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001388
1389 return res;
1390 }
1391
1392 const SByte &operator++(const SByte &val) // Pre-increment
1393 {
John Bauman66b8ab22014-05-06 15:57:45 -04001394 Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantByte((signed char)1));
1395 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001396
1397 return val;
1398 }
1399
1400 RValue<SByte> operator--(const SByte &val, int) // Post-decrement
1401 {
1402 RValue<SByte> res = val;
1403
1404 Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantByte((signed char)1));
John Bauman66b8ab22014-05-06 15:57:45 -04001405 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001406
1407 return res;
1408 }
1409
1410 const SByte &operator--(const SByte &val) // Pre-decrement
1411 {
John Bauman66b8ab22014-05-06 15:57:45 -04001412 Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantByte((signed char)1));
1413 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001414
1415 return val;
1416 }
1417
John Bauman19bac1e2014-05-06 15:23:49 -04001418 RValue<Bool> operator<(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001419 {
1420 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
1421 }
1422
John Bauman19bac1e2014-05-06 15:23:49 -04001423 RValue<Bool> operator<=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001424 {
1425 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
1426 }
1427
John Bauman19bac1e2014-05-06 15:23:49 -04001428 RValue<Bool> operator>(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001429 {
1430 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
1431 }
1432
John Bauman19bac1e2014-05-06 15:23:49 -04001433 RValue<Bool> operator>=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001434 {
1435 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
1436 }
1437
John Bauman19bac1e2014-05-06 15:23:49 -04001438 RValue<Bool> operator!=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001439 {
1440 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1441 }
1442
John Bauman19bac1e2014-05-06 15:23:49 -04001443 RValue<Bool> operator==(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001444 {
1445 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1446 }
1447
John Bauman19bac1e2014-05-06 15:23:49 -04001448 Type *SByte::getType()
John Bauman89401822014-05-06 15:04:28 -04001449 {
Nicolas Capensac230122016-09-20 14:30:06 -04001450 return T(llvm::Type::getInt8Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001451 }
1452
Nicolas Capens81f18302016-01-14 09:32:35 -05001453 Short::Short(Argument<Short> argument)
John Bauman89401822014-05-06 15:04:28 -04001454 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001455 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001456 }
1457
John Bauman19bac1e2014-05-06 15:23:49 -04001458 Short::Short(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04001459 {
John Bauman89401822014-05-06 15:04:28 -04001460 Value *integer = Nucleus::createTrunc(cast.value, Short::getType());
1461
John Bauman66b8ab22014-05-06 15:57:45 -04001462 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04001463 }
1464
1465 Short::Short()
1466 {
John Bauman89401822014-05-06 15:04:28 -04001467 }
1468
1469 Short::Short(short x)
1470 {
John Bauman66b8ab22014-05-06 15:57:45 -04001471 storeValue(Nucleus::createConstantShort(x));
John Bauman89401822014-05-06 15:04:28 -04001472 }
1473
John Bauman19bac1e2014-05-06 15:23:49 -04001474 Short::Short(RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001475 {
John Bauman66b8ab22014-05-06 15:57:45 -04001476 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001477 }
1478
1479 Short::Short(const Short &rhs)
1480 {
John Bauman66b8ab22014-05-06 15:57:45 -04001481 Value *value = rhs.loadValue();
1482 storeValue(value);
1483 }
John Bauman89401822014-05-06 15:04:28 -04001484
John Bauman66b8ab22014-05-06 15:57:45 -04001485 Short::Short(const Reference<Short> &rhs)
1486 {
1487 Value *value = rhs.loadValue();
1488 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001489 }
1490
John Bauman19bac1e2014-05-06 15:23:49 -04001491 RValue<Short> Short::operator=(RValue<Short> rhs) const
John Bauman89401822014-05-06 15:04:28 -04001492 {
John Bauman66b8ab22014-05-06 15:57:45 -04001493 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001494
1495 return rhs;
1496 }
1497
1498 RValue<Short> Short::operator=(const Short &rhs) const
1499 {
John Bauman66b8ab22014-05-06 15:57:45 -04001500 Value *value = rhs.loadValue();
1501 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001502
1503 return RValue<Short>(value);
1504 }
1505
John Bauman66b8ab22014-05-06 15:57:45 -04001506 RValue<Short> Short::operator=(const Reference<Short> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04001507 {
John Bauman66b8ab22014-05-06 15:57:45 -04001508 Value *value = rhs.loadValue();
1509 storeValue(value);
1510
1511 return RValue<Short>(value);
John Bauman89401822014-05-06 15:04:28 -04001512 }
1513
John Bauman19bac1e2014-05-06 15:23:49 -04001514 RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001515 {
1516 return RValue<Short>(Nucleus::createAdd(lhs.value, rhs.value));
1517 }
1518
John Bauman19bac1e2014-05-06 15:23:49 -04001519 RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001520 {
1521 return RValue<Short>(Nucleus::createSub(lhs.value, rhs.value));
1522 }
1523
John Bauman19bac1e2014-05-06 15:23:49 -04001524 RValue<Short> operator*(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001525 {
1526 return RValue<Short>(Nucleus::createMul(lhs.value, rhs.value));
1527 }
1528
John Bauman19bac1e2014-05-06 15:23:49 -04001529 RValue<Short> operator/(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001530 {
1531 return RValue<Short>(Nucleus::createSDiv(lhs.value, rhs.value));
1532 }
1533
John Bauman19bac1e2014-05-06 15:23:49 -04001534 RValue<Short> operator%(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001535 {
1536 return RValue<Short>(Nucleus::createSRem(lhs.value, rhs.value));
1537 }
1538
John Bauman19bac1e2014-05-06 15:23:49 -04001539 RValue<Short> operator&(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001540 {
1541 return RValue<Short>(Nucleus::createAnd(lhs.value, rhs.value));
1542 }
1543
John Bauman19bac1e2014-05-06 15:23:49 -04001544 RValue<Short> operator|(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001545 {
1546 return RValue<Short>(Nucleus::createOr(lhs.value, rhs.value));
1547 }
1548
John Bauman19bac1e2014-05-06 15:23:49 -04001549 RValue<Short> operator^(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001550 {
1551 return RValue<Short>(Nucleus::createXor(lhs.value, rhs.value));
1552 }
1553
John Bauman19bac1e2014-05-06 15:23:49 -04001554 RValue<Short> operator<<(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001555 {
1556 return RValue<Short>(Nucleus::createShl(lhs.value, rhs.value));
1557 }
1558
John Bauman19bac1e2014-05-06 15:23:49 -04001559 RValue<Short> operator>>(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001560 {
1561 return RValue<Short>(Nucleus::createAShr(lhs.value, rhs.value));
1562 }
1563
John Bauman19bac1e2014-05-06 15:23:49 -04001564 RValue<Short> operator+=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001565 {
1566 return lhs = lhs + rhs;
1567 }
1568
John Bauman19bac1e2014-05-06 15:23:49 -04001569 RValue<Short> operator-=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001570 {
1571 return lhs = lhs - rhs;
1572 }
1573
John Bauman19bac1e2014-05-06 15:23:49 -04001574 RValue<Short> operator*=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001575 {
1576 return lhs = lhs * rhs;
1577 }
1578
John Bauman19bac1e2014-05-06 15:23:49 -04001579 RValue<Short> operator/=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001580 {
1581 return lhs = lhs / rhs;
1582 }
1583
John Bauman19bac1e2014-05-06 15:23:49 -04001584 RValue<Short> operator%=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001585 {
1586 return lhs = lhs % rhs;
1587 }
1588
John Bauman19bac1e2014-05-06 15:23:49 -04001589 RValue<Short> operator&=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001590 {
1591 return lhs = lhs & rhs;
1592 }
1593
John Bauman19bac1e2014-05-06 15:23:49 -04001594 RValue<Short> operator|=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001595 {
1596 return lhs = lhs | rhs;
1597 }
1598
John Bauman19bac1e2014-05-06 15:23:49 -04001599 RValue<Short> operator^=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001600 {
1601 return lhs = lhs ^ rhs;
1602 }
1603
John Bauman19bac1e2014-05-06 15:23:49 -04001604 RValue<Short> operator<<=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001605 {
1606 return lhs = lhs << rhs;
1607 }
1608
John Bauman19bac1e2014-05-06 15:23:49 -04001609 RValue<Short> operator>>=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001610 {
1611 return lhs = lhs >> rhs;
1612 }
1613
John Bauman19bac1e2014-05-06 15:23:49 -04001614 RValue<Short> operator+(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001615 {
1616 return val;
1617 }
1618
John Bauman19bac1e2014-05-06 15:23:49 -04001619 RValue<Short> operator-(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001620 {
1621 return RValue<Short>(Nucleus::createNeg(val.value));
1622 }
1623
John Bauman19bac1e2014-05-06 15:23:49 -04001624 RValue<Short> operator~(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001625 {
1626 return RValue<Short>(Nucleus::createNot(val.value));
1627 }
1628
1629 RValue<Short> operator++(const Short &val, int) // Post-increment
1630 {
1631 RValue<Short> res = val;
1632
1633 Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantShort((short)1));
John Bauman66b8ab22014-05-06 15:57:45 -04001634 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001635
1636 return res;
1637 }
1638
1639 const Short &operator++(const Short &val) // Pre-increment
1640 {
John Bauman66b8ab22014-05-06 15:57:45 -04001641 Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantShort((short)1));
1642 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001643
1644 return val;
1645 }
1646
1647 RValue<Short> operator--(const Short &val, int) // Post-decrement
1648 {
1649 RValue<Short> res = val;
1650
1651 Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantShort((short)1));
John Bauman66b8ab22014-05-06 15:57:45 -04001652 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001653
1654 return res;
1655 }
1656
1657 const Short &operator--(const Short &val) // Pre-decrement
1658 {
John Bauman66b8ab22014-05-06 15:57:45 -04001659 Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantShort((short)1));
1660 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001661
1662 return val;
1663 }
1664
John Bauman19bac1e2014-05-06 15:23:49 -04001665 RValue<Bool> operator<(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001666 {
1667 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
1668 }
1669
John Bauman19bac1e2014-05-06 15:23:49 -04001670 RValue<Bool> operator<=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001671 {
1672 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
1673 }
1674
John Bauman19bac1e2014-05-06 15:23:49 -04001675 RValue<Bool> operator>(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001676 {
1677 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
1678 }
1679
John Bauman19bac1e2014-05-06 15:23:49 -04001680 RValue<Bool> operator>=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001681 {
1682 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
1683 }
1684
John Bauman19bac1e2014-05-06 15:23:49 -04001685 RValue<Bool> operator!=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001686 {
1687 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1688 }
1689
John Bauman19bac1e2014-05-06 15:23:49 -04001690 RValue<Bool> operator==(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001691 {
1692 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1693 }
1694
John Bauman19bac1e2014-05-06 15:23:49 -04001695 Type *Short::getType()
John Bauman89401822014-05-06 15:04:28 -04001696 {
Nicolas Capensac230122016-09-20 14:30:06 -04001697 return T(llvm::Type::getInt16Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001698 }
1699
Nicolas Capens81f18302016-01-14 09:32:35 -05001700 UShort::UShort(Argument<UShort> argument)
John Bauman89401822014-05-06 15:04:28 -04001701 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001702 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001703 }
1704
Alexis Hetu77dfab42015-11-23 13:31:22 -05001705 UShort::UShort(RValue<UInt> cast)
1706 {
1707 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
1708
1709 storeValue(integer);
1710 }
1711
Alexis Hetu75b650f2015-11-19 17:40:15 -05001712 UShort::UShort(RValue<Int> cast)
1713 {
1714 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
1715
1716 storeValue(integer);
1717 }
1718
John Bauman89401822014-05-06 15:04:28 -04001719 UShort::UShort()
1720 {
John Bauman89401822014-05-06 15:04:28 -04001721 }
1722
1723 UShort::UShort(unsigned short x)
1724 {
John Bauman66b8ab22014-05-06 15:57:45 -04001725 storeValue(Nucleus::createConstantShort(x));
John Bauman89401822014-05-06 15:04:28 -04001726 }
1727
John Bauman19bac1e2014-05-06 15:23:49 -04001728 UShort::UShort(RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001729 {
John Bauman66b8ab22014-05-06 15:57:45 -04001730 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001731 }
1732
1733 UShort::UShort(const UShort &rhs)
1734 {
John Bauman66b8ab22014-05-06 15:57:45 -04001735 Value *value = rhs.loadValue();
1736 storeValue(value);
1737 }
John Bauman89401822014-05-06 15:04:28 -04001738
John Bauman66b8ab22014-05-06 15:57:45 -04001739 UShort::UShort(const Reference<UShort> &rhs)
1740 {
1741 Value *value = rhs.loadValue();
1742 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001743 }
1744
John Bauman19bac1e2014-05-06 15:23:49 -04001745 RValue<UShort> UShort::operator=(RValue<UShort> rhs) const
John Bauman89401822014-05-06 15:04:28 -04001746 {
John Bauman66b8ab22014-05-06 15:57:45 -04001747 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001748
1749 return rhs;
1750 }
1751
1752 RValue<UShort> UShort::operator=(const UShort &rhs) const
1753 {
John Bauman66b8ab22014-05-06 15:57:45 -04001754 Value *value = rhs.loadValue();
1755 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001756
1757 return RValue<UShort>(value);
1758 }
1759
John Bauman66b8ab22014-05-06 15:57:45 -04001760 RValue<UShort> UShort::operator=(const Reference<UShort> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04001761 {
John Bauman66b8ab22014-05-06 15:57:45 -04001762 Value *value = rhs.loadValue();
1763 storeValue(value);
1764
1765 return RValue<UShort>(value);
John Bauman89401822014-05-06 15:04:28 -04001766 }
1767
John Bauman19bac1e2014-05-06 15:23:49 -04001768 RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001769 {
1770 return RValue<UShort>(Nucleus::createAdd(lhs.value, rhs.value));
1771 }
1772
John Bauman19bac1e2014-05-06 15:23:49 -04001773 RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001774 {
1775 return RValue<UShort>(Nucleus::createSub(lhs.value, rhs.value));
1776 }
1777
John Bauman19bac1e2014-05-06 15:23:49 -04001778 RValue<UShort> operator*(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001779 {
1780 return RValue<UShort>(Nucleus::createMul(lhs.value, rhs.value));
1781 }
1782
John Bauman19bac1e2014-05-06 15:23:49 -04001783 RValue<UShort> operator/(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001784 {
1785 return RValue<UShort>(Nucleus::createUDiv(lhs.value, rhs.value));
1786 }
1787
John Bauman19bac1e2014-05-06 15:23:49 -04001788 RValue<UShort> operator%(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001789 {
1790 return RValue<UShort>(Nucleus::createURem(lhs.value, rhs.value));
1791 }
1792
John Bauman19bac1e2014-05-06 15:23:49 -04001793 RValue<UShort> operator&(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001794 {
1795 return RValue<UShort>(Nucleus::createAnd(lhs.value, rhs.value));
1796 }
1797
John Bauman19bac1e2014-05-06 15:23:49 -04001798 RValue<UShort> operator|(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001799 {
1800 return RValue<UShort>(Nucleus::createOr(lhs.value, rhs.value));
1801 }
1802
John Bauman19bac1e2014-05-06 15:23:49 -04001803 RValue<UShort> operator^(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001804 {
1805 return RValue<UShort>(Nucleus::createXor(lhs.value, rhs.value));
1806 }
1807
John Bauman19bac1e2014-05-06 15:23:49 -04001808 RValue<UShort> operator<<(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001809 {
1810 return RValue<UShort>(Nucleus::createShl(lhs.value, rhs.value));
1811 }
1812
John Bauman19bac1e2014-05-06 15:23:49 -04001813 RValue<UShort> operator>>(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001814 {
1815 return RValue<UShort>(Nucleus::createLShr(lhs.value, rhs.value));
1816 }
1817
John Bauman19bac1e2014-05-06 15:23:49 -04001818 RValue<UShort> operator+=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001819 {
1820 return lhs = lhs + rhs;
1821 }
1822
John Bauman19bac1e2014-05-06 15:23:49 -04001823 RValue<UShort> operator-=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001824 {
1825 return lhs = lhs - rhs;
1826 }
1827
John Bauman19bac1e2014-05-06 15:23:49 -04001828 RValue<UShort> operator*=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001829 {
1830 return lhs = lhs * rhs;
1831 }
1832
John Bauman19bac1e2014-05-06 15:23:49 -04001833 RValue<UShort> operator/=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001834 {
1835 return lhs = lhs / rhs;
1836 }
1837
John Bauman19bac1e2014-05-06 15:23:49 -04001838 RValue<UShort> operator%=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001839 {
1840 return lhs = lhs % rhs;
1841 }
1842
John Bauman19bac1e2014-05-06 15:23:49 -04001843 RValue<UShort> operator&=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001844 {
1845 return lhs = lhs & rhs;
1846 }
1847
John Bauman19bac1e2014-05-06 15:23:49 -04001848 RValue<UShort> operator|=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001849 {
1850 return lhs = lhs | rhs;
1851 }
1852
John Bauman19bac1e2014-05-06 15:23:49 -04001853 RValue<UShort> operator^=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001854 {
1855 return lhs = lhs ^ rhs;
1856 }
1857
John Bauman19bac1e2014-05-06 15:23:49 -04001858 RValue<UShort> operator<<=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001859 {
1860 return lhs = lhs << rhs;
1861 }
1862
John Bauman19bac1e2014-05-06 15:23:49 -04001863 RValue<UShort> operator>>=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001864 {
1865 return lhs = lhs >> rhs;
1866 }
1867
John Bauman19bac1e2014-05-06 15:23:49 -04001868 RValue<UShort> operator+(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001869 {
1870 return val;
1871 }
1872
John Bauman19bac1e2014-05-06 15:23:49 -04001873 RValue<UShort> operator-(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001874 {
1875 return RValue<UShort>(Nucleus::createNeg(val.value));
1876 }
1877
John Bauman19bac1e2014-05-06 15:23:49 -04001878 RValue<UShort> operator~(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001879 {
1880 return RValue<UShort>(Nucleus::createNot(val.value));
1881 }
1882
1883 RValue<UShort> operator++(const UShort &val, int) // Post-increment
1884 {
1885 RValue<UShort> res = val;
1886
1887 Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantShort((unsigned short)1));
John Bauman66b8ab22014-05-06 15:57:45 -04001888 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001889
1890 return res;
1891 }
1892
1893 const UShort &operator++(const UShort &val) // Pre-increment
1894 {
John Bauman66b8ab22014-05-06 15:57:45 -04001895 Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantShort((unsigned short)1));
1896 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001897
1898 return val;
1899 }
1900
1901 RValue<UShort> operator--(const UShort &val, int) // Post-decrement
1902 {
1903 RValue<UShort> res = val;
1904
1905 Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantShort((unsigned short)1));
John Bauman66b8ab22014-05-06 15:57:45 -04001906 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001907
1908 return res;
1909 }
1910
1911 const UShort &operator--(const UShort &val) // Pre-decrement
1912 {
John Bauman66b8ab22014-05-06 15:57:45 -04001913 Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantShort((unsigned short)1));
1914 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001915
1916 return val;
1917 }
1918
John Bauman19bac1e2014-05-06 15:23:49 -04001919 RValue<Bool> operator<(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001920 {
1921 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1922 }
1923
John Bauman19bac1e2014-05-06 15:23:49 -04001924 RValue<Bool> operator<=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001925 {
1926 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1927 }
1928
John Bauman19bac1e2014-05-06 15:23:49 -04001929 RValue<Bool> operator>(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001930 {
1931 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1932 }
1933
John Bauman19bac1e2014-05-06 15:23:49 -04001934 RValue<Bool> operator>=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001935 {
1936 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1937 }
1938
John Bauman19bac1e2014-05-06 15:23:49 -04001939 RValue<Bool> operator!=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001940 {
1941 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1942 }
1943
John Bauman19bac1e2014-05-06 15:23:49 -04001944 RValue<Bool> operator==(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001945 {
1946 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1947 }
1948
John Bauman19bac1e2014-05-06 15:23:49 -04001949 Type *UShort::getType()
John Bauman89401822014-05-06 15:04:28 -04001950 {
Nicolas Capensac230122016-09-20 14:30:06 -04001951 return T(llvm::Type::getInt16Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001952 }
1953
John Bauman19bac1e2014-05-06 15:23:49 -04001954 Type *Byte4::getType()
John Bauman89401822014-05-06 15:04:28 -04001955 {
1956 #if 0
Nicolas Capensac230122016-09-20 14:30:06 -04001957 return T(VectorType::get(Byte::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04001958 #else
1959 return UInt::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
1960 #endif
1961 }
1962
John Bauman19bac1e2014-05-06 15:23:49 -04001963 Type *SByte4::getType()
John Bauman89401822014-05-06 15:04:28 -04001964 {
1965 #if 0
Nicolas Capensac230122016-09-20 14:30:06 -04001966 return T(VectorType::get(SByte::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04001967 #else
1968 return Int::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
1969 #endif
1970 }
1971
1972 Byte8::Byte8()
1973 {
1974 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04001975 }
1976
1977 Byte8::Byte8(byte x0, byte x1, byte x2, byte x3, byte x4, byte x5, byte x6, byte x7)
1978 {
1979 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04001980
1981 Constant *constantVector[8];
1982 constantVector[0] = Nucleus::createConstantByte(x0);
1983 constantVector[1] = Nucleus::createConstantByte(x1);
1984 constantVector[2] = Nucleus::createConstantByte(x2);
1985 constantVector[3] = Nucleus::createConstantByte(x3);
1986 constantVector[4] = Nucleus::createConstantByte(x4);
1987 constantVector[5] = Nucleus::createConstantByte(x5);
1988 constantVector[6] = Nucleus::createConstantByte(x6);
1989 constantVector[7] = Nucleus::createConstantByte(x7);
John Bauman19bac1e2014-05-06 15:23:49 -04001990 Value *vector = Nucleus::createConstantVector(constantVector, 8);
John Bauman89401822014-05-06 15:04:28 -04001991
John Bauman66b8ab22014-05-06 15:57:45 -04001992 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04001993 }
1994
1995 Byte8::Byte8(int64_t x)
1996 {
1997 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04001998
1999 Constant *constantVector[8];
2000 constantVector[0] = Nucleus::createConstantByte((unsigned char)(x >> 0));
2001 constantVector[1] = Nucleus::createConstantByte((unsigned char)(x >> 8));
2002 constantVector[2] = Nucleus::createConstantByte((unsigned char)(x >> 16));
2003 constantVector[3] = Nucleus::createConstantByte((unsigned char)(x >> 24));
2004 constantVector[4] = Nucleus::createConstantByte((unsigned char)(x >> 32));
2005 constantVector[5] = Nucleus::createConstantByte((unsigned char)(x >> 40));
2006 constantVector[6] = Nucleus::createConstantByte((unsigned char)(x >> 48));
2007 constantVector[7] = Nucleus::createConstantByte((unsigned char)(x >> 56));
John Bauman19bac1e2014-05-06 15:23:49 -04002008 Value *vector = Nucleus::createConstantVector(constantVector, 8);
John Bauman89401822014-05-06 15:04:28 -04002009
John Bauman66b8ab22014-05-06 15:57:45 -04002010 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04002011 }
2012
John Bauman19bac1e2014-05-06 15:23:49 -04002013 Byte8::Byte8(RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002014 {
2015 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002016
John Bauman66b8ab22014-05-06 15:57:45 -04002017 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002018 }
2019
2020 Byte8::Byte8(const Byte8 &rhs)
2021 {
2022 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002023
John Bauman66b8ab22014-05-06 15:57:45 -04002024 Value *value = rhs.loadValue();
2025 storeValue(value);
2026 }
2027
2028 Byte8::Byte8(const Reference<Byte8> &rhs)
2029 {
2030 // xyzw.parent = this;
2031
2032 Value *value = rhs.loadValue();
2033 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002034 }
2035
John Bauman19bac1e2014-05-06 15:23:49 -04002036 RValue<Byte8> Byte8::operator=(RValue<Byte8> rhs) const
John Bauman89401822014-05-06 15:04:28 -04002037 {
John Bauman66b8ab22014-05-06 15:57:45 -04002038 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002039
2040 return rhs;
2041 }
2042
2043 RValue<Byte8> Byte8::operator=(const Byte8 &rhs) const
2044 {
John Bauman66b8ab22014-05-06 15:57:45 -04002045 Value *value = rhs.loadValue();
2046 storeValue(value);
2047
2048 return RValue<Byte8>(value);
2049 }
2050
2051 RValue<Byte8> Byte8::operator=(const Reference<Byte8> &rhs) const
2052 {
2053 Value *value = rhs.loadValue();
2054 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002055
2056 return RValue<Byte8>(value);
2057 }
2058
John Bauman19bac1e2014-05-06 15:23:49 -04002059 RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002060 {
John Bauman19bac1e2014-05-06 15:23:49 -04002061 if(CPUID::supportsMMX2())
2062 {
2063 return x86::paddb(lhs, rhs);
2064 }
2065 else
2066 {
2067 return RValue<Byte8>(Nucleus::createAdd(lhs.value, rhs.value));
2068 }
John Bauman89401822014-05-06 15:04:28 -04002069 }
2070
John Bauman19bac1e2014-05-06 15:23:49 -04002071 RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002072 {
John Bauman19bac1e2014-05-06 15:23:49 -04002073 if(CPUID::supportsMMX2())
2074 {
2075 return x86::psubb(lhs, rhs);
2076 }
2077 else
2078 {
2079 return RValue<Byte8>(Nucleus::createSub(lhs.value, rhs.value));
2080 }
John Bauman89401822014-05-06 15:04:28 -04002081 }
2082
John Bauman19bac1e2014-05-06 15:23:49 -04002083// RValue<Byte8> operator*(RValue<Byte8> lhs, RValue<Byte8> rhs)
2084// {
2085// return RValue<Byte8>(Nucleus::createMul(lhs.value, rhs.value));
2086// }
2087
2088// RValue<Byte8> operator/(RValue<Byte8> lhs, RValue<Byte8> rhs)
2089// {
2090// return RValue<Byte8>(Nucleus::createUDiv(lhs.value, rhs.value));
2091// }
2092
2093// RValue<Byte8> operator%(RValue<Byte8> lhs, RValue<Byte8> rhs)
2094// {
2095// return RValue<Byte8>(Nucleus::createURem(lhs.value, rhs.value));
2096// }
2097
2098 RValue<Byte8> operator&(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002099 {
John Bauman19bac1e2014-05-06 15:23:49 -04002100 if(CPUID::supportsMMX2())
2101 {
2102 return As<Byte8>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
2103 }
2104 else
2105 {
2106 return RValue<Byte8>(Nucleus::createAnd(lhs.value, rhs.value));
2107 }
John Bauman89401822014-05-06 15:04:28 -04002108 }
2109
John Bauman19bac1e2014-05-06 15:23:49 -04002110 RValue<Byte8> operator|(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002111 {
John Bauman19bac1e2014-05-06 15:23:49 -04002112 if(CPUID::supportsMMX2())
2113 {
2114 return As<Byte8>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
2115 }
2116 else
2117 {
2118 return RValue<Byte8>(Nucleus::createOr(lhs.value, rhs.value));
2119 }
John Bauman89401822014-05-06 15:04:28 -04002120 }
2121
John Bauman19bac1e2014-05-06 15:23:49 -04002122 RValue<Byte8> operator^(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002123 {
John Bauman19bac1e2014-05-06 15:23:49 -04002124 if(CPUID::supportsMMX2())
2125 {
2126 return As<Byte8>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
2127 }
2128 else
John Bauman66b8ab22014-05-06 15:57:45 -04002129 {
John Bauman19bac1e2014-05-06 15:23:49 -04002130 return RValue<Byte8>(Nucleus::createXor(lhs.value, rhs.value));
2131 }
John Bauman89401822014-05-06 15:04:28 -04002132 }
2133
John Bauman19bac1e2014-05-06 15:23:49 -04002134// RValue<Byte8> operator<<(RValue<Byte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002135// {
2136// return RValue<Byte8>(Nucleus::createShl(lhs.value, rhs.value));
2137// }
2138
John Bauman19bac1e2014-05-06 15:23:49 -04002139// RValue<Byte8> operator>>(RValue<Byte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002140// {
2141// return RValue<Byte8>(Nucleus::createLShr(lhs.value, rhs.value));
2142// }
2143
John Bauman19bac1e2014-05-06 15:23:49 -04002144 RValue<Byte8> operator+=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002145 {
2146 return lhs = lhs + rhs;
2147 }
2148
John Bauman19bac1e2014-05-06 15:23:49 -04002149 RValue<Byte8> operator-=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002150 {
2151 return lhs = lhs - rhs;
2152 }
2153
John Bauman19bac1e2014-05-06 15:23:49 -04002154// RValue<Byte8> operator*=(const Byte8 &lhs, RValue<Byte8> rhs)
2155// {
2156// return lhs = lhs * rhs;
2157// }
John Bauman89401822014-05-06 15:04:28 -04002158
John Bauman19bac1e2014-05-06 15:23:49 -04002159// RValue<Byte8> operator/=(const Byte8 &lhs, RValue<Byte8> rhs)
2160// {
2161// return lhs = lhs / rhs;
2162// }
John Bauman89401822014-05-06 15:04:28 -04002163
John Bauman19bac1e2014-05-06 15:23:49 -04002164// RValue<Byte8> operator%=(const Byte8 &lhs, RValue<Byte8> rhs)
2165// {
2166// return lhs = lhs % rhs;
2167// }
John Bauman89401822014-05-06 15:04:28 -04002168
John Bauman19bac1e2014-05-06 15:23:49 -04002169 RValue<Byte8> operator&=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002170 {
2171 return lhs = lhs & rhs;
2172 }
2173
John Bauman19bac1e2014-05-06 15:23:49 -04002174 RValue<Byte8> operator|=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002175 {
2176 return lhs = lhs | rhs;
2177 }
2178
John Bauman19bac1e2014-05-06 15:23:49 -04002179 RValue<Byte8> operator^=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002180 {
2181 return lhs = lhs ^ rhs;
2182 }
2183
John Bauman19bac1e2014-05-06 15:23:49 -04002184// RValue<Byte8> operator<<=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002185// {
2186// return lhs = lhs << rhs;
2187// }
2188
John Bauman19bac1e2014-05-06 15:23:49 -04002189// RValue<Byte8> operator>>=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002190// {
2191// return lhs = lhs >> rhs;
2192// }
2193
John Bauman19bac1e2014-05-06 15:23:49 -04002194// RValue<Byte8> operator+(RValue<Byte8> val)
2195// {
2196// return val;
2197// }
2198
2199// RValue<Byte8> operator-(RValue<Byte8> val)
2200// {
2201// return RValue<Byte8>(Nucleus::createNeg(val.value));
2202// }
2203
2204 RValue<Byte8> operator~(RValue<Byte8> val)
John Bauman89401822014-05-06 15:04:28 -04002205 {
John Bauman19bac1e2014-05-06 15:23:49 -04002206 if(CPUID::supportsMMX2())
2207 {
2208 return val ^ Byte8(0xFFFFFFFFFFFFFFFF);
2209 }
2210 else
2211 {
2212 return RValue<Byte8>(Nucleus::createNot(val.value));
2213 }
John Bauman89401822014-05-06 15:04:28 -04002214 }
2215
John Bauman19bac1e2014-05-06 15:23:49 -04002216 RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002217 {
2218 return x86::paddusb(x, y);
2219 }
John Bauman66b8ab22014-05-06 15:57:45 -04002220
John Bauman19bac1e2014-05-06 15:23:49 -04002221 RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002222 {
2223 return x86::psubusb(x, y);
2224 }
2225
John Bauman19bac1e2014-05-06 15:23:49 -04002226 RValue<Short4> Unpack(RValue<Byte4> x)
John Bauman89401822014-05-06 15:04:28 -04002227 {
John Bauman19bac1e2014-05-06 15:23:49 -04002228 Value *int2 = Nucleus::createInsertElement(UndefValue::get(VectorType::get(Int::getType(), 2)), x.value, 0);
2229 Value *byte8 = Nucleus::createBitCast(int2, Byte8::getType());
John Bauman89401822014-05-06 15:04:28 -04002230
John Bauman19bac1e2014-05-06 15:23:49 -04002231 return UnpackLow(RValue<Byte8>(byte8), RValue<Byte8>(byte8));
2232 }
John Bauman89401822014-05-06 15:04:28 -04002233
John Bauman19bac1e2014-05-06 15:23:49 -04002234 RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y)
2235 {
2236 if(CPUID::supportsMMX2())
2237 {
2238 return x86::punpcklbw(x, y);
2239 }
2240 else
2241 {
2242 Constant *shuffle[8];
2243 shuffle[0] = Nucleus::createConstantInt(0);
2244 shuffle[1] = Nucleus::createConstantInt(8);
2245 shuffle[2] = Nucleus::createConstantInt(1);
2246 shuffle[3] = Nucleus::createConstantInt(9);
2247 shuffle[4] = Nucleus::createConstantInt(2);
2248 shuffle[5] = Nucleus::createConstantInt(10);
2249 shuffle[6] = Nucleus::createConstantInt(3);
2250 shuffle[7] = Nucleus::createConstantInt(11);
2251
2252 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 8));
2253
2254 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2255 }
John Bauman89401822014-05-06 15:04:28 -04002256 }
John Bauman66b8ab22014-05-06 15:57:45 -04002257
John Bauman19bac1e2014-05-06 15:23:49 -04002258 RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002259 {
John Bauman19bac1e2014-05-06 15:23:49 -04002260 if(CPUID::supportsMMX2())
2261 {
2262 return x86::punpckhbw(x, y);
2263 }
2264 else
2265 {
2266 Constant *shuffle[8];
2267 shuffle[0] = Nucleus::createConstantInt(4);
2268 shuffle[1] = Nucleus::createConstantInt(12);
2269 shuffle[2] = Nucleus::createConstantInt(5);
2270 shuffle[3] = Nucleus::createConstantInt(13);
2271 shuffle[4] = Nucleus::createConstantInt(6);
2272 shuffle[5] = Nucleus::createConstantInt(14);
2273 shuffle[6] = Nucleus::createConstantInt(7);
2274 shuffle[7] = Nucleus::createConstantInt(15);
John Bauman89401822014-05-06 15:04:28 -04002275
John Bauman19bac1e2014-05-06 15:23:49 -04002276 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 8));
John Bauman89401822014-05-06 15:04:28 -04002277
John Bauman19bac1e2014-05-06 15:23:49 -04002278 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2279 }
John Bauman89401822014-05-06 15:04:28 -04002280 }
2281
John Bauman19bac1e2014-05-06 15:23:49 -04002282 RValue<Int> SignMask(RValue<Byte8> x)
John Bauman89401822014-05-06 15:04:28 -04002283 {
2284 return x86::pmovmskb(x);
2285 }
2286
John Bauman19bac1e2014-05-06 15:23:49 -04002287// RValue<Byte8> CmpGT(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002288// {
2289// return x86::pcmpgtb(x, y); // FIXME: Signedness
2290// }
John Bauman66b8ab22014-05-06 15:57:45 -04002291
John Bauman19bac1e2014-05-06 15:23:49 -04002292 RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002293 {
2294 return x86::pcmpeqb(x, y);
2295 }
2296
John Bauman19bac1e2014-05-06 15:23:49 -04002297 Type *Byte8::getType()
John Bauman89401822014-05-06 15:04:28 -04002298 {
John Bauman19bac1e2014-05-06 15:23:49 -04002299 if(CPUID::supportsMMX2())
2300 {
2301 return MMX::getType();
2302 }
2303 else
2304 {
Nicolas Capensac230122016-09-20 14:30:06 -04002305 return T(VectorType::get(Byte::getType(), 8));
John Bauman19bac1e2014-05-06 15:23:49 -04002306 }
John Bauman89401822014-05-06 15:04:28 -04002307 }
2308
2309 SByte8::SByte8()
2310 {
2311 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002312 }
2313
2314 SByte8::SByte8(byte x0, byte x1, byte x2, byte x3, byte x4, byte x5, byte x6, byte x7)
2315 {
2316 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002317
2318 Constant *constantVector[8];
2319 constantVector[0] = Nucleus::createConstantByte(x0);
2320 constantVector[1] = Nucleus::createConstantByte(x1);
2321 constantVector[2] = Nucleus::createConstantByte(x2);
2322 constantVector[3] = Nucleus::createConstantByte(x3);
2323 constantVector[4] = Nucleus::createConstantByte(x4);
2324 constantVector[5] = Nucleus::createConstantByte(x5);
2325 constantVector[6] = Nucleus::createConstantByte(x6);
2326 constantVector[7] = Nucleus::createConstantByte(x7);
John Bauman19bac1e2014-05-06 15:23:49 -04002327 Value *vector = Nucleus::createConstantVector(constantVector, 8);
John Bauman89401822014-05-06 15:04:28 -04002328
John Bauman66b8ab22014-05-06 15:57:45 -04002329 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04002330 }
2331
2332 SByte8::SByte8(int64_t x)
2333 {
2334 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002335
2336 Constant *constantVector[8];
2337 constantVector[0] = Nucleus::createConstantByte((unsigned char)(x >> 0));
2338 constantVector[1] = Nucleus::createConstantByte((unsigned char)(x >> 8));
2339 constantVector[2] = Nucleus::createConstantByte((unsigned char)(x >> 16));
2340 constantVector[3] = Nucleus::createConstantByte((unsigned char)(x >> 24));
2341 constantVector[4] = Nucleus::createConstantByte((unsigned char)(x >> 32));
2342 constantVector[5] = Nucleus::createConstantByte((unsigned char)(x >> 40));
2343 constantVector[6] = Nucleus::createConstantByte((unsigned char)(x >> 48));
2344 constantVector[7] = Nucleus::createConstantByte((unsigned char)(x >> 56));
John Bauman19bac1e2014-05-06 15:23:49 -04002345 Value *vector = Nucleus::createConstantVector(constantVector, 8);
John Bauman89401822014-05-06 15:04:28 -04002346
John Bauman66b8ab22014-05-06 15:57:45 -04002347 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04002348 }
2349
John Bauman19bac1e2014-05-06 15:23:49 -04002350 SByte8::SByte8(RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002351 {
2352 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002353
John Bauman66b8ab22014-05-06 15:57:45 -04002354 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002355 }
2356
2357 SByte8::SByte8(const SByte8 &rhs)
2358 {
2359 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002360
John Bauman66b8ab22014-05-06 15:57:45 -04002361 Value *value = rhs.loadValue();
2362 storeValue(value);
2363 }
2364
2365 SByte8::SByte8(const Reference<SByte8> &rhs)
2366 {
2367 // xyzw.parent = this;
2368
2369 Value *value = rhs.loadValue();
2370 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002371 }
2372
John Bauman19bac1e2014-05-06 15:23:49 -04002373 RValue<SByte8> SByte8::operator=(RValue<SByte8> rhs) const
John Bauman89401822014-05-06 15:04:28 -04002374 {
John Bauman66b8ab22014-05-06 15:57:45 -04002375 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002376
2377 return rhs;
2378 }
2379
2380 RValue<SByte8> SByte8::operator=(const SByte8 &rhs) const
2381 {
John Bauman66b8ab22014-05-06 15:57:45 -04002382 Value *value = rhs.loadValue();
2383 storeValue(value);
2384
2385 return RValue<SByte8>(value);
2386 }
2387
2388 RValue<SByte8> SByte8::operator=(const Reference<SByte8> &rhs) const
2389 {
2390 Value *value = rhs.loadValue();
2391 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002392
2393 return RValue<SByte8>(value);
2394 }
2395
John Bauman19bac1e2014-05-06 15:23:49 -04002396 RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002397 {
John Bauman19bac1e2014-05-06 15:23:49 -04002398 if(CPUID::supportsMMX2())
2399 {
2400 return As<SByte8>(x86::paddb(As<Byte8>(lhs), As<Byte8>(rhs)));
2401 }
2402 else
2403 {
2404 return RValue<SByte8>(Nucleus::createAdd(lhs.value, rhs.value));
2405 }
John Bauman89401822014-05-06 15:04:28 -04002406 }
2407
John Bauman19bac1e2014-05-06 15:23:49 -04002408 RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002409 {
John Bauman19bac1e2014-05-06 15:23:49 -04002410 if(CPUID::supportsMMX2())
2411 {
2412 return As<SByte8>(x86::psubb(As<Byte8>(lhs), As<Byte8>(rhs)));
2413 }
2414 else
2415 {
2416 return RValue<SByte8>(Nucleus::createSub(lhs.value, rhs.value));
2417 }
John Bauman89401822014-05-06 15:04:28 -04002418 }
2419
John Bauman19bac1e2014-05-06 15:23:49 -04002420// RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs)
2421// {
2422// return RValue<SByte8>(Nucleus::createMul(lhs.value, rhs.value));
2423// }
John Bauman89401822014-05-06 15:04:28 -04002424
John Bauman19bac1e2014-05-06 15:23:49 -04002425// RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs)
2426// {
2427// return RValue<SByte8>(Nucleus::createSDiv(lhs.value, rhs.value));
2428// }
John Bauman89401822014-05-06 15:04:28 -04002429
John Bauman19bac1e2014-05-06 15:23:49 -04002430// RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs)
2431// {
2432// return RValue<SByte8>(Nucleus::createSRem(lhs.value, rhs.value));
2433// }
John Bauman89401822014-05-06 15:04:28 -04002434
John Bauman19bac1e2014-05-06 15:23:49 -04002435 RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002436 {
2437 return RValue<SByte8>(Nucleus::createAnd(lhs.value, rhs.value));
2438 }
2439
John Bauman19bac1e2014-05-06 15:23:49 -04002440 RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002441 {
2442 return RValue<SByte8>(Nucleus::createOr(lhs.value, rhs.value));
2443 }
2444
John Bauman19bac1e2014-05-06 15:23:49 -04002445 RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002446 {
2447 return RValue<SByte8>(Nucleus::createXor(lhs.value, rhs.value));
2448 }
2449
John Bauman19bac1e2014-05-06 15:23:49 -04002450// RValue<SByte8> operator<<(RValue<SByte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002451// {
2452// return RValue<SByte8>(Nucleus::createShl(lhs.value, rhs.value));
2453// }
2454
John Bauman19bac1e2014-05-06 15:23:49 -04002455// RValue<SByte8> operator>>(RValue<SByte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002456// {
2457// return RValue<SByte8>(Nucleus::createAShr(lhs.value, rhs.value));
2458// }
2459
John Bauman19bac1e2014-05-06 15:23:49 -04002460 RValue<SByte8> operator+=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002461 {
2462 return lhs = lhs + rhs;
2463 }
2464
John Bauman19bac1e2014-05-06 15:23:49 -04002465 RValue<SByte8> operator-=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002466 {
2467 return lhs = lhs - rhs;
2468 }
2469
John Bauman19bac1e2014-05-06 15:23:49 -04002470// RValue<SByte8> operator*=(const SByte8 &lhs, RValue<SByte8> rhs)
2471// {
2472// return lhs = lhs * rhs;
2473// }
John Bauman89401822014-05-06 15:04:28 -04002474
John Bauman19bac1e2014-05-06 15:23:49 -04002475// RValue<SByte8> operator/=(const SByte8 &lhs, RValue<SByte8> rhs)
2476// {
2477// return lhs = lhs / rhs;
2478// }
John Bauman89401822014-05-06 15:04:28 -04002479
John Bauman19bac1e2014-05-06 15:23:49 -04002480// RValue<SByte8> operator%=(const SByte8 &lhs, RValue<SByte8> rhs)
2481// {
2482// return lhs = lhs % rhs;
2483// }
John Bauman89401822014-05-06 15:04:28 -04002484
John Bauman19bac1e2014-05-06 15:23:49 -04002485 RValue<SByte8> operator&=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002486 {
2487 return lhs = lhs & rhs;
2488 }
2489
John Bauman19bac1e2014-05-06 15:23:49 -04002490 RValue<SByte8> operator|=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002491 {
2492 return lhs = lhs | rhs;
2493 }
2494
John Bauman19bac1e2014-05-06 15:23:49 -04002495 RValue<SByte8> operator^=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002496 {
2497 return lhs = lhs ^ rhs;
2498 }
2499
John Bauman19bac1e2014-05-06 15:23:49 -04002500// RValue<SByte8> operator<<=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002501// {
2502// return lhs = lhs << rhs;
2503// }
2504
John Bauman19bac1e2014-05-06 15:23:49 -04002505// RValue<SByte8> operator>>=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002506// {
2507// return lhs = lhs >> rhs;
2508// }
2509
John Bauman19bac1e2014-05-06 15:23:49 -04002510// RValue<SByte8> operator+(RValue<SByte8> val)
2511// {
2512// return val;
2513// }
2514
2515// RValue<SByte8> operator-(RValue<SByte8> val)
2516// {
2517// return RValue<SByte8>(Nucleus::createNeg(val.value));
2518// }
2519
2520 RValue<SByte8> operator~(RValue<SByte8> val)
John Bauman89401822014-05-06 15:04:28 -04002521 {
John Bauman19bac1e2014-05-06 15:23:49 -04002522 if(CPUID::supportsMMX2())
2523 {
2524 return val ^ SByte8(0xFFFFFFFFFFFFFFFF);
2525 }
2526 else
2527 {
2528 return RValue<SByte8>(Nucleus::createNot(val.value));
2529 }
John Bauman89401822014-05-06 15:04:28 -04002530 }
2531
John Bauman19bac1e2014-05-06 15:23:49 -04002532 RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002533 {
2534 return x86::paddsb(x, y);
2535 }
John Bauman66b8ab22014-05-06 15:57:45 -04002536
John Bauman19bac1e2014-05-06 15:23:49 -04002537 RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002538 {
2539 return x86::psubsb(x, y);
2540 }
2541
John Bauman19bac1e2014-05-06 15:23:49 -04002542 RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002543 {
John Bauman19bac1e2014-05-06 15:23:49 -04002544 if(CPUID::supportsMMX2())
2545 {
2546 return As<Short4>(x86::punpcklbw(As<Byte8>(x), As<Byte8>(y)));
2547 }
2548 else
2549 {
2550 Constant *shuffle[8];
2551 shuffle[0] = Nucleus::createConstantInt(0);
2552 shuffle[1] = Nucleus::createConstantInt(8);
2553 shuffle[2] = Nucleus::createConstantInt(1);
2554 shuffle[3] = Nucleus::createConstantInt(9);
2555 shuffle[4] = Nucleus::createConstantInt(2);
2556 shuffle[5] = Nucleus::createConstantInt(10);
2557 shuffle[6] = Nucleus::createConstantInt(3);
2558 shuffle[7] = Nucleus::createConstantInt(11);
John Bauman89401822014-05-06 15:04:28 -04002559
John Bauman19bac1e2014-05-06 15:23:49 -04002560 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 8));
John Bauman89401822014-05-06 15:04:28 -04002561
John Bauman19bac1e2014-05-06 15:23:49 -04002562 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2563 }
John Bauman89401822014-05-06 15:04:28 -04002564 }
John Bauman66b8ab22014-05-06 15:57:45 -04002565
John Bauman19bac1e2014-05-06 15:23:49 -04002566 RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002567 {
John Bauman19bac1e2014-05-06 15:23:49 -04002568 if(CPUID::supportsMMX2())
2569 {
2570 return As<Short4>(x86::punpckhbw(As<Byte8>(x), As<Byte8>(y)));
2571 }
2572 else
2573 {
2574 Constant *shuffle[8];
2575 shuffle[0] = Nucleus::createConstantInt(4);
2576 shuffle[1] = Nucleus::createConstantInt(12);
2577 shuffle[2] = Nucleus::createConstantInt(5);
2578 shuffle[3] = Nucleus::createConstantInt(13);
2579 shuffle[4] = Nucleus::createConstantInt(6);
2580 shuffle[5] = Nucleus::createConstantInt(14);
2581 shuffle[6] = Nucleus::createConstantInt(7);
2582 shuffle[7] = Nucleus::createConstantInt(15);
John Bauman89401822014-05-06 15:04:28 -04002583
John Bauman19bac1e2014-05-06 15:23:49 -04002584 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 8));
John Bauman89401822014-05-06 15:04:28 -04002585
John Bauman19bac1e2014-05-06 15:23:49 -04002586 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2587 }
John Bauman89401822014-05-06 15:04:28 -04002588 }
2589
John Bauman19bac1e2014-05-06 15:23:49 -04002590 RValue<Int> SignMask(RValue<SByte8> x)
John Bauman89401822014-05-06 15:04:28 -04002591 {
2592 return x86::pmovmskb(As<Byte8>(x));
2593 }
2594
John Bauman19bac1e2014-05-06 15:23:49 -04002595 RValue<Byte8> CmpGT(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002596 {
2597 return x86::pcmpgtb(x, y);
2598 }
John Bauman66b8ab22014-05-06 15:57:45 -04002599
John Bauman19bac1e2014-05-06 15:23:49 -04002600 RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002601 {
2602 return x86::pcmpeqb(As<Byte8>(x), As<Byte8>(y));
2603 }
2604
John Bauman19bac1e2014-05-06 15:23:49 -04002605 Type *SByte8::getType()
John Bauman89401822014-05-06 15:04:28 -04002606 {
John Bauman19bac1e2014-05-06 15:23:49 -04002607 if(CPUID::supportsMMX2())
2608 {
2609 return MMX::getType();
2610 }
2611 else
2612 {
Nicolas Capensac230122016-09-20 14:30:06 -04002613 return T(VectorType::get(SByte::getType(), 8));
John Bauman19bac1e2014-05-06 15:23:49 -04002614 }
John Bauman89401822014-05-06 15:04:28 -04002615 }
2616
John Bauman19bac1e2014-05-06 15:23:49 -04002617 Byte16::Byte16(RValue<Byte16> rhs)
John Bauman89401822014-05-06 15:04:28 -04002618 {
2619 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002620
John Bauman66b8ab22014-05-06 15:57:45 -04002621 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002622 }
2623
2624 Byte16::Byte16(const Byte16 &rhs)
2625 {
2626 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002627
John Bauman66b8ab22014-05-06 15:57:45 -04002628 Value *value = rhs.loadValue();
2629 storeValue(value);
2630 }
2631
2632 Byte16::Byte16(const Reference<Byte16> &rhs)
2633 {
2634 // xyzw.parent = this;
2635
2636 Value *value = rhs.loadValue();
2637 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002638 }
2639
John Bauman19bac1e2014-05-06 15:23:49 -04002640 RValue<Byte16> Byte16::operator=(RValue<Byte16> rhs) const
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 return rhs;
2645 }
2646
2647 RValue<Byte16> Byte16::operator=(const Byte16 &rhs) const
2648 {
John Bauman66b8ab22014-05-06 15:57:45 -04002649 Value *value = rhs.loadValue();
2650 storeValue(value);
2651
2652 return RValue<Byte16>(value);
2653 }
2654
2655 RValue<Byte16> Byte16::operator=(const Reference<Byte16> &rhs) const
2656 {
2657 Value *value = rhs.loadValue();
2658 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002659
2660 return RValue<Byte16>(value);
2661 }
2662
John Bauman19bac1e2014-05-06 15:23:49 -04002663 Type *Byte16::getType()
John Bauman89401822014-05-06 15:04:28 -04002664 {
Nicolas Capensac230122016-09-20 14:30:06 -04002665 return T(VectorType::get(Byte::getType(), 16));
John Bauman89401822014-05-06 15:04:28 -04002666 }
2667
John Bauman19bac1e2014-05-06 15:23:49 -04002668 Type *SByte16::getType()
John Bauman89401822014-05-06 15:04:28 -04002669 {
Nicolas Capensac230122016-09-20 14:30:06 -04002670 return T( VectorType::get(SByte::getType(), 16));
John Bauman89401822014-05-06 15:04:28 -04002671 }
2672
John Bauman19bac1e2014-05-06 15:23:49 -04002673 Short4::Short4(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04002674 {
John Bauman89401822014-05-06 15:04:28 -04002675 Value *extend = Nucleus::createZExt(cast.value, Long::getType());
John Bauman19bac1e2014-05-06 15:23:49 -04002676 Value *swizzle = Swizzle(RValue<Short4>(extend), 0x00).value;
John Bauman66b8ab22014-05-06 15:57:45 -04002677
2678 storeValue(swizzle);
John Bauman89401822014-05-06 15:04:28 -04002679 }
2680
John Bauman19bac1e2014-05-06 15:23:49 -04002681 Short4::Short4(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04002682 {
John Bauman89401822014-05-06 15:04:28 -04002683 Value *short8 = Nucleus::createBitCast(cast.value, Short8::getType());
2684
2685 #if 0 // FIXME: Check codegen (pshuflw phshufhw pshufd)
2686 Constant *pack[8];
2687 pack[0] = Nucleus::createConstantInt(0);
2688 pack[1] = Nucleus::createConstantInt(2);
2689 pack[2] = Nucleus::createConstantInt(4);
2690 pack[3] = Nucleus::createConstantInt(6);
2691
2692 Value *short4 = Nucleus::createShuffleVector(short8, short8, Nucleus::createConstantVector(pack, 4));
2693 #else
2694 Value *packed;
2695
2696 // FIXME: Use Swizzle<Short8>
2697 if(!CPUID::supportsSSSE3())
2698 {
2699 Constant *pshuflw[8];
2700 pshuflw[0] = Nucleus::createConstantInt(0);
2701 pshuflw[1] = Nucleus::createConstantInt(2);
2702 pshuflw[2] = Nucleus::createConstantInt(0);
2703 pshuflw[3] = Nucleus::createConstantInt(2);
2704 pshuflw[4] = Nucleus::createConstantInt(4);
2705 pshuflw[5] = Nucleus::createConstantInt(5);
2706 pshuflw[6] = Nucleus::createConstantInt(6);
2707 pshuflw[7] = Nucleus::createConstantInt(7);
2708
2709 Constant *pshufhw[8];
2710 pshufhw[0] = Nucleus::createConstantInt(0);
2711 pshufhw[1] = Nucleus::createConstantInt(1);
2712 pshufhw[2] = Nucleus::createConstantInt(2);
2713 pshufhw[3] = Nucleus::createConstantInt(3);
2714 pshufhw[4] = Nucleus::createConstantInt(4);
2715 pshufhw[5] = Nucleus::createConstantInt(6);
2716 pshufhw[6] = Nucleus::createConstantInt(4);
2717 pshufhw[7] = Nucleus::createConstantInt(6);
2718
2719 Value *shuffle1 = Nucleus::createShuffleVector(short8, UndefValue::get(Short8::getType()), Nucleus::createConstantVector(pshuflw, 8));
2720 Value *shuffle2 = Nucleus::createShuffleVector(shuffle1, UndefValue::get(Short8::getType()), Nucleus::createConstantVector(pshufhw, 8));
2721 Value *int4 = Nucleus::createBitCast(shuffle2, Int4::getType());
2722 packed = Nucleus::createSwizzle(int4, 0x88);
2723 }
2724 else
2725 {
2726 Constant *pshufb[16];
2727 pshufb[0] = Nucleus::createConstantInt(0);
2728 pshufb[1] = Nucleus::createConstantInt(1);
2729 pshufb[2] = Nucleus::createConstantInt(4);
2730 pshufb[3] = Nucleus::createConstantInt(5);
2731 pshufb[4] = Nucleus::createConstantInt(8);
2732 pshufb[5] = Nucleus::createConstantInt(9);
2733 pshufb[6] = Nucleus::createConstantInt(12);
2734 pshufb[7] = Nucleus::createConstantInt(13);
2735 pshufb[8] = Nucleus::createConstantInt(0);
2736 pshufb[9] = Nucleus::createConstantInt(1);
2737 pshufb[10] = Nucleus::createConstantInt(4);
2738 pshufb[11] = Nucleus::createConstantInt(5);
2739 pshufb[12] = Nucleus::createConstantInt(8);
2740 pshufb[13] = Nucleus::createConstantInt(9);
2741 pshufb[14] = Nucleus::createConstantInt(12);
2742 pshufb[15] = Nucleus::createConstantInt(13);
2743
2744 Value *byte16 = Nucleus::createBitCast(cast.value, Byte16::getType());
2745 packed = Nucleus::createShuffleVector(byte16, UndefValue::get(Byte16::getType()), Nucleus::createConstantVector(pshufb, 16));
2746 }
2747
2748 #if 0 // FIXME: No optimal instruction selection
2749 Value *qword2 = Nucleus::createBitCast(packed, Long2::getType());
2750 Value *element = Nucleus::createExtractElement(qword2, 0);
2751 Value *short4 = Nucleus::createBitCast(element, Short4::getType());
2752 #else // FIXME: Requires SSE
2753 Value *int2 = RValue<Int2>(Int2(RValue<Int4>(packed))).value;
2754 Value *short4 = Nucleus::createBitCast(int2, Short4::getType());
2755 #endif
2756 #endif
2757
John Bauman66b8ab22014-05-06 15:57:45 -04002758 storeValue(short4);
John Bauman89401822014-05-06 15:04:28 -04002759 }
2760
John Bauman19bac1e2014-05-06 15:23:49 -04002761// Short4::Short4(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04002762// {
2763// }
2764
John Bauman19bac1e2014-05-06 15:23:49 -04002765 Short4::Short4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04002766 {
John Bauman89401822014-05-06 15:04:28 -04002767 Int4 v4i32 = Int4(cast);
2768 v4i32 = As<Int4>(x86::packssdw(v4i32, v4i32));
John Bauman66b8ab22014-05-06 15:57:45 -04002769
2770 storeValue(As<Short4>(Int2(v4i32)).value);
John Bauman89401822014-05-06 15:04:28 -04002771 }
2772
2773 Short4::Short4()
2774 {
2775 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002776 }
2777
John Bauman19bac1e2014-05-06 15:23:49 -04002778 Short4::Short4(short xyzw)
2779 {
2780 // xyzw.parent = this;
John Bauman19bac1e2014-05-06 15:23:49 -04002781
2782 Constant *constantVector[4];
2783 constantVector[0] = Nucleus::createConstantShort(xyzw);
2784 constantVector[1] = Nucleus::createConstantShort(xyzw);
2785 constantVector[2] = Nucleus::createConstantShort(xyzw);
2786 constantVector[3] = Nucleus::createConstantShort(xyzw);
2787 Value *vector = Nucleus::createConstantVector(constantVector, 4);
2788
John Bauman66b8ab22014-05-06 15:57:45 -04002789 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman19bac1e2014-05-06 15:23:49 -04002790 }
2791
John Bauman89401822014-05-06 15:04:28 -04002792 Short4::Short4(short x, short y, short z, short w)
2793 {
2794 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002795
2796 Constant *constantVector[4];
2797 constantVector[0] = Nucleus::createConstantShort(x);
2798 constantVector[1] = Nucleus::createConstantShort(y);
2799 constantVector[2] = Nucleus::createConstantShort(z);
2800 constantVector[3] = Nucleus::createConstantShort(w);
John Bauman19bac1e2014-05-06 15:23:49 -04002801 Value *vector = Nucleus::createConstantVector(constantVector, 4);
2802
John Bauman66b8ab22014-05-06 15:57:45 -04002803 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04002804 }
2805
John Bauman19bac1e2014-05-06 15:23:49 -04002806 Short4::Short4(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002807 {
2808 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002809
John Bauman66b8ab22014-05-06 15:57:45 -04002810 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002811 }
2812
2813 Short4::Short4(const Short4 &rhs)
2814 {
2815 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002816
John Bauman66b8ab22014-05-06 15:57:45 -04002817 Value *value = rhs.loadValue();
2818 storeValue(value);
2819 }
2820
2821 Short4::Short4(const Reference<Short4> &rhs)
2822 {
2823 // xyzw.parent = this;
2824
2825 Value *value = rhs.loadValue();
2826 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002827 }
2828
John Bauman19bac1e2014-05-06 15:23:49 -04002829 Short4::Short4(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002830 {
2831 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002832
John Bauman66b8ab22014-05-06 15:57:45 -04002833 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002834 }
2835
2836 Short4::Short4(const UShort4 &rhs)
2837 {
2838 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002839
John Bauman66b8ab22014-05-06 15:57:45 -04002840 storeValue(rhs.loadValue());
2841 }
2842
2843 Short4::Short4(const Reference<UShort4> &rhs)
2844 {
2845 // xyzw.parent = this;
2846
2847 storeValue(rhs.loadValue());
John Bauman89401822014-05-06 15:04:28 -04002848 }
2849
John Bauman19bac1e2014-05-06 15:23:49 -04002850 RValue<Short4> Short4::operator=(RValue<Short4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04002851 {
John Bauman66b8ab22014-05-06 15:57:45 -04002852 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002853
2854 return rhs;
2855 }
2856
2857 RValue<Short4> Short4::operator=(const Short4 &rhs) const
2858 {
John Bauman66b8ab22014-05-06 15:57:45 -04002859 Value *value = rhs.loadValue();
2860 storeValue(value);
2861
2862 return RValue<Short4>(value);
2863 }
2864
2865 RValue<Short4> Short4::operator=(const Reference<Short4> &rhs) const
2866 {
2867 Value *value = rhs.loadValue();
2868 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002869
2870 return RValue<Short4>(value);
2871 }
2872
John Bauman19bac1e2014-05-06 15:23:49 -04002873 RValue<Short4> Short4::operator=(RValue<UShort4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04002874 {
John Bauman66b8ab22014-05-06 15:57:45 -04002875 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002876
John Bauman66b8ab22014-05-06 15:57:45 -04002877 return RValue<Short4>(rhs);
John Bauman89401822014-05-06 15:04:28 -04002878 }
2879
2880 RValue<Short4> Short4::operator=(const UShort4 &rhs) const
2881 {
John Bauman66b8ab22014-05-06 15:57:45 -04002882 Value *value = rhs.loadValue();
2883 storeValue(value);
2884
2885 return RValue<Short4>(value);
2886 }
2887
2888 RValue<Short4> Short4::operator=(const Reference<UShort4> &rhs) const
2889 {
2890 Value *value = rhs.loadValue();
2891 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002892
2893 return RValue<Short4>(value);
2894 }
2895
John Bauman19bac1e2014-05-06 15:23:49 -04002896 RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002897 {
John Bauman19bac1e2014-05-06 15:23:49 -04002898 if(CPUID::supportsMMX2())
2899 {
2900 return x86::paddw(lhs, rhs);
2901 }
2902 else
2903 {
2904 return RValue<Short4>(Nucleus::createAdd(lhs.value, rhs.value));
2905 }
John Bauman89401822014-05-06 15:04:28 -04002906 }
2907
John Bauman19bac1e2014-05-06 15:23:49 -04002908 RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002909 {
John Bauman19bac1e2014-05-06 15:23:49 -04002910 if(CPUID::supportsMMX2())
2911 {
2912 return x86::psubw(lhs, rhs);
2913 }
2914 else
2915 {
2916 return RValue<Short4>(Nucleus::createSub(lhs.value, rhs.value));
2917 }
John Bauman89401822014-05-06 15:04:28 -04002918 }
2919
John Bauman19bac1e2014-05-06 15:23:49 -04002920 RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002921 {
John Bauman19bac1e2014-05-06 15:23:49 -04002922 if(CPUID::supportsMMX2())
2923 {
2924 return x86::pmullw(lhs, rhs);
2925 }
2926 else
2927 {
2928 return RValue<Short4>(Nucleus::createMul(lhs.value, rhs.value));
2929 }
John Bauman89401822014-05-06 15:04:28 -04002930 }
2931
John Bauman19bac1e2014-05-06 15:23:49 -04002932// RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs)
2933// {
2934// return RValue<Short4>(Nucleus::createSDiv(lhs.value, rhs.value));
2935// }
2936
2937// RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs)
2938// {
2939// return RValue<Short4>(Nucleus::createSRem(lhs.value, rhs.value));
2940// }
2941
2942 RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002943 {
John Bauman19bac1e2014-05-06 15:23:49 -04002944 if(CPUID::supportsMMX2())
2945 {
2946 return x86::pand(lhs, rhs);
2947 }
2948 else
2949 {
2950 return RValue<Short4>(Nucleus::createAnd(lhs.value, rhs.value));
2951 }
John Bauman89401822014-05-06 15:04:28 -04002952 }
2953
John Bauman19bac1e2014-05-06 15:23:49 -04002954 RValue<Short4> operator|(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002955 {
John Bauman19bac1e2014-05-06 15:23:49 -04002956 if(CPUID::supportsMMX2())
2957 {
2958 return x86::por(lhs, rhs);
2959 }
2960 else
2961 {
2962 return RValue<Short4>(Nucleus::createOr(lhs.value, rhs.value));
2963 }
John Bauman89401822014-05-06 15:04:28 -04002964 }
2965
John Bauman19bac1e2014-05-06 15:23:49 -04002966 RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002967 {
John Bauman19bac1e2014-05-06 15:23:49 -04002968 if(CPUID::supportsMMX2())
2969 {
2970 return x86::pxor(lhs, rhs);
2971 }
2972 else
2973 {
2974 return RValue<Short4>(Nucleus::createXor(lhs.value, rhs.value));
2975 }
John Bauman89401822014-05-06 15:04:28 -04002976 }
2977
John Bauman19bac1e2014-05-06 15:23:49 -04002978 RValue<Short4> operator<<(RValue<Short4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002979 {
2980 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
2981
2982 return x86::psllw(lhs, rhs);
2983 }
2984
John Bauman19bac1e2014-05-06 15:23:49 -04002985 RValue<Short4> operator>>(RValue<Short4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002986 {
2987 // return RValue<Short4>(Nucleus::createAShr(lhs.value, rhs.value));
2988
2989 return x86::psraw(lhs, rhs);
2990 }
2991
John Bauman19bac1e2014-05-06 15:23:49 -04002992 RValue<Short4> operator<<(RValue<Short4> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04002993 {
2994 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
2995
2996 return x86::psllw(lhs, rhs);
2997 }
2998
John Bauman19bac1e2014-05-06 15:23:49 -04002999 RValue<Short4> operator>>(RValue<Short4> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04003000 {
3001 // return RValue<Short4>(Nucleus::createAShr(lhs.value, rhs.value));
3002
3003 return x86::psraw(lhs, rhs);
3004 }
3005
John Bauman19bac1e2014-05-06 15:23:49 -04003006 RValue<Short4> operator+=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003007 {
3008 return lhs = lhs + rhs;
3009 }
3010
John Bauman19bac1e2014-05-06 15:23:49 -04003011 RValue<Short4> operator-=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003012 {
3013 return lhs = lhs - rhs;
3014 }
3015
John Bauman19bac1e2014-05-06 15:23:49 -04003016 RValue<Short4> operator*=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003017 {
3018 return lhs = lhs * rhs;
3019 }
3020
John Bauman19bac1e2014-05-06 15:23:49 -04003021// RValue<Short4> operator/=(const Short4 &lhs, RValue<Short4> rhs)
3022// {
3023// return lhs = lhs / rhs;
3024// }
John Bauman89401822014-05-06 15:04:28 -04003025
John Bauman19bac1e2014-05-06 15:23:49 -04003026// RValue<Short4> operator%=(const Short4 &lhs, RValue<Short4> rhs)
3027// {
3028// return lhs = lhs % rhs;
3029// }
John Bauman89401822014-05-06 15:04:28 -04003030
John Bauman19bac1e2014-05-06 15:23:49 -04003031 RValue<Short4> operator&=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003032 {
3033 return lhs = lhs & rhs;
3034 }
3035
John Bauman19bac1e2014-05-06 15:23:49 -04003036 RValue<Short4> operator|=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003037 {
3038 return lhs = lhs | rhs;
3039 }
3040
John Bauman19bac1e2014-05-06 15:23:49 -04003041 RValue<Short4> operator^=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003042 {
3043 return lhs = lhs ^ rhs;
3044 }
3045
3046 RValue<Short4> operator<<=(const Short4 &lhs, unsigned char rhs)
3047 {
3048 return lhs = lhs << rhs;
3049 }
3050
3051 RValue<Short4> operator>>=(const Short4 &lhs, unsigned char rhs)
3052 {
3053 return lhs = lhs >> rhs;
3054 }
3055
John Bauman19bac1e2014-05-06 15:23:49 -04003056 RValue<Short4> operator<<=(const Short4 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04003057 {
3058 return lhs = lhs << rhs;
3059 }
3060
John Bauman19bac1e2014-05-06 15:23:49 -04003061 RValue<Short4> operator>>=(const Short4 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04003062 {
3063 return lhs = lhs >> rhs;
3064 }
3065
John Bauman19bac1e2014-05-06 15:23:49 -04003066// RValue<Short4> operator+(RValue<Short4> val)
3067// {
3068// return val;
3069// }
3070
3071 RValue<Short4> operator-(RValue<Short4> val)
John Bauman89401822014-05-06 15:04:28 -04003072 {
John Bauman19bac1e2014-05-06 15:23:49 -04003073 if(CPUID::supportsMMX2())
3074 {
3075 return Short4(0, 0, 0, 0) - val;
3076 }
3077 else
3078 {
3079 return RValue<Short4>(Nucleus::createNeg(val.value));
3080 }
John Bauman89401822014-05-06 15:04:28 -04003081 }
3082
John Bauman19bac1e2014-05-06 15:23:49 -04003083 RValue<Short4> operator~(RValue<Short4> val)
John Bauman89401822014-05-06 15:04:28 -04003084 {
John Bauman19bac1e2014-05-06 15:23:49 -04003085 if(CPUID::supportsMMX2())
3086 {
3087 return val ^ Short4(0xFFFFu, 0xFFFFu, 0xFFFFu, 0xFFFFu);
3088 }
3089 else
3090 {
3091 return RValue<Short4>(Nucleus::createNot(val.value));
3092 }
John Bauman89401822014-05-06 15:04:28 -04003093 }
3094
John Bauman19bac1e2014-05-06 15:23:49 -04003095 RValue<Short4> RoundShort4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04003096 {
3097 RValue<Int4> v4i32 = x86::cvtps2dq(cast);
Nicolas Capens698633a2015-02-04 00:16:13 -05003098 RValue<Short8> v8i16 = x86::packssdw(v4i32, v4i32);
John Bauman66b8ab22014-05-06 15:57:45 -04003099
Nicolas Capens698633a2015-02-04 00:16:13 -05003100 return As<Short4>(Int2(As<Int4>(v8i16)));
John Bauman89401822014-05-06 15:04:28 -04003101 }
3102
John Bauman19bac1e2014-05-06 15:23:49 -04003103 RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003104 {
3105 return x86::pmaxsw(x, y);
3106 }
3107
John Bauman19bac1e2014-05-06 15:23:49 -04003108 RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003109 {
3110 return x86::pminsw(x, y);
3111 }
3112
John Bauman19bac1e2014-05-06 15:23:49 -04003113 RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003114 {
3115 return x86::paddsw(x, y);
3116 }
3117
John Bauman19bac1e2014-05-06 15:23:49 -04003118 RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003119 {
3120 return x86::psubsw(x, y);
3121 }
3122
John Bauman19bac1e2014-05-06 15:23:49 -04003123 RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003124 {
3125 return x86::pmulhw(x, y);
3126 }
3127
John Bauman19bac1e2014-05-06 15:23:49 -04003128 RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003129 {
3130 return x86::pmaddwd(x, y);
3131 }
3132
John Bauman19bac1e2014-05-06 15:23:49 -04003133 RValue<SByte8> Pack(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003134 {
3135 return x86::packsswb(x, y);
3136 }
3137
John Bauman19bac1e2014-05-06 15:23:49 -04003138 RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003139 {
John Bauman19bac1e2014-05-06 15:23:49 -04003140 if(CPUID::supportsMMX2())
3141 {
3142 return x86::punpcklwd(x, y);
3143 }
3144 else
3145 {
3146 Constant *shuffle[4];
3147 shuffle[0] = Nucleus::createConstantInt(0);
3148 shuffle[1] = Nucleus::createConstantInt(4);
3149 shuffle[2] = Nucleus::createConstantInt(1);
3150 shuffle[3] = Nucleus::createConstantInt(5);
John Bauman89401822014-05-06 15:04:28 -04003151
John Bauman19bac1e2014-05-06 15:23:49 -04003152 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 4));
John Bauman89401822014-05-06 15:04:28 -04003153
John Bauman19bac1e2014-05-06 15:23:49 -04003154 return RValue<Int2>(Nucleus::createBitCast(packed, Int2::getType()));
3155 }
John Bauman89401822014-05-06 15:04:28 -04003156 }
3157
John Bauman19bac1e2014-05-06 15:23:49 -04003158 RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003159 {
John Bauman19bac1e2014-05-06 15:23:49 -04003160 if(CPUID::supportsMMX2())
3161 {
3162 return x86::punpckhwd(x, y);
3163 }
3164 else
3165 {
3166 Constant *shuffle[4];
3167 shuffle[0] = Nucleus::createConstantInt(2);
3168 shuffle[1] = Nucleus::createConstantInt(6);
3169 shuffle[2] = Nucleus::createConstantInt(3);
3170 shuffle[3] = Nucleus::createConstantInt(7);
John Bauman89401822014-05-06 15:04:28 -04003171
John Bauman19bac1e2014-05-06 15:23:49 -04003172 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 4));
John Bauman89401822014-05-06 15:04:28 -04003173
John Bauman19bac1e2014-05-06 15:23:49 -04003174 return RValue<Int2>(Nucleus::createBitCast(packed, Int2::getType()));
3175 }
John Bauman89401822014-05-06 15:04:28 -04003176 }
3177
John Bauman19bac1e2014-05-06 15:23:49 -04003178 RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04003179 {
John Bauman19bac1e2014-05-06 15:23:49 -04003180 if(CPUID::supportsMMX2())
3181 {
3182 return x86::pshufw(x, select);
3183 }
3184 else
3185 {
3186 return RValue<Short4>(Nucleus::createSwizzle(x.value, select));
3187 }
John Bauman89401822014-05-06 15:04:28 -04003188 }
3189
John Bauman19bac1e2014-05-06 15:23:49 -04003190 RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i)
John Bauman89401822014-05-06 15:04:28 -04003191 {
John Bauman19bac1e2014-05-06 15:23:49 -04003192 if(CPUID::supportsMMX2())
3193 {
3194 return x86::pinsrw(val, Int(element), i);
3195 }
3196 else
3197 {
3198 return RValue<Short4>(Nucleus::createInsertElement(val.value, element.value, i));
3199 }
John Bauman89401822014-05-06 15:04:28 -04003200 }
3201
John Bauman19bac1e2014-05-06 15:23:49 -04003202 RValue<Short> Extract(RValue<Short4> val, int i)
John Bauman89401822014-05-06 15:04:28 -04003203 {
John Bauman19bac1e2014-05-06 15:23:49 -04003204 if(CPUID::supportsMMX2())
3205 {
3206 return Short(x86::pextrw(val, i));
3207 }
3208 else
3209 {
3210 return RValue<Short>(Nucleus::createExtractElement(val.value, i));
3211 }
John Bauman89401822014-05-06 15:04:28 -04003212 }
3213
John Bauman19bac1e2014-05-06 15:23:49 -04003214 RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003215 {
3216 return x86::pcmpgtw(x, y);
3217 }
3218
John Bauman19bac1e2014-05-06 15:23:49 -04003219 RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003220 {
3221 return x86::pcmpeqw(x, y);
3222 }
3223
John Bauman19bac1e2014-05-06 15:23:49 -04003224 Type *Short4::getType()
John Bauman89401822014-05-06 15:04:28 -04003225 {
John Bauman19bac1e2014-05-06 15:23:49 -04003226 if(CPUID::supportsMMX2())
3227 {
3228 return MMX::getType();
3229 }
3230 else
3231 {
Nicolas Capensac230122016-09-20 14:30:06 -04003232 return T(VectorType::get(Short::getType(), 4));
John Bauman19bac1e2014-05-06 15:23:49 -04003233 }
John Bauman89401822014-05-06 15:04:28 -04003234 }
3235
John Bauman19bac1e2014-05-06 15:23:49 -04003236 UShort4::UShort4(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04003237 {
John Bauman89401822014-05-06 15:04:28 -04003238 *this = Short4(cast);
3239 }
3240
John Bauman19bac1e2014-05-06 15:23:49 -04003241 UShort4::UShort4(RValue<Float4> cast, bool saturate)
John Bauman89401822014-05-06 15:04:28 -04003242 {
John Bauman89401822014-05-06 15:04:28 -04003243 Float4 sat;
3244
3245 if(saturate)
3246 {
3247 if(CPUID::supportsSSE4_1())
3248 {
3249 sat = Min(cast, Float4(0xFFFF)); // packusdw takes care of 0x0000 saturation
3250 }
3251 else
3252 {
3253 sat = Max(Min(cast, Float4(0xFFFF)), Float4(0x0000));
3254 }
3255 }
3256 else
3257 {
3258 sat = cast;
3259 }
3260
3261 Int4 int4(sat);
3262
3263 if(!saturate || !CPUID::supportsSSE4_1())
3264 {
3265 *this = Short4(Int4(int4));
3266 }
3267 else
3268 {
3269 *this = As<Short4>(Int2(As<Int4>(x86::packusdw(As<UInt4>(int4), As<UInt4>(int4)))));
3270 }
3271 }
3272
3273 UShort4::UShort4()
3274 {
3275 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003276 }
3277
Alexis Hetu90c7ad62016-06-27 11:50:40 -04003278 UShort4::UShort4(unsigned short xyzw)
3279 {
3280 // xyzw.parent = this;
3281
3282 Constant *constantVector[4];
3283 constantVector[0] = Nucleus::createConstantShort(xyzw);
3284 constantVector[1] = Nucleus::createConstantShort(xyzw);
3285 constantVector[2] = Nucleus::createConstantShort(xyzw);
3286 constantVector[3] = Nucleus::createConstantShort(xyzw);
3287 Value *vector = Nucleus::createConstantVector(constantVector, 4);
3288
3289 storeValue(Nucleus::createBitCast(vector, getType()));
3290 }
3291
John Bauman89401822014-05-06 15:04:28 -04003292 UShort4::UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w)
3293 {
3294 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003295
3296 Constant *constantVector[4];
3297 constantVector[0] = Nucleus::createConstantShort(x);
3298 constantVector[1] = Nucleus::createConstantShort(y);
3299 constantVector[2] = Nucleus::createConstantShort(z);
3300 constantVector[3] = Nucleus::createConstantShort(w);
John Bauman19bac1e2014-05-06 15:23:49 -04003301 Value *vector = Nucleus::createConstantVector(constantVector, 4);
John Bauman89401822014-05-06 15:04:28 -04003302
John Bauman66b8ab22014-05-06 15:57:45 -04003303 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04003304 }
3305
John Bauman19bac1e2014-05-06 15:23:49 -04003306 UShort4::UShort4(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003307 {
3308 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003309
John Bauman66b8ab22014-05-06 15:57:45 -04003310 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003311 }
3312
3313 UShort4::UShort4(const UShort4 &rhs)
3314 {
3315 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003316
John Bauman66b8ab22014-05-06 15:57:45 -04003317 Value *value = rhs.loadValue();
3318 storeValue(value);
3319 }
3320
3321 UShort4::UShort4(const Reference<UShort4> &rhs)
3322 {
3323 // xyzw.parent = this;
3324
3325 Value *value = rhs.loadValue();
3326 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003327 }
3328
John Bauman19bac1e2014-05-06 15:23:49 -04003329 UShort4::UShort4(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003330 {
3331 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003332
John Bauman66b8ab22014-05-06 15:57:45 -04003333 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003334 }
3335
3336 UShort4::UShort4(const Short4 &rhs)
3337 {
3338 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003339
John Bauman66b8ab22014-05-06 15:57:45 -04003340 Value *value = rhs.loadValue();
3341 storeValue(value);
3342 }
3343
3344 UShort4::UShort4(const Reference<Short4> &rhs)
3345 {
3346 // xyzw.parent = this;
3347
3348 Value *value = rhs.loadValue();
3349 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003350 }
3351
John Bauman19bac1e2014-05-06 15:23:49 -04003352 RValue<UShort4> UShort4::operator=(RValue<UShort4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04003353 {
John Bauman66b8ab22014-05-06 15:57:45 -04003354 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003355
3356 return rhs;
3357 }
3358
3359 RValue<UShort4> UShort4::operator=(const UShort4 &rhs) const
3360 {
John Bauman66b8ab22014-05-06 15:57:45 -04003361 Value *value = rhs.loadValue();
3362 storeValue(value);
3363
3364 return RValue<UShort4>(value);
3365 }
3366
3367 RValue<UShort4> UShort4::operator=(const Reference<UShort4> &rhs) const
3368 {
3369 Value *value = rhs.loadValue();
3370 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003371
3372 return RValue<UShort4>(value);
3373 }
3374
John Bauman19bac1e2014-05-06 15:23:49 -04003375 RValue<UShort4> UShort4::operator=(RValue<Short4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04003376 {
John Bauman66b8ab22014-05-06 15:57:45 -04003377 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003378
John Bauman66b8ab22014-05-06 15:57:45 -04003379 return RValue<UShort4>(rhs);
John Bauman89401822014-05-06 15:04:28 -04003380 }
3381
3382 RValue<UShort4> UShort4::operator=(const Short4 &rhs) const
3383 {
John Bauman66b8ab22014-05-06 15:57:45 -04003384 Value *value = rhs.loadValue();
3385 storeValue(value);
3386
3387 return RValue<UShort4>(value);
3388 }
3389
3390 RValue<UShort4> UShort4::operator=(const Reference<Short4> &rhs) const
3391 {
3392 Value *value = rhs.loadValue();
3393 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003394
3395 return RValue<UShort4>(value);
3396 }
3397
John Bauman19bac1e2014-05-06 15:23:49 -04003398 RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003399 {
John Bauman19bac1e2014-05-06 15:23:49 -04003400 if(CPUID::supportsMMX2())
3401 {
3402 return As<UShort4>(x86::paddw(As<Short4>(lhs), As<Short4>(rhs)));
3403 }
3404 else
3405 {
3406 return RValue<UShort4>(Nucleus::createAdd(lhs.value, rhs.value));
3407 }
John Bauman89401822014-05-06 15:04:28 -04003408 }
3409
John Bauman19bac1e2014-05-06 15:23:49 -04003410 RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003411 {
John Bauman19bac1e2014-05-06 15:23:49 -04003412 if(CPUID::supportsMMX2())
3413 {
3414 return As<UShort4>(x86::psubw(As<Short4>(lhs), As<Short4>(rhs)));
3415 }
3416 else
3417 {
3418 return RValue<UShort4>(Nucleus::createSub(lhs.value, rhs.value));
3419 }
John Bauman89401822014-05-06 15:04:28 -04003420 }
3421
John Bauman19bac1e2014-05-06 15:23:49 -04003422 RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003423 {
John Bauman19bac1e2014-05-06 15:23:49 -04003424 if(CPUID::supportsMMX2())
3425 {
3426 return As<UShort4>(x86::pmullw(As<Short4>(lhs), As<Short4>(rhs)));
3427 }
3428 else
3429 {
3430 return RValue<UShort4>(Nucleus::createMul(lhs.value, rhs.value));
3431 }
John Bauman89401822014-05-06 15:04:28 -04003432 }
3433
John Bauman19bac1e2014-05-06 15:23:49 -04003434 RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003435 {
3436 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
3437
3438 return As<UShort4>(x86::psllw(As<Short4>(lhs), rhs));
3439 }
3440
John Bauman19bac1e2014-05-06 15:23:49 -04003441 RValue<UShort4> operator>>(RValue<UShort4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003442 {
3443 // return RValue<Short4>(Nucleus::createLShr(lhs.value, rhs.value));
3444
3445 return x86::psrlw(lhs, rhs);
3446 }
3447
John Bauman19bac1e2014-05-06 15:23:49 -04003448 RValue<UShort4> operator<<(RValue<UShort4> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04003449 {
3450 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
3451
3452 return As<UShort4>(x86::psllw(As<Short4>(lhs), rhs));
3453 }
3454
John Bauman19bac1e2014-05-06 15:23:49 -04003455 RValue<UShort4> operator>>(RValue<UShort4> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04003456 {
3457 // return RValue<Short4>(Nucleus::createLShr(lhs.value, rhs.value));
3458
3459 return x86::psrlw(lhs, rhs);
3460 }
3461
3462 RValue<UShort4> operator<<=(const UShort4 &lhs, unsigned char rhs)
3463 {
3464 return lhs = lhs << rhs;
3465 }
3466
3467 RValue<UShort4> operator>>=(const UShort4 &lhs, unsigned char rhs)
3468 {
3469 return lhs = lhs >> rhs;
3470 }
3471
John Bauman19bac1e2014-05-06 15:23:49 -04003472 RValue<UShort4> operator<<=(const UShort4 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04003473 {
3474 return lhs = lhs << rhs;
3475 }
3476
John Bauman19bac1e2014-05-06 15:23:49 -04003477 RValue<UShort4> operator>>=(const UShort4 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04003478 {
3479 return lhs = lhs >> rhs;
3480 }
3481
John Bauman19bac1e2014-05-06 15:23:49 -04003482 RValue<UShort4> operator~(RValue<UShort4> val)
John Bauman89401822014-05-06 15:04:28 -04003483 {
John Bauman19bac1e2014-05-06 15:23:49 -04003484 if(CPUID::supportsMMX2())
3485 {
3486 return As<UShort4>(As<Short4>(val) ^ Short4(0xFFFFu, 0xFFFFu, 0xFFFFu, 0xFFFFu));
3487 }
3488 else
3489 {
3490 return RValue<UShort4>(Nucleus::createNot(val.value));
3491 }
John Bauman89401822014-05-06 15:04:28 -04003492 }
3493
John Bauman19bac1e2014-05-06 15:23:49 -04003494 RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003495 {
John Bauman66b8ab22014-05-06 15:57:45 -04003496 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 -04003497 }
3498
John Bauman19bac1e2014-05-06 15:23:49 -04003499 RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003500 {
John Bauman66b8ab22014-05-06 15:57:45 -04003501 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 -04003502 }
3503
John Bauman19bac1e2014-05-06 15:23:49 -04003504 RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003505 {
3506 return x86::paddusw(x, y);
3507 }
3508
John Bauman19bac1e2014-05-06 15:23:49 -04003509 RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003510 {
3511 return x86::psubusw(x, y);
3512 }
3513
John Bauman19bac1e2014-05-06 15:23:49 -04003514 RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003515 {
3516 return x86::pmulhuw(x, y);
3517 }
3518
John Bauman19bac1e2014-05-06 15:23:49 -04003519 RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003520 {
3521 return x86::pavgw(x, y);
3522 }
3523
John Bauman19bac1e2014-05-06 15:23:49 -04003524 RValue<Byte8> Pack(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003525 {
3526 return x86::packuswb(x, y);
3527 }
3528
John Bauman19bac1e2014-05-06 15:23:49 -04003529 Type *UShort4::getType()
John Bauman89401822014-05-06 15:04:28 -04003530 {
John Bauman19bac1e2014-05-06 15:23:49 -04003531 if(CPUID::supportsMMX2())
3532 {
3533 return MMX::getType();
3534 }
3535 else
3536 {
Nicolas Capensac230122016-09-20 14:30:06 -04003537 return T(VectorType::get(UShort::getType(), 4));
John Bauman19bac1e2014-05-06 15:23:49 -04003538 }
John Bauman89401822014-05-06 15:04:28 -04003539 }
3540
3541 Short8::Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7)
3542 {
3543 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003544
3545 Constant *constantVector[8];
3546 constantVector[0] = Nucleus::createConstantShort(c0);
3547 constantVector[1] = Nucleus::createConstantShort(c1);
3548 constantVector[2] = Nucleus::createConstantShort(c2);
3549 constantVector[3] = Nucleus::createConstantShort(c3);
3550 constantVector[4] = Nucleus::createConstantShort(c4);
3551 constantVector[5] = Nucleus::createConstantShort(c5);
3552 constantVector[6] = Nucleus::createConstantShort(c6);
3553 constantVector[7] = Nucleus::createConstantShort(c7);
3554
John Bauman66b8ab22014-05-06 15:57:45 -04003555 storeValue(Nucleus::createConstantVector(constantVector, 8));
John Bauman89401822014-05-06 15:04:28 -04003556 }
3557
John Bauman19bac1e2014-05-06 15:23:49 -04003558 Short8::Short8(RValue<Short8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003559 {
3560 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003561
John Bauman66b8ab22014-05-06 15:57:45 -04003562 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003563 }
3564
Nicolas Capensef8cd662016-06-30 15:34:40 -04003565 Short8::Short8(const Reference<Short8> &rhs)
3566 {
3567 // xyzw.parent = this;
3568
3569 Value *value = rhs.loadValue();
3570 storeValue(value);
3571 }
3572
Nicolas Capens62abb552016-01-05 12:03:47 -05003573 Short8::Short8(RValue<Short4> lo, RValue<Short4> hi)
3574 {
3575 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
3576 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
3577
3578 Value *long2 = UndefValue::get(Long2::getType());
3579 long2 = Nucleus::createInsertElement(long2, loLong, 0);
3580 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
3581 Value *short8 = Nucleus::createBitCast(long2, Short8::getType());
3582
3583 storeValue(short8);
3584 }
3585
John Bauman19bac1e2014-05-06 15:23:49 -04003586 RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003587 {
3588 return RValue<Short8>(Nucleus::createAdd(lhs.value, rhs.value));
3589 }
3590
John Bauman19bac1e2014-05-06 15:23:49 -04003591 RValue<Short8> operator&(RValue<Short8> lhs, RValue<Short8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003592 {
3593 return RValue<Short8>(Nucleus::createAnd(lhs.value, rhs.value));
3594 }
3595
John Bauman19bac1e2014-05-06 15:23:49 -04003596 RValue<Short8> operator<<(RValue<Short8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003597 {
3598 return x86::psllw(lhs, rhs); // FIXME: Fallback required
3599 }
3600
John Bauman19bac1e2014-05-06 15:23:49 -04003601 RValue<Short8> operator>>(RValue<Short8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003602 {
3603 return x86::psraw(lhs, rhs); // FIXME: Fallback required
3604 }
3605
John Bauman19bac1e2014-05-06 15:23:49 -04003606 RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04003607 {
3608 return x86::pmaddwd(x, y); // FIXME: Fallback required
3609 }
3610
Alexis Hetu0f448072016-03-18 10:56:08 -04003611 RValue<Int4> Abs(RValue<Int4> x)
3612 {
3613 if(CPUID::supportsSSSE3())
3614 {
3615 return x86::pabsd(x);
3616 }
3617 else
3618 {
3619 Int4 mask = (x >> 31);
3620 return (mask ^ x) - mask;
3621 }
3622 }
3623
John Bauman19bac1e2014-05-06 15:23:49 -04003624 RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04003625 {
3626 return x86::pmulhw(x, y); // FIXME: Fallback required
3627 }
3628
John Bauman19bac1e2014-05-06 15:23:49 -04003629 Type *Short8::getType()
John Bauman89401822014-05-06 15:04:28 -04003630 {
Nicolas Capensac230122016-09-20 14:30:06 -04003631 return T(VectorType::get(Short::getType(), 8));
John Bauman89401822014-05-06 15:04:28 -04003632 }
3633
3634 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)
3635 {
3636 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003637
3638 Constant *constantVector[8];
3639 constantVector[0] = Nucleus::createConstantShort(c0);
3640 constantVector[1] = Nucleus::createConstantShort(c1);
3641 constantVector[2] = Nucleus::createConstantShort(c2);
3642 constantVector[3] = Nucleus::createConstantShort(c3);
3643 constantVector[4] = Nucleus::createConstantShort(c4);
3644 constantVector[5] = Nucleus::createConstantShort(c5);
3645 constantVector[6] = Nucleus::createConstantShort(c6);
3646 constantVector[7] = Nucleus::createConstantShort(c7);
3647
John Bauman66b8ab22014-05-06 15:57:45 -04003648 storeValue(Nucleus::createConstantVector(constantVector, 8));
John Bauman89401822014-05-06 15:04:28 -04003649 }
3650
John Bauman19bac1e2014-05-06 15:23:49 -04003651 UShort8::UShort8(RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003652 {
3653 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003654
John Bauman66b8ab22014-05-06 15:57:45 -04003655 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003656 }
3657
Nicolas Capensef8cd662016-06-30 15:34:40 -04003658 UShort8::UShort8(const Reference<UShort8> &rhs)
3659 {
3660 // xyzw.parent = this;
3661
3662 Value *value = rhs.loadValue();
3663 storeValue(value);
3664 }
3665
Nicolas Capens62abb552016-01-05 12:03:47 -05003666 UShort8::UShort8(RValue<UShort4> lo, RValue<UShort4> hi)
3667 {
3668 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
3669 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
3670
3671 Value *long2 = UndefValue::get(Long2::getType());
3672 long2 = Nucleus::createInsertElement(long2, loLong, 0);
3673 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
3674 Value *short8 = Nucleus::createBitCast(long2, Short8::getType());
3675
3676 storeValue(short8);
3677 }
3678
John Bauman19bac1e2014-05-06 15:23:49 -04003679 RValue<UShort8> UShort8::operator=(RValue<UShort8> rhs) const
John Bauman89401822014-05-06 15:04:28 -04003680 {
John Bauman66b8ab22014-05-06 15:57:45 -04003681 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003682
3683 return rhs;
3684 }
3685
3686 RValue<UShort8> UShort8::operator=(const UShort8 &rhs) const
3687 {
John Bauman66b8ab22014-05-06 15:57:45 -04003688 Value *value = rhs.loadValue();
3689 storeValue(value);
3690
3691 return RValue<UShort8>(value);
3692 }
3693
3694 RValue<UShort8> UShort8::operator=(const Reference<UShort8> &rhs) const
3695 {
3696 Value *value = rhs.loadValue();
3697 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003698
3699 return RValue<UShort8>(value);
3700 }
3701
John Bauman19bac1e2014-05-06 15:23:49 -04003702 RValue<UShort8> operator&(RValue<UShort8> lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003703 {
3704 return RValue<UShort8>(Nucleus::createAnd(lhs.value, rhs.value));
3705 }
3706
John Bauman19bac1e2014-05-06 15:23:49 -04003707 RValue<UShort8> operator<<(RValue<UShort8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003708 {
3709 return As<UShort8>(x86::psllw(As<Short8>(lhs), rhs)); // FIXME: Fallback required
3710 }
3711
John Bauman19bac1e2014-05-06 15:23:49 -04003712 RValue<UShort8> operator>>(RValue<UShort8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003713 {
3714 return x86::psrlw(lhs, rhs); // FIXME: Fallback required
3715 }
3716
John Bauman19bac1e2014-05-06 15:23:49 -04003717 RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003718 {
3719 return RValue<UShort8>(Nucleus::createAdd(lhs.value, rhs.value));
3720 }
3721
John Bauman19bac1e2014-05-06 15:23:49 -04003722 RValue<UShort8> operator*(RValue<UShort8> lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003723 {
3724 return RValue<UShort8>(Nucleus::createMul(lhs.value, rhs.value));
3725 }
3726
John Bauman19bac1e2014-05-06 15:23:49 -04003727 RValue<UShort8> operator+=(const UShort8 &lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003728 {
3729 return lhs = lhs + rhs;
3730 }
3731
John Bauman19bac1e2014-05-06 15:23:49 -04003732 RValue<UShort8> operator~(RValue<UShort8> val)
John Bauman89401822014-05-06 15:04:28 -04003733 {
3734 return RValue<UShort8>(Nucleus::createNot(val.value));
3735 }
3736
John Bauman19bac1e2014-05-06 15:23:49 -04003737 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 -04003738 {
3739 Constant *pshufb[16];
3740 pshufb[0] = Nucleus::createConstantInt(select0 + 0);
3741 pshufb[1] = Nucleus::createConstantInt(select0 + 1);
3742 pshufb[2] = Nucleus::createConstantInt(select1 + 0);
3743 pshufb[3] = Nucleus::createConstantInt(select1 + 1);
3744 pshufb[4] = Nucleus::createConstantInt(select2 + 0);
3745 pshufb[5] = Nucleus::createConstantInt(select2 + 1);
3746 pshufb[6] = Nucleus::createConstantInt(select3 + 0);
3747 pshufb[7] = Nucleus::createConstantInt(select3 + 1);
3748 pshufb[8] = Nucleus::createConstantInt(select4 + 0);
3749 pshufb[9] = Nucleus::createConstantInt(select4 + 1);
3750 pshufb[10] = Nucleus::createConstantInt(select5 + 0);
3751 pshufb[11] = Nucleus::createConstantInt(select5 + 1);
3752 pshufb[12] = Nucleus::createConstantInt(select6 + 0);
3753 pshufb[13] = Nucleus::createConstantInt(select6 + 1);
3754 pshufb[14] = Nucleus::createConstantInt(select7 + 0);
3755 pshufb[15] = Nucleus::createConstantInt(select7 + 1);
3756
3757 Value *byte16 = Nucleus::createBitCast(x.value, Byte16::getType());
3758 Value *shuffle = Nucleus::createShuffleVector(byte16, UndefValue::get(Byte16::getType()), Nucleus::createConstantVector(pshufb, 16));
3759 Value *short8 = Nucleus::createBitCast(shuffle, UShort8::getType());
3760
3761 return RValue<UShort8>(short8);
3762 }
3763
John Bauman19bac1e2014-05-06 15:23:49 -04003764 RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y)
John Bauman89401822014-05-06 15:04:28 -04003765 {
3766 return x86::pmulhuw(x, y); // FIXME: Fallback required
3767 }
3768
3769 // FIXME: Implement as Shuffle(x, y, Select(i0, ..., i16)) and Shuffle(x, y, SELECT_PACK_REPEAT(element))
John Bauman19bac1e2014-05-06 15:23:49 -04003770// RValue<UShort8> PackRepeat(RValue<Byte16> x, RValue<Byte16> y, int element)
John Bauman89401822014-05-06 15:04:28 -04003771// {
3772// Constant *pshufb[16];
3773// pshufb[0] = Nucleus::createConstantInt(element + 0);
3774// pshufb[1] = Nucleus::createConstantInt(element + 0);
3775// pshufb[2] = Nucleus::createConstantInt(element + 4);
3776// pshufb[3] = Nucleus::createConstantInt(element + 4);
3777// pshufb[4] = Nucleus::createConstantInt(element + 8);
3778// pshufb[5] = Nucleus::createConstantInt(element + 8);
3779// pshufb[6] = Nucleus::createConstantInt(element + 12);
3780// pshufb[7] = Nucleus::createConstantInt(element + 12);
3781// pshufb[8] = Nucleus::createConstantInt(element + 16);
3782// pshufb[9] = Nucleus::createConstantInt(element + 16);
3783// pshufb[10] = Nucleus::createConstantInt(element + 20);
3784// pshufb[11] = Nucleus::createConstantInt(element + 20);
3785// pshufb[12] = Nucleus::createConstantInt(element + 24);
3786// pshufb[13] = Nucleus::createConstantInt(element + 24);
3787// pshufb[14] = Nucleus::createConstantInt(element + 28);
3788// pshufb[15] = Nucleus::createConstantInt(element + 28);
3789//
3790// Value *shuffle = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(pshufb, 16));
3791// Value *short8 = Nucleus::createBitCast(shuffle, UShort8::getType());
3792//
3793// return RValue<UShort8>(short8);
3794// }
3795
John Bauman19bac1e2014-05-06 15:23:49 -04003796 Type *UShort8::getType()
John Bauman89401822014-05-06 15:04:28 -04003797 {
Nicolas Capensac230122016-09-20 14:30:06 -04003798 return T(VectorType::get(UShort::getType(), 8));
John Bauman89401822014-05-06 15:04:28 -04003799 }
3800
Nicolas Capens81f18302016-01-14 09:32:35 -05003801 Int::Int(Argument<Int> argument)
John Bauman89401822014-05-06 15:04:28 -04003802 {
Nicolas Capens81f18302016-01-14 09:32:35 -05003803 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04003804 }
3805
John Bauman19bac1e2014-05-06 15:23:49 -04003806 Int::Int(RValue<Byte> cast)
John Bauman89401822014-05-06 15:04:28 -04003807 {
John Bauman89401822014-05-06 15:04:28 -04003808 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3809
John Bauman66b8ab22014-05-06 15:57:45 -04003810 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003811 }
3812
John Bauman19bac1e2014-05-06 15:23:49 -04003813 Int::Int(RValue<SByte> cast)
John Bauman89401822014-05-06 15:04:28 -04003814 {
John Bauman89401822014-05-06 15:04:28 -04003815 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3816
John Bauman66b8ab22014-05-06 15:57:45 -04003817 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003818 }
3819
John Bauman19bac1e2014-05-06 15:23:49 -04003820 Int::Int(RValue<Short> cast)
John Bauman89401822014-05-06 15:04:28 -04003821 {
John Bauman89401822014-05-06 15:04:28 -04003822 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3823
John Bauman66b8ab22014-05-06 15:57:45 -04003824 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003825 }
3826
John Bauman19bac1e2014-05-06 15:23:49 -04003827 Int::Int(RValue<UShort> cast)
John Bauman89401822014-05-06 15:04:28 -04003828 {
John Bauman89401822014-05-06 15:04:28 -04003829 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3830
John Bauman66b8ab22014-05-06 15:57:45 -04003831 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003832 }
3833
John Bauman19bac1e2014-05-06 15:23:49 -04003834 Int::Int(RValue<Int2> cast)
John Bauman89401822014-05-06 15:04:28 -04003835 {
John Bauman89401822014-05-06 15:04:28 -04003836 *this = Extract(cast, 0);
3837 }
3838
John Bauman19bac1e2014-05-06 15:23:49 -04003839 Int::Int(RValue<Long> cast)
John Bauman89401822014-05-06 15:04:28 -04003840 {
John Bauman89401822014-05-06 15:04:28 -04003841 Value *integer = Nucleus::createTrunc(cast.value, Int::getType());
3842
John Bauman66b8ab22014-05-06 15:57:45 -04003843 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003844 }
3845
John Bauman19bac1e2014-05-06 15:23:49 -04003846 Int::Int(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04003847 {
John Bauman89401822014-05-06 15:04:28 -04003848 Value *integer = Nucleus::createFPToSI(cast.value, Int::getType());
3849
John Bauman66b8ab22014-05-06 15:57:45 -04003850 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003851 }
3852
3853 Int::Int()
3854 {
John Bauman89401822014-05-06 15:04:28 -04003855 }
3856
3857 Int::Int(int x)
3858 {
John Bauman66b8ab22014-05-06 15:57:45 -04003859 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04003860 }
3861
John Bauman19bac1e2014-05-06 15:23:49 -04003862 Int::Int(RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003863 {
John Bauman66b8ab22014-05-06 15:57:45 -04003864 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003865 }
3866
John Bauman19bac1e2014-05-06 15:23:49 -04003867 Int::Int(RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04003868 {
John Bauman66b8ab22014-05-06 15:57:45 -04003869 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003870 }
3871
3872 Int::Int(const Int &rhs)
3873 {
John Bauman66b8ab22014-05-06 15:57:45 -04003874 Value *value = rhs.loadValue();
3875 storeValue(value);
3876 }
John Bauman89401822014-05-06 15:04:28 -04003877
John Bauman66b8ab22014-05-06 15:57:45 -04003878 Int::Int(const Reference<Int> &rhs)
3879 {
3880 Value *value = rhs.loadValue();
3881 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003882 }
3883
3884 Int::Int(const UInt &rhs)
3885 {
John Bauman66b8ab22014-05-06 15:57:45 -04003886 Value *value = rhs.loadValue();
3887 storeValue(value);
3888 }
John Bauman89401822014-05-06 15:04:28 -04003889
John Bauman66b8ab22014-05-06 15:57:45 -04003890 Int::Int(const Reference<UInt> &rhs)
3891 {
3892 Value *value = rhs.loadValue();
3893 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003894 }
3895
3896 RValue<Int> Int::operator=(int rhs) const
3897 {
John Bauman66b8ab22014-05-06 15:57:45 -04003898 return RValue<Int>(storeValue(Nucleus::createConstantInt(rhs)));
John Bauman89401822014-05-06 15:04:28 -04003899 }
3900
John Bauman19bac1e2014-05-06 15:23:49 -04003901 RValue<Int> Int::operator=(RValue<Int> rhs) const
John Bauman89401822014-05-06 15:04:28 -04003902 {
John Bauman66b8ab22014-05-06 15:57:45 -04003903 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003904
3905 return rhs;
3906 }
3907
John Bauman19bac1e2014-05-06 15:23:49 -04003908 RValue<Int> Int::operator=(RValue<UInt> rhs) const
John Bauman89401822014-05-06 15:04:28 -04003909 {
John Bauman66b8ab22014-05-06 15:57:45 -04003910 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003911
John Bauman66b8ab22014-05-06 15:57:45 -04003912 return RValue<Int>(rhs);
John Bauman89401822014-05-06 15:04:28 -04003913 }
3914
3915 RValue<Int> Int::operator=(const Int &rhs) const
3916 {
John Bauman66b8ab22014-05-06 15:57:45 -04003917 Value *value = rhs.loadValue();
3918 storeValue(value);
3919
3920 return RValue<Int>(value);
3921 }
3922
3923 RValue<Int> Int::operator=(const Reference<Int> &rhs) const
3924 {
3925 Value *value = rhs.loadValue();
3926 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003927
3928 return RValue<Int>(value);
3929 }
3930
3931 RValue<Int> Int::operator=(const UInt &rhs) const
3932 {
John Bauman66b8ab22014-05-06 15:57:45 -04003933 Value *value = rhs.loadValue();
3934 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003935
3936 return RValue<Int>(value);
3937 }
3938
John Bauman66b8ab22014-05-06 15:57:45 -04003939 RValue<Int> Int::operator=(const Reference<UInt> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04003940 {
John Bauman66b8ab22014-05-06 15:57:45 -04003941 Value *value = rhs.loadValue();
3942 storeValue(value);
3943
3944 return RValue<Int>(value);
John Bauman89401822014-05-06 15:04:28 -04003945 }
3946
John Bauman19bac1e2014-05-06 15:23:49 -04003947 RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003948 {
3949 return RValue<Int>(Nucleus::createAdd(lhs.value, rhs.value));
3950 }
3951
John Bauman19bac1e2014-05-06 15:23:49 -04003952 RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003953 {
3954 return RValue<Int>(Nucleus::createSub(lhs.value, rhs.value));
3955 }
3956
John Bauman19bac1e2014-05-06 15:23:49 -04003957 RValue<Int> operator*(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003958 {
3959 return RValue<Int>(Nucleus::createMul(lhs.value, rhs.value));
3960 }
3961
John Bauman19bac1e2014-05-06 15:23:49 -04003962 RValue<Int> operator/(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003963 {
3964 return RValue<Int>(Nucleus::createSDiv(lhs.value, rhs.value));
3965 }
3966
John Bauman19bac1e2014-05-06 15:23:49 -04003967 RValue<Int> operator%(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003968 {
3969 return RValue<Int>(Nucleus::createSRem(lhs.value, rhs.value));
3970 }
3971
John Bauman19bac1e2014-05-06 15:23:49 -04003972 RValue<Int> operator&(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003973 {
3974 return RValue<Int>(Nucleus::createAnd(lhs.value, rhs.value));
3975 }
3976
John Bauman19bac1e2014-05-06 15:23:49 -04003977 RValue<Int> operator|(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003978 {
3979 return RValue<Int>(Nucleus::createOr(lhs.value, rhs.value));
3980 }
3981
John Bauman19bac1e2014-05-06 15:23:49 -04003982 RValue<Int> operator^(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003983 {
3984 return RValue<Int>(Nucleus::createXor(lhs.value, rhs.value));
3985 }
3986
John Bauman19bac1e2014-05-06 15:23:49 -04003987 RValue<Int> operator<<(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003988 {
3989 return RValue<Int>(Nucleus::createShl(lhs.value, rhs.value));
3990 }
3991
John Bauman19bac1e2014-05-06 15:23:49 -04003992 RValue<Int> operator>>(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003993 {
3994 return RValue<Int>(Nucleus::createAShr(lhs.value, rhs.value));
3995 }
3996
John Bauman19bac1e2014-05-06 15:23:49 -04003997 RValue<Int> operator+=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003998 {
3999 return lhs = lhs + rhs;
4000 }
4001
John Bauman19bac1e2014-05-06 15:23:49 -04004002 RValue<Int> operator-=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004003 {
4004 return lhs = lhs - rhs;
4005 }
4006
John Bauman19bac1e2014-05-06 15:23:49 -04004007 RValue<Int> operator*=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004008 {
4009 return lhs = lhs * rhs;
4010 }
4011
John Bauman19bac1e2014-05-06 15:23:49 -04004012 RValue<Int> operator/=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004013 {
4014 return lhs = lhs / rhs;
4015 }
4016
John Bauman19bac1e2014-05-06 15:23:49 -04004017 RValue<Int> operator%=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004018 {
4019 return lhs = lhs % rhs;
4020 }
4021
John Bauman19bac1e2014-05-06 15:23:49 -04004022 RValue<Int> operator&=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004023 {
4024 return lhs = lhs & rhs;
4025 }
4026
John Bauman19bac1e2014-05-06 15:23:49 -04004027 RValue<Int> operator|=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004028 {
4029 return lhs = lhs | rhs;
4030 }
4031
John Bauman19bac1e2014-05-06 15:23:49 -04004032 RValue<Int> operator^=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004033 {
4034 return lhs = lhs ^ rhs;
4035 }
4036
John Bauman19bac1e2014-05-06 15:23:49 -04004037 RValue<Int> operator<<=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004038 {
4039 return lhs = lhs << rhs;
4040 }
4041
John Bauman19bac1e2014-05-06 15:23:49 -04004042 RValue<Int> operator>>=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004043 {
4044 return lhs = lhs >> rhs;
4045 }
4046
John Bauman19bac1e2014-05-06 15:23:49 -04004047 RValue<Int> operator+(RValue<Int> val)
John Bauman89401822014-05-06 15:04:28 -04004048 {
4049 return val;
4050 }
4051
John Bauman19bac1e2014-05-06 15:23:49 -04004052 RValue<Int> operator-(RValue<Int> val)
John Bauman89401822014-05-06 15:04:28 -04004053 {
4054 return RValue<Int>(Nucleus::createNeg(val.value));
4055 }
4056
John Bauman19bac1e2014-05-06 15:23:49 -04004057 RValue<Int> operator~(RValue<Int> val)
John Bauman89401822014-05-06 15:04:28 -04004058 {
4059 return RValue<Int>(Nucleus::createNot(val.value));
4060 }
4061
4062 RValue<Int> operator++(const Int &val, int) // Post-increment
4063 {
4064 RValue<Int> res = val;
4065
4066 Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantInt(1));
John Bauman66b8ab22014-05-06 15:57:45 -04004067 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004068
4069 return res;
4070 }
4071
4072 const Int &operator++(const Int &val) // Pre-increment
4073 {
John Bauman66b8ab22014-05-06 15:57:45 -04004074 Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantInt(1));
4075 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004076
4077 return val;
4078 }
4079
4080 RValue<Int> operator--(const Int &val, int) // Post-decrement
4081 {
4082 RValue<Int> res = val;
4083
4084 Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantInt(1));
John Bauman66b8ab22014-05-06 15:57:45 -04004085 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004086
4087 return res;
4088 }
4089
4090 const Int &operator--(const Int &val) // Pre-decrement
4091 {
John Bauman66b8ab22014-05-06 15:57:45 -04004092 Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantInt(1));
4093 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004094
4095 return val;
4096 }
4097
John Bauman19bac1e2014-05-06 15:23:49 -04004098 RValue<Bool> operator<(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004099 {
4100 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
4101 }
4102
John Bauman19bac1e2014-05-06 15:23:49 -04004103 RValue<Bool> operator<=(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004104 {
4105 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
4106 }
4107
John Bauman19bac1e2014-05-06 15:23:49 -04004108 RValue<Bool> operator>(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004109 {
4110 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
4111 }
4112
John Bauman19bac1e2014-05-06 15:23:49 -04004113 RValue<Bool> operator>=(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004114 {
4115 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
4116 }
4117
John Bauman19bac1e2014-05-06 15:23:49 -04004118 RValue<Bool> operator!=(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004119 {
4120 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
4121 }
4122
John Bauman19bac1e2014-05-06 15:23:49 -04004123 RValue<Bool> operator==(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004124 {
4125 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
4126 }
4127
John Bauman19bac1e2014-05-06 15:23:49 -04004128 RValue<Int> Max(RValue<Int> x, RValue<Int> y)
4129 {
4130 return IfThenElse(x > y, x, y);
4131 }
4132
4133 RValue<Int> Min(RValue<Int> x, RValue<Int> y)
4134 {
4135 return IfThenElse(x < y, x, y);
4136 }
4137
4138 RValue<Int> Clamp(RValue<Int> x, RValue<Int> min, RValue<Int> max)
4139 {
4140 return Min(Max(x, min), max);
4141 }
4142
4143 RValue<Int> RoundInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04004144 {
4145 return x86::cvtss2si(cast);
4146
John Bauman66b8ab22014-05-06 15:57:45 -04004147 // return IfThenElse(val > 0.0f, Int(val + 0.5f), Int(val - 0.5f));
John Bauman89401822014-05-06 15:04:28 -04004148 }
4149
John Bauman19bac1e2014-05-06 15:23:49 -04004150 Type *Int::getType()
John Bauman89401822014-05-06 15:04:28 -04004151 {
Nicolas Capensac230122016-09-20 14:30:06 -04004152 return T(llvm::Type::getInt32Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04004153 }
4154
John Bauman19bac1e2014-05-06 15:23:49 -04004155 Long::Long(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04004156 {
John Bauman89401822014-05-06 15:04:28 -04004157 Value *integer = Nucleus::createSExt(cast.value, Long::getType());
4158
John Bauman66b8ab22014-05-06 15:57:45 -04004159 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04004160 }
4161
John Bauman19bac1e2014-05-06 15:23:49 -04004162 Long::Long(RValue<UInt> cast)
John Bauman89401822014-05-06 15:04:28 -04004163 {
John Bauman89401822014-05-06 15:04:28 -04004164 Value *integer = Nucleus::createZExt(cast.value, Long::getType());
4165
John Bauman66b8ab22014-05-06 15:57:45 -04004166 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04004167 }
4168
4169 Long::Long()
4170 {
John Bauman89401822014-05-06 15:04:28 -04004171 }
4172
John Bauman19bac1e2014-05-06 15:23:49 -04004173 Long::Long(RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04004174 {
John Bauman66b8ab22014-05-06 15:57:45 -04004175 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004176 }
4177
4178 RValue<Long> Long::operator=(int64_t rhs) const
4179 {
John Bauman66b8ab22014-05-06 15:57:45 -04004180 return RValue<Long>(storeValue(Nucleus::createConstantInt(rhs)));
John Bauman89401822014-05-06 15:04:28 -04004181 }
4182
John Bauman19bac1e2014-05-06 15:23:49 -04004183 RValue<Long> Long::operator=(RValue<Long> rhs) const
John Bauman89401822014-05-06 15:04:28 -04004184 {
John Bauman66b8ab22014-05-06 15:57:45 -04004185 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004186
4187 return rhs;
4188 }
4189
4190 RValue<Long> Long::operator=(const Long &rhs) const
4191 {
John Bauman66b8ab22014-05-06 15:57:45 -04004192 Value *value = rhs.loadValue();
4193 storeValue(value);
4194
4195 return RValue<Long>(value);
4196 }
4197
4198 RValue<Long> Long::operator=(const Reference<Long> &rhs) const
4199 {
4200 Value *value = rhs.loadValue();
4201 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004202
4203 return RValue<Long>(value);
4204 }
4205
John Bauman19bac1e2014-05-06 15:23:49 -04004206 RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04004207 {
4208 return RValue<Long>(Nucleus::createAdd(lhs.value, rhs.value));
4209 }
4210
John Bauman19bac1e2014-05-06 15:23:49 -04004211 RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04004212 {
4213 return RValue<Long>(Nucleus::createSub(lhs.value, rhs.value));
4214 }
4215
John Bauman19bac1e2014-05-06 15:23:49 -04004216 RValue<Long> operator+=(const Long &lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04004217 {
4218 return lhs = lhs + rhs;
4219 }
4220
John Bauman19bac1e2014-05-06 15:23:49 -04004221 RValue<Long> operator-=(const Long &lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04004222 {
4223 return lhs = lhs - rhs;
4224 }
4225
John Bauman66b8ab22014-05-06 15:57:45 -04004226 RValue<Long> AddAtomic(RValue<Pointer<Long> > x, RValue<Long> y)
John Bauman89401822014-05-06 15:04:28 -04004227 {
John Bauman19bac1e2014-05-06 15:23:49 -04004228 return RValue<Long>(Nucleus::createAtomicAdd(x.value, y.value));
John Bauman89401822014-05-06 15:04:28 -04004229 }
4230
John Bauman19bac1e2014-05-06 15:23:49 -04004231 Type *Long::getType()
John Bauman89401822014-05-06 15:04:28 -04004232 {
Nicolas Capensac230122016-09-20 14:30:06 -04004233 return T(llvm::Type::getInt64Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04004234 }
4235
Nicolas Capens50c96362016-01-04 23:03:59 -05004236 Long1::Long1(const RValue<UInt> cast)
John Bauman89401822014-05-06 15:04:28 -04004237 {
Nicolas Capens50c96362016-01-04 23:03:59 -05004238 Value *undefCast = Nucleus::createInsertElement(UndefValue::get(VectorType::get(Int::getType(), 2)), cast.value, 0);
4239 Value *zeroCast = Nucleus::createInsertElement(undefCast, Nucleus::createConstantInt(0), 1);
John Bauman66b8ab22014-05-06 15:57:45 -04004240
Nicolas Capens50c96362016-01-04 23:03:59 -05004241 storeValue(Nucleus::createBitCast(zeroCast, Long1::getType()));
John Bauman89401822014-05-06 15:04:28 -04004242 }
4243
John Bauman19bac1e2014-05-06 15:23:49 -04004244 Long1::Long1(RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004245 {
John Bauman66b8ab22014-05-06 15:57:45 -04004246 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004247 }
4248
John Bauman19bac1e2014-05-06 15:23:49 -04004249 Type *Long1::getType()
John Bauman89401822014-05-06 15:04:28 -04004250 {
John Bauman19bac1e2014-05-06 15:23:49 -04004251 if(CPUID::supportsMMX2())
4252 {
4253 return MMX::getType();
4254 }
4255 else
4256 {
Nicolas Capensac230122016-09-20 14:30:06 -04004257 return T(VectorType::get(Long::getType(), 1));
John Bauman19bac1e2014-05-06 15:23:49 -04004258 }
John Bauman89401822014-05-06 15:04:28 -04004259 }
4260
John Bauman19bac1e2014-05-06 15:23:49 -04004261 RValue<Long2> UnpackHigh(RValue<Long2> x, RValue<Long2> y)
John Bauman89401822014-05-06 15:04:28 -04004262 {
4263 Constant *shuffle[2];
4264 shuffle[0] = Nucleus::createConstantInt(1);
4265 shuffle[1] = Nucleus::createConstantInt(3);
4266
4267 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 2));
4268
4269 return RValue<Long2>(packed);
4270 }
4271
John Bauman19bac1e2014-05-06 15:23:49 -04004272 Type *Long2::getType()
John Bauman89401822014-05-06 15:04:28 -04004273 {
Nicolas Capensac230122016-09-20 14:30:06 -04004274 return T(VectorType::get(Long::getType(), 2));
John Bauman89401822014-05-06 15:04:28 -04004275 }
4276
Nicolas Capens81f18302016-01-14 09:32:35 -05004277 UInt::UInt(Argument<UInt> argument)
John Bauman89401822014-05-06 15:04:28 -04004278 {
Nicolas Capens81f18302016-01-14 09:32:35 -05004279 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04004280 }
4281
John Bauman19bac1e2014-05-06 15:23:49 -04004282 UInt::UInt(RValue<UShort> cast)
John Bauman89401822014-05-06 15:04:28 -04004283 {
John Bauman89401822014-05-06 15:04:28 -04004284 Value *integer = Nucleus::createZExt(cast.value, UInt::getType());
4285
John Bauman66b8ab22014-05-06 15:57:45 -04004286 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04004287 }
4288
John Bauman19bac1e2014-05-06 15:23:49 -04004289 UInt::UInt(RValue<Long> cast)
John Bauman89401822014-05-06 15:04:28 -04004290 {
John Bauman89401822014-05-06 15:04:28 -04004291 Value *integer = Nucleus::createTrunc(cast.value, UInt::getType());
4292
John Bauman66b8ab22014-05-06 15:57:45 -04004293 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04004294 }
4295
John Bauman19bac1e2014-05-06 15:23:49 -04004296 UInt::UInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04004297 {
Alexis Hetu764d1422016-09-28 08:44:22 -04004298 // Note: createFPToUI is broken, must perform conversion using createFPtoSI
4299 // Value *integer = Nucleus::createFPToUI(cast.value, UInt::getType());
John Bauman89401822014-05-06 15:04:28 -04004300
Alexis Hetu764d1422016-09-28 08:44:22 -04004301 // Smallest positive value representable in UInt, but not in Int
4302 const unsigned int ustart = 0x80000000u;
4303 const float ustartf = float(ustart);
4304
4305 // If the value is negative, store 0, otherwise store the result of the conversion
4306 storeValue((~(As<Int>(cast) >> 31) &
4307 // Check if the value can be represented as an Int
4308 IfThenElse(cast >= ustartf,
4309 // If the value is too large, subtract ustart and re-add it after conversion.
4310 As<Int>(As<UInt>(Int(cast - Float(ustartf))) + UInt(ustart)),
4311 // Otherwise, just convert normally
4312 Int(cast))).value);
John Bauman89401822014-05-06 15:04:28 -04004313 }
4314
4315 UInt::UInt()
4316 {
John Bauman89401822014-05-06 15:04:28 -04004317 }
4318
4319 UInt::UInt(int x)
4320 {
John Bauman66b8ab22014-05-06 15:57:45 -04004321 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04004322 }
4323
4324 UInt::UInt(unsigned int x)
4325 {
John Bauman66b8ab22014-05-06 15:57:45 -04004326 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04004327 }
4328
John Bauman19bac1e2014-05-06 15:23:49 -04004329 UInt::UInt(RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004330 {
John Bauman66b8ab22014-05-06 15:57:45 -04004331 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004332 }
4333
John Bauman19bac1e2014-05-06 15:23:49 -04004334 UInt::UInt(RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004335 {
John Bauman66b8ab22014-05-06 15:57:45 -04004336 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004337 }
4338
4339 UInt::UInt(const UInt &rhs)
4340 {
John Bauman66b8ab22014-05-06 15:57:45 -04004341 Value *value = rhs.loadValue();
4342 storeValue(value);
4343 }
John Bauman89401822014-05-06 15:04:28 -04004344
John Bauman66b8ab22014-05-06 15:57:45 -04004345 UInt::UInt(const Reference<UInt> &rhs)
4346 {
4347 Value *value = rhs.loadValue();
4348 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004349 }
4350
4351 UInt::UInt(const Int &rhs)
4352 {
John Bauman66b8ab22014-05-06 15:57:45 -04004353 Value *value = rhs.loadValue();
4354 storeValue(value);
4355 }
John Bauman89401822014-05-06 15:04:28 -04004356
John Bauman66b8ab22014-05-06 15:57:45 -04004357 UInt::UInt(const Reference<Int> &rhs)
4358 {
4359 Value *value = rhs.loadValue();
4360 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004361 }
4362
4363 RValue<UInt> UInt::operator=(unsigned int rhs) const
4364 {
John Bauman66b8ab22014-05-06 15:57:45 -04004365 return RValue<UInt>(storeValue(Nucleus::createConstantInt(rhs)));
John Bauman89401822014-05-06 15:04:28 -04004366 }
4367
John Bauman19bac1e2014-05-06 15:23:49 -04004368 RValue<UInt> UInt::operator=(RValue<UInt> rhs) const
John Bauman89401822014-05-06 15:04:28 -04004369 {
John Bauman66b8ab22014-05-06 15:57:45 -04004370 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004371
4372 return rhs;
4373 }
4374
John Bauman19bac1e2014-05-06 15:23:49 -04004375 RValue<UInt> UInt::operator=(RValue<Int> rhs) const
John Bauman89401822014-05-06 15:04:28 -04004376 {
John Bauman66b8ab22014-05-06 15:57:45 -04004377 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004378
John Bauman66b8ab22014-05-06 15:57:45 -04004379 return RValue<UInt>(rhs);
John Bauman89401822014-05-06 15:04:28 -04004380 }
4381
4382 RValue<UInt> UInt::operator=(const UInt &rhs) const
4383 {
John Bauman66b8ab22014-05-06 15:57:45 -04004384 Value *value = rhs.loadValue();
4385 storeValue(value);
4386
4387 return RValue<UInt>(value);
4388 }
4389
4390 RValue<UInt> UInt::operator=(const Reference<UInt> &rhs) const
4391 {
4392 Value *value = rhs.loadValue();
4393 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004394
4395 return RValue<UInt>(value);
4396 }
4397
4398 RValue<UInt> UInt::operator=(const Int &rhs) const
4399 {
John Bauman66b8ab22014-05-06 15:57:45 -04004400 Value *value = rhs.loadValue();
4401 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004402
4403 return RValue<UInt>(value);
4404 }
4405
John Bauman66b8ab22014-05-06 15:57:45 -04004406 RValue<UInt> UInt::operator=(const Reference<Int> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04004407 {
John Bauman66b8ab22014-05-06 15:57:45 -04004408 Value *value = rhs.loadValue();
4409 storeValue(value);
4410
4411 return RValue<UInt>(value);
John Bauman89401822014-05-06 15:04:28 -04004412 }
4413
John Bauman19bac1e2014-05-06 15:23:49 -04004414 RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004415 {
4416 return RValue<UInt>(Nucleus::createAdd(lhs.value, rhs.value));
4417 }
4418
John Bauman19bac1e2014-05-06 15:23:49 -04004419 RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004420 {
4421 return RValue<UInt>(Nucleus::createSub(lhs.value, rhs.value));
4422 }
4423
John Bauman19bac1e2014-05-06 15:23:49 -04004424 RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004425 {
4426 return RValue<UInt>(Nucleus::createMul(lhs.value, rhs.value));
4427 }
4428
John Bauman19bac1e2014-05-06 15:23:49 -04004429 RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004430 {
4431 return RValue<UInt>(Nucleus::createUDiv(lhs.value, rhs.value));
4432 }
4433
John Bauman19bac1e2014-05-06 15:23:49 -04004434 RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004435 {
4436 return RValue<UInt>(Nucleus::createURem(lhs.value, rhs.value));
4437 }
4438
John Bauman19bac1e2014-05-06 15:23:49 -04004439 RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004440 {
4441 return RValue<UInt>(Nucleus::createAnd(lhs.value, rhs.value));
4442 }
4443
John Bauman19bac1e2014-05-06 15:23:49 -04004444 RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004445 {
4446 return RValue<UInt>(Nucleus::createOr(lhs.value, rhs.value));
4447 }
4448
John Bauman19bac1e2014-05-06 15:23:49 -04004449 RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004450 {
4451 return RValue<UInt>(Nucleus::createXor(lhs.value, rhs.value));
4452 }
4453
John Bauman19bac1e2014-05-06 15:23:49 -04004454 RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004455 {
4456 return RValue<UInt>(Nucleus::createShl(lhs.value, rhs.value));
4457 }
4458
John Bauman19bac1e2014-05-06 15:23:49 -04004459 RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004460 {
4461 return RValue<UInt>(Nucleus::createLShr(lhs.value, rhs.value));
4462 }
4463
John Bauman19bac1e2014-05-06 15:23:49 -04004464 RValue<UInt> operator+=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004465 {
4466 return lhs = lhs + rhs;
4467 }
4468
John Bauman19bac1e2014-05-06 15:23:49 -04004469 RValue<UInt> operator-=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004470 {
4471 return lhs = lhs - rhs;
4472 }
4473
John Bauman19bac1e2014-05-06 15:23:49 -04004474 RValue<UInt> operator*=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004475 {
4476 return lhs = lhs * rhs;
4477 }
4478
John Bauman19bac1e2014-05-06 15:23:49 -04004479 RValue<UInt> operator/=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004480 {
4481 return lhs = lhs / rhs;
4482 }
4483
John Bauman19bac1e2014-05-06 15:23:49 -04004484 RValue<UInt> operator%=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004485 {
4486 return lhs = lhs % rhs;
4487 }
4488
John Bauman19bac1e2014-05-06 15:23:49 -04004489 RValue<UInt> operator&=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004490 {
4491 return lhs = lhs & rhs;
4492 }
4493
John Bauman19bac1e2014-05-06 15:23:49 -04004494 RValue<UInt> operator|=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004495 {
4496 return lhs = lhs | rhs;
4497 }
4498
John Bauman19bac1e2014-05-06 15:23:49 -04004499 RValue<UInt> operator^=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004500 {
4501 return lhs = lhs ^ rhs;
4502 }
4503
John Bauman19bac1e2014-05-06 15:23:49 -04004504 RValue<UInt> operator<<=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004505 {
4506 return lhs = lhs << rhs;
4507 }
4508
John Bauman19bac1e2014-05-06 15:23:49 -04004509 RValue<UInt> operator>>=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004510 {
4511 return lhs = lhs >> rhs;
4512 }
4513
John Bauman19bac1e2014-05-06 15:23:49 -04004514 RValue<UInt> operator+(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004515 {
4516 return val;
4517 }
4518
John Bauman19bac1e2014-05-06 15:23:49 -04004519 RValue<UInt> operator-(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004520 {
4521 return RValue<UInt>(Nucleus::createNeg(val.value));
4522 }
4523
John Bauman19bac1e2014-05-06 15:23:49 -04004524 RValue<UInt> operator~(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004525 {
4526 return RValue<UInt>(Nucleus::createNot(val.value));
4527 }
4528
4529 RValue<UInt> operator++(const UInt &val, int) // Post-increment
4530 {
4531 RValue<UInt> res = val;
4532
4533 Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantInt(1));
John Bauman66b8ab22014-05-06 15:57:45 -04004534 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004535
4536 return res;
4537 }
4538
4539 const UInt &operator++(const UInt &val) // Pre-increment
4540 {
John Bauman66b8ab22014-05-06 15:57:45 -04004541 Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantInt(1));
4542 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004543
4544 return val;
4545 }
4546
4547 RValue<UInt> operator--(const UInt &val, int) // Post-decrement
4548 {
4549 RValue<UInt> res = val;
4550
4551 Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantInt(1));
John Bauman66b8ab22014-05-06 15:57:45 -04004552 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004553
4554 return res;
4555 }
4556
4557 const UInt &operator--(const UInt &val) // Pre-decrement
4558 {
John Bauman66b8ab22014-05-06 15:57:45 -04004559 Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantInt(1));
4560 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004561
4562 return val;
4563 }
4564
John Bauman19bac1e2014-05-06 15:23:49 -04004565 RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y)
4566 {
4567 return IfThenElse(x > y, x, y);
4568 }
4569
4570 RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y)
4571 {
4572 return IfThenElse(x < y, x, y);
4573 }
4574
4575 RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max)
4576 {
4577 return Min(Max(x, min), max);
4578 }
4579
4580 RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004581 {
4582 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
4583 }
4584
John Bauman19bac1e2014-05-06 15:23:49 -04004585 RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004586 {
4587 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
4588 }
4589
John Bauman19bac1e2014-05-06 15:23:49 -04004590 RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004591 {
4592 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
4593 }
4594
John Bauman19bac1e2014-05-06 15:23:49 -04004595 RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004596 {
4597 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
4598 }
4599
John Bauman19bac1e2014-05-06 15:23:49 -04004600 RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004601 {
4602 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
4603 }
4604
John Bauman19bac1e2014-05-06 15:23:49 -04004605 RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004606 {
4607 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
4608 }
4609
John Bauman19bac1e2014-05-06 15:23:49 -04004610// RValue<UInt> RoundUInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04004611// {
4612// return x86::cvtss2si(val); // FIXME: Unsigned
4613//
John Bauman66b8ab22014-05-06 15:57:45 -04004614// // return IfThenElse(val > 0.0f, Int(val + 0.5f), Int(val - 0.5f));
John Bauman89401822014-05-06 15:04:28 -04004615// }
4616
John Bauman19bac1e2014-05-06 15:23:49 -04004617 Type *UInt::getType()
John Bauman89401822014-05-06 15:04:28 -04004618 {
Nicolas Capensac230122016-09-20 14:30:06 -04004619 return T(llvm::Type::getInt32Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04004620 }
4621
John Bauman19bac1e2014-05-06 15:23:49 -04004622// Int2::Int2(RValue<Int> cast)
4623// {
John Bauman19bac1e2014-05-06 15:23:49 -04004624// Value *extend = Nucleus::createZExt(cast.value, Long::getType());
4625// Value *vector = Nucleus::createBitCast(extend, Int2::getType());
John Bauman66b8ab22014-05-06 15:57:45 -04004626//
John Bauman19bac1e2014-05-06 15:23:49 -04004627// Constant *shuffle[2];
4628// shuffle[0] = Nucleus::createConstantInt(0);
4629// shuffle[1] = Nucleus::createConstantInt(0);
4630//
4631// Value *replicate = Nucleus::createShuffleVector(vector, UndefValue::get(Int2::getType()), Nucleus::createConstantVector(shuffle, 2));
4632//
John Bauman66b8ab22014-05-06 15:57:45 -04004633// storeValue(replicate);
John Bauman19bac1e2014-05-06 15:23:49 -04004634// }
John Bauman89401822014-05-06 15:04:28 -04004635
John Bauman19bac1e2014-05-06 15:23:49 -04004636 Int2::Int2(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04004637 {
John Bauman89401822014-05-06 15:04:28 -04004638 Value *long2 = Nucleus::createBitCast(cast.value, Long2::getType());
4639 Value *element = Nucleus::createExtractElement(long2, 0);
4640 Value *int2 = Nucleus::createBitCast(element, Int2::getType());
4641
John Bauman66b8ab22014-05-06 15:57:45 -04004642 storeValue(int2);
John Bauman89401822014-05-06 15:04:28 -04004643 }
4644
4645 Int2::Int2()
4646 {
4647 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004648 }
4649
4650 Int2::Int2(int x, int y)
4651 {
4652 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004653
4654 Constant *constantVector[2];
4655 constantVector[0] = Nucleus::createConstantInt(x);
4656 constantVector[1] = Nucleus::createConstantInt(y);
John Bauman19bac1e2014-05-06 15:23:49 -04004657 Value *vector = Nucleus::createConstantVector(constantVector, 2);
John Bauman89401822014-05-06 15:04:28 -04004658
John Bauman66b8ab22014-05-06 15:57:45 -04004659 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04004660 }
4661
John Bauman19bac1e2014-05-06 15:23:49 -04004662 Int2::Int2(RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004663 {
4664 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004665
John Bauman66b8ab22014-05-06 15:57:45 -04004666 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004667 }
4668
4669 Int2::Int2(const Int2 &rhs)
4670 {
4671 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004672
John Bauman66b8ab22014-05-06 15:57:45 -04004673 Value *value = rhs.loadValue();
4674 storeValue(value);
4675 }
4676
4677 Int2::Int2(const Reference<Int2> &rhs)
4678 {
4679 // xy.parent = this;
4680
4681 Value *value = rhs.loadValue();
4682 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004683 }
4684
Nicolas Capens62abb552016-01-05 12:03:47 -05004685 Int2::Int2(RValue<Int> lo, RValue<Int> hi)
4686 {
Nicolas Capensb40a2562016-01-05 00:08:45 -05004687 if(CPUID::supportsMMX2())
4688 {
4689 // movd mm0, lo
4690 // movd mm1, hi
4691 // punpckldq mm0, mm1
4692 storeValue(As<Int2>(UnpackLow(As<Int2>(Long1(RValue<UInt>(lo))), As<Int2>(Long1(RValue<UInt>(hi))))).value);
4693 }
4694 else
4695 {
4696 Constant *shuffle[2];
4697 shuffle[0] = Nucleus::createConstantInt(0);
4698 shuffle[1] = Nucleus::createConstantInt(1);
Nicolas Capens05b3d662016-02-25 23:58:33 -05004699
Nicolas Capensac230122016-09-20 14:30:06 -04004700 Value *packed = Nucleus::createShuffleVector(Nucleus::createBitCast(lo.value, T(VectorType::get(Int::getType(), 1))), Nucleus::createBitCast(hi.value, T(VectorType::get(Int::getType(), 1))), Nucleus::createConstantVector(shuffle, 2));
Nicolas Capens05b3d662016-02-25 23:58:33 -05004701
Nicolas Capensb40a2562016-01-05 00:08:45 -05004702 storeValue(Nucleus::createBitCast(packed, Int2::getType()));
4703 }
Nicolas Capens62abb552016-01-05 12:03:47 -05004704 }
4705
John Bauman19bac1e2014-05-06 15:23:49 -04004706 RValue<Int2> Int2::operator=(RValue<Int2> rhs) const
John Bauman89401822014-05-06 15:04:28 -04004707 {
John Bauman66b8ab22014-05-06 15:57:45 -04004708 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004709
4710 return rhs;
4711 }
4712
4713 RValue<Int2> Int2::operator=(const Int2 &rhs) const
4714 {
John Bauman66b8ab22014-05-06 15:57:45 -04004715 Value *value = rhs.loadValue();
4716 storeValue(value);
4717
4718 return RValue<Int2>(value);
4719 }
4720
4721 RValue<Int2> Int2::operator=(const Reference<Int2> &rhs) const
4722 {
4723 Value *value = rhs.loadValue();
4724 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004725
4726 return RValue<Int2>(value);
4727 }
4728
John Bauman19bac1e2014-05-06 15:23:49 -04004729 RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004730 {
John Bauman19bac1e2014-05-06 15:23:49 -04004731 if(CPUID::supportsMMX2())
4732 {
4733 return x86::paddd(lhs, rhs);
4734 }
4735 else
4736 {
4737 return RValue<Int2>(Nucleus::createAdd(lhs.value, rhs.value));
4738 }
John Bauman89401822014-05-06 15:04:28 -04004739 }
4740
John Bauman19bac1e2014-05-06 15:23:49 -04004741 RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004742 {
John Bauman19bac1e2014-05-06 15:23:49 -04004743 if(CPUID::supportsMMX2())
4744 {
4745 return x86::psubd(lhs, rhs);
4746 }
4747 else
4748 {
4749 return RValue<Int2>(Nucleus::createSub(lhs.value, rhs.value));
4750 }
John Bauman89401822014-05-06 15:04:28 -04004751 }
4752
John Bauman19bac1e2014-05-06 15:23:49 -04004753// RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs)
4754// {
4755// return RValue<Int2>(Nucleus::createMul(lhs.value, rhs.value));
4756// }
4757
4758// RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs)
4759// {
4760// return RValue<Int2>(Nucleus::createSDiv(lhs.value, rhs.value));
4761// }
4762
4763// RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs)
4764// {
4765// return RValue<Int2>(Nucleus::createSRem(lhs.value, rhs.value));
4766// }
4767
4768 RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004769 {
John Bauman19bac1e2014-05-06 15:23:49 -04004770 if(CPUID::supportsMMX2())
4771 {
4772 return As<Int2>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
4773 }
4774 else
4775 {
4776 return RValue<Int2>(Nucleus::createAnd(lhs.value, rhs.value));
4777 }
John Bauman89401822014-05-06 15:04:28 -04004778 }
4779
John Bauman19bac1e2014-05-06 15:23:49 -04004780 RValue<Int2> operator|(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004781 {
John Bauman19bac1e2014-05-06 15:23:49 -04004782 if(CPUID::supportsMMX2())
4783 {
4784 return As<Int2>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
4785 }
4786 else
4787 {
4788 return RValue<Int2>(Nucleus::createOr(lhs.value, rhs.value));
4789 }
John Bauman89401822014-05-06 15:04:28 -04004790 }
4791
John Bauman19bac1e2014-05-06 15:23:49 -04004792 RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004793 {
John Bauman19bac1e2014-05-06 15:23:49 -04004794 if(CPUID::supportsMMX2())
4795 {
4796 return As<Int2>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
4797 }
4798 else
4799 {
4800 return RValue<Int2>(Nucleus::createXor(lhs.value, rhs.value));
4801 }
John Bauman89401822014-05-06 15:04:28 -04004802 }
4803
John Bauman19bac1e2014-05-06 15:23:49 -04004804 RValue<Int2> operator<<(RValue<Int2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004805 {
4806 // return RValue<Int2>(Nucleus::createShl(lhs.value, rhs.value));
4807
4808 return x86::pslld(lhs, rhs);
4809 }
4810
John Bauman19bac1e2014-05-06 15:23:49 -04004811 RValue<Int2> operator>>(RValue<Int2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004812 {
4813 // return RValue<Int2>(Nucleus::createAShr(lhs.value, rhs.value));
4814
4815 return x86::psrad(lhs, rhs);
4816 }
4817
John Bauman19bac1e2014-05-06 15:23:49 -04004818 RValue<Int2> operator<<(RValue<Int2> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004819 {
4820 // return RValue<Int2>(Nucleus::createShl(lhs.value, rhs.value));
4821
4822 return x86::pslld(lhs, rhs);
4823 }
4824
John Bauman19bac1e2014-05-06 15:23:49 -04004825 RValue<Int2> operator>>(RValue<Int2> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004826 {
4827 // return RValue<Int2>(Nucleus::createAShr(lhs.value, rhs.value));
4828
4829 return x86::psrad(lhs, rhs);
4830 }
4831
John Bauman19bac1e2014-05-06 15:23:49 -04004832 RValue<Int2> operator+=(const Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004833 {
4834 return lhs = lhs + rhs;
4835 }
4836
John Bauman19bac1e2014-05-06 15:23:49 -04004837 RValue<Int2> operator-=(const Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004838 {
4839 return lhs = lhs - rhs;
4840 }
4841
John Bauman19bac1e2014-05-06 15:23:49 -04004842// RValue<Int2> operator*=(const Int2 &lhs, RValue<Int2> rhs)
4843// {
4844// return lhs = lhs * rhs;
4845// }
John Bauman89401822014-05-06 15:04:28 -04004846
John Bauman19bac1e2014-05-06 15:23:49 -04004847// RValue<Int2> operator/=(const Int2 &lhs, RValue<Int2> rhs)
4848// {
4849// return lhs = lhs / rhs;
4850// }
John Bauman89401822014-05-06 15:04:28 -04004851
John Bauman19bac1e2014-05-06 15:23:49 -04004852// RValue<Int2> operator%=(const Int2 &lhs, RValue<Int2> rhs)
4853// {
4854// return lhs = lhs % rhs;
4855// }
John Bauman89401822014-05-06 15:04:28 -04004856
John Bauman19bac1e2014-05-06 15:23:49 -04004857 RValue<Int2> operator&=(const Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004858 {
4859 return lhs = lhs & rhs;
4860 }
4861
John Bauman19bac1e2014-05-06 15:23:49 -04004862 RValue<Int2> operator|=(const Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004863 {
4864 return lhs = lhs | rhs;
4865 }
4866
John Bauman19bac1e2014-05-06 15:23:49 -04004867 RValue<Int2> operator^=(const Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004868 {
4869 return lhs = lhs ^ rhs;
4870 }
4871
4872 RValue<Int2> operator<<=(const Int2 &lhs, unsigned char rhs)
4873 {
4874 return lhs = lhs << rhs;
4875 }
4876
4877 RValue<Int2> operator>>=(const Int2 &lhs, unsigned char rhs)
4878 {
4879 return lhs = lhs >> rhs;
4880 }
4881
John Bauman19bac1e2014-05-06 15:23:49 -04004882 RValue<Int2> operator<<=(const Int2 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004883 {
4884 return lhs = lhs << rhs;
4885 }
4886
John Bauman19bac1e2014-05-06 15:23:49 -04004887 RValue<Int2> operator>>=(const Int2 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004888 {
4889 return lhs = lhs >> rhs;
4890 }
4891
John Bauman19bac1e2014-05-06 15:23:49 -04004892// RValue<Int2> operator+(RValue<Int2> val)
4893// {
4894// return val;
4895// }
4896
4897// RValue<Int2> operator-(RValue<Int2> val)
4898// {
4899// return RValue<Int2>(Nucleus::createNeg(val.value));
4900// }
4901
4902 RValue<Int2> operator~(RValue<Int2> val)
John Bauman89401822014-05-06 15:04:28 -04004903 {
John Bauman19bac1e2014-05-06 15:23:49 -04004904 if(CPUID::supportsMMX2())
4905 {
4906 return val ^ Int2(0xFFFFFFFF, 0xFFFFFFFF);
4907 }
4908 else
4909 {
4910 return RValue<Int2>(Nucleus::createNot(val.value));
4911 }
John Bauman89401822014-05-06 15:04:28 -04004912 }
4913
John Bauman19bac1e2014-05-06 15:23:49 -04004914 RValue<Long1> UnpackLow(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04004915 {
John Bauman19bac1e2014-05-06 15:23:49 -04004916 if(CPUID::supportsMMX2())
4917 {
4918 return x86::punpckldq(x, y);
4919 }
4920 else
4921 {
4922 Constant *shuffle[2];
4923 shuffle[0] = Nucleus::createConstantInt(0);
4924 shuffle[1] = Nucleus::createConstantInt(2);
John Bauman89401822014-05-06 15:04:28 -04004925
John Bauman19bac1e2014-05-06 15:23:49 -04004926 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 2));
John Bauman89401822014-05-06 15:04:28 -04004927
John Bauman19bac1e2014-05-06 15:23:49 -04004928 return RValue<Long1>(Nucleus::createBitCast(packed, Long1::getType()));
4929 }
John Bauman89401822014-05-06 15:04:28 -04004930 }
John Bauman66b8ab22014-05-06 15:57:45 -04004931
John Bauman19bac1e2014-05-06 15:23:49 -04004932 RValue<Long1> UnpackHigh(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04004933 {
John Bauman19bac1e2014-05-06 15:23:49 -04004934 if(CPUID::supportsMMX2())
4935 {
4936 return x86::punpckhdq(x, y);
4937 }
4938 else
4939 {
4940 Constant *shuffle[2];
4941 shuffle[0] = Nucleus::createConstantInt(1);
4942 shuffle[1] = Nucleus::createConstantInt(3);
John Bauman89401822014-05-06 15:04:28 -04004943
John Bauman19bac1e2014-05-06 15:23:49 -04004944 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 2));
John Bauman89401822014-05-06 15:04:28 -04004945
John Bauman19bac1e2014-05-06 15:23:49 -04004946 return RValue<Long1>(Nucleus::createBitCast(packed, Long1::getType()));
4947 }
John Bauman89401822014-05-06 15:04:28 -04004948 }
4949
John Bauman19bac1e2014-05-06 15:23:49 -04004950 RValue<Int> Extract(RValue<Int2> val, int i)
John Bauman89401822014-05-06 15:04:28 -04004951 {
4952 if(false) // FIXME: LLVM does not generate optimal code
4953 {
4954 return RValue<Int>(Nucleus::createExtractElement(val.value, i));
4955 }
4956 else
4957 {
4958 if(i == 0)
4959 {
Nicolas Capensac230122016-09-20 14:30:06 -04004960 return RValue<Int>(Nucleus::createExtractElement(Nucleus::createBitCast(val.value, T(VectorType::get(Int::getType(), 2))), 0));
John Bauman89401822014-05-06 15:04:28 -04004961 }
4962 else
4963 {
4964 Int2 val2 = As<Int2>(UnpackHigh(val, val));
4965
4966 return Extract(val2, 0);
4967 }
4968 }
4969 }
4970
Nicolas Capensfff3c9b2015-05-13 23:40:44 -04004971 RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i)
4972 {
Nicolas Capensac230122016-09-20 14:30:06 -04004973 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 -04004974 }
John Bauman89401822014-05-06 15:04:28 -04004975
John Bauman19bac1e2014-05-06 15:23:49 -04004976 Type *Int2::getType()
John Bauman89401822014-05-06 15:04:28 -04004977 {
John Bauman19bac1e2014-05-06 15:23:49 -04004978 if(CPUID::supportsMMX2())
4979 {
4980 return MMX::getType();
4981 }
4982 else
4983 {
Nicolas Capensac230122016-09-20 14:30:06 -04004984 return T(VectorType::get(Int::getType(), 2));
John Bauman19bac1e2014-05-06 15:23:49 -04004985 }
John Bauman89401822014-05-06 15:04:28 -04004986 }
4987
4988 UInt2::UInt2()
4989 {
4990 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004991 }
4992
4993 UInt2::UInt2(unsigned int x, unsigned int y)
4994 {
4995 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004996
4997 Constant *constantVector[2];
4998 constantVector[0] = Nucleus::createConstantInt(x);
4999 constantVector[1] = Nucleus::createConstantInt(y);
John Bauman19bac1e2014-05-06 15:23:49 -04005000 Value *vector = Nucleus::createConstantVector(constantVector, 2);
John Bauman89401822014-05-06 15:04:28 -04005001
John Bauman66b8ab22014-05-06 15:57:45 -04005002 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04005003 }
5004
John Bauman19bac1e2014-05-06 15:23:49 -04005005 UInt2::UInt2(RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005006 {
5007 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005008
John Bauman66b8ab22014-05-06 15:57:45 -04005009 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005010 }
5011
5012 UInt2::UInt2(const UInt2 &rhs)
5013 {
5014 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005015
John Bauman66b8ab22014-05-06 15:57:45 -04005016 Value *value = rhs.loadValue();
5017 storeValue(value);
5018 }
5019
5020 UInt2::UInt2(const Reference<UInt2> &rhs)
5021 {
5022 // xy.parent = this;
5023
5024 Value *value = rhs.loadValue();
5025 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005026 }
5027
John Bauman19bac1e2014-05-06 15:23:49 -04005028 RValue<UInt2> UInt2::operator=(RValue<UInt2> rhs) const
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
5035 RValue<UInt2> UInt2::operator=(const UInt2 &rhs) const
5036 {
John Bauman66b8ab22014-05-06 15:57:45 -04005037 Value *value = rhs.loadValue();
5038 storeValue(value);
5039
5040 return RValue<UInt2>(value);
5041 }
5042
5043 RValue<UInt2> UInt2::operator=(const Reference<UInt2> &rhs) const
5044 {
5045 Value *value = rhs.loadValue();
5046 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005047
5048 return RValue<UInt2>(value);
5049 }
5050
John Bauman19bac1e2014-05-06 15:23:49 -04005051 RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005052 {
John Bauman19bac1e2014-05-06 15:23:49 -04005053 if(CPUID::supportsMMX2())
5054 {
5055 return As<UInt2>(x86::paddd(As<Int2>(lhs), As<Int2>(rhs)));
5056 }
5057 else
5058 {
5059 return RValue<UInt2>(Nucleus::createAdd(lhs.value, rhs.value));
5060 }
John Bauman89401822014-05-06 15:04:28 -04005061 }
5062
John Bauman19bac1e2014-05-06 15:23:49 -04005063 RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005064 {
John Bauman19bac1e2014-05-06 15:23:49 -04005065 if(CPUID::supportsMMX2())
5066 {
5067 return As<UInt2>(x86::psubd(As<Int2>(lhs), As<Int2>(rhs)));
5068 }
5069 else
5070 {
5071 return RValue<UInt2>(Nucleus::createSub(lhs.value, rhs.value));
5072 }
John Bauman89401822014-05-06 15:04:28 -04005073 }
5074
John Bauman19bac1e2014-05-06 15:23:49 -04005075// RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs)
5076// {
5077// return RValue<UInt2>(Nucleus::createMul(lhs.value, rhs.value));
5078// }
5079
5080// RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs)
5081// {
5082// return RValue<UInt2>(Nucleus::createUDiv(lhs.value, rhs.value));
5083// }
5084
5085// RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs)
5086// {
5087// return RValue<UInt2>(Nucleus::createURem(lhs.value, rhs.value));
5088// }
5089
5090 RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005091 {
John Bauman19bac1e2014-05-06 15:23:49 -04005092 if(CPUID::supportsMMX2())
5093 {
5094 return As<UInt2>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
5095 }
5096 else
5097 {
5098 return RValue<UInt2>(Nucleus::createAnd(lhs.value, rhs.value));
5099 }
John Bauman89401822014-05-06 15:04:28 -04005100 }
5101
John Bauman19bac1e2014-05-06 15:23:49 -04005102 RValue<UInt2> operator|(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005103 {
John Bauman19bac1e2014-05-06 15:23:49 -04005104 if(CPUID::supportsMMX2())
5105 {
5106 return As<UInt2>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
5107 }
5108 else
5109 {
5110 return RValue<UInt2>(Nucleus::createOr(lhs.value, rhs.value));
5111 }
John Bauman89401822014-05-06 15:04:28 -04005112 }
5113
John Bauman19bac1e2014-05-06 15:23:49 -04005114 RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005115 {
John Bauman19bac1e2014-05-06 15:23:49 -04005116 if(CPUID::supportsMMX2())
5117 {
5118 return As<UInt2>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
5119 }
5120 else
5121 {
5122 return RValue<UInt2>(Nucleus::createXor(lhs.value, rhs.value));
5123 }
John Bauman89401822014-05-06 15:04:28 -04005124 }
5125
John Bauman19bac1e2014-05-06 15:23:49 -04005126 RValue<UInt2> operator<<(RValue<UInt2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005127 {
5128 // return RValue<UInt2>(Nucleus::createShl(lhs.value, rhs.value));
5129
5130 return As<UInt2>(x86::pslld(As<Int2>(lhs), rhs));
5131 }
5132
John Bauman19bac1e2014-05-06 15:23:49 -04005133 RValue<UInt2> operator>>(RValue<UInt2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005134 {
5135 // return RValue<UInt2>(Nucleus::createLShr(lhs.value, rhs.value));
5136
5137 return x86::psrld(lhs, rhs);
5138 }
5139
John Bauman19bac1e2014-05-06 15:23:49 -04005140 RValue<UInt2> operator<<(RValue<UInt2> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04005141 {
5142 // return RValue<UInt2>(Nucleus::createShl(lhs.value, rhs.value));
5143
5144 return As<UInt2>(x86::pslld(As<Int2>(lhs), rhs));
5145 }
5146
John Bauman19bac1e2014-05-06 15:23:49 -04005147 RValue<UInt2> operator>>(RValue<UInt2> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04005148 {
5149 // return RValue<UInt2>(Nucleus::createLShr(lhs.value, rhs.value));
5150
5151 return x86::psrld(lhs, rhs);
5152 }
5153
John Bauman19bac1e2014-05-06 15:23:49 -04005154 RValue<UInt2> operator+=(const UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005155 {
5156 return lhs = lhs + rhs;
5157 }
5158
John Bauman19bac1e2014-05-06 15:23:49 -04005159 RValue<UInt2> operator-=(const UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005160 {
5161 return lhs = lhs - rhs;
5162 }
5163
John Bauman19bac1e2014-05-06 15:23:49 -04005164// RValue<UInt2> operator*=(const UInt2 &lhs, RValue<UInt2> rhs)
5165// {
5166// return lhs = lhs * rhs;
5167// }
John Bauman89401822014-05-06 15:04:28 -04005168
John Bauman19bac1e2014-05-06 15:23:49 -04005169// RValue<UInt2> operator/=(const UInt2 &lhs, RValue<UInt2> rhs)
5170// {
5171// return lhs = lhs / rhs;
5172// }
John Bauman89401822014-05-06 15:04:28 -04005173
John Bauman19bac1e2014-05-06 15:23:49 -04005174// RValue<UInt2> operator%=(const UInt2 &lhs, RValue<UInt2> rhs)
5175// {
5176// return lhs = lhs % rhs;
5177// }
John Bauman89401822014-05-06 15:04:28 -04005178
John Bauman19bac1e2014-05-06 15:23:49 -04005179 RValue<UInt2> operator&=(const UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005180 {
5181 return lhs = lhs & rhs;
5182 }
5183
John Bauman19bac1e2014-05-06 15:23:49 -04005184 RValue<UInt2> operator|=(const UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005185 {
5186 return lhs = lhs | rhs;
5187 }
5188
John Bauman19bac1e2014-05-06 15:23:49 -04005189 RValue<UInt2> operator^=(const UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005190 {
5191 return lhs = lhs ^ rhs;
5192 }
5193
5194 RValue<UInt2> operator<<=(const UInt2 &lhs, unsigned char rhs)
5195 {
5196 return lhs = lhs << rhs;
5197 }
5198
5199 RValue<UInt2> operator>>=(const UInt2 &lhs, unsigned char rhs)
5200 {
5201 return lhs = lhs >> rhs;
5202 }
5203
John Bauman19bac1e2014-05-06 15:23:49 -04005204 RValue<UInt2> operator<<=(const UInt2 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04005205 {
5206 return lhs = lhs << rhs;
5207 }
5208
John Bauman19bac1e2014-05-06 15:23:49 -04005209 RValue<UInt2> operator>>=(const UInt2 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04005210 {
5211 return lhs = lhs >> rhs;
5212 }
5213
John Bauman19bac1e2014-05-06 15:23:49 -04005214// RValue<UInt2> operator+(RValue<UInt2> val)
5215// {
5216// return val;
5217// }
5218
5219// RValue<UInt2> operator-(RValue<UInt2> val)
5220// {
5221// return RValue<UInt2>(Nucleus::createNeg(val.value));
5222// }
5223
5224 RValue<UInt2> operator~(RValue<UInt2> val)
John Bauman89401822014-05-06 15:04:28 -04005225 {
John Bauman19bac1e2014-05-06 15:23:49 -04005226 if(CPUID::supportsMMX2())
5227 {
5228 return val ^ UInt2(0xFFFFFFFF, 0xFFFFFFFF);
5229 }
5230 else
5231 {
5232 return RValue<UInt2>(Nucleus::createNot(val.value));
5233 }
John Bauman89401822014-05-06 15:04:28 -04005234 }
5235
John Bauman19bac1e2014-05-06 15:23:49 -04005236 Type *UInt2::getType()
John Bauman89401822014-05-06 15:04:28 -04005237 {
John Bauman19bac1e2014-05-06 15:23:49 -04005238 if(CPUID::supportsMMX2())
5239 {
5240 return MMX::getType();
5241 }
5242 else
5243 {
Nicolas Capensac230122016-09-20 14:30:06 -04005244 return T(VectorType::get(UInt::getType(), 2));
John Bauman19bac1e2014-05-06 15:23:49 -04005245 }
John Bauman89401822014-05-06 15:04:28 -04005246 }
5247
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005248 Int4::Int4(RValue<Byte4> cast)
5249 {
5250 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
5251 Value *a = Nucleus::createInsertElement(UndefValue::get(Int4::getType()), x, 0);
5252
5253 Value *e;
5254
5255 if (CPUID::supportsSSE4_1())
5256 {
5257 e = x86::pmovzxbd(RValue<Int4>(a)).value;
5258 }
5259 else
5260 {
5261 Constant *swizzle[16];
5262 swizzle[0] = Nucleus::createConstantInt(0);
5263 swizzle[1] = Nucleus::createConstantInt(16);
5264 swizzle[2] = Nucleus::createConstantInt(1);
5265 swizzle[3] = Nucleus::createConstantInt(17);
5266 swizzle[4] = Nucleus::createConstantInt(2);
5267 swizzle[5] = Nucleus::createConstantInt(18);
5268 swizzle[6] = Nucleus::createConstantInt(3);
5269 swizzle[7] = Nucleus::createConstantInt(19);
5270 swizzle[8] = Nucleus::createConstantInt(4);
5271 swizzle[9] = Nucleus::createConstantInt(20);
5272 swizzle[10] = Nucleus::createConstantInt(5);
5273 swizzle[11] = Nucleus::createConstantInt(21);
5274 swizzle[12] = Nucleus::createConstantInt(6);
5275 swizzle[13] = Nucleus::createConstantInt(22);
5276 swizzle[14] = Nucleus::createConstantInt(7);
5277 swizzle[15] = Nucleus::createConstantInt(23);
5278
5279 Value *b = Nucleus::createBitCast(a, Byte16::getType());
5280 Value *c = Nucleus::createShuffleVector(b, Nucleus::createNullValue(Byte16::getType()), Nucleus::createConstantVector(swizzle, 16));
5281
5282 Constant *swizzle2[8];
5283 swizzle2[0] = Nucleus::createConstantInt(0);
5284 swizzle2[1] = Nucleus::createConstantInt(8);
5285 swizzle2[2] = Nucleus::createConstantInt(1);
5286 swizzle2[3] = Nucleus::createConstantInt(9);
5287 swizzle2[4] = Nucleus::createConstantInt(2);
5288 swizzle2[5] = Nucleus::createConstantInt(10);
5289 swizzle2[6] = Nucleus::createConstantInt(3);
5290 swizzle2[7] = Nucleus::createConstantInt(11);
5291
5292 Value *d = Nucleus::createBitCast(c, Short8::getType());
5293 e = Nucleus::createShuffleVector(d, Nucleus::createNullValue(Short8::getType()), Nucleus::createConstantVector(swizzle2, 8));
5294 }
5295
5296 Value *f = Nucleus::createBitCast(e, Int4::getType());
5297 storeValue(f);
5298 }
5299
5300 Int4::Int4(RValue<SByte4> cast)
5301 {
5302 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
5303 Value *a = Nucleus::createInsertElement(UndefValue::get(Int4::getType()), x, 0);
5304
5305 Value *g;
5306
5307 if (CPUID::supportsSSE4_1())
5308 {
5309 g = x86::pmovsxbd(RValue<Int4>(a)).value;
5310 }
5311 else
5312 {
5313 Constant *swizzle[16];
5314 swizzle[0] = Nucleus::createConstantInt(0);
5315 swizzle[1] = Nucleus::createConstantInt(0);
5316 swizzle[2] = Nucleus::createConstantInt(1);
5317 swizzle[3] = Nucleus::createConstantInt(1);
5318 swizzle[4] = Nucleus::createConstantInt(2);
5319 swizzle[5] = Nucleus::createConstantInt(2);
5320 swizzle[6] = Nucleus::createConstantInt(3);
5321 swizzle[7] = Nucleus::createConstantInt(3);
5322 swizzle[8] = Nucleus::createConstantInt(4);
5323 swizzle[9] = Nucleus::createConstantInt(4);
5324 swizzle[10] = Nucleus::createConstantInt(5);
5325 swizzle[11] = Nucleus::createConstantInt(5);
5326 swizzle[12] = Nucleus::createConstantInt(6);
5327 swizzle[13] = Nucleus::createConstantInt(6);
5328 swizzle[14] = Nucleus::createConstantInt(7);
5329 swizzle[15] = Nucleus::createConstantInt(7);
5330
5331 Value *b = Nucleus::createBitCast(a, Byte16::getType());
5332 Value *c = Nucleus::createShuffleVector(b, b, Nucleus::createConstantVector(swizzle, 16));
5333
5334 Constant *swizzle2[8];
5335 swizzle2[0] = Nucleus::createConstantInt(0);
5336 swizzle2[1] = Nucleus::createConstantInt(0);
5337 swizzle2[2] = Nucleus::createConstantInt(1);
5338 swizzle2[3] = Nucleus::createConstantInt(1);
5339 swizzle2[4] = Nucleus::createConstantInt(2);
5340 swizzle2[5] = Nucleus::createConstantInt(2);
5341 swizzle2[6] = Nucleus::createConstantInt(3);
5342 swizzle2[7] = Nucleus::createConstantInt(3);
5343
5344 Value *d = Nucleus::createBitCast(c, Short8::getType());
5345 Value *e = Nucleus::createShuffleVector(d, d, Nucleus::createConstantVector(swizzle2, 8));
5346
5347 Value *f = Nucleus::createBitCast(e, Int4::getType());
5348 // g = Nucleus::createAShr(f, Nucleus::createConstantInt(24));
5349 g = x86::psrad(RValue<Int4>(f), 24).value;
5350 }
5351
5352 storeValue(g);
5353 }
5354
John Bauman19bac1e2014-05-06 15:23:49 -04005355 Int4::Int4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005356 {
5357 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005358
5359 Value *xyzw = Nucleus::createFPToSI(cast.value, Int4::getType());
John Bauman89401822014-05-06 15:04:28 -04005360
John Bauman66b8ab22014-05-06 15:57:45 -04005361 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04005362 }
5363
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005364 Int4::Int4(RValue<Short4> cast)
5365 {
5366 Value *long2 = UndefValue::get(Long2::getType());
5367 Value *element = Nucleus::createBitCast(cast.value, Long::getType());
5368 long2 = Nucleus::createInsertElement(long2, element, 0);
5369 RValue<Int4> vector = RValue<Int4>(Nucleus::createBitCast(long2, Int4::getType()));
Nicolas Capens05b3d662016-02-25 23:58:33 -05005370
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005371 if(CPUID::supportsSSE4_1())
5372 {
5373 storeValue(x86::pmovsxwd(vector).value);
5374 }
5375 else
5376 {
5377 Value *b = Nucleus::createBitCast(vector.value, Short8::getType());
5378
5379 Constant *swizzle[8];
5380 swizzle[0] = Nucleus::createConstantInt(0);
5381 swizzle[1] = Nucleus::createConstantInt(0);
5382 swizzle[2] = Nucleus::createConstantInt(1);
5383 swizzle[3] = Nucleus::createConstantInt(1);
5384 swizzle[4] = Nucleus::createConstantInt(2);
5385 swizzle[5] = Nucleus::createConstantInt(2);
5386 swizzle[6] = Nucleus::createConstantInt(3);
5387 swizzle[7] = Nucleus::createConstantInt(3);
5388
Nicolas Capens6ce5c332015-10-28 01:58:18 -04005389 Value *c = Nucleus::createShuffleVector(b, b, Nucleus::createConstantVector(swizzle, 8));
5390 Value *d = Nucleus::createBitCast(c, Int4::getType());
5391 storeValue(d);
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005392
5393 // Each Short is packed into each Int in the (Short | Short) format.
5394 // Shifting by 16 will retrieve the original Short value.
5395 // Shitfing an Int will propagate the sign bit, which will work
5396 // for both positive and negative values of a Short.
5397 *this >>= 16;
5398 }
5399 }
5400
5401 Int4::Int4(RValue<UShort4> cast)
5402 {
5403 Value *long2 = UndefValue::get(Long2::getType());
5404 Value *element = Nucleus::createBitCast(cast.value, Long::getType());
5405 long2 = Nucleus::createInsertElement(long2, element, 0);
5406 RValue<Int4> vector = RValue<Int4>(Nucleus::createBitCast(long2, Int4::getType()));
5407
5408 if(CPUID::supportsSSE4_1())
5409 {
5410 storeValue(x86::pmovzxwd(RValue<Int4>(vector)).value);
5411 }
5412 else
5413 {
5414 Value *b = Nucleus::createBitCast(vector.value, Short8::getType());
5415
5416 Constant *swizzle[8];
5417 swizzle[0] = Nucleus::createConstantInt(0);
5418 swizzle[1] = Nucleus::createConstantInt(8);
5419 swizzle[2] = Nucleus::createConstantInt(1);
5420 swizzle[3] = Nucleus::createConstantInt(9);
5421 swizzle[4] = Nucleus::createConstantInt(2);
5422 swizzle[5] = Nucleus::createConstantInt(10);
5423 swizzle[6] = Nucleus::createConstantInt(3);
5424 swizzle[7] = Nucleus::createConstantInt(11);
5425
Nicolas Capens6ce5c332015-10-28 01:58:18 -04005426 Value *c = Nucleus::createShuffleVector(b, Nucleus::createNullValue(Short8::getType()), Nucleus::createConstantVector(swizzle, 8));
5427 Value *d = Nucleus::createBitCast(c, Int4::getType());
5428 storeValue(d);
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005429 }
5430 }
5431
John Bauman89401822014-05-06 15:04:28 -04005432 Int4::Int4()
5433 {
5434 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005435 }
5436
5437 Int4::Int4(int xyzw)
5438 {
5439 constant(xyzw, xyzw, xyzw, xyzw);
5440 }
5441
5442 Int4::Int4(int x, int yzw)
5443 {
5444 constant(x, yzw, yzw, yzw);
5445 }
5446
5447 Int4::Int4(int x, int y, int zw)
5448 {
5449 constant(x, y, zw, zw);
5450 }
5451
5452 Int4::Int4(int x, int y, int z, int w)
5453 {
5454 constant(x, y, z, w);
5455 }
5456
5457 void Int4::constant(int x, int y, int z, int w)
5458 {
5459 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005460
5461 Constant *constantVector[4];
5462 constantVector[0] = Nucleus::createConstantInt(x);
5463 constantVector[1] = Nucleus::createConstantInt(y);
5464 constantVector[2] = Nucleus::createConstantInt(z);
5465 constantVector[3] = Nucleus::createConstantInt(w);
5466
John Bauman66b8ab22014-05-06 15:57:45 -04005467 storeValue(Nucleus::createConstantVector(constantVector, 4));
John Bauman89401822014-05-06 15:04:28 -04005468 }
5469
John Bauman19bac1e2014-05-06 15:23:49 -04005470 Int4::Int4(RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005471 {
5472 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005473
John Bauman66b8ab22014-05-06 15:57:45 -04005474 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005475 }
5476
5477 Int4::Int4(const Int4 &rhs)
5478 {
5479 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005480
John Bauman66b8ab22014-05-06 15:57:45 -04005481 Value *value = rhs.loadValue();
5482 storeValue(value);
5483 }
5484
5485 Int4::Int4(const Reference<Int4> &rhs)
5486 {
5487 // xyzw.parent = this;
5488
5489 Value *value = rhs.loadValue();
5490 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005491 }
5492
John Bauman19bac1e2014-05-06 15:23:49 -04005493 Int4::Int4(RValue<UInt4> rhs)
5494 {
5495 // xyzw.parent = this;
John Bauman19bac1e2014-05-06 15:23:49 -04005496
John Bauman66b8ab22014-05-06 15:57:45 -04005497 storeValue(rhs.value);
John Bauman19bac1e2014-05-06 15:23:49 -04005498 }
5499
5500 Int4::Int4(const UInt4 &rhs)
5501 {
5502 // xyzw.parent = this;
John Bauman19bac1e2014-05-06 15:23:49 -04005503
John Bauman66b8ab22014-05-06 15:57:45 -04005504 Value *value = rhs.loadValue();
5505 storeValue(value);
5506 }
5507
5508 Int4::Int4(const Reference<UInt4> &rhs)
5509 {
5510 // xyzw.parent = this;
5511
5512 Value *value = rhs.loadValue();
5513 storeValue(value);
John Bauman19bac1e2014-05-06 15:23:49 -04005514 }
5515
Nicolas Capens62abb552016-01-05 12:03:47 -05005516 Int4::Int4(RValue<Int2> lo, RValue<Int2> hi)
5517 {
Nicolas Capens24c8cf02016-08-15 15:33:14 -04005518 // xyzw.parent = this;
5519
Nicolas Capens62abb552016-01-05 12:03:47 -05005520 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
5521 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
5522
5523 Value *long2 = UndefValue::get(Long2::getType());
5524 long2 = Nucleus::createInsertElement(long2, loLong, 0);
5525 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
5526 Value *int4 = Nucleus::createBitCast(long2, Int4::getType());
5527
5528 storeValue(int4);
5529 }
5530
Nicolas Capens24c8cf02016-08-15 15:33:14 -04005531 Int4::Int4(RValue<Int> rhs)
5532 {
5533 // xyzw.parent = this;
5534
5535 Value *vector = loadValue();
5536 Value *insert = Nucleus::createInsertElement(vector, rhs.value, 0);
5537
5538 Constant *swizzle[4];
5539 swizzle[0] = Nucleus::createConstantInt(0);
5540 swizzle[1] = Nucleus::createConstantInt(0);
5541 swizzle[2] = Nucleus::createConstantInt(0);
5542 swizzle[3] = Nucleus::createConstantInt(0);
5543
5544 Value *replicate = Nucleus::createShuffleVector(insert, UndefValue::get(Int4::getType()), Nucleus::createConstantVector(swizzle, 4));
5545
5546 storeValue(replicate);
5547 }
5548
5549 Int4::Int4(const Int &rhs)
5550 {
5551 // xyzw.parent = this;
5552
5553 *this = RValue<Int>(rhs.loadValue());
5554 }
5555
5556 Int4::Int4(const Reference<Int> &rhs)
5557 {
5558 // xyzw.parent = this;
5559
5560 *this = RValue<Int>(rhs.loadValue());
5561 }
5562
John Bauman19bac1e2014-05-06 15:23:49 -04005563 RValue<Int4> Int4::operator=(RValue<Int4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04005564 {
John Bauman66b8ab22014-05-06 15:57:45 -04005565 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005566
5567 return rhs;
5568 }
5569
5570 RValue<Int4> Int4::operator=(const Int4 &rhs) const
5571 {
John Bauman66b8ab22014-05-06 15:57:45 -04005572 Value *value = rhs.loadValue();
5573 storeValue(value);
5574
5575 return RValue<Int4>(value);
5576 }
5577
5578 RValue<Int4> Int4::operator=(const Reference<Int4> &rhs) const
5579 {
5580 Value *value = rhs.loadValue();
5581 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005582
5583 return RValue<Int4>(value);
5584 }
5585
John Bauman19bac1e2014-05-06 15:23:49 -04005586 RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005587 {
5588 return RValue<Int4>(Nucleus::createAdd(lhs.value, rhs.value));
5589 }
5590
John Bauman19bac1e2014-05-06 15:23:49 -04005591 RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005592 {
5593 return RValue<Int4>(Nucleus::createSub(lhs.value, rhs.value));
5594 }
5595
John Bauman19bac1e2014-05-06 15:23:49 -04005596 RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005597 {
5598 return RValue<Int4>(Nucleus::createMul(lhs.value, rhs.value));
5599 }
5600
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005601 RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs)
5602 {
5603 return RValue<Int4>(Nucleus::createSDiv(lhs.value, rhs.value));
5604 }
John Bauman89401822014-05-06 15:04:28 -04005605
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005606 RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs)
5607 {
5608 return RValue<Int4>(Nucleus::createSRem(lhs.value, rhs.value));
5609 }
John Bauman89401822014-05-06 15:04:28 -04005610
John Bauman19bac1e2014-05-06 15:23:49 -04005611 RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005612 {
5613 return RValue<Int4>(Nucleus::createAnd(lhs.value, rhs.value));
5614 }
5615
John Bauman19bac1e2014-05-06 15:23:49 -04005616 RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005617 {
5618 return RValue<Int4>(Nucleus::createOr(lhs.value, rhs.value));
5619 }
5620
John Bauman19bac1e2014-05-06 15:23:49 -04005621 RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005622 {
5623 return RValue<Int4>(Nucleus::createXor(lhs.value, rhs.value));
5624 }
5625
John Bauman19bac1e2014-05-06 15:23:49 -04005626 RValue<Int4> operator<<(RValue<Int4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005627 {
John Bauman89401822014-05-06 15:04:28 -04005628 return x86::pslld(lhs, rhs);
5629 }
5630
John Bauman19bac1e2014-05-06 15:23:49 -04005631 RValue<Int4> operator>>(RValue<Int4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005632 {
John Bauman89401822014-05-06 15:04:28 -04005633 return x86::psrad(lhs, rhs);
5634 }
5635
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005636 RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs)
5637 {
5638 return RValue<Int4>(Nucleus::createShl(lhs.value, rhs.value));
5639 }
5640
5641 RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs)
5642 {
5643 return RValue<Int4>(Nucleus::createAShr(lhs.value, rhs.value));
5644 }
5645
John Bauman19bac1e2014-05-06 15:23:49 -04005646 RValue<Int4> operator+=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005647 {
5648 return lhs = lhs + rhs;
5649 }
5650
John Bauman19bac1e2014-05-06 15:23:49 -04005651 RValue<Int4> operator-=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005652 {
5653 return lhs = lhs - rhs;
5654 }
5655
John Bauman19bac1e2014-05-06 15:23:49 -04005656 RValue<Int4> operator*=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005657 {
5658 return lhs = lhs * rhs;
5659 }
5660
John Bauman19bac1e2014-05-06 15:23:49 -04005661// RValue<Int4> operator/=(const Int4 &lhs, RValue<Int4> rhs)
5662// {
5663// return lhs = lhs / rhs;
5664// }
John Bauman89401822014-05-06 15:04:28 -04005665
John Bauman19bac1e2014-05-06 15:23:49 -04005666// RValue<Int4> operator%=(const Int4 &lhs, RValue<Int4> rhs)
5667// {
5668// return lhs = lhs % rhs;
5669// }
John Bauman89401822014-05-06 15:04:28 -04005670
John Bauman19bac1e2014-05-06 15:23:49 -04005671 RValue<Int4> operator&=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005672 {
5673 return lhs = lhs & rhs;
5674 }
5675
John Bauman19bac1e2014-05-06 15:23:49 -04005676 RValue<Int4> operator|=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005677 {
5678 return lhs = lhs | rhs;
5679 }
5680
John Bauman19bac1e2014-05-06 15:23:49 -04005681 RValue<Int4> operator^=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005682 {
5683 return lhs = lhs ^ rhs;
5684 }
5685
5686 RValue<Int4> operator<<=(const Int4 &lhs, unsigned char rhs)
5687 {
5688 return lhs = lhs << rhs;
5689 }
5690
5691 RValue<Int4> operator>>=(const Int4 &lhs, unsigned char rhs)
5692 {
5693 return lhs = lhs >> rhs;
5694 }
5695
John Bauman19bac1e2014-05-06 15:23:49 -04005696 RValue<Int4> operator+(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005697 {
5698 return val;
5699 }
5700
John Bauman19bac1e2014-05-06 15:23:49 -04005701 RValue<Int4> operator-(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005702 {
5703 return RValue<Int4>(Nucleus::createNeg(val.value));
5704 }
5705
John Bauman19bac1e2014-05-06 15:23:49 -04005706 RValue<Int4> operator~(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005707 {
5708 return RValue<Int4>(Nucleus::createNot(val.value));
5709 }
5710
John Bauman19bac1e2014-05-06 15:23:49 -04005711 RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y)
5712 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005713 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
Alexis Hetufb603992016-04-26 11:50:40 -04005714 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5715 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
5716 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005717 }
5718
5719 RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y)
5720 {
5721 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLT(x.value, y.value), Int4::getType()));
5722 }
5723
5724 RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y)
5725 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005726 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5727 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5728 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLE(x.value, y.value), Int4::getType()));
5729 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGT(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005730 }
5731
5732 RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y)
5733 {
5734 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
5735 }
5736
5737 RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y)
5738 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005739 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5740 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5741 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGE(x.value, y.value), Int4::getType()));
5742 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLT(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005743 }
5744
5745 RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y)
5746 {
5747 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGT(x.value, y.value), Int4::getType()));
5748 }
5749
5750 RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y)
5751 {
5752 if(CPUID::supportsSSE4_1())
5753 {
5754 return x86::pmaxsd(x, y);
5755 }
5756 else
5757 {
5758 RValue<Int4> greater = CmpNLE(x, y);
5759 return x & greater | y & ~greater;
5760 }
5761 }
5762
5763 RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y)
5764 {
5765 if(CPUID::supportsSSE4_1())
5766 {
5767 return x86::pminsd(x, y);
5768 }
5769 else
5770 {
5771 RValue<Int4> less = CmpLT(x, y);
5772 return x & less | y & ~less;
5773 }
5774 }
5775
5776 RValue<Int4> RoundInt(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005777 {
5778 return x86::cvtps2dq(cast);
5779 }
5780
John Bauman19bac1e2014-05-06 15:23:49 -04005781 RValue<Short8> Pack(RValue<Int4> x, RValue<Int4> y)
John Bauman89401822014-05-06 15:04:28 -04005782 {
5783 return x86::packssdw(x, y);
5784 }
5785
John Bauman19bac1e2014-05-06 15:23:49 -04005786 RValue<Int> Extract(RValue<Int4> x, int i)
John Bauman89401822014-05-06 15:04:28 -04005787 {
5788 return RValue<Int>(Nucleus::createExtractElement(x.value, i));
5789 }
5790
John Bauman19bac1e2014-05-06 15:23:49 -04005791 RValue<Int4> Insert(RValue<Int4> x, RValue<Int> element, int i)
John Bauman89401822014-05-06 15:04:28 -04005792 {
5793 return RValue<Int4>(Nucleus::createInsertElement(x.value, element.value, i));
5794 }
5795
John Bauman19bac1e2014-05-06 15:23:49 -04005796 RValue<Int> SignMask(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04005797 {
5798 return x86::movmskps(As<Float4>(x));
5799 }
5800
John Bauman19bac1e2014-05-06 15:23:49 -04005801 RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04005802 {
5803 return RValue<Int4>(Nucleus::createSwizzle(x.value, select));
5804 }
5805
John Bauman19bac1e2014-05-06 15:23:49 -04005806 Type *Int4::getType()
John Bauman89401822014-05-06 15:04:28 -04005807 {
Nicolas Capensac230122016-09-20 14:30:06 -04005808 return T(VectorType::get(Int::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04005809 }
5810
John Bauman19bac1e2014-05-06 15:23:49 -04005811 UInt4::UInt4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005812 {
5813 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005814
Alexis Hetu764d1422016-09-28 08:44:22 -04005815 // Note: createFPToUI is broken, must perform conversion using createFPtoSI
5816 // Value *xyzw = Nucleus::createFPToUI(cast.value, UInt4::getType());
John Bauman89401822014-05-06 15:04:28 -04005817
Alexis Hetu764d1422016-09-28 08:44:22 -04005818 // Smallest positive value representable in UInt, but not in Int
5819 const unsigned int ustart = 0x80000000u;
5820 const float ustartf = float(ustart);
5821
5822 // Check if the value can be represented as an Int
5823 Int4 uiValue = CmpNLT(cast, Float4(ustartf));
5824 // If the value is too large, subtract ustart and re-add it after conversion.
5825 uiValue = (uiValue & As<Int4>(As<UInt4>(Int4(cast - Float4(ustartf))) + UInt4(ustart))) |
5826 // Otherwise, just convert normally
5827 (~uiValue & Int4(cast));
5828 // If the value is negative, store 0, otherwise store the result of the conversion
5829 storeValue((~(As<Int4>(cast) >> 31) & uiValue).value);
John Bauman89401822014-05-06 15:04:28 -04005830 }
5831
5832 UInt4::UInt4()
5833 {
5834 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005835 }
5836
John Bauman19bac1e2014-05-06 15:23:49 -04005837 UInt4::UInt4(int xyzw)
5838 {
5839 constant(xyzw, xyzw, xyzw, xyzw);
5840 }
5841
5842 UInt4::UInt4(int x, int yzw)
5843 {
5844 constant(x, yzw, yzw, yzw);
5845 }
5846
5847 UInt4::UInt4(int x, int y, int zw)
5848 {
5849 constant(x, y, zw, zw);
5850 }
5851
5852 UInt4::UInt4(int x, int y, int z, int w)
5853 {
5854 constant(x, y, z, w);
5855 }
5856
5857 void UInt4::constant(int x, int y, int z, int w)
John Bauman89401822014-05-06 15:04:28 -04005858 {
5859 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005860
5861 Constant *constantVector[4];
5862 constantVector[0] = Nucleus::createConstantInt(x);
5863 constantVector[1] = Nucleus::createConstantInt(y);
5864 constantVector[2] = Nucleus::createConstantInt(z);
5865 constantVector[3] = Nucleus::createConstantInt(w);
5866
John Bauman66b8ab22014-05-06 15:57:45 -04005867 storeValue(Nucleus::createConstantVector(constantVector, 4));
John Bauman89401822014-05-06 15:04:28 -04005868 }
5869
John Bauman19bac1e2014-05-06 15:23:49 -04005870 UInt4::UInt4(RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005871 {
5872 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005873
John Bauman66b8ab22014-05-06 15:57:45 -04005874 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005875 }
5876
5877 UInt4::UInt4(const UInt4 &rhs)
5878 {
5879 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005880
John Bauman66b8ab22014-05-06 15:57:45 -04005881 Value *value = rhs.loadValue();
5882 storeValue(value);
5883 }
5884
5885 UInt4::UInt4(const Reference<UInt4> &rhs)
5886 {
5887 // xyzw.parent = this;
5888
5889 Value *value = rhs.loadValue();
5890 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005891 }
5892
John Bauman19bac1e2014-05-06 15:23:49 -04005893 UInt4::UInt4(RValue<Int4> rhs)
5894 {
5895 // xyzw.parent = this;
John Bauman19bac1e2014-05-06 15:23:49 -04005896
John Bauman66b8ab22014-05-06 15:57:45 -04005897 storeValue(rhs.value);
John Bauman19bac1e2014-05-06 15:23:49 -04005898 }
5899
5900 UInt4::UInt4(const Int4 &rhs)
5901 {
5902 // xyzw.parent = this;
John Bauman19bac1e2014-05-06 15:23:49 -04005903
John Bauman66b8ab22014-05-06 15:57:45 -04005904 Value *value = rhs.loadValue();
5905 storeValue(value);
5906 }
5907
5908 UInt4::UInt4(const Reference<Int4> &rhs)
5909 {
5910 // xyzw.parent = this;
5911
5912 Value *value = rhs.loadValue();
5913 storeValue(value);
John Bauman19bac1e2014-05-06 15:23:49 -04005914 }
5915
Nicolas Capens62abb552016-01-05 12:03:47 -05005916 UInt4::UInt4(RValue<UInt2> lo, RValue<UInt2> hi)
5917 {
5918 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
5919 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
5920
5921 Value *long2 = UndefValue::get(Long2::getType());
5922 long2 = Nucleus::createInsertElement(long2, loLong, 0);
5923 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
5924 Value *uint4 = Nucleus::createBitCast(long2, Int4::getType());
5925
5926 storeValue(uint4);
5927 }
5928
John Bauman19bac1e2014-05-06 15:23:49 -04005929 RValue<UInt4> UInt4::operator=(RValue<UInt4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04005930 {
John Bauman66b8ab22014-05-06 15:57:45 -04005931 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005932
5933 return rhs;
5934 }
5935
5936 RValue<UInt4> UInt4::operator=(const UInt4 &rhs) const
5937 {
John Bauman66b8ab22014-05-06 15:57:45 -04005938 Value *value = rhs.loadValue();
5939 storeValue(value);
5940
5941 return RValue<UInt4>(value);
5942 }
5943
5944 RValue<UInt4> UInt4::operator=(const Reference<UInt4> &rhs) const
5945 {
5946 Value *value = rhs.loadValue();
5947 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005948
5949 return RValue<UInt4>(value);
5950 }
5951
John Bauman19bac1e2014-05-06 15:23:49 -04005952 RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005953 {
5954 return RValue<UInt4>(Nucleus::createAdd(lhs.value, rhs.value));
5955 }
5956
John Bauman19bac1e2014-05-06 15:23:49 -04005957 RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005958 {
5959 return RValue<UInt4>(Nucleus::createSub(lhs.value, rhs.value));
5960 }
5961
John Bauman19bac1e2014-05-06 15:23:49 -04005962 RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005963 {
5964 return RValue<UInt4>(Nucleus::createMul(lhs.value, rhs.value));
5965 }
5966
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005967 RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs)
5968 {
5969 return RValue<UInt4>(Nucleus::createUDiv(lhs.value, rhs.value));
5970 }
John Bauman89401822014-05-06 15:04:28 -04005971
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005972 RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs)
5973 {
5974 return RValue<UInt4>(Nucleus::createURem(lhs.value, rhs.value));
5975 }
John Bauman89401822014-05-06 15:04:28 -04005976
John Bauman19bac1e2014-05-06 15:23:49 -04005977 RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005978 {
5979 return RValue<UInt4>(Nucleus::createAnd(lhs.value, rhs.value));
5980 }
5981
John Bauman19bac1e2014-05-06 15:23:49 -04005982 RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005983 {
5984 return RValue<UInt4>(Nucleus::createOr(lhs.value, rhs.value));
5985 }
5986
John Bauman19bac1e2014-05-06 15:23:49 -04005987 RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005988 {
5989 return RValue<UInt4>(Nucleus::createXor(lhs.value, rhs.value));
5990 }
5991
John Bauman19bac1e2014-05-06 15:23:49 -04005992 RValue<UInt4> operator<<(RValue<UInt4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005993 {
John Bauman89401822014-05-06 15:04:28 -04005994 return As<UInt4>(x86::pslld(As<Int4>(lhs), rhs));
5995 }
5996
John Bauman19bac1e2014-05-06 15:23:49 -04005997 RValue<UInt4> operator>>(RValue<UInt4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005998 {
John Bauman89401822014-05-06 15:04:28 -04005999 return x86::psrld(lhs, rhs);
6000 }
6001
Alexis Hetud9d27bb2015-08-18 15:22:15 -04006002 RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs)
6003 {
6004 return RValue<UInt4>(Nucleus::createShl(lhs.value, rhs.value));
6005 }
6006
6007 RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs)
6008 {
6009 return RValue<UInt4>(Nucleus::createLShr(lhs.value, rhs.value));
6010 }
6011
John Bauman19bac1e2014-05-06 15:23:49 -04006012 RValue<UInt4> operator+=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006013 {
6014 return lhs = lhs + rhs;
6015 }
6016
John Bauman19bac1e2014-05-06 15:23:49 -04006017 RValue<UInt4> operator-=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006018 {
6019 return lhs = lhs - rhs;
6020 }
6021
John Bauman19bac1e2014-05-06 15:23:49 -04006022 RValue<UInt4> operator*=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006023 {
6024 return lhs = lhs * rhs;
6025 }
6026
John Bauman19bac1e2014-05-06 15:23:49 -04006027// RValue<UInt4> operator/=(const UInt4 &lhs, RValue<UInt4> rhs)
6028// {
6029// return lhs = lhs / rhs;
6030// }
John Bauman89401822014-05-06 15:04:28 -04006031
John Bauman19bac1e2014-05-06 15:23:49 -04006032// RValue<UInt4> operator%=(const UInt4 &lhs, RValue<UInt4> rhs)
6033// {
6034// return lhs = lhs % rhs;
6035// }
John Bauman89401822014-05-06 15:04:28 -04006036
John Bauman19bac1e2014-05-06 15:23:49 -04006037 RValue<UInt4> operator&=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006038 {
6039 return lhs = lhs & rhs;
6040 }
6041
John Bauman19bac1e2014-05-06 15:23:49 -04006042 RValue<UInt4> operator|=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006043 {
6044 return lhs = lhs | rhs;
6045 }
6046
John Bauman19bac1e2014-05-06 15:23:49 -04006047 RValue<UInt4> operator^=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006048 {
6049 return lhs = lhs ^ rhs;
6050 }
6051
6052 RValue<UInt4> operator<<=(const UInt4 &lhs, unsigned char rhs)
6053 {
6054 return lhs = lhs << rhs;
6055 }
6056
6057 RValue<UInt4> operator>>=(const UInt4 &lhs, unsigned char rhs)
6058 {
6059 return lhs = lhs >> rhs;
6060 }
6061
John Bauman19bac1e2014-05-06 15:23:49 -04006062 RValue<UInt4> operator+(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04006063 {
6064 return val;
6065 }
6066
John Bauman19bac1e2014-05-06 15:23:49 -04006067 RValue<UInt4> operator-(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04006068 {
6069 return RValue<UInt4>(Nucleus::createNeg(val.value));
6070 }
6071
John Bauman19bac1e2014-05-06 15:23:49 -04006072 RValue<UInt4> operator~(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04006073 {
6074 return RValue<UInt4>(Nucleus::createNot(val.value));
6075 }
6076
John Bauman19bac1e2014-05-06 15:23:49 -04006077 RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y)
6078 {
Nicolas Capens197226a2016-04-27 23:08:50 -04006079 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
Alexis Hetufb603992016-04-26 11:50:40 -04006080 // Restore the following line when LLVM is updated to a version where this issue is fixed.
6081 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
6082 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04006083 }
6084
6085 RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y)
6086 {
6087 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULT(x.value, y.value), Int4::getType()));
6088 }
6089
6090 RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y)
6091 {
Nicolas Capens197226a2016-04-27 23:08:50 -04006092 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
6093 // Restore the following line when LLVM is updated to a version where this issue is fixed.
6094 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULE(x.value, y.value), Int4::getType()));
6095 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGT(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04006096 }
6097
6098 RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y)
6099 {
6100 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
6101 }
6102
6103 RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y)
6104 {
Nicolas Capens197226a2016-04-27 23:08:50 -04006105 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
6106 // Restore the following line when LLVM is updated to a version where this issue is fixed.
6107 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGE(x.value, y.value), Int4::getType()));
6108 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULT(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04006109 }
6110
6111 RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y)
6112 {
6113 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGT(x.value, y.value), Int4::getType()));
6114 }
6115
6116 RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y)
6117 {
6118 if(CPUID::supportsSSE4_1())
6119 {
6120 return x86::pmaxud(x, y);
6121 }
6122 else
6123 {
6124 RValue<UInt4> greater = CmpNLE(x, y);
6125 return x & greater | y & ~greater;
6126 }
6127 }
6128
6129 RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y)
6130 {
6131 if(CPUID::supportsSSE4_1())
6132 {
6133 return x86::pminud(x, y);
6134 }
6135 else
6136 {
6137 RValue<UInt4> less = CmpLT(x, y);
6138 return x & less | y & ~less;
6139 }
6140 }
6141
6142 RValue<UShort8> Pack(RValue<UInt4> x, RValue<UInt4> y)
John Bauman89401822014-05-06 15:04:28 -04006143 {
6144 return x86::packusdw(x, y); // FIXME: Fallback required
6145 }
6146
John Bauman19bac1e2014-05-06 15:23:49 -04006147 Type *UInt4::getType()
John Bauman89401822014-05-06 15:04:28 -04006148 {
Nicolas Capensac230122016-09-20 14:30:06 -04006149 return T(VectorType::get(UInt::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04006150 }
6151
John Bauman19bac1e2014-05-06 15:23:49 -04006152 Float::Float(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04006153 {
John Bauman89401822014-05-06 15:04:28 -04006154 Value *integer = Nucleus::createSIToFP(cast.value, Float::getType());
6155
John Bauman66b8ab22014-05-06 15:57:45 -04006156 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04006157 }
6158
6159 Float::Float()
6160 {
John Bauman66b8ab22014-05-06 15:57:45 -04006161
John Bauman89401822014-05-06 15:04:28 -04006162 }
6163
6164 Float::Float(float x)
6165 {
John Bauman66b8ab22014-05-06 15:57:45 -04006166 storeValue(Nucleus::createConstantFloat(x));
John Bauman89401822014-05-06 15:04:28 -04006167 }
6168
John Bauman19bac1e2014-05-06 15:23:49 -04006169 Float::Float(RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006170 {
John Bauman66b8ab22014-05-06 15:57:45 -04006171 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04006172 }
6173
6174 Float::Float(const Float &rhs)
6175 {
John Bauman66b8ab22014-05-06 15:57:45 -04006176 Value *value = rhs.loadValue();
6177 storeValue(value);
6178 }
John Bauman89401822014-05-06 15:04:28 -04006179
John Bauman66b8ab22014-05-06 15:57:45 -04006180 Float::Float(const Reference<Float> &rhs)
6181 {
6182 Value *value = rhs.loadValue();
6183 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04006184 }
6185
John Bauman19bac1e2014-05-06 15:23:49 -04006186 RValue<Float> Float::operator=(RValue<Float> rhs) const
John Bauman89401822014-05-06 15:04:28 -04006187 {
John Bauman66b8ab22014-05-06 15:57:45 -04006188 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04006189
6190 return rhs;
6191 }
6192
6193 RValue<Float> Float::operator=(const Float &rhs) const
6194 {
John Bauman66b8ab22014-05-06 15:57:45 -04006195 Value *value = rhs.loadValue();
6196 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04006197
6198 return RValue<Float>(value);
6199 }
6200
John Bauman66b8ab22014-05-06 15:57:45 -04006201 RValue<Float> Float::operator=(const Reference<Float> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04006202 {
John Bauman66b8ab22014-05-06 15:57:45 -04006203 Value *value = rhs.loadValue();
6204 storeValue(value);
6205
6206 return RValue<Float>(value);
John Bauman89401822014-05-06 15:04:28 -04006207 }
6208
John Bauman19bac1e2014-05-06 15:23:49 -04006209 RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006210 {
6211 return RValue<Float>(Nucleus::createFAdd(lhs.value, rhs.value));
6212 }
6213
John Bauman19bac1e2014-05-06 15:23:49 -04006214 RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006215 {
6216 return RValue<Float>(Nucleus::createFSub(lhs.value, rhs.value));
6217 }
6218
John Bauman19bac1e2014-05-06 15:23:49 -04006219 RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006220 {
6221 return RValue<Float>(Nucleus::createFMul(lhs.value, rhs.value));
6222 }
6223
John Bauman19bac1e2014-05-06 15:23:49 -04006224 RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006225 {
6226 return RValue<Float>(Nucleus::createFDiv(lhs.value, rhs.value));
6227 }
6228
John Bauman19bac1e2014-05-06 15:23:49 -04006229 RValue<Float> operator+=(const Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006230 {
6231 return lhs = lhs + rhs;
6232 }
6233
John Bauman19bac1e2014-05-06 15:23:49 -04006234 RValue<Float> operator-=(const Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006235 {
6236 return lhs = lhs - rhs;
6237 }
6238
John Bauman19bac1e2014-05-06 15:23:49 -04006239 RValue<Float> operator*=(const Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006240 {
6241 return lhs = lhs * rhs;
6242 }
6243
John Bauman19bac1e2014-05-06 15:23:49 -04006244 RValue<Float> operator/=(const Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006245 {
6246 return lhs = lhs / rhs;
6247 }
6248
John Bauman19bac1e2014-05-06 15:23:49 -04006249 RValue<Float> operator+(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006250 {
6251 return val;
6252 }
6253
John Bauman19bac1e2014-05-06 15:23:49 -04006254 RValue<Float> operator-(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006255 {
6256 return RValue<Float>(Nucleus::createFNeg(val.value));
6257 }
6258
John Bauman19bac1e2014-05-06 15:23:49 -04006259 RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006260 {
6261 return RValue<Bool>(Nucleus::createFCmpOLT(lhs.value, rhs.value));
6262 }
6263
John Bauman19bac1e2014-05-06 15:23:49 -04006264 RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006265 {
6266 return RValue<Bool>(Nucleus::createFCmpOLE(lhs.value, rhs.value));
6267 }
6268
John Bauman19bac1e2014-05-06 15:23:49 -04006269 RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006270 {
6271 return RValue<Bool>(Nucleus::createFCmpOGT(lhs.value, rhs.value));
6272 }
6273
John Bauman19bac1e2014-05-06 15:23:49 -04006274 RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006275 {
6276 return RValue<Bool>(Nucleus::createFCmpOGE(lhs.value, rhs.value));
6277 }
6278
John Bauman19bac1e2014-05-06 15:23:49 -04006279 RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006280 {
6281 return RValue<Bool>(Nucleus::createFCmpONE(lhs.value, rhs.value));
6282 }
6283
John Bauman19bac1e2014-05-06 15:23:49 -04006284 RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006285 {
6286 return RValue<Bool>(Nucleus::createFCmpOEQ(lhs.value, rhs.value));
6287 }
6288
John Bauman19bac1e2014-05-06 15:23:49 -04006289 RValue<Float> Abs(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006290 {
John Bauman66b8ab22014-05-06 15:57:45 -04006291 return IfThenElse(x > 0.0f, x, -x);
John Bauman89401822014-05-06 15:04:28 -04006292 }
6293
John Bauman19bac1e2014-05-06 15:23:49 -04006294 RValue<Float> Max(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006295 {
6296 return IfThenElse(x > y, x, y);
6297 }
6298
John Bauman19bac1e2014-05-06 15:23:49 -04006299 RValue<Float> Min(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006300 {
6301 return IfThenElse(x < y, x, y);
6302 }
6303
Nicolas Capens05b3d662016-02-25 23:58:33 -05006304 RValue<Float> Rcp_pp(RValue<Float> x, bool exactAtPow2)
John Bauman89401822014-05-06 15:04:28 -04006305 {
Nicolas Capens05b3d662016-02-25 23:58:33 -05006306 if(exactAtPow2)
6307 {
6308 // rcpss uses a piecewise-linear approximation which minimizes the relative error
6309 // but is not exact at power-of-two values. Rectify by multiplying by the inverse.
6310 return x86::rcpss(x) * Float(1.0f / _mm_cvtss_f32(_mm_rcp_ss(_mm_set_ps1(1.0f))));
6311 }
6312 else
6313 {
6314 return x86::rcpss(x);
6315 }
John Bauman89401822014-05-06 15:04:28 -04006316 }
John Bauman66b8ab22014-05-06 15:57:45 -04006317
John Bauman19bac1e2014-05-06 15:23:49 -04006318 RValue<Float> RcpSqrt_pp(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006319 {
6320 return x86::rsqrtss(x);
6321 }
6322
John Bauman19bac1e2014-05-06 15:23:49 -04006323 RValue<Float> Sqrt(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006324 {
6325 return x86::sqrtss(x);
6326 }
6327
John Bauman19bac1e2014-05-06 15:23:49 -04006328 RValue<Float> Round(RValue<Float> x)
6329 {
6330 if(CPUID::supportsSSE4_1())
6331 {
6332 return x86::roundss(x, 0);
6333 }
6334 else
6335 {
6336 return Float4(Round(Float4(x))).x;
6337 }
6338 }
6339
6340 RValue<Float> Trunc(RValue<Float> x)
6341 {
6342 if(CPUID::supportsSSE4_1())
6343 {
6344 return x86::roundss(x, 3);
6345 }
6346 else
6347 {
6348 return Float(Int(x)); // Rounded toward zero
6349 }
6350 }
6351
6352 RValue<Float> Frac(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006353 {
6354 if(CPUID::supportsSSE4_1())
6355 {
6356 return x - x86::floorss(x);
6357 }
6358 else
6359 {
John Bauman19bac1e2014-05-06 15:23:49 -04006360 return Float4(Frac(Float4(x))).x;
John Bauman89401822014-05-06 15:04:28 -04006361 }
6362 }
6363
John Bauman19bac1e2014-05-06 15:23:49 -04006364 RValue<Float> Floor(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006365 {
6366 if(CPUID::supportsSSE4_1())
6367 {
6368 return x86::floorss(x);
6369 }
6370 else
6371 {
6372 return Float4(Floor(Float4(x))).x;
6373 }
6374 }
6375
John Bauman19bac1e2014-05-06 15:23:49 -04006376 RValue<Float> Ceil(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006377 {
John Bauman19bac1e2014-05-06 15:23:49 -04006378 if(CPUID::supportsSSE4_1())
6379 {
6380 return x86::ceilss(x);
6381 }
6382 else
6383 {
6384 return Float4(Ceil(Float4(x))).x;
6385 }
John Bauman89401822014-05-06 15:04:28 -04006386 }
6387
John Bauman19bac1e2014-05-06 15:23:49 -04006388 Type *Float::getType()
John Bauman89401822014-05-06 15:04:28 -04006389 {
Nicolas Capensac230122016-09-20 14:30:06 -04006390 return T(llvm::Type::getFloatTy(*::context));
John Bauman89401822014-05-06 15:04:28 -04006391 }
6392
John Bauman19bac1e2014-05-06 15:23:49 -04006393 Float2::Float2(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04006394 {
6395 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006396
6397 Value *int64x2 = Nucleus::createBitCast(cast.value, Long2::getType());
6398 Value *int64 = Nucleus::createExtractElement(int64x2, 0);
6399 Value *float2 = Nucleus::createBitCast(int64, Float2::getType());
6400
John Bauman66b8ab22014-05-06 15:57:45 -04006401 storeValue(float2);
John Bauman89401822014-05-06 15:04:28 -04006402 }
6403
John Bauman19bac1e2014-05-06 15:23:49 -04006404 Type *Float2::getType()
John Bauman89401822014-05-06 15:04:28 -04006405 {
Nicolas Capensac230122016-09-20 14:30:06 -04006406 return T(VectorType::get(Float::getType(), 2));
John Bauman89401822014-05-06 15:04:28 -04006407 }
6408
John Bauman19bac1e2014-05-06 15:23:49 -04006409 Float4::Float4(RValue<Byte4> cast)
John Bauman89401822014-05-06 15:04:28 -04006410 {
6411 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006412
6413 #if 0
6414 Value *xyzw = Nucleus::createUIToFP(cast.value, Float4::getType()); // FIXME: Crashes
6415 #elif 0
John Bauman66b8ab22014-05-06 15:57:45 -04006416 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04006417
6418 Value *i8x = Nucleus::createExtractElement(cast.value, 0);
6419 Value *f32x = Nucleus::createUIToFP(i8x, Float::getType());
6420 Value *x = Nucleus::createInsertElement(vector, f32x, 0);
6421
6422 Value *i8y = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(1));
6423 Value *f32y = Nucleus::createUIToFP(i8y, Float::getType());
6424 Value *xy = Nucleus::createInsertElement(x, f32y, Nucleus::createConstantInt(1));
6425
6426 Value *i8z = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(2));
6427 Value *f32z = Nucleus::createUIToFP(i8z, Float::getType());
6428 Value *xyz = Nucleus::createInsertElement(xy, f32z, Nucleus::createConstantInt(2));
6429
6430 Value *i8w = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(3));
6431 Value *f32w = Nucleus::createUIToFP(i8w, Float::getType());
6432 Value *xyzw = Nucleus::createInsertElement(xyz, f32w, Nucleus::createConstantInt(3));
6433 #else
Meng-Lin Wu601d0052016-06-10 14:18:41 -04006434 Value *a = Int4(cast).loadValue();
6435 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04006436 #endif
John Bauman66b8ab22014-05-06 15:57:45 -04006437
6438 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04006439 }
6440
John Bauman19bac1e2014-05-06 15:23:49 -04006441 Float4::Float4(RValue<SByte4> cast)
John Bauman89401822014-05-06 15:04:28 -04006442 {
6443 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006444
6445 #if 0
6446 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType()); // FIXME: Crashes
6447 #elif 0
John Bauman66b8ab22014-05-06 15:57:45 -04006448 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04006449
6450 Value *i8x = Nucleus::createExtractElement(cast.value, 0);
6451 Value *f32x = Nucleus::createSIToFP(i8x, Float::getType());
6452 Value *x = Nucleus::createInsertElement(vector, f32x, 0);
6453
6454 Value *i8y = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(1));
6455 Value *f32y = Nucleus::createSIToFP(i8y, Float::getType());
6456 Value *xy = Nucleus::createInsertElement(x, f32y, Nucleus::createConstantInt(1));
6457
6458 Value *i8z = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(2));
6459 Value *f32z = Nucleus::createSIToFP(i8z, Float::getType());
6460 Value *xyz = Nucleus::createInsertElement(xy, f32z, Nucleus::createConstantInt(2));
6461
6462 Value *i8w = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(3));
6463 Value *f32w = Nucleus::createSIToFP(i8w, Float::getType());
6464 Value *xyzw = Nucleus::createInsertElement(xyz, f32w, Nucleus::createConstantInt(3));
6465 #else
Meng-Lin Wu601d0052016-06-10 14:18:41 -04006466 Value *a = Int4(cast).loadValue();
6467 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04006468 #endif
John Bauman66b8ab22014-05-06 15:57:45 -04006469
6470 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04006471 }
6472
John Bauman19bac1e2014-05-06 15:23:49 -04006473 Float4::Float4(RValue<Short4> cast)
John Bauman89401822014-05-06 15:04:28 -04006474 {
6475 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006476
Alexis Hetu2aa852f2015-10-14 16:32:39 -04006477 Int4 c(cast);
6478 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
John Bauman89401822014-05-06 15:04:28 -04006479 }
6480
John Bauman19bac1e2014-05-06 15:23:49 -04006481 Float4::Float4(RValue<UShort4> cast)
John Bauman89401822014-05-06 15:04:28 -04006482 {
6483 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006484
Alexis Hetu2aa852f2015-10-14 16:32:39 -04006485 Int4 c(cast);
6486 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
John Bauman89401822014-05-06 15:04:28 -04006487 }
6488
John Bauman19bac1e2014-05-06 15:23:49 -04006489 Float4::Float4(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04006490 {
6491 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006492
6493 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04006494
John Bauman66b8ab22014-05-06 15:57:45 -04006495 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04006496 }
6497
John Bauman19bac1e2014-05-06 15:23:49 -04006498 Float4::Float4(RValue<UInt4> cast)
John Bauman89401822014-05-06 15:04:28 -04006499 {
6500 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006501
6502 Value *xyzw = Nucleus::createUIToFP(cast.value, Float4::getType());
6503
John Bauman66b8ab22014-05-06 15:57:45 -04006504 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04006505 }
6506
6507 Float4::Float4()
6508 {
6509 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006510 }
John Bauman66b8ab22014-05-06 15:57:45 -04006511
John Bauman89401822014-05-06 15:04:28 -04006512 Float4::Float4(float xyzw)
6513 {
6514 constant(xyzw, xyzw, xyzw, xyzw);
6515 }
6516
6517 Float4::Float4(float x, float yzw)
6518 {
6519 constant(x, yzw, yzw, yzw);
6520 }
6521
6522 Float4::Float4(float x, float y, float zw)
6523 {
6524 constant(x, y, zw, zw);
6525 }
6526
6527 Float4::Float4(float x, float y, float z, float w)
6528 {
6529 constant(x, y, z, w);
6530 }
6531
6532 void Float4::constant(float x, float y, float z, float w)
6533 {
6534 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006535
6536 Constant *constantVector[4];
6537 constantVector[0] = Nucleus::createConstantFloat(x);
6538 constantVector[1] = Nucleus::createConstantFloat(y);
6539 constantVector[2] = Nucleus::createConstantFloat(z);
6540 constantVector[3] = Nucleus::createConstantFloat(w);
6541
John Bauman66b8ab22014-05-06 15:57:45 -04006542 storeValue(Nucleus::createConstantVector(constantVector, 4));
John Bauman89401822014-05-06 15:04:28 -04006543 }
6544
John Bauman19bac1e2014-05-06 15:23:49 -04006545 Float4::Float4(RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006546 {
6547 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006548
John Bauman66b8ab22014-05-06 15:57:45 -04006549 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04006550 }
6551
6552 Float4::Float4(const Float4 &rhs)
6553 {
6554 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006555
John Bauman66b8ab22014-05-06 15:57:45 -04006556 Value *value = rhs.loadValue();
6557 storeValue(value);
6558 }
6559
6560 Float4::Float4(const Reference<Float4> &rhs)
6561 {
6562 xyzw.parent = this;
6563
6564 Value *value = rhs.loadValue();
6565 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04006566 }
6567
John Bauman19bac1e2014-05-06 15:23:49 -04006568 Float4::Float4(RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006569 {
6570 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006571
John Bauman66b8ab22014-05-06 15:57:45 -04006572 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04006573 Value *insert = Nucleus::createInsertElement(vector, rhs.value, 0);
6574
6575 Constant *swizzle[4];
6576 swizzle[0] = Nucleus::createConstantInt(0);
6577 swizzle[1] = Nucleus::createConstantInt(0);
6578 swizzle[2] = Nucleus::createConstantInt(0);
6579 swizzle[3] = Nucleus::createConstantInt(0);
6580
6581 Value *replicate = Nucleus::createShuffleVector(insert, UndefValue::get(Float4::getType()), Nucleus::createConstantVector(swizzle, 4));
6582
John Bauman66b8ab22014-05-06 15:57:45 -04006583 storeValue(replicate);
John Bauman89401822014-05-06 15:04:28 -04006584 }
6585
6586 Float4::Float4(const Float &rhs)
6587 {
6588 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006589
John Bauman66b8ab22014-05-06 15:57:45 -04006590 *this = RValue<Float>(rhs.loadValue());
6591 }
John Bauman89401822014-05-06 15:04:28 -04006592
John Bauman66b8ab22014-05-06 15:57:45 -04006593 Float4::Float4(const Reference<Float> &rhs)
6594 {
6595 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006596
John Bauman66b8ab22014-05-06 15:57:45 -04006597 *this = RValue<Float>(rhs.loadValue());
John Bauman89401822014-05-06 15:04:28 -04006598 }
6599
6600 RValue<Float4> Float4::operator=(float x) const
6601 {
6602 return *this = Float4(x, x, x, x);
6603 }
6604
John Bauman19bac1e2014-05-06 15:23:49 -04006605 RValue<Float4> Float4::operator=(RValue<Float4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04006606 {
John Bauman66b8ab22014-05-06 15:57:45 -04006607 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04006608
6609 return rhs;
6610 }
6611
6612 RValue<Float4> Float4::operator=(const Float4 &rhs) const
6613 {
John Bauman66b8ab22014-05-06 15:57:45 -04006614 Value *value = rhs.loadValue();
6615 storeValue(value);
6616
6617 return RValue<Float4>(value);
6618 }
6619
6620 RValue<Float4> Float4::operator=(const Reference<Float4> &rhs) const
6621 {
6622 Value *value = rhs.loadValue();
6623 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04006624
6625 return RValue<Float4>(value);
6626 }
6627
John Bauman19bac1e2014-05-06 15:23:49 -04006628 RValue<Float4> Float4::operator=(RValue<Float> rhs) const
John Bauman89401822014-05-06 15:04:28 -04006629 {
6630 return *this = Float4(rhs);
6631 }
6632
6633 RValue<Float4> Float4::operator=(const Float &rhs) const
6634 {
6635 return *this = Float4(rhs);
6636 }
6637
John Bauman66b8ab22014-05-06 15:57:45 -04006638 RValue<Float4> Float4::operator=(const Reference<Float> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04006639 {
John Bauman66b8ab22014-05-06 15:57:45 -04006640 return *this = Float4(rhs);
John Bauman89401822014-05-06 15:04:28 -04006641 }
6642
John Bauman19bac1e2014-05-06 15:23:49 -04006643 RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006644 {
6645 return RValue<Float4>(Nucleus::createFAdd(lhs.value, rhs.value));
6646 }
6647
John Bauman19bac1e2014-05-06 15:23:49 -04006648 RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006649 {
6650 return RValue<Float4>(Nucleus::createFSub(lhs.value, rhs.value));
6651 }
6652
John Bauman19bac1e2014-05-06 15:23:49 -04006653 RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006654 {
6655 return RValue<Float4>(Nucleus::createFMul(lhs.value, rhs.value));
6656 }
6657
John Bauman19bac1e2014-05-06 15:23:49 -04006658 RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006659 {
6660 return RValue<Float4>(Nucleus::createFDiv(lhs.value, rhs.value));
6661 }
6662
John Bauman19bac1e2014-05-06 15:23:49 -04006663 RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006664 {
6665 return RValue<Float4>(Nucleus::createFRem(lhs.value, rhs.value));
6666 }
6667
John Bauman19bac1e2014-05-06 15:23:49 -04006668 RValue<Float4> operator+=(const Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006669 {
6670 return lhs = lhs + rhs;
6671 }
6672
John Bauman19bac1e2014-05-06 15:23:49 -04006673 RValue<Float4> operator-=(const Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006674 {
6675 return lhs = lhs - rhs;
6676 }
6677
John Bauman19bac1e2014-05-06 15:23:49 -04006678 RValue<Float4> operator*=(const Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006679 {
6680 return lhs = lhs * rhs;
6681 }
6682
John Bauman19bac1e2014-05-06 15:23:49 -04006683 RValue<Float4> operator/=(const Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006684 {
6685 return lhs = lhs / rhs;
6686 }
6687
John Bauman19bac1e2014-05-06 15:23:49 -04006688 RValue<Float4> operator%=(const Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006689 {
6690 return lhs = lhs % rhs;
6691 }
6692
John Bauman19bac1e2014-05-06 15:23:49 -04006693 RValue<Float4> operator+(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006694 {
6695 return val;
6696 }
6697
John Bauman19bac1e2014-05-06 15:23:49 -04006698 RValue<Float4> operator-(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006699 {
6700 return RValue<Float4>(Nucleus::createFNeg(val.value));
6701 }
6702
John Bauman19bac1e2014-05-06 15:23:49 -04006703 RValue<Float4> Abs(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006704 {
6705 Value *vector = Nucleus::createBitCast(x.value, Int4::getType());
6706
6707 Constant *constantVector[4];
6708 constantVector[0] = Nucleus::createConstantInt(0x7FFFFFFF);
6709 constantVector[1] = Nucleus::createConstantInt(0x7FFFFFFF);
6710 constantVector[2] = Nucleus::createConstantInt(0x7FFFFFFF);
6711 constantVector[3] = Nucleus::createConstantInt(0x7FFFFFFF);
6712
6713 Value *result = Nucleus::createAnd(vector, Nucleus::createConstantVector(constantVector, 4));
6714
6715 return RValue<Float4>(Nucleus::createBitCast(result, Float4::getType()));
6716 }
6717
John Bauman19bac1e2014-05-06 15:23:49 -04006718 RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006719 {
6720 return x86::maxps(x, y);
6721 }
6722
John Bauman19bac1e2014-05-06 15:23:49 -04006723 RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006724 {
6725 return x86::minps(x, y);
6726 }
6727
Nicolas Capens05b3d662016-02-25 23:58:33 -05006728 RValue<Float4> Rcp_pp(RValue<Float4> x, bool exactAtPow2)
John Bauman89401822014-05-06 15:04:28 -04006729 {
Nicolas Capens05b3d662016-02-25 23:58:33 -05006730 if(exactAtPow2)
6731 {
6732 // rcpps uses a piecewise-linear approximation which minimizes the relative error
6733 // but is not exact at power-of-two values. Rectify by multiplying by the inverse.
6734 return x86::rcpps(x) * Float4(1.0f / _mm_cvtss_f32(_mm_rcp_ss(_mm_set_ps1(1.0f))));
6735 }
6736 else
6737 {
6738 return x86::rcpps(x);
6739 }
John Bauman89401822014-05-06 15:04:28 -04006740 }
John Bauman66b8ab22014-05-06 15:57:45 -04006741
John Bauman19bac1e2014-05-06 15:23:49 -04006742 RValue<Float4> RcpSqrt_pp(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006743 {
6744 return x86::rsqrtps(x);
6745 }
6746
John Bauman19bac1e2014-05-06 15:23:49 -04006747 RValue<Float4> Sqrt(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006748 {
6749 return x86::sqrtps(x);
6750 }
6751
John Bauman19bac1e2014-05-06 15:23:49 -04006752 RValue<Float4> Insert(const Float4 &val, RValue<Float> element, int i)
John Bauman89401822014-05-06 15:04:28 -04006753 {
John Bauman66b8ab22014-05-06 15:57:45 -04006754 llvm::Value *value = val.loadValue();
John Bauman89401822014-05-06 15:04:28 -04006755 llvm::Value *insert = Nucleus::createInsertElement(value, element.value, i);
6756
6757 val = RValue<Float4>(insert);
6758
6759 return val;
6760 }
6761
John Bauman19bac1e2014-05-06 15:23:49 -04006762 RValue<Float> Extract(RValue<Float4> x, int i)
John Bauman89401822014-05-06 15:04:28 -04006763 {
6764 return RValue<Float>(Nucleus::createExtractElement(x.value, i));
6765 }
6766
John Bauman19bac1e2014-05-06 15:23:49 -04006767 RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04006768 {
6769 return RValue<Float4>(Nucleus::createSwizzle(x.value, select));
6770 }
6771
John Bauman19bac1e2014-05-06 15:23:49 -04006772 RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006773 {
6774 Constant *shuffle[4];
6775 shuffle[0] = Nucleus::createConstantInt(((imm >> 0) & 0x03) + 0);
6776 shuffle[1] = Nucleus::createConstantInt(((imm >> 2) & 0x03) + 0);
6777 shuffle[2] = Nucleus::createConstantInt(((imm >> 4) & 0x03) + 4);
6778 shuffle[3] = Nucleus::createConstantInt(((imm >> 6) & 0x03) + 4);
6779
6780 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 4)));
6781 }
6782
John Bauman19bac1e2014-05-06 15:23:49 -04006783 RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006784 {
6785 Constant *shuffle[4];
6786 shuffle[0] = Nucleus::createConstantInt(0);
6787 shuffle[1] = Nucleus::createConstantInt(4);
6788 shuffle[2] = Nucleus::createConstantInt(1);
6789 shuffle[3] = Nucleus::createConstantInt(5);
6790
6791 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 4)));
6792 }
6793
John Bauman19bac1e2014-05-06 15:23:49 -04006794 RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006795 {
6796 Constant *shuffle[4];
6797 shuffle[0] = Nucleus::createConstantInt(2);
6798 shuffle[1] = Nucleus::createConstantInt(6);
6799 shuffle[2] = Nucleus::createConstantInt(3);
6800 shuffle[3] = Nucleus::createConstantInt(7);
6801
6802 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 4)));
6803 }
John Bauman66b8ab22014-05-06 15:57:45 -04006804
John Bauman19bac1e2014-05-06 15:23:49 -04006805 RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04006806 {
John Bauman66b8ab22014-05-06 15:57:45 -04006807 Value *vector = lhs.loadValue();
John Bauman89401822014-05-06 15:04:28 -04006808 Value *shuffle = Nucleus::createMask(vector, rhs.value, select);
John Bauman66b8ab22014-05-06 15:57:45 -04006809 lhs.storeValue(shuffle);
John Bauman89401822014-05-06 15:04:28 -04006810
6811 return RValue<Float4>(shuffle);
6812 }
6813
John Bauman19bac1e2014-05-06 15:23:49 -04006814 RValue<Int> SignMask(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006815 {
6816 return x86::movmskps(x);
6817 }
6818
John Bauman19bac1e2014-05-06 15:23:49 -04006819 RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006820 {
6821 // return As<Int4>(x86::cmpeqps(x, y));
6822 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOEQ(x.value, y.value), Int4::getType()));
6823 }
6824
John Bauman19bac1e2014-05-06 15:23:49 -04006825 RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006826 {
6827 // return As<Int4>(x86::cmpltps(x, y));
6828 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOLT(x.value, y.value), Int4::getType()));
6829 }
6830
John Bauman19bac1e2014-05-06 15:23:49 -04006831 RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006832 {
6833 // return As<Int4>(x86::cmpleps(x, y));
6834 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOLE(x.value, y.value), Int4::getType()));
6835 }
6836
John Bauman19bac1e2014-05-06 15:23:49 -04006837 RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006838 {
6839 // return As<Int4>(x86::cmpneqps(x, y));
6840 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpONE(x.value, y.value), Int4::getType()));
6841 }
6842
John Bauman19bac1e2014-05-06 15:23:49 -04006843 RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006844 {
6845 // return As<Int4>(x86::cmpnltps(x, y));
6846 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOGE(x.value, y.value), Int4::getType()));
6847 }
6848
John Bauman19bac1e2014-05-06 15:23:49 -04006849 RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006850 {
6851 // return As<Int4>(x86::cmpnleps(x, y));
6852 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOGT(x.value, y.value), Int4::getType()));
6853 }
6854
John Bauman19bac1e2014-05-06 15:23:49 -04006855 RValue<Float4> Round(RValue<Float4> x)
6856 {
6857 if(CPUID::supportsSSE4_1())
6858 {
6859 return x86::roundps(x, 0);
6860 }
6861 else
6862 {
6863 return Float4(RoundInt(x));
6864 }
6865 }
6866
6867 RValue<Float4> Trunc(RValue<Float4> x)
6868 {
6869 if(CPUID::supportsSSE4_1())
6870 {
6871 return x86::roundps(x, 3);
6872 }
6873 else
6874 {
6875 return Float4(Int4(x)); // Rounded toward zero
6876 }
6877 }
6878
6879 RValue<Float4> Frac(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006880 {
6881 if(CPUID::supportsSSE4_1())
6882 {
6883 return x - x86::floorps(x);
6884 }
6885 else
6886 {
John Bauman19bac1e2014-05-06 15:23:49 -04006887 Float4 frc = x - Float4(Int4(x)); // Signed fractional part
John Bauman89401822014-05-06 15:04:28 -04006888
John Bauman19bac1e2014-05-06 15:23:49 -04006889 return frc + As<Float4>(As<Int4>(CmpNLE(Float4(0.0f), frc)) & As<Int4>(Float4(1, 1, 1, 1)));
John Bauman89401822014-05-06 15:04:28 -04006890 }
6891 }
6892
John Bauman19bac1e2014-05-06 15:23:49 -04006893 RValue<Float4> Floor(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006894 {
6895 if(CPUID::supportsSSE4_1())
6896 {
6897 return x86::floorps(x);
6898 }
6899 else
6900 {
John Bauman19bac1e2014-05-06 15:23:49 -04006901 return x - Frac(x);
John Bauman89401822014-05-06 15:04:28 -04006902 }
6903 }
6904
John Bauman19bac1e2014-05-06 15:23:49 -04006905 RValue<Float4> Ceil(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006906 {
John Bauman19bac1e2014-05-06 15:23:49 -04006907 if(CPUID::supportsSSE4_1())
6908 {
6909 return x86::ceilps(x);
6910 }
6911 else
6912 {
6913 return -Floor(-x);
6914 }
John Bauman89401822014-05-06 15:04:28 -04006915 }
6916
John Bauman19bac1e2014-05-06 15:23:49 -04006917 Type *Float4::getType()
John Bauman89401822014-05-06 15:04:28 -04006918 {
Nicolas Capensac230122016-09-20 14:30:06 -04006919 return T(VectorType::get(Float::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04006920 }
6921
Nicolas Capens81f18302016-01-14 09:32:35 -05006922 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006923 {
Nicolas Capens81f18302016-01-14 09:32:35 -05006924 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Nucleus::createConstantInt(offset)));
John Bauman89401822014-05-06 15:04:28 -04006925 }
6926
Nicolas Capens81f18302016-01-14 09:32:35 -05006927 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006928 {
Nicolas Capens81f18302016-01-14 09:32:35 -05006929 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, offset.value));
John Bauman89401822014-05-06 15:04:28 -04006930 }
6931
Nicolas Capens81f18302016-01-14 09:32:35 -05006932 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006933 {
Nicolas Capens81f18302016-01-14 09:32:35 -05006934 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, offset.value));
John Bauman89401822014-05-06 15:04:28 -04006935 }
6936
Nicolas Capens81f18302016-01-14 09:32:35 -05006937 RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006938 {
6939 return lhs = lhs + offset;
6940 }
6941
Nicolas Capens81f18302016-01-14 09:32:35 -05006942 RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006943 {
6944 return lhs = lhs + offset;
6945 }
6946
Nicolas Capens81f18302016-01-14 09:32:35 -05006947 RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006948 {
6949 return lhs = lhs + offset;
6950 }
6951
Nicolas Capens81f18302016-01-14 09:32:35 -05006952 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006953 {
6954 return lhs + -offset;
6955 }
6956
Nicolas Capens81f18302016-01-14 09:32:35 -05006957 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006958 {
6959 return lhs + -offset;
6960 }
6961
Nicolas Capens81f18302016-01-14 09:32:35 -05006962 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006963 {
6964 return lhs + -offset;
6965 }
6966
Nicolas Capens81f18302016-01-14 09:32:35 -05006967 RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006968 {
6969 return lhs = lhs - offset;
6970 }
6971
Nicolas Capens81f18302016-01-14 09:32:35 -05006972 RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006973 {
6974 return lhs = lhs - offset;
6975 }
6976
Nicolas Capens81f18302016-01-14 09:32:35 -05006977 RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006978 {
6979 return lhs = lhs - offset;
6980 }
6981
6982 void Return()
6983 {
John Bauman89401822014-05-06 15:04:28 -04006984 Nucleus::createRetVoid();
6985 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
John Bauman19bac1e2014-05-06 15:23:49 -04006986 Nucleus::createUnreachable();
6987 }
6988
6989 void Return(bool ret)
6990 {
John Bauman19bac1e2014-05-06 15:23:49 -04006991 Nucleus::createRet(Nucleus::createConstantBool(ret));
6992 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
6993 Nucleus::createUnreachable();
John Bauman89401822014-05-06 15:04:28 -04006994 }
6995
6996 void Return(const Int &ret)
6997 {
John Bauman66b8ab22014-05-06 15:57:45 -04006998 Nucleus::createRet(ret.loadValue());
John Bauman89401822014-05-06 15:04:28 -04006999 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
John Bauman19bac1e2014-05-06 15:23:49 -04007000 Nucleus::createUnreachable();
John Bauman89401822014-05-06 15:04:28 -04007001 }
7002
7003 BasicBlock *beginLoop()
7004 {
7005 BasicBlock *loopBB = Nucleus::createBasicBlock();
7006
7007 Nucleus::createBr(loopBB);
John Bauman66b8ab22014-05-06 15:57:45 -04007008 Nucleus::setInsertBlock(loopBB);
John Bauman89401822014-05-06 15:04:28 -04007009
7010 return loopBB;
7011 }
7012
John Bauman19bac1e2014-05-06 15:23:49 -04007013 bool branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB)
John Bauman89401822014-05-06 15:04:28 -04007014 {
7015 Nucleus::createCondBr(cmp.value, bodyBB, endBB);
John Bauman66b8ab22014-05-06 15:57:45 -04007016 Nucleus::setInsertBlock(bodyBB);
7017
John Bauman89401822014-05-06 15:04:28 -04007018 return true;
7019 }
7020
7021 bool elseBlock(BasicBlock *falseBB)
7022 {
7023 falseBB->back().eraseFromParent();
John Bauman66b8ab22014-05-06 15:57:45 -04007024 Nucleus::setInsertBlock(falseBB);
John Bauman89401822014-05-06 15:04:28 -04007025
7026 return true;
7027 }
7028
7029 RValue<Long> Ticks()
7030 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007031 llvm::Function *rdtsc = Intrinsic::getDeclaration(::module, Intrinsic::readcyclecounter);
John Bauman89401822014-05-06 15:04:28 -04007032
7033 return RValue<Long>(Nucleus::createCall(rdtsc));
7034 }
John Bauman89401822014-05-06 15:04:28 -04007035}
7036
7037namespace sw
7038{
7039 namespace x86
7040 {
John Bauman19bac1e2014-05-06 15:23:49 -04007041 RValue<Int> cvtss2si(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04007042 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007043 llvm::Function *cvtss2si = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cvtss2si);
John Bauman66b8ab22014-05-06 15:57:45 -04007044
John Bauman89401822014-05-06 15:04:28 -04007045 Float4 vector;
7046 vector.x = val;
7047
7048 return RValue<Int>(Nucleus::createCall(cvtss2si, RValue<Float4>(vector).value));
7049 }
7050
John Bauman19bac1e2014-05-06 15:23:49 -04007051 RValue<Int2> cvtps2pi(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04007052 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007053 llvm::Function *cvtps2pi = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cvtps2pi);
John Bauman89401822014-05-06 15:04:28 -04007054
7055 return RValue<Int2>(Nucleus::createCall(cvtps2pi, val.value));
7056 }
7057
John Bauman19bac1e2014-05-06 15:23:49 -04007058 RValue<Int2> cvttps2pi(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04007059 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007060 llvm::Function *cvttps2pi = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cvttps2pi);
John Bauman89401822014-05-06 15:04:28 -04007061
7062 return RValue<Int2>(Nucleus::createCall(cvttps2pi, val.value));
7063 }
7064
John Bauman19bac1e2014-05-06 15:23:49 -04007065 RValue<Int4> cvtps2dq(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04007066 {
7067 if(CPUID::supportsSSE2())
7068 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007069 llvm::Function *cvtps2dq = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_cvtps2dq);
John Bauman89401822014-05-06 15:04:28 -04007070
7071 return RValue<Int4>(Nucleus::createCall(cvtps2dq, val.value));
7072 }
7073 else
7074 {
7075 Int2 lo = x86::cvtps2pi(val);
7076 Int2 hi = x86::cvtps2pi(Swizzle(val, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04007077
Nicolas Capens62abb552016-01-05 12:03:47 -05007078 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007079 }
7080 }
7081
John Bauman19bac1e2014-05-06 15:23:49 -04007082 RValue<Float> rcpss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04007083 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007084 llvm::Function *rcpss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rcp_ss);
John Bauman89401822014-05-06 15:04:28 -04007085
7086 Value *vector = Nucleus::createInsertElement(UndefValue::get(Float4::getType()), val.value, 0);
John Bauman66b8ab22014-05-06 15:57:45 -04007087
John Bauman89401822014-05-06 15:04:28 -04007088 return RValue<Float>(Nucleus::createExtractElement(Nucleus::createCall(rcpss, vector), 0));
7089 }
7090
John Bauman19bac1e2014-05-06 15:23:49 -04007091 RValue<Float> sqrtss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04007092 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007093 llvm::Function *sqrtss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_sqrt_ss);
John Bauman89401822014-05-06 15:04:28 -04007094
7095 Value *vector = Nucleus::createInsertElement(UndefValue::get(Float4::getType()), val.value, 0);
John Bauman66b8ab22014-05-06 15:57:45 -04007096
John Bauman89401822014-05-06 15:04:28 -04007097 return RValue<Float>(Nucleus::createExtractElement(Nucleus::createCall(sqrtss, vector), 0));
7098 }
7099
John Bauman19bac1e2014-05-06 15:23:49 -04007100 RValue<Float> rsqrtss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04007101 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007102 llvm::Function *rsqrtss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rsqrt_ss);
John Bauman66b8ab22014-05-06 15:57:45 -04007103
John Bauman89401822014-05-06 15:04:28 -04007104 Value *vector = Nucleus::createInsertElement(UndefValue::get(Float4::getType()), val.value, 0);
7105
7106 return RValue<Float>(Nucleus::createExtractElement(Nucleus::createCall(rsqrtss, vector), 0));
7107 }
7108
John Bauman19bac1e2014-05-06 15:23:49 -04007109 RValue<Float4> rcpps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04007110 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007111 llvm::Function *rcpps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rcp_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04007112
John Bauman89401822014-05-06 15:04:28 -04007113 return RValue<Float4>(Nucleus::createCall(rcpps, val.value));
7114 }
7115
John Bauman19bac1e2014-05-06 15:23:49 -04007116 RValue<Float4> sqrtps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04007117 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007118 llvm::Function *sqrtps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_sqrt_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04007119
John Bauman89401822014-05-06 15:04:28 -04007120 return RValue<Float4>(Nucleus::createCall(sqrtps, val.value));
7121 }
7122
John Bauman19bac1e2014-05-06 15:23:49 -04007123 RValue<Float4> rsqrtps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04007124 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007125 llvm::Function *rsqrtps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rsqrt_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04007126
John Bauman89401822014-05-06 15:04:28 -04007127 return RValue<Float4>(Nucleus::createCall(rsqrtps, val.value));
7128 }
7129
John Bauman19bac1e2014-05-06 15:23:49 -04007130 RValue<Float4> maxps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007131 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007132 llvm::Function *maxps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_max_ps);
John Bauman89401822014-05-06 15:04:28 -04007133
7134 return RValue<Float4>(Nucleus::createCall(maxps, x.value, y.value));
7135 }
7136
John Bauman19bac1e2014-05-06 15:23:49 -04007137 RValue<Float4> minps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007138 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007139 llvm::Function *minps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_min_ps);
John Bauman89401822014-05-06 15:04:28 -04007140
7141 return RValue<Float4>(Nucleus::createCall(minps, x.value, y.value));
7142 }
7143
John Bauman19bac1e2014-05-06 15:23:49 -04007144 RValue<Float> roundss(RValue<Float> val, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04007145 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007146 llvm::Function *roundss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_round_ss);
John Bauman89401822014-05-06 15:04:28 -04007147
7148 Value *undef = UndefValue::get(Float4::getType());
7149 Value *vector = Nucleus::createInsertElement(undef, val.value, 0);
7150
7151 return RValue<Float>(Nucleus::createExtractElement(Nucleus::createCall(roundss, undef, vector, Nucleus::createConstantInt(imm)), 0));
7152 }
7153
John Bauman19bac1e2014-05-06 15:23:49 -04007154 RValue<Float> floorss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04007155 {
7156 return roundss(val, 1);
7157 }
7158
John Bauman19bac1e2014-05-06 15:23:49 -04007159 RValue<Float> ceilss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04007160 {
7161 return roundss(val, 2);
7162 }
7163
John Bauman19bac1e2014-05-06 15:23:49 -04007164 RValue<Float4> roundps(RValue<Float4> val, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04007165 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007166 llvm::Function *roundps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_round_ps);
John Bauman89401822014-05-06 15:04:28 -04007167
7168 return RValue<Float4>(Nucleus::createCall(roundps, val.value, Nucleus::createConstantInt(imm)));
7169 }
7170
John Bauman19bac1e2014-05-06 15:23:49 -04007171 RValue<Float4> floorps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04007172 {
7173 return roundps(val, 1);
7174 }
7175
John Bauman19bac1e2014-05-06 15:23:49 -04007176 RValue<Float4> ceilps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04007177 {
7178 return roundps(val, 2);
7179 }
7180
John Bauman19bac1e2014-05-06 15:23:49 -04007181 RValue<Float4> cmpps(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04007182 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007183 llvm::Function *cmpps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cmp_ps);
John Bauman89401822014-05-06 15:04:28 -04007184
7185 return RValue<Float4>(Nucleus::createCall(cmpps, x.value, y.value, Nucleus::createConstantByte(imm)));
7186 }
7187
John Bauman19bac1e2014-05-06 15:23:49 -04007188 RValue<Float4> cmpeqps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007189 {
7190 return cmpps(x, y, 0);
7191 }
7192
John Bauman19bac1e2014-05-06 15:23:49 -04007193 RValue<Float4> cmpltps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007194 {
7195 return cmpps(x, y, 1);
7196 }
7197
John Bauman19bac1e2014-05-06 15:23:49 -04007198 RValue<Float4> cmpleps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007199 {
7200 return cmpps(x, y, 2);
7201 }
7202
John Bauman19bac1e2014-05-06 15:23:49 -04007203 RValue<Float4> cmpunordps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007204 {
7205 return cmpps(x, y, 3);
7206 }
7207
John Bauman19bac1e2014-05-06 15:23:49 -04007208 RValue<Float4> cmpneqps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007209 {
7210 return cmpps(x, y, 4);
7211 }
7212
John Bauman19bac1e2014-05-06 15:23:49 -04007213 RValue<Float4> cmpnltps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007214 {
7215 return cmpps(x, y, 5);
7216 }
7217
John Bauman19bac1e2014-05-06 15:23:49 -04007218 RValue<Float4> cmpnleps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007219 {
7220 return cmpps(x, y, 6);
7221 }
7222
John Bauman19bac1e2014-05-06 15:23:49 -04007223 RValue<Float4> cmpordps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007224 {
7225 return cmpps(x, y, 7);
7226 }
7227
John Bauman19bac1e2014-05-06 15:23:49 -04007228 RValue<Float> cmpss(RValue<Float> x, RValue<Float> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04007229 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007230 llvm::Function *cmpss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cmp_ss);
John Bauman89401822014-05-06 15:04:28 -04007231
7232 Value *vector1 = Nucleus::createInsertElement(UndefValue::get(Float4::getType()), x.value, 0);
7233 Value *vector2 = Nucleus::createInsertElement(UndefValue::get(Float4::getType()), y.value, 0);
7234
7235 return RValue<Float>(Nucleus::createExtractElement(Nucleus::createCall(cmpss, vector1, vector2, Nucleus::createConstantByte(imm)), 0));
7236 }
7237
John Bauman19bac1e2014-05-06 15:23:49 -04007238 RValue<Float> cmpeqss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007239 {
7240 return cmpss(x, y, 0);
7241 }
7242
John Bauman19bac1e2014-05-06 15:23:49 -04007243 RValue<Float> cmpltss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007244 {
7245 return cmpss(x, y, 1);
7246 }
7247
John Bauman19bac1e2014-05-06 15:23:49 -04007248 RValue<Float> cmpless(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007249 {
7250 return cmpss(x, y, 2);
7251 }
7252
John Bauman19bac1e2014-05-06 15:23:49 -04007253 RValue<Float> cmpunordss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007254 {
7255 return cmpss(x, y, 3);
7256 }
7257
John Bauman19bac1e2014-05-06 15:23:49 -04007258 RValue<Float> cmpneqss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007259 {
7260 return cmpss(x, y, 4);
7261 }
7262
John Bauman19bac1e2014-05-06 15:23:49 -04007263 RValue<Float> cmpnltss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007264 {
7265 return cmpss(x, y, 5);
7266 }
7267
John Bauman19bac1e2014-05-06 15:23:49 -04007268 RValue<Float> cmpnless(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007269 {
7270 return cmpss(x, y, 6);
7271 }
7272
John Bauman19bac1e2014-05-06 15:23:49 -04007273 RValue<Float> cmpordss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007274 {
7275 return cmpss(x, y, 7);
7276 }
7277
Alexis Hetu0f448072016-03-18 10:56:08 -04007278 RValue<Int4> pabsd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007279 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007280 llvm::Function *pabsd = Intrinsic::getDeclaration(::module, Intrinsic::x86_ssse3_pabs_d_128);
John Bauman89401822014-05-06 15:04:28 -04007281
Alexis Hetu0f448072016-03-18 10:56:08 -04007282 return RValue<Int4>(Nucleus::createCall(pabsd, x.value));
John Bauman89401822014-05-06 15:04:28 -04007283 }
7284
John Bauman19bac1e2014-05-06 15:23:49 -04007285 RValue<Short4> paddsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007286 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007287 llvm::Function *paddsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padds_w);
John Bauman89401822014-05-06 15:04:28 -04007288
John Bauman19bac1e2014-05-06 15:23:49 -04007289 return As<Short4>(RValue<MMX>(Nucleus::createCall(paddsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007290 }
John Bauman66b8ab22014-05-06 15:57:45 -04007291
John Bauman19bac1e2014-05-06 15:23:49 -04007292 RValue<Short4> psubsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007293 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007294 llvm::Function *psubsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubs_w);
John Bauman89401822014-05-06 15:04:28 -04007295
John Bauman19bac1e2014-05-06 15:23:49 -04007296 return As<Short4>(RValue<MMX>(Nucleus::createCall(psubsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007297 }
7298
John Bauman19bac1e2014-05-06 15:23:49 -04007299 RValue<UShort4> paddusw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007300 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007301 llvm::Function *paddusw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_paddus_w);
John Bauman89401822014-05-06 15:04:28 -04007302
John Bauman19bac1e2014-05-06 15:23:49 -04007303 return As<UShort4>(RValue<MMX>(Nucleus::createCall(paddusw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007304 }
John Bauman66b8ab22014-05-06 15:57:45 -04007305
John Bauman19bac1e2014-05-06 15:23:49 -04007306 RValue<UShort4> psubusw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007307 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007308 llvm::Function *psubusw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubus_w);
John Bauman89401822014-05-06 15:04:28 -04007309
John Bauman19bac1e2014-05-06 15:23:49 -04007310 return As<UShort4>(RValue<MMX>(Nucleus::createCall(psubusw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007311 }
7312
John Bauman19bac1e2014-05-06 15:23:49 -04007313 RValue<SByte8> paddsb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04007314 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007315 llvm::Function *paddsb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padds_b);
John Bauman89401822014-05-06 15:04:28 -04007316
John Bauman19bac1e2014-05-06 15:23:49 -04007317 return As<SByte8>(RValue<MMX>(Nucleus::createCall(paddsb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007318 }
John Bauman66b8ab22014-05-06 15:57:45 -04007319
John Bauman19bac1e2014-05-06 15:23:49 -04007320 RValue<SByte8> psubsb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04007321 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007322 llvm::Function *psubsb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubs_b);
John Bauman89401822014-05-06 15:04:28 -04007323
John Bauman19bac1e2014-05-06 15:23:49 -04007324 return As<SByte8>(RValue<MMX>(Nucleus::createCall(psubsb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007325 }
John Bauman66b8ab22014-05-06 15:57:45 -04007326
John Bauman19bac1e2014-05-06 15:23:49 -04007327 RValue<Byte8> paddusb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04007328 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007329 llvm::Function *paddusb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_paddus_b);
John Bauman89401822014-05-06 15:04:28 -04007330
John Bauman19bac1e2014-05-06 15:23:49 -04007331 return As<Byte8>(RValue<MMX>(Nucleus::createCall(paddusb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007332 }
John Bauman66b8ab22014-05-06 15:57:45 -04007333
John Bauman19bac1e2014-05-06 15:23:49 -04007334 RValue<Byte8> psubusb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04007335 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007336 llvm::Function *psubusb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubus_b);
John Bauman89401822014-05-06 15:04:28 -04007337
John Bauman19bac1e2014-05-06 15:23:49 -04007338 return As<Byte8>(RValue<MMX>(Nucleus::createCall(psubusb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007339 }
7340
John Bauman19bac1e2014-05-06 15:23:49 -04007341 RValue<Short4> paddw(RValue<Short4> x, RValue<Short4> y)
7342 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007343 llvm::Function *paddw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padd_w);
John Bauman19bac1e2014-05-06 15:23:49 -04007344
7345 return As<Short4>(RValue<MMX>(Nucleus::createCall(paddw, As<MMX>(x).value, As<MMX>(y).value)));
7346 }
7347
7348 RValue<Short4> psubw(RValue<Short4> x, RValue<Short4> y)
7349 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007350 llvm::Function *psubw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psub_w);
John Bauman19bac1e2014-05-06 15:23:49 -04007351
7352 return As<Short4>(RValue<MMX>(Nucleus::createCall(psubw, As<MMX>(x).value, As<MMX>(y).value)));
7353 }
7354
7355 RValue<Short4> pmullw(RValue<Short4> x, RValue<Short4> y)
7356 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007357 llvm::Function *pmullw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmull_w);
John Bauman19bac1e2014-05-06 15:23:49 -04007358
7359 return As<Short4>(RValue<MMX>(Nucleus::createCall(pmullw, As<MMX>(x).value, As<MMX>(y).value)));
7360 }
7361
7362 RValue<Short4> pand(RValue<Short4> x, RValue<Short4> y)
7363 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007364 llvm::Function *pand = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pand);
John Bauman19bac1e2014-05-06 15:23:49 -04007365
7366 return As<Short4>(RValue<MMX>(Nucleus::createCall(pand, As<MMX>(x).value, As<MMX>(y).value)));
7367 }
7368
7369 RValue<Short4> por(RValue<Short4> x, RValue<Short4> y)
7370 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007371 llvm::Function *por = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_por);
John Bauman19bac1e2014-05-06 15:23:49 -04007372
7373 return As<Short4>(RValue<MMX>(Nucleus::createCall(por, As<MMX>(x).value, As<MMX>(y).value)));
7374 }
7375
7376 RValue<Short4> pxor(RValue<Short4> x, RValue<Short4> y)
7377 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007378 llvm::Function *pxor = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pxor);
John Bauman19bac1e2014-05-06 15:23:49 -04007379
7380 return As<Short4>(RValue<MMX>(Nucleus::createCall(pxor, As<MMX>(x).value, As<MMX>(y).value)));
7381 }
7382
7383 RValue<Short4> pshufw(RValue<Short4> x, unsigned char y)
7384 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007385 llvm::Function *pshufw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_pshuf_w);
John Bauman19bac1e2014-05-06 15:23:49 -04007386
7387 return As<Short4>(RValue<MMX>(Nucleus::createCall(pshufw, As<MMX>(x).value, Nucleus::createConstantByte(y))));
7388 }
7389
7390 RValue<Int2> punpcklwd(RValue<Short4> x, RValue<Short4> y)
7391 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007392 llvm::Function *punpcklwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpcklwd);
John Bauman19bac1e2014-05-06 15:23:49 -04007393
7394 return As<Int2>(RValue<MMX>(Nucleus::createCall(punpcklwd, As<MMX>(x).value, As<MMX>(y).value)));
7395 }
7396
7397 RValue<Int2> punpckhwd(RValue<Short4> x, RValue<Short4> y)
7398 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007399 llvm::Function *punpckhwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckhwd);
John Bauman19bac1e2014-05-06 15:23:49 -04007400
7401 return As<Int2>(RValue<MMX>(Nucleus::createCall(punpckhwd, As<MMX>(x).value, As<MMX>(y).value)));
7402 }
7403
7404 RValue<Short4> pinsrw(RValue<Short4> x, RValue<Int> y, unsigned int i)
7405 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007406 llvm::Function *pinsrw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pinsr_w);
John Bauman19bac1e2014-05-06 15:23:49 -04007407
7408 return As<Short4>(RValue<MMX>(Nucleus::createCall(pinsrw, As<MMX>(x).value, y.value, Nucleus::createConstantInt(i))));
7409 }
7410
7411 RValue<Int> pextrw(RValue<Short4> x, unsigned int i)
7412 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007413 llvm::Function *pextrw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pextr_w);
John Bauman19bac1e2014-05-06 15:23:49 -04007414
7415 return RValue<Int>(Nucleus::createCall(pextrw, As<MMX>(x).value, Nucleus::createConstantInt(i)));
7416 }
7417
7418 RValue<Long1> punpckldq(RValue<Int2> x, RValue<Int2> y)
7419 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007420 llvm::Function *punpckldq = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckldq);
John Bauman19bac1e2014-05-06 15:23:49 -04007421
7422 return As<Long1>(RValue<MMX>(Nucleus::createCall(punpckldq, As<MMX>(x).value, As<MMX>(y).value)));
7423 }
7424
7425 RValue<Long1> punpckhdq(RValue<Int2> x, RValue<Int2> y)
7426 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007427 llvm::Function *punpckhdq = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckhdq);
John Bauman19bac1e2014-05-06 15:23:49 -04007428
7429 return As<Long1>(RValue<MMX>(Nucleus::createCall(punpckhdq, As<MMX>(x).value, As<MMX>(y).value)));
7430 }
7431
7432 RValue<Short4> punpcklbw(RValue<Byte8> x, RValue<Byte8> y)
7433 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007434 llvm::Function *punpcklbw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpcklbw);
John Bauman19bac1e2014-05-06 15:23:49 -04007435
7436 return As<Short4>(RValue<MMX>(Nucleus::createCall(punpcklbw, As<MMX>(x).value, As<MMX>(y).value)));
7437 }
7438
7439 RValue<Short4> punpckhbw(RValue<Byte8> x, RValue<Byte8> y)
7440 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007441 llvm::Function *punpckhbw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckhbw);
John Bauman19bac1e2014-05-06 15:23:49 -04007442
7443 return As<Short4>(RValue<MMX>(Nucleus::createCall(punpckhbw, As<MMX>(x).value, As<MMX>(y).value)));
7444 }
7445
7446 RValue<Byte8> paddb(RValue<Byte8> x, RValue<Byte8> y)
7447 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007448 llvm::Function *paddb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padd_b);
John Bauman19bac1e2014-05-06 15:23:49 -04007449
7450 return As<Byte8>(RValue<MMX>(Nucleus::createCall(paddb, As<MMX>(x).value, As<MMX>(y).value)));
7451 }
7452
7453 RValue<Byte8> psubb(RValue<Byte8> x, RValue<Byte8> y)
7454 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007455 llvm::Function *psubb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psub_b);
John Bauman19bac1e2014-05-06 15:23:49 -04007456
7457 return As<Byte8>(RValue<MMX>(Nucleus::createCall(psubb, As<MMX>(x).value, As<MMX>(y).value)));
7458 }
7459
7460 RValue<Int2> paddd(RValue<Int2> x, RValue<Int2> y)
7461 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007462 llvm::Function *paddd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padd_d);
John Bauman19bac1e2014-05-06 15:23:49 -04007463
7464 return As<Int2>(RValue<MMX>(Nucleus::createCall(paddd, As<MMX>(x).value, As<MMX>(y).value)));
7465 }
7466
7467 RValue<Int2> psubd(RValue<Int2> x, RValue<Int2> y)
7468 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007469 llvm::Function *psubd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psub_d);
John Bauman19bac1e2014-05-06 15:23:49 -04007470
7471 return As<Int2>(RValue<MMX>(Nucleus::createCall(psubd, As<MMX>(x).value, As<MMX>(y).value)));
7472 }
7473
7474 RValue<UShort4> pavgw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007475 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007476 llvm::Function *pavgw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pavg_w);
John Bauman89401822014-05-06 15:04:28 -04007477
John Bauman19bac1e2014-05-06 15:23:49 -04007478 return As<UShort4>(RValue<MMX>(Nucleus::createCall(pavgw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007479 }
7480
John Bauman19bac1e2014-05-06 15:23:49 -04007481 RValue<Short4> pmaxsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007482 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007483 llvm::Function *pmaxsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmaxs_w);
John Bauman89401822014-05-06 15:04:28 -04007484
John Bauman19bac1e2014-05-06 15:23:49 -04007485 return As<Short4>(RValue<MMX>(Nucleus::createCall(pmaxsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007486 }
7487
John Bauman19bac1e2014-05-06 15:23:49 -04007488 RValue<Short4> pminsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007489 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007490 llvm::Function *pminsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmins_w);
John Bauman89401822014-05-06 15:04:28 -04007491
John Bauman19bac1e2014-05-06 15:23:49 -04007492 return As<Short4>(RValue<MMX>(Nucleus::createCall(pminsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007493 }
7494
John Bauman19bac1e2014-05-06 15:23:49 -04007495 RValue<Short4> pcmpgtw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007496 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007497 llvm::Function *pcmpgtw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpgt_w);
John Bauman89401822014-05-06 15:04:28 -04007498
John Bauman19bac1e2014-05-06 15:23:49 -04007499 return As<Short4>(RValue<MMX>(Nucleus::createCall(pcmpgtw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007500 }
7501
John Bauman19bac1e2014-05-06 15:23:49 -04007502 RValue<Short4> pcmpeqw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007503 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007504 llvm::Function *pcmpeqw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpeq_w);
John Bauman89401822014-05-06 15:04:28 -04007505
John Bauman19bac1e2014-05-06 15:23:49 -04007506 return As<Short4>(RValue<MMX>(Nucleus::createCall(pcmpeqw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007507 }
7508
John Bauman19bac1e2014-05-06 15:23:49 -04007509 RValue<Byte8> pcmpgtb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04007510 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007511 llvm::Function *pcmpgtb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpgt_b);
John Bauman89401822014-05-06 15:04:28 -04007512
John Bauman19bac1e2014-05-06 15:23:49 -04007513 return As<Byte8>(RValue<MMX>(Nucleus::createCall(pcmpgtb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007514 }
7515
John Bauman19bac1e2014-05-06 15:23:49 -04007516 RValue<Byte8> pcmpeqb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04007517 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007518 llvm::Function *pcmpeqb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpeq_b);
John Bauman89401822014-05-06 15:04:28 -04007519
John Bauman19bac1e2014-05-06 15:23:49 -04007520 return As<Byte8>(RValue<MMX>(Nucleus::createCall(pcmpeqb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007521 }
7522
John Bauman19bac1e2014-05-06 15:23:49 -04007523 RValue<Short4> packssdw(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04007524 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007525 llvm::Function *packssdw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_packssdw);
John Bauman89401822014-05-06 15:04:28 -04007526
John Bauman19bac1e2014-05-06 15:23:49 -04007527 return As<Short4>(RValue<MMX>(Nucleus::createCall(packssdw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007528 }
7529
John Bauman19bac1e2014-05-06 15:23:49 -04007530 RValue<Short8> packssdw(RValue<Int4> x, RValue<Int4> y)
John Bauman89401822014-05-06 15:04:28 -04007531 {
7532 if(CPUID::supportsSSE2())
7533 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007534 llvm::Function *packssdw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_packssdw_128);
John Bauman89401822014-05-06 15:04:28 -04007535
7536 return RValue<Short8>(Nucleus::createCall(packssdw, x.value, y.value));
7537 }
7538 else
7539 {
7540 Int2 loX = Int2(x);
7541 Int2 hiX = Int2(Swizzle(x, 0xEE));
7542
7543 Int2 loY = Int2(y);
7544 Int2 hiY = Int2(Swizzle(y, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04007545
John Bauman89401822014-05-06 15:04:28 -04007546 Short4 lo = x86::packssdw(loX, hiX);
7547 Short4 hi = x86::packssdw(loY, hiY);
John Bauman66b8ab22014-05-06 15:57:45 -04007548
Nicolas Capens62abb552016-01-05 12:03:47 -05007549 return Short8(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007550 }
7551 }
7552
John Bauman19bac1e2014-05-06 15:23:49 -04007553 RValue<SByte8> packsswb(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007554 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007555 llvm::Function *packsswb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_packsswb);
John Bauman89401822014-05-06 15:04:28 -04007556
John Bauman19bac1e2014-05-06 15:23:49 -04007557 return As<SByte8>(RValue<MMX>(Nucleus::createCall(packsswb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007558 }
7559
John Bauman19bac1e2014-05-06 15:23:49 -04007560 RValue<Byte8> packuswb(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007561 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007562 llvm::Function *packuswb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_packuswb);
John Bauman89401822014-05-06 15:04:28 -04007563
John Bauman19bac1e2014-05-06 15:23:49 -04007564 return As<Byte8>(RValue<MMX>(Nucleus::createCall(packuswb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007565 }
7566
John Bauman19bac1e2014-05-06 15:23:49 -04007567 RValue<UShort8> packusdw(RValue<UInt4> x, RValue<UInt4> y)
John Bauman89401822014-05-06 15:04:28 -04007568 {
7569 if(CPUID::supportsSSE4_1())
7570 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007571 llvm::Function *packusdw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_packusdw);
John Bauman66b8ab22014-05-06 15:57:45 -04007572
John Bauman89401822014-05-06 15:04:28 -04007573 return RValue<UShort8>(Nucleus::createCall(packusdw, x.value, y.value));
7574 }
7575 else
7576 {
7577 // FIXME: Not an exact replacement!
John Bauman19bac1e2014-05-06 15:23:49 -04007578 return As<UShort8>(packssdw(As<Int4>(x - UInt4(0x00008000, 0x00008000, 0x00008000, 0x00008000)), As<Int4>(y - UInt4(0x00008000, 0x00008000, 0x00008000, 0x00008000))) + Short8(0x8000u, 0x8000u, 0x8000u, 0x8000u, 0x8000u, 0x8000u, 0x8000u, 0x8000u));
John Bauman89401822014-05-06 15:04:28 -04007579 }
7580 }
7581
John Bauman19bac1e2014-05-06 15:23:49 -04007582 RValue<UShort4> psrlw(RValue<UShort4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007583 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007584 llvm::Function *psrlw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrli_w);
John Bauman89401822014-05-06 15:04:28 -04007585
John Bauman19bac1e2014-05-06 15:23:49 -04007586 return As<UShort4>(RValue<MMX>(Nucleus::createCall(psrlw, As<MMX>(x).value, Nucleus::createConstantInt(y))));
John Bauman89401822014-05-06 15:04:28 -04007587 }
7588
John Bauman19bac1e2014-05-06 15:23:49 -04007589 RValue<UShort8> psrlw(RValue<UShort8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007590 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007591 llvm::Function *psrlw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrli_w);
John Bauman89401822014-05-06 15:04:28 -04007592
7593 return RValue<UShort8>(Nucleus::createCall(psrlw, x.value, Nucleus::createConstantInt(y)));
7594 }
7595
John Bauman19bac1e2014-05-06 15:23:49 -04007596 RValue<Short4> psraw(RValue<Short4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007597 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007598 llvm::Function *psraw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrai_w);
John Bauman89401822014-05-06 15:04:28 -04007599
John Bauman19bac1e2014-05-06 15:23:49 -04007600 return As<Short4>(RValue<MMX>(Nucleus::createCall(psraw, As<MMX>(x).value, Nucleus::createConstantInt(y))));
John Bauman89401822014-05-06 15:04:28 -04007601 }
7602
John Bauman19bac1e2014-05-06 15:23:49 -04007603 RValue<Short8> psraw(RValue<Short8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007604 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007605 llvm::Function *psraw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrai_w);
John Bauman89401822014-05-06 15:04:28 -04007606
7607 return RValue<Short8>(Nucleus::createCall(psraw, x.value, Nucleus::createConstantInt(y)));
7608 }
7609
John Bauman19bac1e2014-05-06 15:23:49 -04007610 RValue<Short4> psllw(RValue<Short4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007611 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007612 llvm::Function *psllw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pslli_w);
John Bauman89401822014-05-06 15:04:28 -04007613
John Bauman19bac1e2014-05-06 15:23:49 -04007614 return As<Short4>(RValue<MMX>(Nucleus::createCall(psllw, As<MMX>(x).value, Nucleus::createConstantInt(y))));
John Bauman89401822014-05-06 15:04:28 -04007615 }
7616
John Bauman19bac1e2014-05-06 15:23:49 -04007617 RValue<Short8> psllw(RValue<Short8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007618 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007619 llvm::Function *psllw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pslli_w);
John Bauman89401822014-05-06 15:04:28 -04007620
7621 return RValue<Short8>(Nucleus::createCall(psllw, x.value, Nucleus::createConstantInt(y)));
7622 }
7623
John Bauman19bac1e2014-05-06 15:23:49 -04007624 RValue<Int2> pslld(RValue<Int2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007625 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007626 llvm::Function *pslld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pslli_d);
John Bauman89401822014-05-06 15:04:28 -04007627
John Bauman19bac1e2014-05-06 15:23:49 -04007628 return As<Int2>(RValue<MMX>(Nucleus::createCall(pslld, As<MMX>(x).value, Nucleus::createConstantInt(y))));
John Bauman89401822014-05-06 15:04:28 -04007629 }
7630
John Bauman19bac1e2014-05-06 15:23:49 -04007631 RValue<Int4> pslld(RValue<Int4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007632 {
7633 if(CPUID::supportsSSE2())
7634 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007635 llvm::Function *pslld = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pslli_d);
John Bauman89401822014-05-06 15:04:28 -04007636
7637 return RValue<Int4>(Nucleus::createCall(pslld, x.value, Nucleus::createConstantInt(y)));
7638 }
7639 else
7640 {
7641 Int2 lo = Int2(x);
7642 Int2 hi = Int2(Swizzle(x, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04007643
John Bauman89401822014-05-06 15:04:28 -04007644 lo = x86::pslld(lo, y);
7645 hi = x86::pslld(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04007646
Nicolas Capens62abb552016-01-05 12:03:47 -05007647 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007648 }
7649 }
7650
John Bauman19bac1e2014-05-06 15:23:49 -04007651 RValue<Int2> psrad(RValue<Int2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007652 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007653 llvm::Function *psrad = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrai_d);
John Bauman89401822014-05-06 15:04:28 -04007654
John Bauman19bac1e2014-05-06 15:23:49 -04007655 return As<Int2>(RValue<MMX>(Nucleus::createCall(psrad, As<MMX>(x).value, Nucleus::createConstantInt(y))));
John Bauman89401822014-05-06 15:04:28 -04007656 }
7657
John Bauman19bac1e2014-05-06 15:23:49 -04007658 RValue<Int4> psrad(RValue<Int4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007659 {
7660 if(CPUID::supportsSSE2())
7661 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007662 llvm::Function *psrad = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrai_d);
John Bauman89401822014-05-06 15:04:28 -04007663
7664 return RValue<Int4>(Nucleus::createCall(psrad, x.value, Nucleus::createConstantInt(y)));
7665 }
7666 else
7667 {
7668 Int2 lo = Int2(x);
7669 Int2 hi = Int2(Swizzle(x, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04007670
John Bauman89401822014-05-06 15:04:28 -04007671 lo = x86::psrad(lo, y);
7672 hi = x86::psrad(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04007673
Nicolas Capens62abb552016-01-05 12:03:47 -05007674 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007675 }
7676 }
7677
John Bauman19bac1e2014-05-06 15:23:49 -04007678 RValue<UInt2> psrld(RValue<UInt2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007679 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007680 llvm::Function *psrld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrli_d);
John Bauman89401822014-05-06 15:04:28 -04007681
John Bauman19bac1e2014-05-06 15:23:49 -04007682 return As<UInt2>(RValue<MMX>(Nucleus::createCall(psrld, As<MMX>(x).value, Nucleus::createConstantInt(y))));
John Bauman89401822014-05-06 15:04:28 -04007683 }
7684
John Bauman19bac1e2014-05-06 15:23:49 -04007685 RValue<UInt4> psrld(RValue<UInt4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007686 {
7687 if(CPUID::supportsSSE2())
7688 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007689 llvm::Function *psrld = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrli_d);
John Bauman89401822014-05-06 15:04:28 -04007690
7691 return RValue<UInt4>(Nucleus::createCall(psrld, x.value, Nucleus::createConstantInt(y)));
7692 }
7693 else
7694 {
7695 UInt2 lo = As<UInt2>(Int2(As<Int4>(x)));
7696 UInt2 hi = As<UInt2>(Int2(Swizzle(As<Int4>(x), 0xEE)));
John Bauman66b8ab22014-05-06 15:57:45 -04007697
John Bauman89401822014-05-06 15:04:28 -04007698 lo = x86::psrld(lo, y);
7699 hi = x86::psrld(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04007700
Nicolas Capens62abb552016-01-05 12:03:47 -05007701 return UInt4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007702 }
7703 }
7704
John Bauman19bac1e2014-05-06 15:23:49 -04007705 RValue<UShort4> psrlw(RValue<UShort4> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007706 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007707 llvm::Function *psrlw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrl_w);
John Bauman89401822014-05-06 15:04:28 -04007708
John Bauman19bac1e2014-05-06 15:23:49 -04007709 return As<UShort4>(RValue<MMX>(Nucleus::createCall(psrlw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007710 }
7711
John Bauman19bac1e2014-05-06 15:23:49 -04007712 RValue<Short4> psraw(RValue<Short4> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007713 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007714 llvm::Function *psraw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psra_w);
John Bauman89401822014-05-06 15:04:28 -04007715
John Bauman19bac1e2014-05-06 15:23:49 -04007716 return As<Short4>(RValue<MMX>(Nucleus::createCall(psraw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007717 }
7718
John Bauman19bac1e2014-05-06 15:23:49 -04007719 RValue<Short4> psllw(RValue<Short4> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007720 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007721 llvm::Function *psllw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psll_w);
John Bauman89401822014-05-06 15:04:28 -04007722
John Bauman19bac1e2014-05-06 15:23:49 -04007723 return As<Short4>(RValue<MMX>(Nucleus::createCall(psllw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007724 }
7725
John Bauman19bac1e2014-05-06 15:23:49 -04007726 RValue<Int2> pslld(RValue<Int2> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007727 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007728 llvm::Function *pslld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psll_d);
John Bauman89401822014-05-06 15:04:28 -04007729
John Bauman19bac1e2014-05-06 15:23:49 -04007730 return As<Int2>(RValue<MMX>(Nucleus::createCall(pslld, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007731 }
7732
John Bauman19bac1e2014-05-06 15:23:49 -04007733 RValue<UInt2> psrld(RValue<UInt2> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007734 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007735 llvm::Function *psrld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrl_d);
John Bauman89401822014-05-06 15:04:28 -04007736
John Bauman19bac1e2014-05-06 15:23:49 -04007737 return As<UInt2>(RValue<MMX>(Nucleus::createCall(psrld, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007738 }
7739
John Bauman19bac1e2014-05-06 15:23:49 -04007740 RValue<Int2> psrad(RValue<Int2> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007741 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007742 llvm::Function *psrld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psra_d);
John Bauman89401822014-05-06 15:04:28 -04007743
John Bauman19bac1e2014-05-06 15:23:49 -04007744 return As<Int2>(RValue<MMX>(Nucleus::createCall(psrld, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007745 }
7746
John Bauman19bac1e2014-05-06 15:23:49 -04007747 RValue<Int4> pmaxsd(RValue<Int4> x, RValue<Int4> y)
7748 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007749 llvm::Function *pmaxsd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmaxsd);
John Bauman19bac1e2014-05-06 15:23:49 -04007750
7751 return RValue<Int4>(Nucleus::createCall(pmaxsd, x.value, y.value));
7752 }
7753
7754 RValue<Int4> pminsd(RValue<Int4> x, RValue<Int4> y)
7755 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007756 llvm::Function *pminsd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pminsd);
John Bauman19bac1e2014-05-06 15:23:49 -04007757
7758 return RValue<Int4>(Nucleus::createCall(pminsd, x.value, y.value));
7759 }
7760
7761 RValue<UInt4> pmaxud(RValue<UInt4> x, RValue<UInt4> y)
7762 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007763 llvm::Function *pmaxud = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmaxud);
John Bauman19bac1e2014-05-06 15:23:49 -04007764
John Bauman66b8ab22014-05-06 15:57:45 -04007765 return RValue<UInt4>(Nucleus::createCall(pmaxud, x.value, y.value));
John Bauman19bac1e2014-05-06 15:23:49 -04007766 }
7767
7768 RValue<UInt4> pminud(RValue<UInt4> x, RValue<UInt4> y)
7769 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007770 llvm::Function *pminud = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pminud);
John Bauman19bac1e2014-05-06 15:23:49 -04007771
John Bauman66b8ab22014-05-06 15:57:45 -04007772 return RValue<UInt4>(Nucleus::createCall(pminud, x.value, y.value));
John Bauman19bac1e2014-05-06 15:23:49 -04007773 }
7774
7775 RValue<Short4> pmulhw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007776 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007777 llvm::Function *pmulhw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmulh_w);
John Bauman89401822014-05-06 15:04:28 -04007778
John Bauman19bac1e2014-05-06 15:23:49 -04007779 return As<Short4>(RValue<MMX>(Nucleus::createCall(pmulhw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007780 }
7781
John Bauman19bac1e2014-05-06 15:23:49 -04007782 RValue<UShort4> pmulhuw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007783 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007784 llvm::Function *pmulhuw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmulhu_w);
John Bauman89401822014-05-06 15:04:28 -04007785
John Bauman19bac1e2014-05-06 15:23:49 -04007786 return As<UShort4>(RValue<MMX>(Nucleus::createCall(pmulhuw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007787 }
7788
John Bauman19bac1e2014-05-06 15:23:49 -04007789 RValue<Int2> pmaddwd(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007790 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007791 llvm::Function *pmaddwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmadd_wd);
John Bauman89401822014-05-06 15:04:28 -04007792
John Bauman19bac1e2014-05-06 15:23:49 -04007793 return As<Int2>(RValue<MMX>(Nucleus::createCall(pmaddwd, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007794 }
7795
John Bauman19bac1e2014-05-06 15:23:49 -04007796 RValue<Short8> pmulhw(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04007797 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007798 llvm::Function *pmulhw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pmulh_w);
John Bauman89401822014-05-06 15:04:28 -04007799
7800 return RValue<Short8>(Nucleus::createCall(pmulhw, x.value, y.value));
7801 }
7802
John Bauman19bac1e2014-05-06 15:23:49 -04007803 RValue<UShort8> pmulhuw(RValue<UShort8> x, RValue<UShort8> y)
John Bauman89401822014-05-06 15:04:28 -04007804 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007805 llvm::Function *pmulhuw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pmulhu_w);
John Bauman89401822014-05-06 15:04:28 -04007806
7807 return RValue<UShort8>(Nucleus::createCall(pmulhuw, x.value, y.value));
7808 }
7809
John Bauman19bac1e2014-05-06 15:23:49 -04007810 RValue<Int4> pmaddwd(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04007811 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007812 llvm::Function *pmaddwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pmadd_wd);
John Bauman89401822014-05-06 15:04:28 -04007813
7814 return RValue<Int4>(Nucleus::createCall(pmaddwd, x.value, y.value));
7815 }
7816
John Bauman19bac1e2014-05-06 15:23:49 -04007817 RValue<Int> movmskps(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04007818 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007819 llvm::Function *movmskps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_movmsk_ps);
John Bauman89401822014-05-06 15:04:28 -04007820
7821 return RValue<Int>(Nucleus::createCall(movmskps, x.value));
7822 }
7823
John Bauman19bac1e2014-05-06 15:23:49 -04007824 RValue<Int> pmovmskb(RValue<Byte8> x)
John Bauman89401822014-05-06 15:04:28 -04007825 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007826 llvm::Function *pmovmskb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmovmskb);
John Bauman89401822014-05-06 15:04:28 -04007827
John Bauman19bac1e2014-05-06 15:23:49 -04007828 return RValue<Int>(Nucleus::createCall(pmovmskb, As<MMX>(x).value));
John Bauman89401822014-05-06 15:04:28 -04007829 }
7830
Nicolas Capens81f18302016-01-14 09:32:35 -05007831 //RValue<Int2> movd(RValue<Pointer<Int>> x)
John Bauman89401822014-05-06 15:04:28 -04007832 //{
7833 // Value *element = Nucleus::createLoad(x.value);
7834
7835 //// Value *int2 = UndefValue::get(Int2::getType());
7836 //// int2 = Nucleus::createInsertElement(int2, element, ConstantInt::get(Int::getType(), 0));
7837
7838 // Value *int2 = Nucleus::createBitCast(Nucleus::createZExt(element, Long::getType()), Int2::getType());
7839
7840 // return RValue<Int2>(int2);
7841 //}
7842
John Bauman19bac1e2014-05-06 15:23:49 -04007843 //RValue<Int2> movdq2q(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007844 //{
7845 // Value *long2 = Nucleus::createBitCast(x.value, Long2::getType());
7846 // Value *element = Nucleus::createExtractElement(long2, ConstantInt::get(Int::getType(), 0));
7847
7848 // return RValue<Int2>(Nucleus::createBitCast(element, Int2::getType()));
7849 //}
7850
John Bauman19bac1e2014-05-06 15:23:49 -04007851 RValue<Int4> pmovzxbd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007852 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007853 llvm::Function *pmovzxbd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovzxbd);
John Bauman66b8ab22014-05-06 15:57:45 -04007854
John Bauman89401822014-05-06 15:04:28 -04007855 return RValue<Int4>(Nucleus::createCall(pmovzxbd, Nucleus::createBitCast(x.value, Byte16::getType())));
7856 }
7857
John Bauman19bac1e2014-05-06 15:23:49 -04007858 RValue<Int4> pmovsxbd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007859 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007860 llvm::Function *pmovsxbd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovsxbd);
John Bauman66b8ab22014-05-06 15:57:45 -04007861
John Bauman89401822014-05-06 15:04:28 -04007862 return RValue<Int4>(Nucleus::createCall(pmovsxbd, Nucleus::createBitCast(x.value, SByte16::getType())));
7863 }
7864
John Bauman19bac1e2014-05-06 15:23:49 -04007865 RValue<Int4> pmovzxwd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007866 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007867 llvm::Function *pmovzxwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovzxwd);
John Bauman66b8ab22014-05-06 15:57:45 -04007868
John Bauman89401822014-05-06 15:04:28 -04007869 return RValue<Int4>(Nucleus::createCall(pmovzxwd, Nucleus::createBitCast(x.value, UShort8::getType())));
7870 }
7871
John Bauman19bac1e2014-05-06 15:23:49 -04007872 RValue<Int4> pmovsxwd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007873 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007874 llvm::Function *pmovsxwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovsxwd);
John Bauman66b8ab22014-05-06 15:57:45 -04007875
John Bauman89401822014-05-06 15:04:28 -04007876 return RValue<Int4>(Nucleus::createCall(pmovsxwd, Nucleus::createBitCast(x.value, Short8::getType())));
7877 }
7878
7879 void emms()
7880 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007881 llvm::Function *emms = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_emms);
John Bauman89401822014-05-06 15:04:28 -04007882
7883 Nucleus::createCall(emms);
7884 }
7885 }
7886}