blob: ab9a1513199a8612e51f4f6f07f8dd096dce6b2e [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 Capensac230122016-09-20 14:30:06 -040078 class Type : public llvm::Type
79 {
80 };
81
82 inline Type *T(llvm::Type *t)
83 {
84 return reinterpret_cast<Type*>(t);
85 }
86
87 inline std::vector<llvm::Type*> &T(std::vector<Type*> &t)
88 {
89 return reinterpret_cast<std::vector<llvm::Type*>&>(t);
90 }
91
John Bauman89401822014-05-06 15:04:28 -040092 Nucleus::Nucleus()
93 {
Nicolas Capensb7ea9842015-04-01 10:54:59 -040094 codegenMutex.lock(); // Reactor and LLVM are currently not thread safe
95
John Bauman19bac1e2014-05-06 15:23:49 -040096 InitializeNativeTarget();
John Bauman89401822014-05-06 15:04:28 -040097 JITEmitDebugInfo = false;
98
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -040099 if(!::context)
John Bauman89401822014-05-06 15:04:28 -0400100 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400101 ::context = new LLVMContext();
John Bauman89401822014-05-06 15:04:28 -0400102 }
103
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400104 ::module = new Module("", *::context);
105 ::routineManager = new RoutineManager();
John Bauman66b8ab22014-05-06 15:57:45 -0400106
John Bauman89401822014-05-06 15:04:28 -0400107 #if defined(__x86_64__)
108 const char *architecture = "x86-64";
109 #else
110 const char *architecture = "x86";
111 #endif
112
113 SmallVector<std::string, 1> MAttrs;
114 MAttrs.push_back(CPUID::supportsMMX() ? "+mmx" : "-mmx");
115 MAttrs.push_back(CPUID::supportsCMOV() ? "+cmov" : "-cmov");
116 MAttrs.push_back(CPUID::supportsSSE() ? "+sse" : "-sse");
117 MAttrs.push_back(CPUID::supportsSSE2() ? "+sse2" : "-sse2");
118 MAttrs.push_back(CPUID::supportsSSE3() ? "+sse3" : "-sse3");
119 MAttrs.push_back(CPUID::supportsSSSE3() ? "+ssse3" : "-ssse3");
120 MAttrs.push_back(CPUID::supportsSSE4_1() ? "+sse41" : "-sse41");
121
John Bauman19bac1e2014-05-06 15:23:49 -0400122 std::string error;
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400123 TargetMachine *targetMachine = EngineBuilder::selectTarget(::module, architecture, "", MAttrs, Reloc::Default, CodeModel::JITDefault, &error);
124 ::executionEngine = JIT::createJIT(::module, 0, ::routineManager, CodeGenOpt::Aggressive, true, targetMachine);
John Bauman89401822014-05-06 15:04:28 -0400125
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400126 if(!::builder)
John Bauman89401822014-05-06 15:04:28 -0400127 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400128 ::builder = new IRBuilder<>(*::context);
John Bauman89401822014-05-06 15:04:28 -0400129
John Bauman66b8ab22014-05-06 15:57:45 -0400130 #if defined(_WIN32)
131 HMODULE CodeAnalyst = LoadLibrary("CAJitNtfyLib.dll");
132 if(CodeAnalyst)
133 {
134 CodeAnalystInitialize = (bool(*)())GetProcAddress(CodeAnalyst, "CAJIT_Initialize");
135 CodeAnalystCompleteJITLog = (void(*)())GetProcAddress(CodeAnalyst, "CAJIT_CompleteJITLog");
136 CodeAnalystLogJITCode = (bool(*)(const void*, unsigned int, const wchar_t*))GetProcAddress(CodeAnalyst, "CAJIT_LogJITCode");
137
138 CodeAnalystInitialize();
139 }
140 #endif
John Bauman89401822014-05-06 15:04:28 -0400141 }
142 }
143
144 Nucleus::~Nucleus()
145 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400146 delete ::executionEngine;
147 ::executionEngine = nullptr;
John Bauman89401822014-05-06 15:04:28 -0400148
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400149 ::routineManager = nullptr;
150 ::function = nullptr;
151 ::module = nullptr;
Nicolas Capensb7ea9842015-04-01 10:54:59 -0400152
153 codegenMutex.unlock();
John Bauman89401822014-05-06 15:04:28 -0400154 }
155
156 Routine *Nucleus::acquireRoutine(const wchar_t *name, bool runOptimizations)
157 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400158 if(::builder->GetInsertBlock()->empty() || !::builder->GetInsertBlock()->back().isTerminator())
John Bauman19bac1e2014-05-06 15:23:49 -0400159 {
Nicolas Capensac230122016-09-20 14:30:06 -0400160 llvm::Type *type = ::function->getReturnType();
John Bauman19bac1e2014-05-06 15:23:49 -0400161
162 if(type->isVoidTy())
163 {
164 createRetVoid();
165 }
166 else
167 {
168 createRet(UndefValue::get(type));
169 }
170 }
John Bauman89401822014-05-06 15:04:28 -0400171
172 if(false)
173 {
John Bauman66b8ab22014-05-06 15:57:45 -0400174 std::string error;
175 raw_fd_ostream file("llvm-dump-unopt.txt", error);
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400176 ::module->print(file, 0);
John Bauman89401822014-05-06 15:04:28 -0400177 }
178
179 if(runOptimizations)
180 {
181 optimize();
182 }
183
184 if(false)
185 {
John Bauman66b8ab22014-05-06 15:57:45 -0400186 std::string error;
187 raw_fd_ostream file("llvm-dump-opt.txt", error);
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400188 ::module->print(file, 0);
John Bauman89401822014-05-06 15:04:28 -0400189 }
190
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400191 void *entry = ::executionEngine->getPointerToFunction(::function);
192 Routine *routine = ::routineManager->acquireRoutine(entry);
John Bauman89401822014-05-06 15:04:28 -0400193
194 if(CodeAnalystLogJITCode)
195 {
Nicolas Capensd946e0a2014-06-26 11:31:08 -0400196 CodeAnalystLogJITCode(routine->getEntry(), routine->getCodeSize(), name);
John Bauman89401822014-05-06 15:04:28 -0400197 }
198
199 return routine;
200 }
201
202 void Nucleus::optimize()
203 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400204 static PassManager *passManager = nullptr;
John Bauman66b8ab22014-05-06 15:57:45 -0400205
John Bauman89401822014-05-06 15:04:28 -0400206 if(!passManager)
207 {
208 passManager = new PassManager();
209
210 UnsafeFPMath = true;
211 // NoInfsFPMath = true;
212 // NoNaNsFPMath = true;
213
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400214 passManager->add(new TargetData(*::executionEngine->getTargetData()));
John Bauman89401822014-05-06 15:04:28 -0400215 passManager->add(createScalarReplAggregatesPass());
216
217 for(int pass = 0; pass < 10 && optimization[pass] != Disabled; pass++)
218 {
219 switch(optimization[pass])
220 {
221 case Disabled: break;
222 case CFGSimplification: passManager->add(createCFGSimplificationPass()); break;
223 case LICM: passManager->add(createLICMPass()); break;
224 case AggressiveDCE: passManager->add(createAggressiveDCEPass()); break;
225 case GVN: passManager->add(createGVNPass()); break;
226 case InstructionCombining: passManager->add(createInstructionCombiningPass()); break;
227 case Reassociate: passManager->add(createReassociatePass()); break;
228 case DeadStoreElimination: passManager->add(createDeadStoreEliminationPass()); break;
229 case SCCP: passManager->add(createSCCPPass()); break;
John Bauman19bac1e2014-05-06 15:23:49 -0400230 case ScalarReplAggregates: passManager->add(createScalarReplAggregatesPass()); break;
John Bauman89401822014-05-06 15:04:28 -0400231 default:
232 assert(false);
233 }
234 }
235 }
236
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400237 passManager->run(*::module);
John Bauman89401822014-05-06 15:04:28 -0400238 }
239
John Bauman19bac1e2014-05-06 15:23:49 -0400240 Value *Nucleus::allocateStackVariable(Type *type, int arraySize)
John Bauman89401822014-05-06 15:04:28 -0400241 {
242 // Need to allocate it in the entry block for mem2reg to work
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400243 BasicBlock &entryBlock = ::function->getEntryBlock();
John Bauman89401822014-05-06 15:04:28 -0400244
245 Instruction *declaration;
246
247 if(arraySize)
248 {
249 declaration = new AllocaInst(type, Nucleus::createConstantInt(arraySize));
250 }
251 else
252 {
253 declaration = new AllocaInst(type, (Value*)0);
254 }
255
256 entryBlock.getInstList().push_front(declaration);
257
258 return declaration;
259 }
260
261 BasicBlock *Nucleus::createBasicBlock()
262 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400263 return BasicBlock::Create(*::context, "", ::function);
John Bauman89401822014-05-06 15:04:28 -0400264 }
265
266 BasicBlock *Nucleus::getInsertBlock()
267 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400268 return ::builder->GetInsertBlock();
John Bauman89401822014-05-06 15:04:28 -0400269 }
270
271 void Nucleus::setInsertBlock(BasicBlock *basicBlock)
272 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400273 // assert(::builder->GetInsertBlock()->back().isTerminator());
274 return ::builder->SetInsertPoint(basicBlock);
John Bauman89401822014-05-06 15:04:28 -0400275 }
276
277 BasicBlock *Nucleus::getPredecessor(BasicBlock *basicBlock)
278 {
279 return *pred_begin(basicBlock);
280 }
281
Nicolas Capensac230122016-09-20 14:30:06 -0400282 void Nucleus::createFunction(Type *ReturnType, std::vector<Type*> &Params)
John Bauman89401822014-05-06 15:04:28 -0400283 {
Nicolas Capensac230122016-09-20 14:30:06 -0400284 llvm::FunctionType *functionType = llvm::FunctionType::get(ReturnType, T(Params), false);
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400285 ::function = llvm::Function::Create(functionType, llvm::GlobalValue::InternalLinkage, "", ::module);
286 ::function->setCallingConv(llvm::CallingConv::C);
John Bauman89401822014-05-06 15:04:28 -0400287
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400288 ::builder->SetInsertPoint(BasicBlock::Create(*::context, "", ::function));
John Bauman89401822014-05-06 15:04:28 -0400289 }
290
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400291 llvm::Value *Nucleus::getArgument(unsigned int index)
John Bauman89401822014-05-06 15:04:28 -0400292 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400293 llvm::Function::arg_iterator args = ::function->arg_begin();
John Bauman89401822014-05-06 15:04:28 -0400294
295 while(index)
296 {
297 args++;
298 index--;
299 }
300
301 return &*args;
302 }
303
304 Value *Nucleus::createRetVoid()
305 {
John Bauman66b8ab22014-05-06 15:57:45 -0400306 x86::emms();
307
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400308 return ::builder->CreateRetVoid();
John Bauman89401822014-05-06 15:04:28 -0400309 }
310
311 Value *Nucleus::createRet(Value *V)
312 {
John Bauman66b8ab22014-05-06 15:57:45 -0400313 x86::emms();
314
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400315 return ::builder->CreateRet(V);
John Bauman89401822014-05-06 15:04:28 -0400316 }
317
318 Value *Nucleus::createBr(BasicBlock *dest)
319 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400320 return ::builder->CreateBr(dest);
John Bauman89401822014-05-06 15:04:28 -0400321 }
322
323 Value *Nucleus::createCondBr(Value *cond, BasicBlock *ifTrue, BasicBlock *ifFalse)
324 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400325 return ::builder->CreateCondBr(cond, ifTrue, ifFalse);
John Bauman89401822014-05-06 15:04:28 -0400326 }
327
328 Value *Nucleus::createAdd(Value *lhs, Value *rhs)
329 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400330 return ::builder->CreateAdd(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400331 }
332
333 Value *Nucleus::createSub(Value *lhs, Value *rhs)
334 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400335 return ::builder->CreateSub(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400336 }
337
338 Value *Nucleus::createMul(Value *lhs, Value *rhs)
339 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400340 return ::builder->CreateMul(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400341 }
342
343 Value *Nucleus::createUDiv(Value *lhs, Value *rhs)
344 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400345 return ::builder->CreateUDiv(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400346 }
347
348 Value *Nucleus::createSDiv(Value *lhs, Value *rhs)
349 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400350 return ::builder->CreateSDiv(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400351 }
352
353 Value *Nucleus::createFAdd(Value *lhs, Value *rhs)
354 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400355 return ::builder->CreateFAdd(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400356 }
357
358 Value *Nucleus::createFSub(Value *lhs, Value *rhs)
359 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400360 return ::builder->CreateFSub(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400361 }
362
363 Value *Nucleus::createFMul(Value *lhs, Value *rhs)
364 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400365 return ::builder->CreateFMul(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400366 }
367
368 Value *Nucleus::createFDiv(Value *lhs, Value *rhs)
369 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400370 return ::builder->CreateFDiv(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400371 }
372
373 Value *Nucleus::createURem(Value *lhs, Value *rhs)
374 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400375 return ::builder->CreateURem(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400376 }
377
378 Value *Nucleus::createSRem(Value *lhs, Value *rhs)
379 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400380 return ::builder->CreateSRem(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400381 }
382
383 Value *Nucleus::createFRem(Value *lhs, Value *rhs)
384 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400385 return ::builder->CreateFRem(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400386 }
387
388 Value *Nucleus::createShl(Value *lhs, Value *rhs)
389 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400390 return ::builder->CreateShl(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400391 }
392
393 Value *Nucleus::createLShr(Value *lhs, Value *rhs)
394 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400395 return ::builder->CreateLShr(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400396 }
397
398 Value *Nucleus::createAShr(Value *lhs, Value *rhs)
399 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400400 return ::builder->CreateAShr(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400401 }
402
403 Value *Nucleus::createAnd(Value *lhs, Value *rhs)
404 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400405 return ::builder->CreateAnd(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400406 }
407
408 Value *Nucleus::createOr(Value *lhs, Value *rhs)
409 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400410 return ::builder->CreateOr(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400411 }
412
413 Value *Nucleus::createXor(Value *lhs, Value *rhs)
414 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400415 return ::builder->CreateXor(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400416 }
417
418 Value *Nucleus::createNeg(Value *V)
419 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400420 return ::builder->CreateNeg(V);
John Bauman89401822014-05-06 15:04:28 -0400421 }
422
423 Value *Nucleus::createFNeg(Value *V)
424 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400425 return ::builder->CreateFNeg(V);
John Bauman89401822014-05-06 15:04:28 -0400426 }
427
428 Value *Nucleus::createNot(Value *V)
429 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400430 return ::builder->CreateNot(V);
John Bauman89401822014-05-06 15:04:28 -0400431 }
432
433 Value *Nucleus::createLoad(Value *ptr, bool isVolatile, unsigned int align)
434 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400435 return ::builder->Insert(new LoadInst(ptr, "", isVolatile, align));
John Bauman89401822014-05-06 15:04:28 -0400436 }
437
438 Value *Nucleus::createStore(Value *value, Value *ptr, bool isVolatile, unsigned int align)
439 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400440 return ::builder->Insert(new StoreInst(value, ptr, isVolatile, align));
John Bauman89401822014-05-06 15:04:28 -0400441 }
442
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400443 Value *Nucleus::createStore(Constant *constant, Value *ptr, bool isVolatile, unsigned int align)
444 {
445 return ::builder->Insert(new StoreInst(constant, ptr, isVolatile, align));
446 }
447
John Bauman89401822014-05-06 15:04:28 -0400448 Value *Nucleus::createGEP(Value *ptr, Value *index)
449 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400450 return ::builder->CreateGEP(ptr, index);
John Bauman89401822014-05-06 15:04:28 -0400451 }
452
John Bauman19bac1e2014-05-06 15:23:49 -0400453 Value *Nucleus::createAtomicAdd(Value *ptr, Value *value)
454 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400455 return ::builder->CreateAtomicRMW(AtomicRMWInst::Add, ptr, value, SequentiallyConsistent);
John Bauman19bac1e2014-05-06 15:23:49 -0400456 }
457
458 Value *Nucleus::createTrunc(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400459 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400460 return ::builder->CreateTrunc(V, destType);
John Bauman89401822014-05-06 15:04:28 -0400461 }
462
John Bauman19bac1e2014-05-06 15:23:49 -0400463 Value *Nucleus::createZExt(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400464 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400465 return ::builder->CreateZExt(V, destType);
John Bauman89401822014-05-06 15:04:28 -0400466 }
467
John Bauman19bac1e2014-05-06 15:23:49 -0400468 Value *Nucleus::createSExt(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400469 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400470 return ::builder->CreateSExt(V, destType);
John Bauman89401822014-05-06 15:04:28 -0400471 }
472
John Bauman19bac1e2014-05-06 15:23:49 -0400473 Value *Nucleus::createFPToSI(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400474 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400475 return ::builder->CreateFPToSI(V, destType);
John Bauman89401822014-05-06 15:04:28 -0400476 }
477
John Bauman19bac1e2014-05-06 15:23:49 -0400478 Value *Nucleus::createUIToFP(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400479 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400480 return ::builder->CreateUIToFP(V, destType);
John Bauman89401822014-05-06 15:04:28 -0400481 }
482
John Bauman19bac1e2014-05-06 15:23:49 -0400483 Value *Nucleus::createSIToFP(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400484 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400485 return ::builder->CreateSIToFP(V, destType);
John Bauman89401822014-05-06 15:04:28 -0400486 }
487
John Bauman19bac1e2014-05-06 15:23:49 -0400488 Value *Nucleus::createFPTrunc(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400489 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400490 return ::builder->CreateFPTrunc(V, destType);
John Bauman89401822014-05-06 15:04:28 -0400491 }
492
John Bauman19bac1e2014-05-06 15:23:49 -0400493 Value *Nucleus::createFPExt(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400494 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400495 return ::builder->CreateFPExt(V, destType);
John Bauman89401822014-05-06 15:04:28 -0400496 }
497
John Bauman19bac1e2014-05-06 15:23:49 -0400498 Value *Nucleus::createPtrToInt(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400499 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400500 return ::builder->CreatePtrToInt(V, destType);
John Bauman89401822014-05-06 15:04:28 -0400501 }
502
John Bauman19bac1e2014-05-06 15:23:49 -0400503 Value *Nucleus::createIntToPtr(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400504 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400505 return ::builder->CreateIntToPtr(V, destType);
John Bauman89401822014-05-06 15:04:28 -0400506 }
507
John Bauman19bac1e2014-05-06 15:23:49 -0400508 Value *Nucleus::createBitCast(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400509 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400510 return ::builder->CreateBitCast(V, destType);
John Bauman89401822014-05-06 15:04:28 -0400511 }
512
John Bauman19bac1e2014-05-06 15:23:49 -0400513 Value *Nucleus::createIntCast(Value *V, Type *destType, bool isSigned)
John Bauman89401822014-05-06 15:04:28 -0400514 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400515 return ::builder->CreateIntCast(V, destType, isSigned);
John Bauman89401822014-05-06 15:04:28 -0400516 }
517
518 Value *Nucleus::createICmpEQ(Value *lhs, Value *rhs)
519 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400520 return ::builder->CreateICmpEQ(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400521 }
522
523 Value *Nucleus::createICmpNE(Value *lhs, Value *rhs)
524 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400525 return ::builder->CreateICmpNE(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400526 }
527
528 Value *Nucleus::createICmpUGT(Value *lhs, Value *rhs)
529 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400530 return ::builder->CreateICmpUGT(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400531 }
532
533 Value *Nucleus::createICmpUGE(Value *lhs, Value *rhs)
534 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400535 return ::builder->CreateICmpUGE(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400536 }
537
538 Value *Nucleus::createICmpULT(Value *lhs, Value *rhs)
539 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400540 return ::builder->CreateICmpULT(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400541 }
542
543 Value *Nucleus::createICmpULE(Value *lhs, Value *rhs)
544 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400545 return ::builder->CreateICmpULE(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400546 }
547
548 Value *Nucleus::createICmpSGT(Value *lhs, Value *rhs)
549 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400550 return ::builder->CreateICmpSGT(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400551 }
552
553 Value *Nucleus::createICmpSGE(Value *lhs, Value *rhs)
554 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400555 return ::builder->CreateICmpSGE(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400556 }
557
558 Value *Nucleus::createICmpSLT(Value *lhs, Value *rhs)
559 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400560 return ::builder->CreateICmpSLT(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400561 }
562
563 Value *Nucleus::createICmpSLE(Value *lhs, Value *rhs)
564 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400565 return ::builder->CreateICmpSLE(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400566 }
567
568 Value *Nucleus::createFCmpOEQ(Value *lhs, Value *rhs)
569 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400570 return ::builder->CreateFCmpOEQ(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400571 }
572
573 Value *Nucleus::createFCmpOGT(Value *lhs, Value *rhs)
574 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400575 return ::builder->CreateFCmpOGT(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400576 }
577
578 Value *Nucleus::createFCmpOGE(Value *lhs, Value *rhs)
579 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400580 return ::builder->CreateFCmpOGE(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400581 }
582
583 Value *Nucleus::createFCmpOLT(Value *lhs, Value *rhs)
584 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400585 return ::builder->CreateFCmpOLT(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400586 }
587
588 Value *Nucleus::createFCmpOLE(Value *lhs, Value *rhs)
589 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400590 return ::builder->CreateFCmpOLE(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400591 }
592
593 Value *Nucleus::createFCmpONE(Value *lhs, Value *rhs)
594 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400595 return ::builder->CreateFCmpONE(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400596 }
597
598 Value *Nucleus::createFCmpORD(Value *lhs, Value *rhs)
599 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400600 return ::builder->CreateFCmpORD(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400601 }
602
603 Value *Nucleus::createFCmpUNO(Value *lhs, Value *rhs)
604 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400605 return ::builder->CreateFCmpUNO(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400606 }
607
608 Value *Nucleus::createFCmpUEQ(Value *lhs, Value *rhs)
609 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400610 return ::builder->CreateFCmpUEQ(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400611 }
612
613 Value *Nucleus::createFCmpUGT(Value *lhs, Value *rhs)
614 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400615 return ::builder->CreateFCmpUGT(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400616 }
617
618 Value *Nucleus::createFCmpUGE(Value *lhs, Value *rhs)
619 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400620 return ::builder->CreateFCmpUGE(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400621 }
622
623 Value *Nucleus::createFCmpULT(Value *lhs, Value *rhs)
624 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400625 return ::builder->CreateFCmpULT(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400626 }
627
628 Value *Nucleus::createFCmpULE(Value *lhs, Value *rhs)
629 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400630 return ::builder->CreateFCmpULE(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400631 }
632
633 Value *Nucleus::createFCmpUNE(Value *lhs, Value *rhs)
634 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400635 return ::builder->CreateFCmpULE(lhs, rhs);
John Bauman89401822014-05-06 15:04:28 -0400636 }
637
638 Value *Nucleus::createCall(Value *callee)
639 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400640 return ::builder->CreateCall(callee);
John Bauman89401822014-05-06 15:04:28 -0400641 }
642
643 Value *Nucleus::createCall(Value *callee, Value *arg)
644 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400645 return ::builder->CreateCall(callee, arg);
John Bauman89401822014-05-06 15:04:28 -0400646 }
647
648 Value *Nucleus::createCall(Value *callee, Value *arg1, Value *arg2)
649 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400650 return ::builder->CreateCall2(callee, arg1, arg2);
John Bauman89401822014-05-06 15:04:28 -0400651 }
652
653 Value *Nucleus::createCall(Value *callee, Value *arg1, Value *arg2, Value *arg3)
654 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400655 return ::builder->CreateCall3(callee, arg1, arg2, arg3);
John Bauman89401822014-05-06 15:04:28 -0400656 }
657
658 Value *Nucleus::createCall(Value *callee, Value *arg1, Value *arg2, Value *arg3, Value *arg4)
659 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400660 return ::builder->CreateCall4(callee, arg1, arg2, arg3, arg4);
John Bauman89401822014-05-06 15:04:28 -0400661 }
662
663 Value *Nucleus::createExtractElement(Value *vector, int index)
664 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400665 return ::builder->CreateExtractElement(vector, createConstantInt(index));
John Bauman89401822014-05-06 15:04:28 -0400666 }
667
668 Value *Nucleus::createInsertElement(Value *vector, Value *element, int index)
669 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400670 return ::builder->CreateInsertElement(vector, element, createConstantInt(index));
John Bauman89401822014-05-06 15:04:28 -0400671 }
672
673 Value *Nucleus::createShuffleVector(Value *V1, Value *V2, Value *mask)
674 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400675 return ::builder->CreateShuffleVector(V1, V2, mask);
John Bauman89401822014-05-06 15:04:28 -0400676 }
677
678 Value *Nucleus::createSelect(Value *C, Value *ifTrue, Value *ifFalse)
679 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400680 return ::builder->CreateSelect(C, ifTrue, ifFalse);
John Bauman89401822014-05-06 15:04:28 -0400681 }
682
683 Value *Nucleus::createSwitch(llvm::Value *V, llvm::BasicBlock *Dest, unsigned NumCases)
684 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400685 return ::builder->CreateSwitch(V, Dest, NumCases);
John Bauman89401822014-05-06 15:04:28 -0400686 }
687
688 void Nucleus::addSwitchCase(llvm::Value *Switch, int Case, llvm::BasicBlock *Branch)
689 {
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400690 static_cast<SwitchInst*>(Switch)->addCase(llvm::ConstantInt::get(Type::getInt32Ty(*::context), Case, true), Branch);
John Bauman89401822014-05-06 15:04:28 -0400691 }
692
693 Value *Nucleus::createUnreachable()
694 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400695 return ::builder->CreateUnreachable();
John Bauman89401822014-05-06 15:04:28 -0400696 }
697
698 Value *Nucleus::createSwizzle(Value *val, unsigned char select)
699 {
700 Constant *swizzle[4];
701 swizzle[0] = Nucleus::createConstantInt((select >> 0) & 0x03);
702 swizzle[1] = Nucleus::createConstantInt((select >> 2) & 0x03);
703 swizzle[2] = Nucleus::createConstantInt((select >> 4) & 0x03);
704 swizzle[3] = Nucleus::createConstantInt((select >> 6) & 0x03);
705
706 Value *shuffle = Nucleus::createShuffleVector(val, UndefValue::get(val->getType()), Nucleus::createConstantVector(swizzle, 4));
707
708 return shuffle;
709 }
710
711 Value *Nucleus::createMask(Value *lhs, Value *rhs, unsigned char select)
712 {
713 bool mask[4] = {false, false, false, false};
714
715 mask[(select >> 0) & 0x03] = true;
716 mask[(select >> 2) & 0x03] = true;
717 mask[(select >> 4) & 0x03] = true;
718 mask[(select >> 6) & 0x03] = true;
719
720 Constant *swizzle[4];
721 swizzle[0] = Nucleus::createConstantInt(mask[0] ? 4 : 0);
722 swizzle[1] = Nucleus::createConstantInt(mask[1] ? 5 : 1);
723 swizzle[2] = Nucleus::createConstantInt(mask[2] ? 6 : 2);
724 swizzle[3] = Nucleus::createConstantInt(mask[3] ? 7 : 3);
725
726 Value *shuffle = Nucleus::createShuffleVector(lhs, rhs, Nucleus::createConstantVector(swizzle, 4));
727
728 return shuffle;
729 }
730
Nicolas Capensac230122016-09-20 14:30:06 -0400731 llvm::Constant *Nucleus::createConstantPointer(const void *address, Type *Ty, bool isConstant, unsigned int Align)
John Bauman89401822014-05-06 15:04:28 -0400732 {
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400733 const GlobalValue *existingGlobal = ::executionEngine->getGlobalValueAtAddress(const_cast<void*>(address)); // FIXME: Const
John Bauman89401822014-05-06 15:04:28 -0400734
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400735 if(existingGlobal)
736 {
737 return (llvm::Constant*)existingGlobal;
738 }
John Bauman89401822014-05-06 15:04:28 -0400739
Nicolas Capensac230122016-09-20 14:30:06 -0400740 llvm::GlobalValue *global = new llvm::GlobalVariable(*::module, Ty, isConstant, llvm::GlobalValue::ExternalLinkage, 0, "");
741
John Bauman89401822014-05-06 15:04:28 -0400742 global->setAlignment(Align);
743
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400744 ::executionEngine->addGlobalMapping(global, const_cast<void*>(address));
745
John Bauman89401822014-05-06 15:04:28 -0400746 return global;
747 }
748
Nicolas Capensac230122016-09-20 14:30:06 -0400749 Type *Nucleus::getPointerType(Type *ElementType)
John Bauman89401822014-05-06 15:04:28 -0400750 {
Nicolas Capensac230122016-09-20 14:30:06 -0400751 return T(llvm::PointerType::get(ElementType, 0));
John Bauman89401822014-05-06 15:04:28 -0400752 }
753
Nicolas Capensac230122016-09-20 14:30:06 -0400754 llvm::Constant *Nucleus::createNullValue(Type *Ty)
John Bauman89401822014-05-06 15:04:28 -0400755 {
756 return llvm::Constant::getNullValue(Ty);
757 }
758
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400759 llvm::Constant *Nucleus::createConstantInt(int64_t i)
John Bauman89401822014-05-06 15:04:28 -0400760 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400761 return llvm::ConstantInt::get(Type::getInt64Ty(*::context), i, true);
John Bauman89401822014-05-06 15:04:28 -0400762 }
763
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400764 llvm::Constant *Nucleus::createConstantInt(int i)
John Bauman89401822014-05-06 15:04:28 -0400765 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400766 return llvm::ConstantInt::get(Type::getInt32Ty(*::context), i, true);
John Bauman89401822014-05-06 15:04:28 -0400767 }
768
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400769 llvm::Constant *Nucleus::createConstantInt(unsigned int i)
John Bauman89401822014-05-06 15:04:28 -0400770 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400771 return llvm::ConstantInt::get(Type::getInt32Ty(*::context), i, false);
John Bauman89401822014-05-06 15:04:28 -0400772 }
773
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400774 llvm::Constant *Nucleus::createConstantBool(bool b)
John Bauman89401822014-05-06 15:04:28 -0400775 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400776 return llvm::ConstantInt::get(Type::getInt1Ty(*::context), b);
John Bauman89401822014-05-06 15:04:28 -0400777 }
778
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400779 llvm::Constant *Nucleus::createConstantByte(signed char i)
John Bauman89401822014-05-06 15:04:28 -0400780 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400781 return llvm::ConstantInt::get(Type::getInt8Ty(*::context), i, true);
John Bauman89401822014-05-06 15:04:28 -0400782 }
783
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400784 llvm::Constant *Nucleus::createConstantByte(unsigned char i)
John Bauman89401822014-05-06 15:04:28 -0400785 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400786 return llvm::ConstantInt::get(Type::getInt8Ty(*::context), i, false);
John Bauman89401822014-05-06 15:04:28 -0400787 }
788
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400789 llvm::Constant *Nucleus::createConstantShort(short i)
John Bauman89401822014-05-06 15:04:28 -0400790 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400791 return llvm::ConstantInt::get(Type::getInt16Ty(*::context), i, true);
John Bauman89401822014-05-06 15:04:28 -0400792 }
793
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400794 llvm::Constant *Nucleus::createConstantShort(unsigned short i)
John Bauman89401822014-05-06 15:04:28 -0400795 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -0400796 return llvm::ConstantInt::get(Type::getInt16Ty(*::context), i, false);
John Bauman89401822014-05-06 15:04:28 -0400797 }
798
799 llvm::Constant *Nucleus::createConstantFloat(float x)
800 {
801 return ConstantFP::get(Float::getType(), x);
802 }
803
Nicolas Capensac230122016-09-20 14:30:06 -0400804 llvm::Value *Nucleus::createNullPointer(Type *Ty)
John Bauman89401822014-05-06 15:04:28 -0400805 {
806 return llvm::ConstantPointerNull::get(llvm::PointerType::get(Ty, 0));
807 }
808
John Bauman19bac1e2014-05-06 15:23:49 -0400809 llvm::Value *Nucleus::createConstantVector(llvm::Constant *const *Vals, unsigned NumVals)
John Bauman89401822014-05-06 15:04:28 -0400810 {
John Bauman19bac1e2014-05-06 15:23:49 -0400811 return llvm::ConstantVector::get(llvm::ArrayRef<llvm::Constant*>(Vals, NumVals));
John Bauman89401822014-05-06 15:04:28 -0400812 }
813
John Bauman19bac1e2014-05-06 15:23:49 -0400814 Type *Void::getType()
John Bauman89401822014-05-06 15:04:28 -0400815 {
Nicolas Capensac230122016-09-20 14:30:06 -0400816 return T(llvm::Type::getVoidTy(*::context));
John Bauman89401822014-05-06 15:04:28 -0400817 }
818
Nicolas Capensac230122016-09-20 14:30:06 -0400819 LValue::LValue(Type *type, int arraySize)
John Bauman66b8ab22014-05-06 15:57:45 -0400820 {
821 address = Nucleus::allocateStackVariable(type, arraySize);
822 }
823
824 llvm::Value *LValue::loadValue(unsigned int alignment) const
825 {
826 return Nucleus::createLoad(address, false, alignment);
827 }
828
829 llvm::Value *LValue::storeValue(llvm::Value *value, unsigned int alignment) const
830 {
831 return Nucleus::createStore(value, address, false, alignment);
832 }
833
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400834 llvm::Value *LValue::storeValue(llvm::Constant *constant, unsigned int alignment) const
835 {
836 return Nucleus::createStore(constant, address, false, alignment);
837 }
838
John Bauman66b8ab22014-05-06 15:57:45 -0400839 llvm::Value *LValue::getAddress(llvm::Value *index) const
840 {
841 return Nucleus::createGEP(address, index);
842 }
843
Nicolas Capens4f738a12016-09-20 15:46:16 -0400844 class MMX : public Variable<MMX>
845 {
846 public:
847 static Type *getType();
848 };
849
John Bauman19bac1e2014-05-06 15:23:49 -0400850 Type *MMX::getType()
851 {
Nicolas Capensac230122016-09-20 14:30:06 -0400852 return T(llvm::Type::getX86_MMXTy(*::context));
John Bauman19bac1e2014-05-06 15:23:49 -0400853 }
854
Nicolas Capens81f18302016-01-14 09:32:35 -0500855 Bool::Bool(Argument<Bool> argument)
John Bauman89401822014-05-06 15:04:28 -0400856 {
Nicolas Capens81f18302016-01-14 09:32:35 -0500857 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -0400858 }
859
860 Bool::Bool()
861 {
John Bauman89401822014-05-06 15:04:28 -0400862 }
863
864 Bool::Bool(bool x)
865 {
John Bauman66b8ab22014-05-06 15:57:45 -0400866 storeValue(Nucleus::createConstantBool(x));
John Bauman89401822014-05-06 15:04:28 -0400867 }
868
John Bauman19bac1e2014-05-06 15:23:49 -0400869 Bool::Bool(RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400870 {
John Bauman66b8ab22014-05-06 15:57:45 -0400871 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400872 }
873
874 Bool::Bool(const Bool &rhs)
875 {
John Bauman66b8ab22014-05-06 15:57:45 -0400876 Value *value = rhs.loadValue();
877 storeValue(value);
878 }
John Bauman89401822014-05-06 15:04:28 -0400879
John Bauman66b8ab22014-05-06 15:57:45 -0400880 Bool::Bool(const Reference<Bool> &rhs)
881 {
882 Value *value = rhs.loadValue();
883 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400884 }
885
John Bauman19bac1e2014-05-06 15:23:49 -0400886 RValue<Bool> Bool::operator=(RValue<Bool> rhs) const
John Bauman89401822014-05-06 15:04:28 -0400887 {
John Bauman66b8ab22014-05-06 15:57:45 -0400888 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400889
890 return rhs;
891 }
892
893 RValue<Bool> Bool::operator=(const Bool &rhs) const
894 {
John Bauman66b8ab22014-05-06 15:57:45 -0400895 Value *value = rhs.loadValue();
896 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400897
898 return RValue<Bool>(value);
899 }
900
John Bauman66b8ab22014-05-06 15:57:45 -0400901 RValue<Bool> Bool::operator=(const Reference<Bool> &rhs) const
John Bauman89401822014-05-06 15:04:28 -0400902 {
John Bauman66b8ab22014-05-06 15:57:45 -0400903 Value *value = rhs.loadValue();
904 storeValue(value);
905
906 return RValue<Bool>(value);
John Bauman89401822014-05-06 15:04:28 -0400907 }
908
John Bauman19bac1e2014-05-06 15:23:49 -0400909 RValue<Bool> operator!(RValue<Bool> val)
John Bauman89401822014-05-06 15:04:28 -0400910 {
911 return RValue<Bool>(Nucleus::createNot(val.value));
912 }
913
John Bauman19bac1e2014-05-06 15:23:49 -0400914 RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400915 {
916 return RValue<Bool>(Nucleus::createAnd(lhs.value, rhs.value));
917 }
918
John Bauman19bac1e2014-05-06 15:23:49 -0400919 RValue<Bool> operator||(RValue<Bool> lhs, RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400920 {
921 return RValue<Bool>(Nucleus::createOr(lhs.value, rhs.value));
922 }
923
John Bauman19bac1e2014-05-06 15:23:49 -0400924 Type *Bool::getType()
John Bauman89401822014-05-06 15:04:28 -0400925 {
Nicolas Capensac230122016-09-20 14:30:06 -0400926 return T(llvm::Type::getInt1Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -0400927 }
928
Nicolas Capens81f18302016-01-14 09:32:35 -0500929 Byte::Byte(Argument<Byte> argument)
John Bauman89401822014-05-06 15:04:28 -0400930 {
Nicolas Capens81f18302016-01-14 09:32:35 -0500931 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -0400932 }
933
John Bauman19bac1e2014-05-06 15:23:49 -0400934 Byte::Byte(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -0400935 {
John Bauman89401822014-05-06 15:04:28 -0400936 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
937
John Bauman66b8ab22014-05-06 15:57:45 -0400938 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -0400939 }
940
Alexis Hetu77dfab42015-11-23 13:31:22 -0500941 Byte::Byte(RValue<UInt> cast)
942 {
943 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
944
945 storeValue(integer);
946 }
947
948 Byte::Byte(RValue<UShort> cast)
949 {
950 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
951
952 storeValue(integer);
953 }
954
John Bauman89401822014-05-06 15:04:28 -0400955 Byte::Byte()
956 {
John Bauman89401822014-05-06 15:04:28 -0400957 }
958
959 Byte::Byte(int x)
960 {
John Bauman66b8ab22014-05-06 15:57:45 -0400961 storeValue(Nucleus::createConstantByte((unsigned char)x));
John Bauman89401822014-05-06 15:04:28 -0400962 }
963
964 Byte::Byte(unsigned char x)
965 {
John Bauman66b8ab22014-05-06 15:57:45 -0400966 storeValue(Nucleus::createConstantByte(x));
John Bauman89401822014-05-06 15:04:28 -0400967 }
968
John Bauman19bac1e2014-05-06 15:23:49 -0400969 Byte::Byte(RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400970 {
John Bauman66b8ab22014-05-06 15:57:45 -0400971 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400972 }
973
974 Byte::Byte(const Byte &rhs)
975 {
John Bauman66b8ab22014-05-06 15:57:45 -0400976 Value *value = rhs.loadValue();
977 storeValue(value);
978 }
John Bauman89401822014-05-06 15:04:28 -0400979
John Bauman66b8ab22014-05-06 15:57:45 -0400980 Byte::Byte(const Reference<Byte> &rhs)
981 {
982 Value *value = rhs.loadValue();
983 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400984 }
985
John Bauman19bac1e2014-05-06 15:23:49 -0400986 RValue<Byte> Byte::operator=(RValue<Byte> rhs) const
John Bauman89401822014-05-06 15:04:28 -0400987 {
John Bauman66b8ab22014-05-06 15:57:45 -0400988 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400989
990 return rhs;
991 }
992
993 RValue<Byte> Byte::operator=(const Byte &rhs) const
994 {
John Bauman66b8ab22014-05-06 15:57:45 -0400995 Value *value = rhs.loadValue();
996 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400997
998 return RValue<Byte>(value);
999 }
1000
John Bauman66b8ab22014-05-06 15:57:45 -04001001 RValue<Byte> Byte::operator=(const Reference<Byte> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04001002 {
John Bauman66b8ab22014-05-06 15:57:45 -04001003 Value *value = rhs.loadValue();
1004 storeValue(value);
1005
1006 return RValue<Byte>(value);
John Bauman89401822014-05-06 15:04:28 -04001007 }
1008
John Bauman19bac1e2014-05-06 15:23:49 -04001009 RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001010 {
1011 return RValue<Byte>(Nucleus::createAdd(lhs.value, rhs.value));
1012 }
1013
John Bauman19bac1e2014-05-06 15:23:49 -04001014 RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001015 {
1016 return RValue<Byte>(Nucleus::createSub(lhs.value, rhs.value));
1017 }
1018
John Bauman19bac1e2014-05-06 15:23:49 -04001019 RValue<Byte> operator*(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001020 {
1021 return RValue<Byte>(Nucleus::createMul(lhs.value, rhs.value));
1022 }
1023
John Bauman19bac1e2014-05-06 15:23:49 -04001024 RValue<Byte> operator/(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001025 {
1026 return RValue<Byte>(Nucleus::createUDiv(lhs.value, rhs.value));
1027 }
1028
John Bauman19bac1e2014-05-06 15:23:49 -04001029 RValue<Byte> operator%(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001030 {
1031 return RValue<Byte>(Nucleus::createURem(lhs.value, rhs.value));
1032 }
1033
John Bauman19bac1e2014-05-06 15:23:49 -04001034 RValue<Byte> operator&(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001035 {
1036 return RValue<Byte>(Nucleus::createAnd(lhs.value, rhs.value));
1037 }
1038
John Bauman19bac1e2014-05-06 15:23:49 -04001039 RValue<Byte> operator|(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001040 {
1041 return RValue<Byte>(Nucleus::createOr(lhs.value, rhs.value));
1042 }
1043
John Bauman19bac1e2014-05-06 15:23:49 -04001044 RValue<Byte> operator^(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001045 {
1046 return RValue<Byte>(Nucleus::createXor(lhs.value, rhs.value));
1047 }
1048
John Bauman19bac1e2014-05-06 15:23:49 -04001049 RValue<Byte> operator<<(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001050 {
1051 return RValue<Byte>(Nucleus::createShl(lhs.value, rhs.value));
1052 }
1053
John Bauman19bac1e2014-05-06 15:23:49 -04001054 RValue<Byte> operator>>(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001055 {
1056 return RValue<Byte>(Nucleus::createLShr(lhs.value, rhs.value));
1057 }
1058
John Bauman19bac1e2014-05-06 15:23:49 -04001059 RValue<Byte> operator+=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001060 {
1061 return lhs = lhs + rhs;
1062 }
1063
John Bauman19bac1e2014-05-06 15:23:49 -04001064 RValue<Byte> operator-=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001065 {
1066 return lhs = lhs - rhs;
1067 }
1068
John Bauman19bac1e2014-05-06 15:23:49 -04001069 RValue<Byte> operator*=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001070 {
1071 return lhs = lhs * rhs;
1072 }
1073
John Bauman19bac1e2014-05-06 15:23:49 -04001074 RValue<Byte> operator/=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001075 {
1076 return lhs = lhs / rhs;
1077 }
1078
John Bauman19bac1e2014-05-06 15:23:49 -04001079 RValue<Byte> operator%=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001080 {
1081 return lhs = lhs % rhs;
1082 }
1083
John Bauman19bac1e2014-05-06 15:23:49 -04001084 RValue<Byte> operator&=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001085 {
1086 return lhs = lhs & rhs;
1087 }
1088
John Bauman19bac1e2014-05-06 15:23:49 -04001089 RValue<Byte> operator|=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001090 {
1091 return lhs = lhs | rhs;
1092 }
1093
John Bauman19bac1e2014-05-06 15:23:49 -04001094 RValue<Byte> operator^=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001095 {
1096 return lhs = lhs ^ rhs;
1097 }
1098
John Bauman19bac1e2014-05-06 15:23:49 -04001099 RValue<Byte> operator<<=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001100 {
1101 return lhs = lhs << rhs;
1102 }
1103
John Bauman19bac1e2014-05-06 15:23:49 -04001104 RValue<Byte> operator>>=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001105 {
1106 return lhs = lhs >> rhs;
1107 }
1108
John Bauman19bac1e2014-05-06 15:23:49 -04001109 RValue<Byte> operator+(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001110 {
1111 return val;
1112 }
1113
John Bauman19bac1e2014-05-06 15:23:49 -04001114 RValue<Byte> operator-(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001115 {
1116 return RValue<Byte>(Nucleus::createNeg(val.value));
1117 }
1118
John Bauman19bac1e2014-05-06 15:23:49 -04001119 RValue<Byte> operator~(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001120 {
1121 return RValue<Byte>(Nucleus::createNot(val.value));
1122 }
1123
1124 RValue<Byte> operator++(const Byte &val, int) // Post-increment
1125 {
1126 RValue<Byte> res = val;
1127
1128 Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantByte((unsigned char)1));
John Bauman66b8ab22014-05-06 15:57:45 -04001129 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001130
1131 return res;
1132 }
1133
1134 const Byte &operator++(const Byte &val) // Pre-increment
1135 {
John Bauman66b8ab22014-05-06 15:57:45 -04001136 Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantByte((unsigned char)1));
1137 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001138
1139 return val;
1140 }
1141
1142 RValue<Byte> operator--(const Byte &val, int) // Post-decrement
1143 {
1144 RValue<Byte> res = val;
1145
1146 Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantByte((unsigned char)1));
John Bauman66b8ab22014-05-06 15:57:45 -04001147 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001148
1149 return res;
1150 }
1151
1152 const Byte &operator--(const Byte &val) // Pre-decrement
1153 {
John Bauman66b8ab22014-05-06 15:57:45 -04001154 Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantByte((unsigned char)1));
1155 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001156
1157 return val;
1158 }
1159
John Bauman19bac1e2014-05-06 15:23:49 -04001160 RValue<Bool> operator<(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001161 {
1162 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1163 }
1164
John Bauman19bac1e2014-05-06 15:23:49 -04001165 RValue<Bool> operator<=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001166 {
1167 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1168 }
1169
John Bauman19bac1e2014-05-06 15:23:49 -04001170 RValue<Bool> operator>(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001171 {
1172 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1173 }
1174
John Bauman19bac1e2014-05-06 15:23:49 -04001175 RValue<Bool> operator>=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001176 {
1177 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1178 }
1179
John Bauman19bac1e2014-05-06 15:23:49 -04001180 RValue<Bool> operator!=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001181 {
1182 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1183 }
1184
John Bauman19bac1e2014-05-06 15:23:49 -04001185 RValue<Bool> operator==(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001186 {
1187 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1188 }
1189
John Bauman19bac1e2014-05-06 15:23:49 -04001190 Type *Byte::getType()
John Bauman89401822014-05-06 15:04:28 -04001191 {
Nicolas Capensac230122016-09-20 14:30:06 -04001192 return T(llvm::Type::getInt8Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001193 }
1194
Nicolas Capens81f18302016-01-14 09:32:35 -05001195 SByte::SByte(Argument<SByte> argument)
John Bauman89401822014-05-06 15:04:28 -04001196 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001197 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001198 }
1199
Alexis Hetu77dfab42015-11-23 13:31:22 -05001200 SByte::SByte(RValue<Int> cast)
1201 {
1202 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1203
1204 storeValue(integer);
1205 }
1206
1207 SByte::SByte(RValue<Short> cast)
1208 {
1209 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1210
1211 storeValue(integer);
1212 }
1213
John Bauman89401822014-05-06 15:04:28 -04001214 SByte::SByte()
1215 {
John Bauman89401822014-05-06 15:04:28 -04001216 }
1217
1218 SByte::SByte(signed char x)
1219 {
John Bauman66b8ab22014-05-06 15:57:45 -04001220 storeValue(Nucleus::createConstantByte(x));
John Bauman89401822014-05-06 15:04:28 -04001221 }
1222
John Bauman19bac1e2014-05-06 15:23:49 -04001223 SByte::SByte(RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001224 {
John Bauman66b8ab22014-05-06 15:57:45 -04001225 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001226 }
1227
1228 SByte::SByte(const SByte &rhs)
1229 {
John Bauman66b8ab22014-05-06 15:57:45 -04001230 Value *value = rhs.loadValue();
1231 storeValue(value);
1232 }
John Bauman89401822014-05-06 15:04:28 -04001233
John Bauman66b8ab22014-05-06 15:57:45 -04001234 SByte::SByte(const Reference<SByte> &rhs)
1235 {
1236 Value *value = rhs.loadValue();
1237 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001238 }
1239
John Bauman19bac1e2014-05-06 15:23:49 -04001240 RValue<SByte> SByte::operator=(RValue<SByte> rhs) const
John Bauman89401822014-05-06 15:04:28 -04001241 {
John Bauman66b8ab22014-05-06 15:57:45 -04001242 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001243
1244 return rhs;
1245 }
1246
1247 RValue<SByte> SByte::operator=(const SByte &rhs) const
1248 {
John Bauman66b8ab22014-05-06 15:57:45 -04001249 Value *value = rhs.loadValue();
1250 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001251
1252 return RValue<SByte>(value);
1253 }
1254
John Bauman66b8ab22014-05-06 15:57:45 -04001255 RValue<SByte> SByte::operator=(const Reference<SByte> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04001256 {
John Bauman66b8ab22014-05-06 15:57:45 -04001257 Value *value = rhs.loadValue();
1258 storeValue(value);
1259
1260 return RValue<SByte>(value);
John Bauman89401822014-05-06 15:04:28 -04001261 }
1262
John Bauman19bac1e2014-05-06 15:23:49 -04001263 RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001264 {
1265 return RValue<SByte>(Nucleus::createAdd(lhs.value, rhs.value));
1266 }
1267
John Bauman19bac1e2014-05-06 15:23:49 -04001268 RValue<SByte> operator-(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001269 {
1270 return RValue<SByte>(Nucleus::createSub(lhs.value, rhs.value));
1271 }
1272
John Bauman19bac1e2014-05-06 15:23:49 -04001273 RValue<SByte> operator*(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001274 {
1275 return RValue<SByte>(Nucleus::createMul(lhs.value, rhs.value));
1276 }
1277
John Bauman19bac1e2014-05-06 15:23:49 -04001278 RValue<SByte> operator/(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001279 {
1280 return RValue<SByte>(Nucleus::createSDiv(lhs.value, rhs.value));
1281 }
1282
John Bauman19bac1e2014-05-06 15:23:49 -04001283 RValue<SByte> operator%(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001284 {
1285 return RValue<SByte>(Nucleus::createSRem(lhs.value, rhs.value));
1286 }
1287
John Bauman19bac1e2014-05-06 15:23:49 -04001288 RValue<SByte> operator&(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001289 {
1290 return RValue<SByte>(Nucleus::createAnd(lhs.value, rhs.value));
1291 }
1292
John Bauman19bac1e2014-05-06 15:23:49 -04001293 RValue<SByte> operator|(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001294 {
1295 return RValue<SByte>(Nucleus::createOr(lhs.value, rhs.value));
1296 }
1297
John Bauman19bac1e2014-05-06 15:23:49 -04001298 RValue<SByte> operator^(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001299 {
1300 return RValue<SByte>(Nucleus::createXor(lhs.value, rhs.value));
1301 }
1302
John Bauman19bac1e2014-05-06 15:23:49 -04001303 RValue<SByte> operator<<(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001304 {
1305 return RValue<SByte>(Nucleus::createShl(lhs.value, rhs.value));
1306 }
1307
John Bauman19bac1e2014-05-06 15:23:49 -04001308 RValue<SByte> operator>>(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001309 {
1310 return RValue<SByte>(Nucleus::createAShr(lhs.value, rhs.value));
1311 }
1312
John Bauman19bac1e2014-05-06 15:23:49 -04001313 RValue<SByte> operator+=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001314 {
1315 return lhs = lhs + rhs;
1316 }
1317
John Bauman19bac1e2014-05-06 15:23:49 -04001318 RValue<SByte> operator-=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001319 {
1320 return lhs = lhs - rhs;
1321 }
1322
John Bauman19bac1e2014-05-06 15:23:49 -04001323 RValue<SByte> operator*=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001324 {
1325 return lhs = lhs * rhs;
1326 }
1327
John Bauman19bac1e2014-05-06 15:23:49 -04001328 RValue<SByte> operator/=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001329 {
1330 return lhs = lhs / rhs;
1331 }
1332
John Bauman19bac1e2014-05-06 15:23:49 -04001333 RValue<SByte> operator%=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001334 {
1335 return lhs = lhs % rhs;
1336 }
1337
John Bauman19bac1e2014-05-06 15:23:49 -04001338 RValue<SByte> operator&=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001339 {
1340 return lhs = lhs & rhs;
1341 }
1342
John Bauman19bac1e2014-05-06 15:23:49 -04001343 RValue<SByte> operator|=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001344 {
1345 return lhs = lhs | rhs;
1346 }
1347
John Bauman19bac1e2014-05-06 15:23:49 -04001348 RValue<SByte> operator^=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001349 {
1350 return lhs = lhs ^ rhs;
1351 }
1352
John Bauman19bac1e2014-05-06 15:23:49 -04001353 RValue<SByte> operator<<=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001354 {
1355 return lhs = lhs << rhs;
1356 }
1357
John Bauman19bac1e2014-05-06 15:23:49 -04001358 RValue<SByte> operator>>=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001359 {
1360 return lhs = lhs >> rhs;
1361 }
1362
John Bauman19bac1e2014-05-06 15:23:49 -04001363 RValue<SByte> operator+(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001364 {
1365 return val;
1366 }
1367
John Bauman19bac1e2014-05-06 15:23:49 -04001368 RValue<SByte> operator-(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001369 {
1370 return RValue<SByte>(Nucleus::createNeg(val.value));
1371 }
1372
John Bauman19bac1e2014-05-06 15:23:49 -04001373 RValue<SByte> operator~(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001374 {
1375 return RValue<SByte>(Nucleus::createNot(val.value));
1376 }
1377
1378 RValue<SByte> operator++(const SByte &val, int) // Post-increment
1379 {
1380 RValue<SByte> res = val;
1381
1382 Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantByte((signed char)1));
John Bauman66b8ab22014-05-06 15:57:45 -04001383 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001384
1385 return res;
1386 }
1387
1388 const SByte &operator++(const SByte &val) // Pre-increment
1389 {
John Bauman66b8ab22014-05-06 15:57:45 -04001390 Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantByte((signed char)1));
1391 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001392
1393 return val;
1394 }
1395
1396 RValue<SByte> operator--(const SByte &val, int) // Post-decrement
1397 {
1398 RValue<SByte> res = val;
1399
1400 Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantByte((signed char)1));
John Bauman66b8ab22014-05-06 15:57:45 -04001401 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001402
1403 return res;
1404 }
1405
1406 const SByte &operator--(const SByte &val) // Pre-decrement
1407 {
John Bauman66b8ab22014-05-06 15:57:45 -04001408 Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantByte((signed char)1));
1409 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001410
1411 return val;
1412 }
1413
John Bauman19bac1e2014-05-06 15:23:49 -04001414 RValue<Bool> operator<(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001415 {
1416 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
1417 }
1418
John Bauman19bac1e2014-05-06 15:23:49 -04001419 RValue<Bool> operator<=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001420 {
1421 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
1422 }
1423
John Bauman19bac1e2014-05-06 15:23:49 -04001424 RValue<Bool> operator>(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001425 {
1426 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
1427 }
1428
John Bauman19bac1e2014-05-06 15:23:49 -04001429 RValue<Bool> operator>=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001430 {
1431 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
1432 }
1433
John Bauman19bac1e2014-05-06 15:23:49 -04001434 RValue<Bool> operator!=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001435 {
1436 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1437 }
1438
John Bauman19bac1e2014-05-06 15:23:49 -04001439 RValue<Bool> operator==(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001440 {
1441 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1442 }
1443
John Bauman19bac1e2014-05-06 15:23:49 -04001444 Type *SByte::getType()
John Bauman89401822014-05-06 15:04:28 -04001445 {
Nicolas Capensac230122016-09-20 14:30:06 -04001446 return T(llvm::Type::getInt8Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001447 }
1448
Nicolas Capens81f18302016-01-14 09:32:35 -05001449 Short::Short(Argument<Short> argument)
John Bauman89401822014-05-06 15:04:28 -04001450 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001451 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001452 }
1453
John Bauman19bac1e2014-05-06 15:23:49 -04001454 Short::Short(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04001455 {
John Bauman89401822014-05-06 15:04:28 -04001456 Value *integer = Nucleus::createTrunc(cast.value, Short::getType());
1457
John Bauman66b8ab22014-05-06 15:57:45 -04001458 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04001459 }
1460
1461 Short::Short()
1462 {
John Bauman89401822014-05-06 15:04:28 -04001463 }
1464
1465 Short::Short(short x)
1466 {
John Bauman66b8ab22014-05-06 15:57:45 -04001467 storeValue(Nucleus::createConstantShort(x));
John Bauman89401822014-05-06 15:04:28 -04001468 }
1469
John Bauman19bac1e2014-05-06 15:23:49 -04001470 Short::Short(RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001471 {
John Bauman66b8ab22014-05-06 15:57:45 -04001472 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001473 }
1474
1475 Short::Short(const Short &rhs)
1476 {
John Bauman66b8ab22014-05-06 15:57:45 -04001477 Value *value = rhs.loadValue();
1478 storeValue(value);
1479 }
John Bauman89401822014-05-06 15:04:28 -04001480
John Bauman66b8ab22014-05-06 15:57:45 -04001481 Short::Short(const Reference<Short> &rhs)
1482 {
1483 Value *value = rhs.loadValue();
1484 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001485 }
1486
John Bauman19bac1e2014-05-06 15:23:49 -04001487 RValue<Short> Short::operator=(RValue<Short> rhs) const
John Bauman89401822014-05-06 15:04:28 -04001488 {
John Bauman66b8ab22014-05-06 15:57:45 -04001489 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001490
1491 return rhs;
1492 }
1493
1494 RValue<Short> Short::operator=(const Short &rhs) const
1495 {
John Bauman66b8ab22014-05-06 15:57:45 -04001496 Value *value = rhs.loadValue();
1497 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001498
1499 return RValue<Short>(value);
1500 }
1501
John Bauman66b8ab22014-05-06 15:57:45 -04001502 RValue<Short> Short::operator=(const Reference<Short> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04001503 {
John Bauman66b8ab22014-05-06 15:57:45 -04001504 Value *value = rhs.loadValue();
1505 storeValue(value);
1506
1507 return RValue<Short>(value);
John Bauman89401822014-05-06 15:04:28 -04001508 }
1509
John Bauman19bac1e2014-05-06 15:23:49 -04001510 RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001511 {
1512 return RValue<Short>(Nucleus::createAdd(lhs.value, rhs.value));
1513 }
1514
John Bauman19bac1e2014-05-06 15:23:49 -04001515 RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001516 {
1517 return RValue<Short>(Nucleus::createSub(lhs.value, rhs.value));
1518 }
1519
John Bauman19bac1e2014-05-06 15:23:49 -04001520 RValue<Short> operator*(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001521 {
1522 return RValue<Short>(Nucleus::createMul(lhs.value, rhs.value));
1523 }
1524
John Bauman19bac1e2014-05-06 15:23:49 -04001525 RValue<Short> operator/(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001526 {
1527 return RValue<Short>(Nucleus::createSDiv(lhs.value, rhs.value));
1528 }
1529
John Bauman19bac1e2014-05-06 15:23:49 -04001530 RValue<Short> operator%(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001531 {
1532 return RValue<Short>(Nucleus::createSRem(lhs.value, rhs.value));
1533 }
1534
John Bauman19bac1e2014-05-06 15:23:49 -04001535 RValue<Short> operator&(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001536 {
1537 return RValue<Short>(Nucleus::createAnd(lhs.value, rhs.value));
1538 }
1539
John Bauman19bac1e2014-05-06 15:23:49 -04001540 RValue<Short> operator|(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001541 {
1542 return RValue<Short>(Nucleus::createOr(lhs.value, rhs.value));
1543 }
1544
John Bauman19bac1e2014-05-06 15:23:49 -04001545 RValue<Short> operator^(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001546 {
1547 return RValue<Short>(Nucleus::createXor(lhs.value, rhs.value));
1548 }
1549
John Bauman19bac1e2014-05-06 15:23:49 -04001550 RValue<Short> operator<<(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001551 {
1552 return RValue<Short>(Nucleus::createShl(lhs.value, rhs.value));
1553 }
1554
John Bauman19bac1e2014-05-06 15:23:49 -04001555 RValue<Short> operator>>(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001556 {
1557 return RValue<Short>(Nucleus::createAShr(lhs.value, rhs.value));
1558 }
1559
John Bauman19bac1e2014-05-06 15:23:49 -04001560 RValue<Short> operator+=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001561 {
1562 return lhs = lhs + rhs;
1563 }
1564
John Bauman19bac1e2014-05-06 15:23:49 -04001565 RValue<Short> operator-=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001566 {
1567 return lhs = lhs - rhs;
1568 }
1569
John Bauman19bac1e2014-05-06 15:23:49 -04001570 RValue<Short> operator*=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001571 {
1572 return lhs = lhs * rhs;
1573 }
1574
John Bauman19bac1e2014-05-06 15:23:49 -04001575 RValue<Short> operator/=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001576 {
1577 return lhs = lhs / rhs;
1578 }
1579
John Bauman19bac1e2014-05-06 15:23:49 -04001580 RValue<Short> operator%=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001581 {
1582 return lhs = lhs % rhs;
1583 }
1584
John Bauman19bac1e2014-05-06 15:23:49 -04001585 RValue<Short> operator&=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001586 {
1587 return lhs = lhs & rhs;
1588 }
1589
John Bauman19bac1e2014-05-06 15:23:49 -04001590 RValue<Short> operator|=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001591 {
1592 return lhs = lhs | rhs;
1593 }
1594
John Bauman19bac1e2014-05-06 15:23:49 -04001595 RValue<Short> operator^=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001596 {
1597 return lhs = lhs ^ rhs;
1598 }
1599
John Bauman19bac1e2014-05-06 15:23:49 -04001600 RValue<Short> operator<<=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001601 {
1602 return lhs = lhs << rhs;
1603 }
1604
John Bauman19bac1e2014-05-06 15:23:49 -04001605 RValue<Short> operator>>=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001606 {
1607 return lhs = lhs >> rhs;
1608 }
1609
John Bauman19bac1e2014-05-06 15:23:49 -04001610 RValue<Short> operator+(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001611 {
1612 return val;
1613 }
1614
John Bauman19bac1e2014-05-06 15:23:49 -04001615 RValue<Short> operator-(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001616 {
1617 return RValue<Short>(Nucleus::createNeg(val.value));
1618 }
1619
John Bauman19bac1e2014-05-06 15:23:49 -04001620 RValue<Short> operator~(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001621 {
1622 return RValue<Short>(Nucleus::createNot(val.value));
1623 }
1624
1625 RValue<Short> operator++(const Short &val, int) // Post-increment
1626 {
1627 RValue<Short> res = val;
1628
1629 Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantShort((short)1));
John Bauman66b8ab22014-05-06 15:57:45 -04001630 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001631
1632 return res;
1633 }
1634
1635 const Short &operator++(const Short &val) // Pre-increment
1636 {
John Bauman66b8ab22014-05-06 15:57:45 -04001637 Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantShort((short)1));
1638 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001639
1640 return val;
1641 }
1642
1643 RValue<Short> operator--(const Short &val, int) // Post-decrement
1644 {
1645 RValue<Short> res = val;
1646
1647 Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantShort((short)1));
John Bauman66b8ab22014-05-06 15:57:45 -04001648 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001649
1650 return res;
1651 }
1652
1653 const Short &operator--(const Short &val) // Pre-decrement
1654 {
John Bauman66b8ab22014-05-06 15:57:45 -04001655 Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantShort((short)1));
1656 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001657
1658 return val;
1659 }
1660
John Bauman19bac1e2014-05-06 15:23:49 -04001661 RValue<Bool> operator<(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001662 {
1663 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
1664 }
1665
John Bauman19bac1e2014-05-06 15:23:49 -04001666 RValue<Bool> operator<=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001667 {
1668 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
1669 }
1670
John Bauman19bac1e2014-05-06 15:23:49 -04001671 RValue<Bool> operator>(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001672 {
1673 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
1674 }
1675
John Bauman19bac1e2014-05-06 15:23:49 -04001676 RValue<Bool> operator>=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001677 {
1678 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
1679 }
1680
John Bauman19bac1e2014-05-06 15:23:49 -04001681 RValue<Bool> operator!=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001682 {
1683 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1684 }
1685
John Bauman19bac1e2014-05-06 15:23:49 -04001686 RValue<Bool> operator==(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001687 {
1688 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1689 }
1690
John Bauman19bac1e2014-05-06 15:23:49 -04001691 Type *Short::getType()
John Bauman89401822014-05-06 15:04:28 -04001692 {
Nicolas Capensac230122016-09-20 14:30:06 -04001693 return T(llvm::Type::getInt16Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001694 }
1695
Nicolas Capens81f18302016-01-14 09:32:35 -05001696 UShort::UShort(Argument<UShort> argument)
John Bauman89401822014-05-06 15:04:28 -04001697 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001698 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001699 }
1700
Alexis Hetu77dfab42015-11-23 13:31:22 -05001701 UShort::UShort(RValue<UInt> cast)
1702 {
1703 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
1704
1705 storeValue(integer);
1706 }
1707
Alexis Hetu75b650f2015-11-19 17:40:15 -05001708 UShort::UShort(RValue<Int> cast)
1709 {
1710 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
1711
1712 storeValue(integer);
1713 }
1714
John Bauman89401822014-05-06 15:04:28 -04001715 UShort::UShort()
1716 {
John Bauman89401822014-05-06 15:04:28 -04001717 }
1718
1719 UShort::UShort(unsigned short x)
1720 {
John Bauman66b8ab22014-05-06 15:57:45 -04001721 storeValue(Nucleus::createConstantShort(x));
John Bauman89401822014-05-06 15:04:28 -04001722 }
1723
John Bauman19bac1e2014-05-06 15:23:49 -04001724 UShort::UShort(RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001725 {
John Bauman66b8ab22014-05-06 15:57:45 -04001726 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001727 }
1728
1729 UShort::UShort(const UShort &rhs)
1730 {
John Bauman66b8ab22014-05-06 15:57:45 -04001731 Value *value = rhs.loadValue();
1732 storeValue(value);
1733 }
John Bauman89401822014-05-06 15:04:28 -04001734
John Bauman66b8ab22014-05-06 15:57:45 -04001735 UShort::UShort(const Reference<UShort> &rhs)
1736 {
1737 Value *value = rhs.loadValue();
1738 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001739 }
1740
John Bauman19bac1e2014-05-06 15:23:49 -04001741 RValue<UShort> UShort::operator=(RValue<UShort> rhs) const
John Bauman89401822014-05-06 15:04:28 -04001742 {
John Bauman66b8ab22014-05-06 15:57:45 -04001743 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001744
1745 return rhs;
1746 }
1747
1748 RValue<UShort> UShort::operator=(const UShort &rhs) const
1749 {
John Bauman66b8ab22014-05-06 15:57:45 -04001750 Value *value = rhs.loadValue();
1751 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001752
1753 return RValue<UShort>(value);
1754 }
1755
John Bauman66b8ab22014-05-06 15:57:45 -04001756 RValue<UShort> UShort::operator=(const Reference<UShort> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04001757 {
John Bauman66b8ab22014-05-06 15:57:45 -04001758 Value *value = rhs.loadValue();
1759 storeValue(value);
1760
1761 return RValue<UShort>(value);
John Bauman89401822014-05-06 15:04:28 -04001762 }
1763
John Bauman19bac1e2014-05-06 15:23:49 -04001764 RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001765 {
1766 return RValue<UShort>(Nucleus::createAdd(lhs.value, rhs.value));
1767 }
1768
John Bauman19bac1e2014-05-06 15:23:49 -04001769 RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001770 {
1771 return RValue<UShort>(Nucleus::createSub(lhs.value, rhs.value));
1772 }
1773
John Bauman19bac1e2014-05-06 15:23:49 -04001774 RValue<UShort> operator*(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001775 {
1776 return RValue<UShort>(Nucleus::createMul(lhs.value, rhs.value));
1777 }
1778
John Bauman19bac1e2014-05-06 15:23:49 -04001779 RValue<UShort> operator/(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001780 {
1781 return RValue<UShort>(Nucleus::createUDiv(lhs.value, rhs.value));
1782 }
1783
John Bauman19bac1e2014-05-06 15:23:49 -04001784 RValue<UShort> operator%(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001785 {
1786 return RValue<UShort>(Nucleus::createURem(lhs.value, rhs.value));
1787 }
1788
John Bauman19bac1e2014-05-06 15:23:49 -04001789 RValue<UShort> operator&(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001790 {
1791 return RValue<UShort>(Nucleus::createAnd(lhs.value, rhs.value));
1792 }
1793
John Bauman19bac1e2014-05-06 15:23:49 -04001794 RValue<UShort> operator|(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001795 {
1796 return RValue<UShort>(Nucleus::createOr(lhs.value, rhs.value));
1797 }
1798
John Bauman19bac1e2014-05-06 15:23:49 -04001799 RValue<UShort> operator^(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001800 {
1801 return RValue<UShort>(Nucleus::createXor(lhs.value, rhs.value));
1802 }
1803
John Bauman19bac1e2014-05-06 15:23:49 -04001804 RValue<UShort> operator<<(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001805 {
1806 return RValue<UShort>(Nucleus::createShl(lhs.value, rhs.value));
1807 }
1808
John Bauman19bac1e2014-05-06 15:23:49 -04001809 RValue<UShort> operator>>(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001810 {
1811 return RValue<UShort>(Nucleus::createLShr(lhs.value, rhs.value));
1812 }
1813
John Bauman19bac1e2014-05-06 15:23:49 -04001814 RValue<UShort> operator+=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001815 {
1816 return lhs = lhs + rhs;
1817 }
1818
John Bauman19bac1e2014-05-06 15:23:49 -04001819 RValue<UShort> operator-=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001820 {
1821 return lhs = lhs - rhs;
1822 }
1823
John Bauman19bac1e2014-05-06 15:23:49 -04001824 RValue<UShort> operator*=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001825 {
1826 return lhs = lhs * rhs;
1827 }
1828
John Bauman19bac1e2014-05-06 15:23:49 -04001829 RValue<UShort> operator/=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001830 {
1831 return lhs = lhs / rhs;
1832 }
1833
John Bauman19bac1e2014-05-06 15:23:49 -04001834 RValue<UShort> operator%=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001835 {
1836 return lhs = lhs % rhs;
1837 }
1838
John Bauman19bac1e2014-05-06 15:23:49 -04001839 RValue<UShort> operator&=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001840 {
1841 return lhs = lhs & rhs;
1842 }
1843
John Bauman19bac1e2014-05-06 15:23:49 -04001844 RValue<UShort> operator|=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001845 {
1846 return lhs = lhs | rhs;
1847 }
1848
John Bauman19bac1e2014-05-06 15:23:49 -04001849 RValue<UShort> operator^=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001850 {
1851 return lhs = lhs ^ rhs;
1852 }
1853
John Bauman19bac1e2014-05-06 15:23:49 -04001854 RValue<UShort> operator<<=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001855 {
1856 return lhs = lhs << rhs;
1857 }
1858
John Bauman19bac1e2014-05-06 15:23:49 -04001859 RValue<UShort> operator>>=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001860 {
1861 return lhs = lhs >> rhs;
1862 }
1863
John Bauman19bac1e2014-05-06 15:23:49 -04001864 RValue<UShort> operator+(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001865 {
1866 return val;
1867 }
1868
John Bauman19bac1e2014-05-06 15:23:49 -04001869 RValue<UShort> operator-(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001870 {
1871 return RValue<UShort>(Nucleus::createNeg(val.value));
1872 }
1873
John Bauman19bac1e2014-05-06 15:23:49 -04001874 RValue<UShort> operator~(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001875 {
1876 return RValue<UShort>(Nucleus::createNot(val.value));
1877 }
1878
1879 RValue<UShort> operator++(const UShort &val, int) // Post-increment
1880 {
1881 RValue<UShort> res = val;
1882
1883 Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantShort((unsigned short)1));
John Bauman66b8ab22014-05-06 15:57:45 -04001884 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001885
1886 return res;
1887 }
1888
1889 const UShort &operator++(const UShort &val) // Pre-increment
1890 {
John Bauman66b8ab22014-05-06 15:57:45 -04001891 Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantShort((unsigned short)1));
1892 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001893
1894 return val;
1895 }
1896
1897 RValue<UShort> operator--(const UShort &val, int) // Post-decrement
1898 {
1899 RValue<UShort> res = val;
1900
1901 Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantShort((unsigned short)1));
John Bauman66b8ab22014-05-06 15:57:45 -04001902 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001903
1904 return res;
1905 }
1906
1907 const UShort &operator--(const UShort &val) // Pre-decrement
1908 {
John Bauman66b8ab22014-05-06 15:57:45 -04001909 Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantShort((unsigned short)1));
1910 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001911
1912 return val;
1913 }
1914
John Bauman19bac1e2014-05-06 15:23:49 -04001915 RValue<Bool> operator<(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001916 {
1917 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1918 }
1919
John Bauman19bac1e2014-05-06 15:23:49 -04001920 RValue<Bool> operator<=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001921 {
1922 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1923 }
1924
John Bauman19bac1e2014-05-06 15:23:49 -04001925 RValue<Bool> operator>(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001926 {
1927 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1928 }
1929
John Bauman19bac1e2014-05-06 15:23:49 -04001930 RValue<Bool> operator>=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001931 {
1932 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1933 }
1934
John Bauman19bac1e2014-05-06 15:23:49 -04001935 RValue<Bool> operator!=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001936 {
1937 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1938 }
1939
John Bauman19bac1e2014-05-06 15:23:49 -04001940 RValue<Bool> operator==(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001941 {
1942 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1943 }
1944
John Bauman19bac1e2014-05-06 15:23:49 -04001945 Type *UShort::getType()
John Bauman89401822014-05-06 15:04:28 -04001946 {
Nicolas Capensac230122016-09-20 14:30:06 -04001947 return T(llvm::Type::getInt16Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04001948 }
1949
John Bauman19bac1e2014-05-06 15:23:49 -04001950 Type *Byte4::getType()
John Bauman89401822014-05-06 15:04:28 -04001951 {
1952 #if 0
Nicolas Capensac230122016-09-20 14:30:06 -04001953 return T(VectorType::get(Byte::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04001954 #else
1955 return UInt::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
1956 #endif
1957 }
1958
John Bauman19bac1e2014-05-06 15:23:49 -04001959 Type *SByte4::getType()
John Bauman89401822014-05-06 15:04:28 -04001960 {
1961 #if 0
Nicolas Capensac230122016-09-20 14:30:06 -04001962 return T(VectorType::get(SByte::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04001963 #else
1964 return Int::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
1965 #endif
1966 }
1967
1968 Byte8::Byte8()
1969 {
1970 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04001971 }
1972
1973 Byte8::Byte8(byte x0, byte x1, byte x2, byte x3, byte x4, byte x5, byte x6, byte x7)
1974 {
1975 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04001976
1977 Constant *constantVector[8];
1978 constantVector[0] = Nucleus::createConstantByte(x0);
1979 constantVector[1] = Nucleus::createConstantByte(x1);
1980 constantVector[2] = Nucleus::createConstantByte(x2);
1981 constantVector[3] = Nucleus::createConstantByte(x3);
1982 constantVector[4] = Nucleus::createConstantByte(x4);
1983 constantVector[5] = Nucleus::createConstantByte(x5);
1984 constantVector[6] = Nucleus::createConstantByte(x6);
1985 constantVector[7] = Nucleus::createConstantByte(x7);
John Bauman19bac1e2014-05-06 15:23:49 -04001986 Value *vector = Nucleus::createConstantVector(constantVector, 8);
John Bauman89401822014-05-06 15:04:28 -04001987
John Bauman66b8ab22014-05-06 15:57:45 -04001988 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04001989 }
1990
1991 Byte8::Byte8(int64_t x)
1992 {
1993 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04001994
1995 Constant *constantVector[8];
1996 constantVector[0] = Nucleus::createConstantByte((unsigned char)(x >> 0));
1997 constantVector[1] = Nucleus::createConstantByte((unsigned char)(x >> 8));
1998 constantVector[2] = Nucleus::createConstantByte((unsigned char)(x >> 16));
1999 constantVector[3] = Nucleus::createConstantByte((unsigned char)(x >> 24));
2000 constantVector[4] = Nucleus::createConstantByte((unsigned char)(x >> 32));
2001 constantVector[5] = Nucleus::createConstantByte((unsigned char)(x >> 40));
2002 constantVector[6] = Nucleus::createConstantByte((unsigned char)(x >> 48));
2003 constantVector[7] = Nucleus::createConstantByte((unsigned char)(x >> 56));
John Bauman19bac1e2014-05-06 15:23:49 -04002004 Value *vector = Nucleus::createConstantVector(constantVector, 8);
John Bauman89401822014-05-06 15:04:28 -04002005
John Bauman66b8ab22014-05-06 15:57:45 -04002006 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04002007 }
2008
John Bauman19bac1e2014-05-06 15:23:49 -04002009 Byte8::Byte8(RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002010 {
2011 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002012
John Bauman66b8ab22014-05-06 15:57:45 -04002013 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002014 }
2015
2016 Byte8::Byte8(const Byte8 &rhs)
2017 {
2018 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002019
John Bauman66b8ab22014-05-06 15:57:45 -04002020 Value *value = rhs.loadValue();
2021 storeValue(value);
2022 }
2023
2024 Byte8::Byte8(const Reference<Byte8> &rhs)
2025 {
2026 // xyzw.parent = this;
2027
2028 Value *value = rhs.loadValue();
2029 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002030 }
2031
John Bauman19bac1e2014-05-06 15:23:49 -04002032 RValue<Byte8> Byte8::operator=(RValue<Byte8> rhs) const
John Bauman89401822014-05-06 15:04:28 -04002033 {
John Bauman66b8ab22014-05-06 15:57:45 -04002034 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002035
2036 return rhs;
2037 }
2038
2039 RValue<Byte8> Byte8::operator=(const Byte8 &rhs) const
2040 {
John Bauman66b8ab22014-05-06 15:57:45 -04002041 Value *value = rhs.loadValue();
2042 storeValue(value);
2043
2044 return RValue<Byte8>(value);
2045 }
2046
2047 RValue<Byte8> Byte8::operator=(const Reference<Byte8> &rhs) const
2048 {
2049 Value *value = rhs.loadValue();
2050 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002051
2052 return RValue<Byte8>(value);
2053 }
2054
John Bauman19bac1e2014-05-06 15:23:49 -04002055 RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002056 {
John Bauman19bac1e2014-05-06 15:23:49 -04002057 if(CPUID::supportsMMX2())
2058 {
2059 return x86::paddb(lhs, rhs);
2060 }
2061 else
2062 {
2063 return RValue<Byte8>(Nucleus::createAdd(lhs.value, rhs.value));
2064 }
John Bauman89401822014-05-06 15:04:28 -04002065 }
2066
John Bauman19bac1e2014-05-06 15:23:49 -04002067 RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002068 {
John Bauman19bac1e2014-05-06 15:23:49 -04002069 if(CPUID::supportsMMX2())
2070 {
2071 return x86::psubb(lhs, rhs);
2072 }
2073 else
2074 {
2075 return RValue<Byte8>(Nucleus::createSub(lhs.value, rhs.value));
2076 }
John Bauman89401822014-05-06 15:04:28 -04002077 }
2078
John Bauman19bac1e2014-05-06 15:23:49 -04002079// RValue<Byte8> operator*(RValue<Byte8> lhs, RValue<Byte8> rhs)
2080// {
2081// return RValue<Byte8>(Nucleus::createMul(lhs.value, rhs.value));
2082// }
2083
2084// RValue<Byte8> operator/(RValue<Byte8> lhs, RValue<Byte8> rhs)
2085// {
2086// return RValue<Byte8>(Nucleus::createUDiv(lhs.value, rhs.value));
2087// }
2088
2089// RValue<Byte8> operator%(RValue<Byte8> lhs, RValue<Byte8> rhs)
2090// {
2091// return RValue<Byte8>(Nucleus::createURem(lhs.value, rhs.value));
2092// }
2093
2094 RValue<Byte8> operator&(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002095 {
John Bauman19bac1e2014-05-06 15:23:49 -04002096 if(CPUID::supportsMMX2())
2097 {
2098 return As<Byte8>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
2099 }
2100 else
2101 {
2102 return RValue<Byte8>(Nucleus::createAnd(lhs.value, rhs.value));
2103 }
John Bauman89401822014-05-06 15:04:28 -04002104 }
2105
John Bauman19bac1e2014-05-06 15:23:49 -04002106 RValue<Byte8> operator|(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002107 {
John Bauman19bac1e2014-05-06 15:23:49 -04002108 if(CPUID::supportsMMX2())
2109 {
2110 return As<Byte8>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
2111 }
2112 else
2113 {
2114 return RValue<Byte8>(Nucleus::createOr(lhs.value, rhs.value));
2115 }
John Bauman89401822014-05-06 15:04:28 -04002116 }
2117
John Bauman19bac1e2014-05-06 15:23:49 -04002118 RValue<Byte8> operator^(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002119 {
John Bauman19bac1e2014-05-06 15:23:49 -04002120 if(CPUID::supportsMMX2())
2121 {
2122 return As<Byte8>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
2123 }
2124 else
John Bauman66b8ab22014-05-06 15:57:45 -04002125 {
John Bauman19bac1e2014-05-06 15:23:49 -04002126 return RValue<Byte8>(Nucleus::createXor(lhs.value, rhs.value));
2127 }
John Bauman89401822014-05-06 15:04:28 -04002128 }
2129
John Bauman19bac1e2014-05-06 15:23:49 -04002130// RValue<Byte8> operator<<(RValue<Byte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002131// {
2132// return RValue<Byte8>(Nucleus::createShl(lhs.value, rhs.value));
2133// }
2134
John Bauman19bac1e2014-05-06 15:23:49 -04002135// RValue<Byte8> operator>>(RValue<Byte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002136// {
2137// return RValue<Byte8>(Nucleus::createLShr(lhs.value, rhs.value));
2138// }
2139
John Bauman19bac1e2014-05-06 15:23:49 -04002140 RValue<Byte8> operator+=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002141 {
2142 return lhs = lhs + rhs;
2143 }
2144
John Bauman19bac1e2014-05-06 15:23:49 -04002145 RValue<Byte8> operator-=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002146 {
2147 return lhs = lhs - rhs;
2148 }
2149
John Bauman19bac1e2014-05-06 15:23:49 -04002150// RValue<Byte8> operator*=(const Byte8 &lhs, RValue<Byte8> rhs)
2151// {
2152// return lhs = lhs * rhs;
2153// }
John Bauman89401822014-05-06 15:04:28 -04002154
John Bauman19bac1e2014-05-06 15:23:49 -04002155// RValue<Byte8> operator/=(const Byte8 &lhs, RValue<Byte8> rhs)
2156// {
2157// return lhs = lhs / rhs;
2158// }
John Bauman89401822014-05-06 15:04:28 -04002159
John Bauman19bac1e2014-05-06 15:23:49 -04002160// RValue<Byte8> operator%=(const Byte8 &lhs, RValue<Byte8> rhs)
2161// {
2162// return lhs = lhs % rhs;
2163// }
John Bauman89401822014-05-06 15:04:28 -04002164
John Bauman19bac1e2014-05-06 15:23:49 -04002165 RValue<Byte8> operator&=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002166 {
2167 return lhs = lhs & rhs;
2168 }
2169
John Bauman19bac1e2014-05-06 15:23:49 -04002170 RValue<Byte8> operator|=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002171 {
2172 return lhs = lhs | rhs;
2173 }
2174
John Bauman19bac1e2014-05-06 15:23:49 -04002175 RValue<Byte8> operator^=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002176 {
2177 return lhs = lhs ^ rhs;
2178 }
2179
John Bauman19bac1e2014-05-06 15:23:49 -04002180// RValue<Byte8> operator<<=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002181// {
2182// return lhs = lhs << rhs;
2183// }
2184
John Bauman19bac1e2014-05-06 15:23:49 -04002185// RValue<Byte8> operator>>=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002186// {
2187// return lhs = lhs >> rhs;
2188// }
2189
John Bauman19bac1e2014-05-06 15:23:49 -04002190// RValue<Byte8> operator+(RValue<Byte8> val)
2191// {
2192// return val;
2193// }
2194
2195// RValue<Byte8> operator-(RValue<Byte8> val)
2196// {
2197// return RValue<Byte8>(Nucleus::createNeg(val.value));
2198// }
2199
2200 RValue<Byte8> operator~(RValue<Byte8> val)
John Bauman89401822014-05-06 15:04:28 -04002201 {
John Bauman19bac1e2014-05-06 15:23:49 -04002202 if(CPUID::supportsMMX2())
2203 {
2204 return val ^ Byte8(0xFFFFFFFFFFFFFFFF);
2205 }
2206 else
2207 {
2208 return RValue<Byte8>(Nucleus::createNot(val.value));
2209 }
John Bauman89401822014-05-06 15:04:28 -04002210 }
2211
John Bauman19bac1e2014-05-06 15:23:49 -04002212 RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002213 {
2214 return x86::paddusb(x, y);
2215 }
John Bauman66b8ab22014-05-06 15:57:45 -04002216
John Bauman19bac1e2014-05-06 15:23:49 -04002217 RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002218 {
2219 return x86::psubusb(x, y);
2220 }
2221
John Bauman19bac1e2014-05-06 15:23:49 -04002222 RValue<Short4> Unpack(RValue<Byte4> x)
John Bauman89401822014-05-06 15:04:28 -04002223 {
John Bauman19bac1e2014-05-06 15:23:49 -04002224 Value *int2 = Nucleus::createInsertElement(UndefValue::get(VectorType::get(Int::getType(), 2)), x.value, 0);
2225 Value *byte8 = Nucleus::createBitCast(int2, Byte8::getType());
John Bauman89401822014-05-06 15:04:28 -04002226
John Bauman19bac1e2014-05-06 15:23:49 -04002227 return UnpackLow(RValue<Byte8>(byte8), RValue<Byte8>(byte8));
2228 }
John Bauman89401822014-05-06 15:04:28 -04002229
John Bauman19bac1e2014-05-06 15:23:49 -04002230 RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y)
2231 {
2232 if(CPUID::supportsMMX2())
2233 {
2234 return x86::punpcklbw(x, y);
2235 }
2236 else
2237 {
2238 Constant *shuffle[8];
2239 shuffle[0] = Nucleus::createConstantInt(0);
2240 shuffle[1] = Nucleus::createConstantInt(8);
2241 shuffle[2] = Nucleus::createConstantInt(1);
2242 shuffle[3] = Nucleus::createConstantInt(9);
2243 shuffle[4] = Nucleus::createConstantInt(2);
2244 shuffle[5] = Nucleus::createConstantInt(10);
2245 shuffle[6] = Nucleus::createConstantInt(3);
2246 shuffle[7] = Nucleus::createConstantInt(11);
2247
2248 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 8));
2249
2250 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2251 }
John Bauman89401822014-05-06 15:04:28 -04002252 }
John Bauman66b8ab22014-05-06 15:57:45 -04002253
John Bauman19bac1e2014-05-06 15:23:49 -04002254 RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002255 {
John Bauman19bac1e2014-05-06 15:23:49 -04002256 if(CPUID::supportsMMX2())
2257 {
2258 return x86::punpckhbw(x, y);
2259 }
2260 else
2261 {
2262 Constant *shuffle[8];
2263 shuffle[0] = Nucleus::createConstantInt(4);
2264 shuffle[1] = Nucleus::createConstantInt(12);
2265 shuffle[2] = Nucleus::createConstantInt(5);
2266 shuffle[3] = Nucleus::createConstantInt(13);
2267 shuffle[4] = Nucleus::createConstantInt(6);
2268 shuffle[5] = Nucleus::createConstantInt(14);
2269 shuffle[6] = Nucleus::createConstantInt(7);
2270 shuffle[7] = Nucleus::createConstantInt(15);
John Bauman89401822014-05-06 15:04:28 -04002271
John Bauman19bac1e2014-05-06 15:23:49 -04002272 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 8));
John Bauman89401822014-05-06 15:04:28 -04002273
John Bauman19bac1e2014-05-06 15:23:49 -04002274 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2275 }
John Bauman89401822014-05-06 15:04:28 -04002276 }
2277
John Bauman19bac1e2014-05-06 15:23:49 -04002278 RValue<Int> SignMask(RValue<Byte8> x)
John Bauman89401822014-05-06 15:04:28 -04002279 {
2280 return x86::pmovmskb(x);
2281 }
2282
John Bauman19bac1e2014-05-06 15:23:49 -04002283// RValue<Byte8> CmpGT(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002284// {
2285// return x86::pcmpgtb(x, y); // FIXME: Signedness
2286// }
John Bauman66b8ab22014-05-06 15:57:45 -04002287
John Bauman19bac1e2014-05-06 15:23:49 -04002288 RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002289 {
2290 return x86::pcmpeqb(x, y);
2291 }
2292
John Bauman19bac1e2014-05-06 15:23:49 -04002293 Type *Byte8::getType()
John Bauman89401822014-05-06 15:04:28 -04002294 {
John Bauman19bac1e2014-05-06 15:23:49 -04002295 if(CPUID::supportsMMX2())
2296 {
2297 return MMX::getType();
2298 }
2299 else
2300 {
Nicolas Capensac230122016-09-20 14:30:06 -04002301 return T(VectorType::get(Byte::getType(), 8));
John Bauman19bac1e2014-05-06 15:23:49 -04002302 }
John Bauman89401822014-05-06 15:04:28 -04002303 }
2304
2305 SByte8::SByte8()
2306 {
2307 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002308 }
2309
2310 SByte8::SByte8(byte x0, byte x1, byte x2, byte x3, byte x4, byte x5, byte x6, byte x7)
2311 {
2312 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002313
2314 Constant *constantVector[8];
2315 constantVector[0] = Nucleus::createConstantByte(x0);
2316 constantVector[1] = Nucleus::createConstantByte(x1);
2317 constantVector[2] = Nucleus::createConstantByte(x2);
2318 constantVector[3] = Nucleus::createConstantByte(x3);
2319 constantVector[4] = Nucleus::createConstantByte(x4);
2320 constantVector[5] = Nucleus::createConstantByte(x5);
2321 constantVector[6] = Nucleus::createConstantByte(x6);
2322 constantVector[7] = Nucleus::createConstantByte(x7);
John Bauman19bac1e2014-05-06 15:23:49 -04002323 Value *vector = Nucleus::createConstantVector(constantVector, 8);
John Bauman89401822014-05-06 15:04:28 -04002324
John Bauman66b8ab22014-05-06 15:57:45 -04002325 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04002326 }
2327
2328 SByte8::SByte8(int64_t x)
2329 {
2330 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002331
2332 Constant *constantVector[8];
2333 constantVector[0] = Nucleus::createConstantByte((unsigned char)(x >> 0));
2334 constantVector[1] = Nucleus::createConstantByte((unsigned char)(x >> 8));
2335 constantVector[2] = Nucleus::createConstantByte((unsigned char)(x >> 16));
2336 constantVector[3] = Nucleus::createConstantByte((unsigned char)(x >> 24));
2337 constantVector[4] = Nucleus::createConstantByte((unsigned char)(x >> 32));
2338 constantVector[5] = Nucleus::createConstantByte((unsigned char)(x >> 40));
2339 constantVector[6] = Nucleus::createConstantByte((unsigned char)(x >> 48));
2340 constantVector[7] = Nucleus::createConstantByte((unsigned char)(x >> 56));
John Bauman19bac1e2014-05-06 15:23:49 -04002341 Value *vector = Nucleus::createConstantVector(constantVector, 8);
John Bauman89401822014-05-06 15:04:28 -04002342
John Bauman66b8ab22014-05-06 15:57:45 -04002343 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04002344 }
2345
John Bauman19bac1e2014-05-06 15:23:49 -04002346 SByte8::SByte8(RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002347 {
2348 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002349
John Bauman66b8ab22014-05-06 15:57:45 -04002350 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002351 }
2352
2353 SByte8::SByte8(const SByte8 &rhs)
2354 {
2355 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002356
John Bauman66b8ab22014-05-06 15:57:45 -04002357 Value *value = rhs.loadValue();
2358 storeValue(value);
2359 }
2360
2361 SByte8::SByte8(const Reference<SByte8> &rhs)
2362 {
2363 // xyzw.parent = this;
2364
2365 Value *value = rhs.loadValue();
2366 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002367 }
2368
John Bauman19bac1e2014-05-06 15:23:49 -04002369 RValue<SByte8> SByte8::operator=(RValue<SByte8> rhs) const
John Bauman89401822014-05-06 15:04:28 -04002370 {
John Bauman66b8ab22014-05-06 15:57:45 -04002371 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002372
2373 return rhs;
2374 }
2375
2376 RValue<SByte8> SByte8::operator=(const SByte8 &rhs) const
2377 {
John Bauman66b8ab22014-05-06 15:57:45 -04002378 Value *value = rhs.loadValue();
2379 storeValue(value);
2380
2381 return RValue<SByte8>(value);
2382 }
2383
2384 RValue<SByte8> SByte8::operator=(const Reference<SByte8> &rhs) const
2385 {
2386 Value *value = rhs.loadValue();
2387 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002388
2389 return RValue<SByte8>(value);
2390 }
2391
John Bauman19bac1e2014-05-06 15:23:49 -04002392 RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002393 {
John Bauman19bac1e2014-05-06 15:23:49 -04002394 if(CPUID::supportsMMX2())
2395 {
2396 return As<SByte8>(x86::paddb(As<Byte8>(lhs), As<Byte8>(rhs)));
2397 }
2398 else
2399 {
2400 return RValue<SByte8>(Nucleus::createAdd(lhs.value, rhs.value));
2401 }
John Bauman89401822014-05-06 15:04:28 -04002402 }
2403
John Bauman19bac1e2014-05-06 15:23:49 -04002404 RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002405 {
John Bauman19bac1e2014-05-06 15:23:49 -04002406 if(CPUID::supportsMMX2())
2407 {
2408 return As<SByte8>(x86::psubb(As<Byte8>(lhs), As<Byte8>(rhs)));
2409 }
2410 else
2411 {
2412 return RValue<SByte8>(Nucleus::createSub(lhs.value, rhs.value));
2413 }
John Bauman89401822014-05-06 15:04:28 -04002414 }
2415
John Bauman19bac1e2014-05-06 15:23:49 -04002416// RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs)
2417// {
2418// return RValue<SByte8>(Nucleus::createMul(lhs.value, rhs.value));
2419// }
John Bauman89401822014-05-06 15:04:28 -04002420
John Bauman19bac1e2014-05-06 15:23:49 -04002421// RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs)
2422// {
2423// return RValue<SByte8>(Nucleus::createSDiv(lhs.value, rhs.value));
2424// }
John Bauman89401822014-05-06 15:04:28 -04002425
John Bauman19bac1e2014-05-06 15:23:49 -04002426// RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs)
2427// {
2428// return RValue<SByte8>(Nucleus::createSRem(lhs.value, rhs.value));
2429// }
John Bauman89401822014-05-06 15:04:28 -04002430
John Bauman19bac1e2014-05-06 15:23:49 -04002431 RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002432 {
2433 return RValue<SByte8>(Nucleus::createAnd(lhs.value, rhs.value));
2434 }
2435
John Bauman19bac1e2014-05-06 15:23:49 -04002436 RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002437 {
2438 return RValue<SByte8>(Nucleus::createOr(lhs.value, rhs.value));
2439 }
2440
John Bauman19bac1e2014-05-06 15:23:49 -04002441 RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002442 {
2443 return RValue<SByte8>(Nucleus::createXor(lhs.value, rhs.value));
2444 }
2445
John Bauman19bac1e2014-05-06 15:23:49 -04002446// RValue<SByte8> operator<<(RValue<SByte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002447// {
2448// return RValue<SByte8>(Nucleus::createShl(lhs.value, rhs.value));
2449// }
2450
John Bauman19bac1e2014-05-06 15:23:49 -04002451// RValue<SByte8> operator>>(RValue<SByte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002452// {
2453// return RValue<SByte8>(Nucleus::createAShr(lhs.value, rhs.value));
2454// }
2455
John Bauman19bac1e2014-05-06 15:23:49 -04002456 RValue<SByte8> operator+=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002457 {
2458 return lhs = lhs + rhs;
2459 }
2460
John Bauman19bac1e2014-05-06 15:23:49 -04002461 RValue<SByte8> operator-=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002462 {
2463 return lhs = lhs - rhs;
2464 }
2465
John Bauman19bac1e2014-05-06 15:23:49 -04002466// RValue<SByte8> operator*=(const SByte8 &lhs, RValue<SByte8> rhs)
2467// {
2468// return lhs = lhs * rhs;
2469// }
John Bauman89401822014-05-06 15:04:28 -04002470
John Bauman19bac1e2014-05-06 15:23:49 -04002471// RValue<SByte8> operator/=(const SByte8 &lhs, RValue<SByte8> rhs)
2472// {
2473// return lhs = lhs / rhs;
2474// }
John Bauman89401822014-05-06 15:04:28 -04002475
John Bauman19bac1e2014-05-06 15:23:49 -04002476// RValue<SByte8> operator%=(const SByte8 &lhs, RValue<SByte8> rhs)
2477// {
2478// return lhs = lhs % rhs;
2479// }
John Bauman89401822014-05-06 15:04:28 -04002480
John Bauman19bac1e2014-05-06 15:23:49 -04002481 RValue<SByte8> operator&=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002482 {
2483 return lhs = lhs & rhs;
2484 }
2485
John Bauman19bac1e2014-05-06 15:23:49 -04002486 RValue<SByte8> operator|=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002487 {
2488 return lhs = lhs | rhs;
2489 }
2490
John Bauman19bac1e2014-05-06 15:23:49 -04002491 RValue<SByte8> operator^=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002492 {
2493 return lhs = lhs ^ rhs;
2494 }
2495
John Bauman19bac1e2014-05-06 15:23:49 -04002496// RValue<SByte8> operator<<=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002497// {
2498// return lhs = lhs << rhs;
2499// }
2500
John Bauman19bac1e2014-05-06 15:23:49 -04002501// RValue<SByte8> operator>>=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002502// {
2503// return lhs = lhs >> rhs;
2504// }
2505
John Bauman19bac1e2014-05-06 15:23:49 -04002506// RValue<SByte8> operator+(RValue<SByte8> val)
2507// {
2508// return val;
2509// }
2510
2511// RValue<SByte8> operator-(RValue<SByte8> val)
2512// {
2513// return RValue<SByte8>(Nucleus::createNeg(val.value));
2514// }
2515
2516 RValue<SByte8> operator~(RValue<SByte8> val)
John Bauman89401822014-05-06 15:04:28 -04002517 {
John Bauman19bac1e2014-05-06 15:23:49 -04002518 if(CPUID::supportsMMX2())
2519 {
2520 return val ^ SByte8(0xFFFFFFFFFFFFFFFF);
2521 }
2522 else
2523 {
2524 return RValue<SByte8>(Nucleus::createNot(val.value));
2525 }
John Bauman89401822014-05-06 15:04:28 -04002526 }
2527
John Bauman19bac1e2014-05-06 15:23:49 -04002528 RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002529 {
2530 return x86::paddsb(x, y);
2531 }
John Bauman66b8ab22014-05-06 15:57:45 -04002532
John Bauman19bac1e2014-05-06 15:23:49 -04002533 RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002534 {
2535 return x86::psubsb(x, y);
2536 }
2537
John Bauman19bac1e2014-05-06 15:23:49 -04002538 RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002539 {
John Bauman19bac1e2014-05-06 15:23:49 -04002540 if(CPUID::supportsMMX2())
2541 {
2542 return As<Short4>(x86::punpcklbw(As<Byte8>(x), As<Byte8>(y)));
2543 }
2544 else
2545 {
2546 Constant *shuffle[8];
2547 shuffle[0] = Nucleus::createConstantInt(0);
2548 shuffle[1] = Nucleus::createConstantInt(8);
2549 shuffle[2] = Nucleus::createConstantInt(1);
2550 shuffle[3] = Nucleus::createConstantInt(9);
2551 shuffle[4] = Nucleus::createConstantInt(2);
2552 shuffle[5] = Nucleus::createConstantInt(10);
2553 shuffle[6] = Nucleus::createConstantInt(3);
2554 shuffle[7] = Nucleus::createConstantInt(11);
John Bauman89401822014-05-06 15:04:28 -04002555
John Bauman19bac1e2014-05-06 15:23:49 -04002556 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 8));
John Bauman89401822014-05-06 15:04:28 -04002557
John Bauman19bac1e2014-05-06 15:23:49 -04002558 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2559 }
John Bauman89401822014-05-06 15:04:28 -04002560 }
John Bauman66b8ab22014-05-06 15:57:45 -04002561
John Bauman19bac1e2014-05-06 15:23:49 -04002562 RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002563 {
John Bauman19bac1e2014-05-06 15:23:49 -04002564 if(CPUID::supportsMMX2())
2565 {
2566 return As<Short4>(x86::punpckhbw(As<Byte8>(x), As<Byte8>(y)));
2567 }
2568 else
2569 {
2570 Constant *shuffle[8];
2571 shuffle[0] = Nucleus::createConstantInt(4);
2572 shuffle[1] = Nucleus::createConstantInt(12);
2573 shuffle[2] = Nucleus::createConstantInt(5);
2574 shuffle[3] = Nucleus::createConstantInt(13);
2575 shuffle[4] = Nucleus::createConstantInt(6);
2576 shuffle[5] = Nucleus::createConstantInt(14);
2577 shuffle[6] = Nucleus::createConstantInt(7);
2578 shuffle[7] = Nucleus::createConstantInt(15);
John Bauman89401822014-05-06 15:04:28 -04002579
John Bauman19bac1e2014-05-06 15:23:49 -04002580 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 8));
John Bauman89401822014-05-06 15:04:28 -04002581
John Bauman19bac1e2014-05-06 15:23:49 -04002582 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2583 }
John Bauman89401822014-05-06 15:04:28 -04002584 }
2585
John Bauman19bac1e2014-05-06 15:23:49 -04002586 RValue<Int> SignMask(RValue<SByte8> x)
John Bauman89401822014-05-06 15:04:28 -04002587 {
2588 return x86::pmovmskb(As<Byte8>(x));
2589 }
2590
John Bauman19bac1e2014-05-06 15:23:49 -04002591 RValue<Byte8> CmpGT(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002592 {
2593 return x86::pcmpgtb(x, y);
2594 }
John Bauman66b8ab22014-05-06 15:57:45 -04002595
John Bauman19bac1e2014-05-06 15:23:49 -04002596 RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002597 {
2598 return x86::pcmpeqb(As<Byte8>(x), As<Byte8>(y));
2599 }
2600
John Bauman19bac1e2014-05-06 15:23:49 -04002601 Type *SByte8::getType()
John Bauman89401822014-05-06 15:04:28 -04002602 {
John Bauman19bac1e2014-05-06 15:23:49 -04002603 if(CPUID::supportsMMX2())
2604 {
2605 return MMX::getType();
2606 }
2607 else
2608 {
Nicolas Capensac230122016-09-20 14:30:06 -04002609 return T(VectorType::get(SByte::getType(), 8));
John Bauman19bac1e2014-05-06 15:23:49 -04002610 }
John Bauman89401822014-05-06 15:04:28 -04002611 }
2612
John Bauman19bac1e2014-05-06 15:23:49 -04002613 Byte16::Byte16(RValue<Byte16> rhs)
John Bauman89401822014-05-06 15:04:28 -04002614 {
2615 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002616
John Bauman66b8ab22014-05-06 15:57:45 -04002617 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002618 }
2619
2620 Byte16::Byte16(const Byte16 &rhs)
2621 {
2622 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002623
John Bauman66b8ab22014-05-06 15:57:45 -04002624 Value *value = rhs.loadValue();
2625 storeValue(value);
2626 }
2627
2628 Byte16::Byte16(const Reference<Byte16> &rhs)
2629 {
2630 // xyzw.parent = this;
2631
2632 Value *value = rhs.loadValue();
2633 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002634 }
2635
John Bauman19bac1e2014-05-06 15:23:49 -04002636 RValue<Byte16> Byte16::operator=(RValue<Byte16> rhs) const
John Bauman89401822014-05-06 15:04:28 -04002637 {
John Bauman66b8ab22014-05-06 15:57:45 -04002638 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002639
2640 return rhs;
2641 }
2642
2643 RValue<Byte16> Byte16::operator=(const Byte16 &rhs) const
2644 {
John Bauman66b8ab22014-05-06 15:57:45 -04002645 Value *value = rhs.loadValue();
2646 storeValue(value);
2647
2648 return RValue<Byte16>(value);
2649 }
2650
2651 RValue<Byte16> Byte16::operator=(const Reference<Byte16> &rhs) const
2652 {
2653 Value *value = rhs.loadValue();
2654 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002655
2656 return RValue<Byte16>(value);
2657 }
2658
John Bauman19bac1e2014-05-06 15:23:49 -04002659 Type *Byte16::getType()
John Bauman89401822014-05-06 15:04:28 -04002660 {
Nicolas Capensac230122016-09-20 14:30:06 -04002661 return T(VectorType::get(Byte::getType(), 16));
John Bauman89401822014-05-06 15:04:28 -04002662 }
2663
John Bauman19bac1e2014-05-06 15:23:49 -04002664 Type *SByte16::getType()
John Bauman89401822014-05-06 15:04:28 -04002665 {
Nicolas Capensac230122016-09-20 14:30:06 -04002666 return T( VectorType::get(SByte::getType(), 16));
John Bauman89401822014-05-06 15:04:28 -04002667 }
2668
John Bauman19bac1e2014-05-06 15:23:49 -04002669 Short4::Short4(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04002670 {
John Bauman89401822014-05-06 15:04:28 -04002671 Value *extend = Nucleus::createZExt(cast.value, Long::getType());
John Bauman19bac1e2014-05-06 15:23:49 -04002672 Value *swizzle = Swizzle(RValue<Short4>(extend), 0x00).value;
John Bauman66b8ab22014-05-06 15:57:45 -04002673
2674 storeValue(swizzle);
John Bauman89401822014-05-06 15:04:28 -04002675 }
2676
John Bauman19bac1e2014-05-06 15:23:49 -04002677 Short4::Short4(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04002678 {
John Bauman89401822014-05-06 15:04:28 -04002679 Value *short8 = Nucleus::createBitCast(cast.value, Short8::getType());
2680
2681 #if 0 // FIXME: Check codegen (pshuflw phshufhw pshufd)
2682 Constant *pack[8];
2683 pack[0] = Nucleus::createConstantInt(0);
2684 pack[1] = Nucleus::createConstantInt(2);
2685 pack[2] = Nucleus::createConstantInt(4);
2686 pack[3] = Nucleus::createConstantInt(6);
2687
2688 Value *short4 = Nucleus::createShuffleVector(short8, short8, Nucleus::createConstantVector(pack, 4));
2689 #else
2690 Value *packed;
2691
2692 // FIXME: Use Swizzle<Short8>
2693 if(!CPUID::supportsSSSE3())
2694 {
2695 Constant *pshuflw[8];
2696 pshuflw[0] = Nucleus::createConstantInt(0);
2697 pshuflw[1] = Nucleus::createConstantInt(2);
2698 pshuflw[2] = Nucleus::createConstantInt(0);
2699 pshuflw[3] = Nucleus::createConstantInt(2);
2700 pshuflw[4] = Nucleus::createConstantInt(4);
2701 pshuflw[5] = Nucleus::createConstantInt(5);
2702 pshuflw[6] = Nucleus::createConstantInt(6);
2703 pshuflw[7] = Nucleus::createConstantInt(7);
2704
2705 Constant *pshufhw[8];
2706 pshufhw[0] = Nucleus::createConstantInt(0);
2707 pshufhw[1] = Nucleus::createConstantInt(1);
2708 pshufhw[2] = Nucleus::createConstantInt(2);
2709 pshufhw[3] = Nucleus::createConstantInt(3);
2710 pshufhw[4] = Nucleus::createConstantInt(4);
2711 pshufhw[5] = Nucleus::createConstantInt(6);
2712 pshufhw[6] = Nucleus::createConstantInt(4);
2713 pshufhw[7] = Nucleus::createConstantInt(6);
2714
2715 Value *shuffle1 = Nucleus::createShuffleVector(short8, UndefValue::get(Short8::getType()), Nucleus::createConstantVector(pshuflw, 8));
2716 Value *shuffle2 = Nucleus::createShuffleVector(shuffle1, UndefValue::get(Short8::getType()), Nucleus::createConstantVector(pshufhw, 8));
2717 Value *int4 = Nucleus::createBitCast(shuffle2, Int4::getType());
2718 packed = Nucleus::createSwizzle(int4, 0x88);
2719 }
2720 else
2721 {
2722 Constant *pshufb[16];
2723 pshufb[0] = Nucleus::createConstantInt(0);
2724 pshufb[1] = Nucleus::createConstantInt(1);
2725 pshufb[2] = Nucleus::createConstantInt(4);
2726 pshufb[3] = Nucleus::createConstantInt(5);
2727 pshufb[4] = Nucleus::createConstantInt(8);
2728 pshufb[5] = Nucleus::createConstantInt(9);
2729 pshufb[6] = Nucleus::createConstantInt(12);
2730 pshufb[7] = Nucleus::createConstantInt(13);
2731 pshufb[8] = Nucleus::createConstantInt(0);
2732 pshufb[9] = Nucleus::createConstantInt(1);
2733 pshufb[10] = Nucleus::createConstantInt(4);
2734 pshufb[11] = Nucleus::createConstantInt(5);
2735 pshufb[12] = Nucleus::createConstantInt(8);
2736 pshufb[13] = Nucleus::createConstantInt(9);
2737 pshufb[14] = Nucleus::createConstantInt(12);
2738 pshufb[15] = Nucleus::createConstantInt(13);
2739
2740 Value *byte16 = Nucleus::createBitCast(cast.value, Byte16::getType());
2741 packed = Nucleus::createShuffleVector(byte16, UndefValue::get(Byte16::getType()), Nucleus::createConstantVector(pshufb, 16));
2742 }
2743
2744 #if 0 // FIXME: No optimal instruction selection
2745 Value *qword2 = Nucleus::createBitCast(packed, Long2::getType());
2746 Value *element = Nucleus::createExtractElement(qword2, 0);
2747 Value *short4 = Nucleus::createBitCast(element, Short4::getType());
2748 #else // FIXME: Requires SSE
2749 Value *int2 = RValue<Int2>(Int2(RValue<Int4>(packed))).value;
2750 Value *short4 = Nucleus::createBitCast(int2, Short4::getType());
2751 #endif
2752 #endif
2753
John Bauman66b8ab22014-05-06 15:57:45 -04002754 storeValue(short4);
John Bauman89401822014-05-06 15:04:28 -04002755 }
2756
John Bauman19bac1e2014-05-06 15:23:49 -04002757// Short4::Short4(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04002758// {
2759// }
2760
John Bauman19bac1e2014-05-06 15:23:49 -04002761 Short4::Short4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04002762 {
John Bauman89401822014-05-06 15:04:28 -04002763 Int4 v4i32 = Int4(cast);
2764 v4i32 = As<Int4>(x86::packssdw(v4i32, v4i32));
John Bauman66b8ab22014-05-06 15:57:45 -04002765
2766 storeValue(As<Short4>(Int2(v4i32)).value);
John Bauman89401822014-05-06 15:04:28 -04002767 }
2768
2769 Short4::Short4()
2770 {
2771 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002772 }
2773
John Bauman19bac1e2014-05-06 15:23:49 -04002774 Short4::Short4(short xyzw)
2775 {
2776 // xyzw.parent = this;
John Bauman19bac1e2014-05-06 15:23:49 -04002777
2778 Constant *constantVector[4];
2779 constantVector[0] = Nucleus::createConstantShort(xyzw);
2780 constantVector[1] = Nucleus::createConstantShort(xyzw);
2781 constantVector[2] = Nucleus::createConstantShort(xyzw);
2782 constantVector[3] = Nucleus::createConstantShort(xyzw);
2783 Value *vector = Nucleus::createConstantVector(constantVector, 4);
2784
John Bauman66b8ab22014-05-06 15:57:45 -04002785 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman19bac1e2014-05-06 15:23:49 -04002786 }
2787
John Bauman89401822014-05-06 15:04:28 -04002788 Short4::Short4(short x, short y, short z, short w)
2789 {
2790 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002791
2792 Constant *constantVector[4];
2793 constantVector[0] = Nucleus::createConstantShort(x);
2794 constantVector[1] = Nucleus::createConstantShort(y);
2795 constantVector[2] = Nucleus::createConstantShort(z);
2796 constantVector[3] = Nucleus::createConstantShort(w);
John Bauman19bac1e2014-05-06 15:23:49 -04002797 Value *vector = Nucleus::createConstantVector(constantVector, 4);
2798
John Bauman66b8ab22014-05-06 15:57:45 -04002799 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04002800 }
2801
John Bauman19bac1e2014-05-06 15:23:49 -04002802 Short4::Short4(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002803 {
2804 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002805
John Bauman66b8ab22014-05-06 15:57:45 -04002806 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002807 }
2808
2809 Short4::Short4(const Short4 &rhs)
2810 {
2811 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002812
John Bauman66b8ab22014-05-06 15:57:45 -04002813 Value *value = rhs.loadValue();
2814 storeValue(value);
2815 }
2816
2817 Short4::Short4(const Reference<Short4> &rhs)
2818 {
2819 // xyzw.parent = this;
2820
2821 Value *value = rhs.loadValue();
2822 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002823 }
2824
John Bauman19bac1e2014-05-06 15:23:49 -04002825 Short4::Short4(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002826 {
2827 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002828
John Bauman66b8ab22014-05-06 15:57:45 -04002829 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002830 }
2831
2832 Short4::Short4(const UShort4 &rhs)
2833 {
2834 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002835
John Bauman66b8ab22014-05-06 15:57:45 -04002836 storeValue(rhs.loadValue());
2837 }
2838
2839 Short4::Short4(const Reference<UShort4> &rhs)
2840 {
2841 // xyzw.parent = this;
2842
2843 storeValue(rhs.loadValue());
John Bauman89401822014-05-06 15:04:28 -04002844 }
2845
John Bauman19bac1e2014-05-06 15:23:49 -04002846 RValue<Short4> Short4::operator=(RValue<Short4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04002847 {
John Bauman66b8ab22014-05-06 15:57:45 -04002848 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002849
2850 return rhs;
2851 }
2852
2853 RValue<Short4> Short4::operator=(const Short4 &rhs) const
2854 {
John Bauman66b8ab22014-05-06 15:57:45 -04002855 Value *value = rhs.loadValue();
2856 storeValue(value);
2857
2858 return RValue<Short4>(value);
2859 }
2860
2861 RValue<Short4> Short4::operator=(const Reference<Short4> &rhs) const
2862 {
2863 Value *value = rhs.loadValue();
2864 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002865
2866 return RValue<Short4>(value);
2867 }
2868
John Bauman19bac1e2014-05-06 15:23:49 -04002869 RValue<Short4> Short4::operator=(RValue<UShort4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04002870 {
John Bauman66b8ab22014-05-06 15:57:45 -04002871 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002872
John Bauman66b8ab22014-05-06 15:57:45 -04002873 return RValue<Short4>(rhs);
John Bauman89401822014-05-06 15:04:28 -04002874 }
2875
2876 RValue<Short4> Short4::operator=(const UShort4 &rhs) const
2877 {
John Bauman66b8ab22014-05-06 15:57:45 -04002878 Value *value = rhs.loadValue();
2879 storeValue(value);
2880
2881 return RValue<Short4>(value);
2882 }
2883
2884 RValue<Short4> Short4::operator=(const Reference<UShort4> &rhs) const
2885 {
2886 Value *value = rhs.loadValue();
2887 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002888
2889 return RValue<Short4>(value);
2890 }
2891
John Bauman19bac1e2014-05-06 15:23:49 -04002892 RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002893 {
John Bauman19bac1e2014-05-06 15:23:49 -04002894 if(CPUID::supportsMMX2())
2895 {
2896 return x86::paddw(lhs, rhs);
2897 }
2898 else
2899 {
2900 return RValue<Short4>(Nucleus::createAdd(lhs.value, rhs.value));
2901 }
John Bauman89401822014-05-06 15:04:28 -04002902 }
2903
John Bauman19bac1e2014-05-06 15:23:49 -04002904 RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002905 {
John Bauman19bac1e2014-05-06 15:23:49 -04002906 if(CPUID::supportsMMX2())
2907 {
2908 return x86::psubw(lhs, rhs);
2909 }
2910 else
2911 {
2912 return RValue<Short4>(Nucleus::createSub(lhs.value, rhs.value));
2913 }
John Bauman89401822014-05-06 15:04:28 -04002914 }
2915
John Bauman19bac1e2014-05-06 15:23:49 -04002916 RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002917 {
John Bauman19bac1e2014-05-06 15:23:49 -04002918 if(CPUID::supportsMMX2())
2919 {
2920 return x86::pmullw(lhs, rhs);
2921 }
2922 else
2923 {
2924 return RValue<Short4>(Nucleus::createMul(lhs.value, rhs.value));
2925 }
John Bauman89401822014-05-06 15:04:28 -04002926 }
2927
John Bauman19bac1e2014-05-06 15:23:49 -04002928// RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs)
2929// {
2930// return RValue<Short4>(Nucleus::createSDiv(lhs.value, rhs.value));
2931// }
2932
2933// RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs)
2934// {
2935// return RValue<Short4>(Nucleus::createSRem(lhs.value, rhs.value));
2936// }
2937
2938 RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002939 {
John Bauman19bac1e2014-05-06 15:23:49 -04002940 if(CPUID::supportsMMX2())
2941 {
2942 return x86::pand(lhs, rhs);
2943 }
2944 else
2945 {
2946 return RValue<Short4>(Nucleus::createAnd(lhs.value, rhs.value));
2947 }
John Bauman89401822014-05-06 15:04:28 -04002948 }
2949
John Bauman19bac1e2014-05-06 15:23:49 -04002950 RValue<Short4> operator|(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002951 {
John Bauman19bac1e2014-05-06 15:23:49 -04002952 if(CPUID::supportsMMX2())
2953 {
2954 return x86::por(lhs, rhs);
2955 }
2956 else
2957 {
2958 return RValue<Short4>(Nucleus::createOr(lhs.value, rhs.value));
2959 }
John Bauman89401822014-05-06 15:04:28 -04002960 }
2961
John Bauman19bac1e2014-05-06 15:23:49 -04002962 RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002963 {
John Bauman19bac1e2014-05-06 15:23:49 -04002964 if(CPUID::supportsMMX2())
2965 {
2966 return x86::pxor(lhs, rhs);
2967 }
2968 else
2969 {
2970 return RValue<Short4>(Nucleus::createXor(lhs.value, rhs.value));
2971 }
John Bauman89401822014-05-06 15:04:28 -04002972 }
2973
John Bauman19bac1e2014-05-06 15:23:49 -04002974 RValue<Short4> operator<<(RValue<Short4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002975 {
2976 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
2977
2978 return x86::psllw(lhs, rhs);
2979 }
2980
John Bauman19bac1e2014-05-06 15:23:49 -04002981 RValue<Short4> operator>>(RValue<Short4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002982 {
2983 // return RValue<Short4>(Nucleus::createAShr(lhs.value, rhs.value));
2984
2985 return x86::psraw(lhs, rhs);
2986 }
2987
John Bauman19bac1e2014-05-06 15:23:49 -04002988 RValue<Short4> operator<<(RValue<Short4> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04002989 {
2990 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
2991
2992 return x86::psllw(lhs, rhs);
2993 }
2994
John Bauman19bac1e2014-05-06 15:23:49 -04002995 RValue<Short4> operator>>(RValue<Short4> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04002996 {
2997 // return RValue<Short4>(Nucleus::createAShr(lhs.value, rhs.value));
2998
2999 return x86::psraw(lhs, rhs);
3000 }
3001
John Bauman19bac1e2014-05-06 15:23:49 -04003002 RValue<Short4> operator+=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003003 {
3004 return lhs = lhs + rhs;
3005 }
3006
John Bauman19bac1e2014-05-06 15:23:49 -04003007 RValue<Short4> operator-=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003008 {
3009 return lhs = lhs - rhs;
3010 }
3011
John Bauman19bac1e2014-05-06 15:23:49 -04003012 RValue<Short4> operator*=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003013 {
3014 return lhs = lhs * rhs;
3015 }
3016
John Bauman19bac1e2014-05-06 15:23:49 -04003017// RValue<Short4> operator/=(const Short4 &lhs, RValue<Short4> rhs)
3018// {
3019// return lhs = lhs / rhs;
3020// }
John Bauman89401822014-05-06 15:04:28 -04003021
John Bauman19bac1e2014-05-06 15:23:49 -04003022// RValue<Short4> operator%=(const Short4 &lhs, RValue<Short4> rhs)
3023// {
3024// return lhs = lhs % rhs;
3025// }
John Bauman89401822014-05-06 15:04:28 -04003026
John Bauman19bac1e2014-05-06 15:23:49 -04003027 RValue<Short4> operator&=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003028 {
3029 return lhs = lhs & rhs;
3030 }
3031
John Bauman19bac1e2014-05-06 15:23:49 -04003032 RValue<Short4> operator|=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003033 {
3034 return lhs = lhs | rhs;
3035 }
3036
John Bauman19bac1e2014-05-06 15:23:49 -04003037 RValue<Short4> operator^=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003038 {
3039 return lhs = lhs ^ rhs;
3040 }
3041
3042 RValue<Short4> operator<<=(const Short4 &lhs, unsigned char rhs)
3043 {
3044 return lhs = lhs << rhs;
3045 }
3046
3047 RValue<Short4> operator>>=(const Short4 &lhs, unsigned char rhs)
3048 {
3049 return lhs = lhs >> rhs;
3050 }
3051
John Bauman19bac1e2014-05-06 15:23:49 -04003052 RValue<Short4> operator<<=(const Short4 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04003053 {
3054 return lhs = lhs << rhs;
3055 }
3056
John Bauman19bac1e2014-05-06 15:23:49 -04003057 RValue<Short4> operator>>=(const Short4 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04003058 {
3059 return lhs = lhs >> rhs;
3060 }
3061
John Bauman19bac1e2014-05-06 15:23:49 -04003062// RValue<Short4> operator+(RValue<Short4> val)
3063// {
3064// return val;
3065// }
3066
3067 RValue<Short4> operator-(RValue<Short4> val)
John Bauman89401822014-05-06 15:04:28 -04003068 {
John Bauman19bac1e2014-05-06 15:23:49 -04003069 if(CPUID::supportsMMX2())
3070 {
3071 return Short4(0, 0, 0, 0) - val;
3072 }
3073 else
3074 {
3075 return RValue<Short4>(Nucleus::createNeg(val.value));
3076 }
John Bauman89401822014-05-06 15:04:28 -04003077 }
3078
John Bauman19bac1e2014-05-06 15:23:49 -04003079 RValue<Short4> operator~(RValue<Short4> val)
John Bauman89401822014-05-06 15:04:28 -04003080 {
John Bauman19bac1e2014-05-06 15:23:49 -04003081 if(CPUID::supportsMMX2())
3082 {
3083 return val ^ Short4(0xFFFFu, 0xFFFFu, 0xFFFFu, 0xFFFFu);
3084 }
3085 else
3086 {
3087 return RValue<Short4>(Nucleus::createNot(val.value));
3088 }
John Bauman89401822014-05-06 15:04:28 -04003089 }
3090
John Bauman19bac1e2014-05-06 15:23:49 -04003091 RValue<Short4> RoundShort4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04003092 {
3093 RValue<Int4> v4i32 = x86::cvtps2dq(cast);
Nicolas Capens698633a2015-02-04 00:16:13 -05003094 RValue<Short8> v8i16 = x86::packssdw(v4i32, v4i32);
John Bauman66b8ab22014-05-06 15:57:45 -04003095
Nicolas Capens698633a2015-02-04 00:16:13 -05003096 return As<Short4>(Int2(As<Int4>(v8i16)));
John Bauman89401822014-05-06 15:04:28 -04003097 }
3098
John Bauman19bac1e2014-05-06 15:23:49 -04003099 RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003100 {
3101 return x86::pmaxsw(x, y);
3102 }
3103
John Bauman19bac1e2014-05-06 15:23:49 -04003104 RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003105 {
3106 return x86::pminsw(x, y);
3107 }
3108
John Bauman19bac1e2014-05-06 15:23:49 -04003109 RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003110 {
3111 return x86::paddsw(x, y);
3112 }
3113
John Bauman19bac1e2014-05-06 15:23:49 -04003114 RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003115 {
3116 return x86::psubsw(x, y);
3117 }
3118
John Bauman19bac1e2014-05-06 15:23:49 -04003119 RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003120 {
3121 return x86::pmulhw(x, y);
3122 }
3123
John Bauman19bac1e2014-05-06 15:23:49 -04003124 RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003125 {
3126 return x86::pmaddwd(x, y);
3127 }
3128
John Bauman19bac1e2014-05-06 15:23:49 -04003129 RValue<SByte8> Pack(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003130 {
3131 return x86::packsswb(x, y);
3132 }
3133
John Bauman19bac1e2014-05-06 15:23:49 -04003134 RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003135 {
John Bauman19bac1e2014-05-06 15:23:49 -04003136 if(CPUID::supportsMMX2())
3137 {
3138 return x86::punpcklwd(x, y);
3139 }
3140 else
3141 {
3142 Constant *shuffle[4];
3143 shuffle[0] = Nucleus::createConstantInt(0);
3144 shuffle[1] = Nucleus::createConstantInt(4);
3145 shuffle[2] = Nucleus::createConstantInt(1);
3146 shuffle[3] = Nucleus::createConstantInt(5);
John Bauman89401822014-05-06 15:04:28 -04003147
John Bauman19bac1e2014-05-06 15:23:49 -04003148 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 4));
John Bauman89401822014-05-06 15:04:28 -04003149
John Bauman19bac1e2014-05-06 15:23:49 -04003150 return RValue<Int2>(Nucleus::createBitCast(packed, Int2::getType()));
3151 }
John Bauman89401822014-05-06 15:04:28 -04003152 }
3153
John Bauman19bac1e2014-05-06 15:23:49 -04003154 RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003155 {
John Bauman19bac1e2014-05-06 15:23:49 -04003156 if(CPUID::supportsMMX2())
3157 {
3158 return x86::punpckhwd(x, y);
3159 }
3160 else
3161 {
3162 Constant *shuffle[4];
3163 shuffle[0] = Nucleus::createConstantInt(2);
3164 shuffle[1] = Nucleus::createConstantInt(6);
3165 shuffle[2] = Nucleus::createConstantInt(3);
3166 shuffle[3] = Nucleus::createConstantInt(7);
John Bauman89401822014-05-06 15:04:28 -04003167
John Bauman19bac1e2014-05-06 15:23:49 -04003168 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 4));
John Bauman89401822014-05-06 15:04:28 -04003169
John Bauman19bac1e2014-05-06 15:23:49 -04003170 return RValue<Int2>(Nucleus::createBitCast(packed, Int2::getType()));
3171 }
John Bauman89401822014-05-06 15:04:28 -04003172 }
3173
John Bauman19bac1e2014-05-06 15:23:49 -04003174 RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04003175 {
John Bauman19bac1e2014-05-06 15:23:49 -04003176 if(CPUID::supportsMMX2())
3177 {
3178 return x86::pshufw(x, select);
3179 }
3180 else
3181 {
3182 return RValue<Short4>(Nucleus::createSwizzle(x.value, select));
3183 }
John Bauman89401822014-05-06 15:04:28 -04003184 }
3185
John Bauman19bac1e2014-05-06 15:23:49 -04003186 RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i)
John Bauman89401822014-05-06 15:04:28 -04003187 {
John Bauman19bac1e2014-05-06 15:23:49 -04003188 if(CPUID::supportsMMX2())
3189 {
3190 return x86::pinsrw(val, Int(element), i);
3191 }
3192 else
3193 {
3194 return RValue<Short4>(Nucleus::createInsertElement(val.value, element.value, i));
3195 }
John Bauman89401822014-05-06 15:04:28 -04003196 }
3197
John Bauman19bac1e2014-05-06 15:23:49 -04003198 RValue<Short> Extract(RValue<Short4> val, int i)
John Bauman89401822014-05-06 15:04:28 -04003199 {
John Bauman19bac1e2014-05-06 15:23:49 -04003200 if(CPUID::supportsMMX2())
3201 {
3202 return Short(x86::pextrw(val, i));
3203 }
3204 else
3205 {
3206 return RValue<Short>(Nucleus::createExtractElement(val.value, i));
3207 }
John Bauman89401822014-05-06 15:04:28 -04003208 }
3209
John Bauman19bac1e2014-05-06 15:23:49 -04003210 RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003211 {
3212 return x86::pcmpgtw(x, y);
3213 }
3214
John Bauman19bac1e2014-05-06 15:23:49 -04003215 RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003216 {
3217 return x86::pcmpeqw(x, y);
3218 }
3219
John Bauman19bac1e2014-05-06 15:23:49 -04003220 Type *Short4::getType()
John Bauman89401822014-05-06 15:04:28 -04003221 {
John Bauman19bac1e2014-05-06 15:23:49 -04003222 if(CPUID::supportsMMX2())
3223 {
3224 return MMX::getType();
3225 }
3226 else
3227 {
Nicolas Capensac230122016-09-20 14:30:06 -04003228 return T(VectorType::get(Short::getType(), 4));
John Bauman19bac1e2014-05-06 15:23:49 -04003229 }
John Bauman89401822014-05-06 15:04:28 -04003230 }
3231
John Bauman19bac1e2014-05-06 15:23:49 -04003232 UShort4::UShort4(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04003233 {
John Bauman89401822014-05-06 15:04:28 -04003234 *this = Short4(cast);
3235 }
3236
John Bauman19bac1e2014-05-06 15:23:49 -04003237 UShort4::UShort4(RValue<Float4> cast, bool saturate)
John Bauman89401822014-05-06 15:04:28 -04003238 {
John Bauman89401822014-05-06 15:04:28 -04003239 Float4 sat;
3240
3241 if(saturate)
3242 {
3243 if(CPUID::supportsSSE4_1())
3244 {
3245 sat = Min(cast, Float4(0xFFFF)); // packusdw takes care of 0x0000 saturation
3246 }
3247 else
3248 {
3249 sat = Max(Min(cast, Float4(0xFFFF)), Float4(0x0000));
3250 }
3251 }
3252 else
3253 {
3254 sat = cast;
3255 }
3256
3257 Int4 int4(sat);
3258
3259 if(!saturate || !CPUID::supportsSSE4_1())
3260 {
3261 *this = Short4(Int4(int4));
3262 }
3263 else
3264 {
3265 *this = As<Short4>(Int2(As<Int4>(x86::packusdw(As<UInt4>(int4), As<UInt4>(int4)))));
3266 }
3267 }
3268
3269 UShort4::UShort4()
3270 {
3271 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003272 }
3273
Alexis Hetu90c7ad62016-06-27 11:50:40 -04003274 UShort4::UShort4(unsigned short xyzw)
3275 {
3276 // xyzw.parent = this;
3277
3278 Constant *constantVector[4];
3279 constantVector[0] = Nucleus::createConstantShort(xyzw);
3280 constantVector[1] = Nucleus::createConstantShort(xyzw);
3281 constantVector[2] = Nucleus::createConstantShort(xyzw);
3282 constantVector[3] = Nucleus::createConstantShort(xyzw);
3283 Value *vector = Nucleus::createConstantVector(constantVector, 4);
3284
3285 storeValue(Nucleus::createBitCast(vector, getType()));
3286 }
3287
John Bauman89401822014-05-06 15:04:28 -04003288 UShort4::UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w)
3289 {
3290 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003291
3292 Constant *constantVector[4];
3293 constantVector[0] = Nucleus::createConstantShort(x);
3294 constantVector[1] = Nucleus::createConstantShort(y);
3295 constantVector[2] = Nucleus::createConstantShort(z);
3296 constantVector[3] = Nucleus::createConstantShort(w);
John Bauman19bac1e2014-05-06 15:23:49 -04003297 Value *vector = Nucleus::createConstantVector(constantVector, 4);
John Bauman89401822014-05-06 15:04:28 -04003298
John Bauman66b8ab22014-05-06 15:57:45 -04003299 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04003300 }
3301
John Bauman19bac1e2014-05-06 15:23:49 -04003302 UShort4::UShort4(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003303 {
3304 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003305
John Bauman66b8ab22014-05-06 15:57:45 -04003306 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003307 }
3308
3309 UShort4::UShort4(const UShort4 &rhs)
3310 {
3311 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003312
John Bauman66b8ab22014-05-06 15:57:45 -04003313 Value *value = rhs.loadValue();
3314 storeValue(value);
3315 }
3316
3317 UShort4::UShort4(const Reference<UShort4> &rhs)
3318 {
3319 // xyzw.parent = this;
3320
3321 Value *value = rhs.loadValue();
3322 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003323 }
3324
John Bauman19bac1e2014-05-06 15:23:49 -04003325 UShort4::UShort4(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003326 {
3327 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003328
John Bauman66b8ab22014-05-06 15:57:45 -04003329 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003330 }
3331
3332 UShort4::UShort4(const Short4 &rhs)
3333 {
3334 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003335
John Bauman66b8ab22014-05-06 15:57:45 -04003336 Value *value = rhs.loadValue();
3337 storeValue(value);
3338 }
3339
3340 UShort4::UShort4(const Reference<Short4> &rhs)
3341 {
3342 // xyzw.parent = this;
3343
3344 Value *value = rhs.loadValue();
3345 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003346 }
3347
John Bauman19bac1e2014-05-06 15:23:49 -04003348 RValue<UShort4> UShort4::operator=(RValue<UShort4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04003349 {
John Bauman66b8ab22014-05-06 15:57:45 -04003350 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003351
3352 return rhs;
3353 }
3354
3355 RValue<UShort4> UShort4::operator=(const UShort4 &rhs) const
3356 {
John Bauman66b8ab22014-05-06 15:57:45 -04003357 Value *value = rhs.loadValue();
3358 storeValue(value);
3359
3360 return RValue<UShort4>(value);
3361 }
3362
3363 RValue<UShort4> UShort4::operator=(const Reference<UShort4> &rhs) const
3364 {
3365 Value *value = rhs.loadValue();
3366 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003367
3368 return RValue<UShort4>(value);
3369 }
3370
John Bauman19bac1e2014-05-06 15:23:49 -04003371 RValue<UShort4> UShort4::operator=(RValue<Short4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04003372 {
John Bauman66b8ab22014-05-06 15:57:45 -04003373 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003374
John Bauman66b8ab22014-05-06 15:57:45 -04003375 return RValue<UShort4>(rhs);
John Bauman89401822014-05-06 15:04:28 -04003376 }
3377
3378 RValue<UShort4> UShort4::operator=(const Short4 &rhs) const
3379 {
John Bauman66b8ab22014-05-06 15:57:45 -04003380 Value *value = rhs.loadValue();
3381 storeValue(value);
3382
3383 return RValue<UShort4>(value);
3384 }
3385
3386 RValue<UShort4> UShort4::operator=(const Reference<Short4> &rhs) const
3387 {
3388 Value *value = rhs.loadValue();
3389 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003390
3391 return RValue<UShort4>(value);
3392 }
3393
John Bauman19bac1e2014-05-06 15:23:49 -04003394 RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003395 {
John Bauman19bac1e2014-05-06 15:23:49 -04003396 if(CPUID::supportsMMX2())
3397 {
3398 return As<UShort4>(x86::paddw(As<Short4>(lhs), As<Short4>(rhs)));
3399 }
3400 else
3401 {
3402 return RValue<UShort4>(Nucleus::createAdd(lhs.value, rhs.value));
3403 }
John Bauman89401822014-05-06 15:04:28 -04003404 }
3405
John Bauman19bac1e2014-05-06 15:23:49 -04003406 RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003407 {
John Bauman19bac1e2014-05-06 15:23:49 -04003408 if(CPUID::supportsMMX2())
3409 {
3410 return As<UShort4>(x86::psubw(As<Short4>(lhs), As<Short4>(rhs)));
3411 }
3412 else
3413 {
3414 return RValue<UShort4>(Nucleus::createSub(lhs.value, rhs.value));
3415 }
John Bauman89401822014-05-06 15:04:28 -04003416 }
3417
John Bauman19bac1e2014-05-06 15:23:49 -04003418 RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003419 {
John Bauman19bac1e2014-05-06 15:23:49 -04003420 if(CPUID::supportsMMX2())
3421 {
3422 return As<UShort4>(x86::pmullw(As<Short4>(lhs), As<Short4>(rhs)));
3423 }
3424 else
3425 {
3426 return RValue<UShort4>(Nucleus::createMul(lhs.value, rhs.value));
3427 }
John Bauman89401822014-05-06 15:04:28 -04003428 }
3429
John Bauman19bac1e2014-05-06 15:23:49 -04003430 RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003431 {
3432 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
3433
3434 return As<UShort4>(x86::psllw(As<Short4>(lhs), rhs));
3435 }
3436
John Bauman19bac1e2014-05-06 15:23:49 -04003437 RValue<UShort4> operator>>(RValue<UShort4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003438 {
3439 // return RValue<Short4>(Nucleus::createLShr(lhs.value, rhs.value));
3440
3441 return x86::psrlw(lhs, rhs);
3442 }
3443
John Bauman19bac1e2014-05-06 15:23:49 -04003444 RValue<UShort4> operator<<(RValue<UShort4> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04003445 {
3446 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
3447
3448 return As<UShort4>(x86::psllw(As<Short4>(lhs), rhs));
3449 }
3450
John Bauman19bac1e2014-05-06 15:23:49 -04003451 RValue<UShort4> operator>>(RValue<UShort4> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04003452 {
3453 // return RValue<Short4>(Nucleus::createLShr(lhs.value, rhs.value));
3454
3455 return x86::psrlw(lhs, rhs);
3456 }
3457
3458 RValue<UShort4> operator<<=(const UShort4 &lhs, unsigned char rhs)
3459 {
3460 return lhs = lhs << rhs;
3461 }
3462
3463 RValue<UShort4> operator>>=(const UShort4 &lhs, unsigned char rhs)
3464 {
3465 return lhs = lhs >> rhs;
3466 }
3467
John Bauman19bac1e2014-05-06 15:23:49 -04003468 RValue<UShort4> operator<<=(const UShort4 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04003469 {
3470 return lhs = lhs << rhs;
3471 }
3472
John Bauman19bac1e2014-05-06 15:23:49 -04003473 RValue<UShort4> operator>>=(const UShort4 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04003474 {
3475 return lhs = lhs >> rhs;
3476 }
3477
John Bauman19bac1e2014-05-06 15:23:49 -04003478 RValue<UShort4> operator~(RValue<UShort4> val)
John Bauman89401822014-05-06 15:04:28 -04003479 {
John Bauman19bac1e2014-05-06 15:23:49 -04003480 if(CPUID::supportsMMX2())
3481 {
3482 return As<UShort4>(As<Short4>(val) ^ Short4(0xFFFFu, 0xFFFFu, 0xFFFFu, 0xFFFFu));
3483 }
3484 else
3485 {
3486 return RValue<UShort4>(Nucleus::createNot(val.value));
3487 }
John Bauman89401822014-05-06 15:04:28 -04003488 }
3489
John Bauman19bac1e2014-05-06 15:23:49 -04003490 RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003491 {
John Bauman66b8ab22014-05-06 15:57:45 -04003492 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 -04003493 }
3494
John Bauman19bac1e2014-05-06 15:23:49 -04003495 RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003496 {
John Bauman66b8ab22014-05-06 15:57:45 -04003497 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 -04003498 }
3499
John Bauman19bac1e2014-05-06 15:23:49 -04003500 RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003501 {
3502 return x86::paddusw(x, y);
3503 }
3504
John Bauman19bac1e2014-05-06 15:23:49 -04003505 RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003506 {
3507 return x86::psubusw(x, y);
3508 }
3509
John Bauman19bac1e2014-05-06 15:23:49 -04003510 RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003511 {
3512 return x86::pmulhuw(x, y);
3513 }
3514
John Bauman19bac1e2014-05-06 15:23:49 -04003515 RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003516 {
3517 return x86::pavgw(x, y);
3518 }
3519
John Bauman19bac1e2014-05-06 15:23:49 -04003520 RValue<Byte8> Pack(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04003521 {
3522 return x86::packuswb(x, y);
3523 }
3524
John Bauman19bac1e2014-05-06 15:23:49 -04003525 Type *UShort4::getType()
John Bauman89401822014-05-06 15:04:28 -04003526 {
John Bauman19bac1e2014-05-06 15:23:49 -04003527 if(CPUID::supportsMMX2())
3528 {
3529 return MMX::getType();
3530 }
3531 else
3532 {
Nicolas Capensac230122016-09-20 14:30:06 -04003533 return T(VectorType::get(UShort::getType(), 4));
John Bauman19bac1e2014-05-06 15:23:49 -04003534 }
John Bauman89401822014-05-06 15:04:28 -04003535 }
3536
3537 Short8::Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7)
3538 {
3539 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003540
3541 Constant *constantVector[8];
3542 constantVector[0] = Nucleus::createConstantShort(c0);
3543 constantVector[1] = Nucleus::createConstantShort(c1);
3544 constantVector[2] = Nucleus::createConstantShort(c2);
3545 constantVector[3] = Nucleus::createConstantShort(c3);
3546 constantVector[4] = Nucleus::createConstantShort(c4);
3547 constantVector[5] = Nucleus::createConstantShort(c5);
3548 constantVector[6] = Nucleus::createConstantShort(c6);
3549 constantVector[7] = Nucleus::createConstantShort(c7);
3550
John Bauman66b8ab22014-05-06 15:57:45 -04003551 storeValue(Nucleus::createConstantVector(constantVector, 8));
John Bauman89401822014-05-06 15:04:28 -04003552 }
3553
John Bauman19bac1e2014-05-06 15:23:49 -04003554 Short8::Short8(RValue<Short8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003555 {
3556 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003557
John Bauman66b8ab22014-05-06 15:57:45 -04003558 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003559 }
3560
Nicolas Capensef8cd662016-06-30 15:34:40 -04003561 Short8::Short8(const Reference<Short8> &rhs)
3562 {
3563 // xyzw.parent = this;
3564
3565 Value *value = rhs.loadValue();
3566 storeValue(value);
3567 }
3568
Nicolas Capens62abb552016-01-05 12:03:47 -05003569 Short8::Short8(RValue<Short4> lo, RValue<Short4> hi)
3570 {
3571 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
3572 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
3573
3574 Value *long2 = UndefValue::get(Long2::getType());
3575 long2 = Nucleus::createInsertElement(long2, loLong, 0);
3576 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
3577 Value *short8 = Nucleus::createBitCast(long2, Short8::getType());
3578
3579 storeValue(short8);
3580 }
3581
John Bauman19bac1e2014-05-06 15:23:49 -04003582 RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003583 {
3584 return RValue<Short8>(Nucleus::createAdd(lhs.value, rhs.value));
3585 }
3586
John Bauman19bac1e2014-05-06 15:23:49 -04003587 RValue<Short8> operator&(RValue<Short8> lhs, RValue<Short8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003588 {
3589 return RValue<Short8>(Nucleus::createAnd(lhs.value, rhs.value));
3590 }
3591
John Bauman19bac1e2014-05-06 15:23:49 -04003592 RValue<Short8> operator<<(RValue<Short8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003593 {
3594 return x86::psllw(lhs, rhs); // FIXME: Fallback required
3595 }
3596
John Bauman19bac1e2014-05-06 15:23:49 -04003597 RValue<Short8> operator>>(RValue<Short8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003598 {
3599 return x86::psraw(lhs, rhs); // FIXME: Fallback required
3600 }
3601
John Bauman19bac1e2014-05-06 15:23:49 -04003602 RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04003603 {
3604 return x86::pmaddwd(x, y); // FIXME: Fallback required
3605 }
3606
Alexis Hetu0f448072016-03-18 10:56:08 -04003607 RValue<Int4> Abs(RValue<Int4> x)
3608 {
3609 if(CPUID::supportsSSSE3())
3610 {
3611 return x86::pabsd(x);
3612 }
3613 else
3614 {
3615 Int4 mask = (x >> 31);
3616 return (mask ^ x) - mask;
3617 }
3618 }
3619
John Bauman19bac1e2014-05-06 15:23:49 -04003620 RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04003621 {
3622 return x86::pmulhw(x, y); // FIXME: Fallback required
3623 }
3624
John Bauman19bac1e2014-05-06 15:23:49 -04003625 Type *Short8::getType()
John Bauman89401822014-05-06 15:04:28 -04003626 {
Nicolas Capensac230122016-09-20 14:30:06 -04003627 return T(VectorType::get(Short::getType(), 8));
John Bauman89401822014-05-06 15:04:28 -04003628 }
3629
3630 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)
3631 {
3632 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003633
3634 Constant *constantVector[8];
3635 constantVector[0] = Nucleus::createConstantShort(c0);
3636 constantVector[1] = Nucleus::createConstantShort(c1);
3637 constantVector[2] = Nucleus::createConstantShort(c2);
3638 constantVector[3] = Nucleus::createConstantShort(c3);
3639 constantVector[4] = Nucleus::createConstantShort(c4);
3640 constantVector[5] = Nucleus::createConstantShort(c5);
3641 constantVector[6] = Nucleus::createConstantShort(c6);
3642 constantVector[7] = Nucleus::createConstantShort(c7);
3643
John Bauman66b8ab22014-05-06 15:57:45 -04003644 storeValue(Nucleus::createConstantVector(constantVector, 8));
John Bauman89401822014-05-06 15:04:28 -04003645 }
3646
John Bauman19bac1e2014-05-06 15:23:49 -04003647 UShort8::UShort8(RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003648 {
3649 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003650
John Bauman66b8ab22014-05-06 15:57:45 -04003651 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003652 }
3653
Nicolas Capensef8cd662016-06-30 15:34:40 -04003654 UShort8::UShort8(const Reference<UShort8> &rhs)
3655 {
3656 // xyzw.parent = this;
3657
3658 Value *value = rhs.loadValue();
3659 storeValue(value);
3660 }
3661
Nicolas Capens62abb552016-01-05 12:03:47 -05003662 UShort8::UShort8(RValue<UShort4> lo, RValue<UShort4> hi)
3663 {
3664 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
3665 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
3666
3667 Value *long2 = UndefValue::get(Long2::getType());
3668 long2 = Nucleus::createInsertElement(long2, loLong, 0);
3669 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
3670 Value *short8 = Nucleus::createBitCast(long2, Short8::getType());
3671
3672 storeValue(short8);
3673 }
3674
John Bauman19bac1e2014-05-06 15:23:49 -04003675 RValue<UShort8> UShort8::operator=(RValue<UShort8> rhs) const
John Bauman89401822014-05-06 15:04:28 -04003676 {
John Bauman66b8ab22014-05-06 15:57:45 -04003677 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003678
3679 return rhs;
3680 }
3681
3682 RValue<UShort8> UShort8::operator=(const UShort8 &rhs) const
3683 {
John Bauman66b8ab22014-05-06 15:57:45 -04003684 Value *value = rhs.loadValue();
3685 storeValue(value);
3686
3687 return RValue<UShort8>(value);
3688 }
3689
3690 RValue<UShort8> UShort8::operator=(const Reference<UShort8> &rhs) const
3691 {
3692 Value *value = rhs.loadValue();
3693 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003694
3695 return RValue<UShort8>(value);
3696 }
3697
John Bauman19bac1e2014-05-06 15:23:49 -04003698 RValue<UShort8> operator&(RValue<UShort8> lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003699 {
3700 return RValue<UShort8>(Nucleus::createAnd(lhs.value, rhs.value));
3701 }
3702
John Bauman19bac1e2014-05-06 15:23:49 -04003703 RValue<UShort8> operator<<(RValue<UShort8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003704 {
3705 return As<UShort8>(x86::psllw(As<Short8>(lhs), rhs)); // FIXME: Fallback required
3706 }
3707
John Bauman19bac1e2014-05-06 15:23:49 -04003708 RValue<UShort8> operator>>(RValue<UShort8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04003709 {
3710 return x86::psrlw(lhs, rhs); // FIXME: Fallback required
3711 }
3712
John Bauman19bac1e2014-05-06 15:23:49 -04003713 RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003714 {
3715 return RValue<UShort8>(Nucleus::createAdd(lhs.value, rhs.value));
3716 }
3717
John Bauman19bac1e2014-05-06 15:23:49 -04003718 RValue<UShort8> operator*(RValue<UShort8> lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003719 {
3720 return RValue<UShort8>(Nucleus::createMul(lhs.value, rhs.value));
3721 }
3722
John Bauman19bac1e2014-05-06 15:23:49 -04003723 RValue<UShort8> operator+=(const UShort8 &lhs, RValue<UShort8> rhs)
John Bauman89401822014-05-06 15:04:28 -04003724 {
3725 return lhs = lhs + rhs;
3726 }
3727
John Bauman19bac1e2014-05-06 15:23:49 -04003728 RValue<UShort8> operator~(RValue<UShort8> val)
John Bauman89401822014-05-06 15:04:28 -04003729 {
3730 return RValue<UShort8>(Nucleus::createNot(val.value));
3731 }
3732
John Bauman19bac1e2014-05-06 15:23:49 -04003733 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 -04003734 {
3735 Constant *pshufb[16];
3736 pshufb[0] = Nucleus::createConstantInt(select0 + 0);
3737 pshufb[1] = Nucleus::createConstantInt(select0 + 1);
3738 pshufb[2] = Nucleus::createConstantInt(select1 + 0);
3739 pshufb[3] = Nucleus::createConstantInt(select1 + 1);
3740 pshufb[4] = Nucleus::createConstantInt(select2 + 0);
3741 pshufb[5] = Nucleus::createConstantInt(select2 + 1);
3742 pshufb[6] = Nucleus::createConstantInt(select3 + 0);
3743 pshufb[7] = Nucleus::createConstantInt(select3 + 1);
3744 pshufb[8] = Nucleus::createConstantInt(select4 + 0);
3745 pshufb[9] = Nucleus::createConstantInt(select4 + 1);
3746 pshufb[10] = Nucleus::createConstantInt(select5 + 0);
3747 pshufb[11] = Nucleus::createConstantInt(select5 + 1);
3748 pshufb[12] = Nucleus::createConstantInt(select6 + 0);
3749 pshufb[13] = Nucleus::createConstantInt(select6 + 1);
3750 pshufb[14] = Nucleus::createConstantInt(select7 + 0);
3751 pshufb[15] = Nucleus::createConstantInt(select7 + 1);
3752
3753 Value *byte16 = Nucleus::createBitCast(x.value, Byte16::getType());
3754 Value *shuffle = Nucleus::createShuffleVector(byte16, UndefValue::get(Byte16::getType()), Nucleus::createConstantVector(pshufb, 16));
3755 Value *short8 = Nucleus::createBitCast(shuffle, UShort8::getType());
3756
3757 return RValue<UShort8>(short8);
3758 }
3759
John Bauman19bac1e2014-05-06 15:23:49 -04003760 RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y)
John Bauman89401822014-05-06 15:04:28 -04003761 {
3762 return x86::pmulhuw(x, y); // FIXME: Fallback required
3763 }
3764
3765 // FIXME: Implement as Shuffle(x, y, Select(i0, ..., i16)) and Shuffle(x, y, SELECT_PACK_REPEAT(element))
John Bauman19bac1e2014-05-06 15:23:49 -04003766// RValue<UShort8> PackRepeat(RValue<Byte16> x, RValue<Byte16> y, int element)
John Bauman89401822014-05-06 15:04:28 -04003767// {
3768// Constant *pshufb[16];
3769// pshufb[0] = Nucleus::createConstantInt(element + 0);
3770// pshufb[1] = Nucleus::createConstantInt(element + 0);
3771// pshufb[2] = Nucleus::createConstantInt(element + 4);
3772// pshufb[3] = Nucleus::createConstantInt(element + 4);
3773// pshufb[4] = Nucleus::createConstantInt(element + 8);
3774// pshufb[5] = Nucleus::createConstantInt(element + 8);
3775// pshufb[6] = Nucleus::createConstantInt(element + 12);
3776// pshufb[7] = Nucleus::createConstantInt(element + 12);
3777// pshufb[8] = Nucleus::createConstantInt(element + 16);
3778// pshufb[9] = Nucleus::createConstantInt(element + 16);
3779// pshufb[10] = Nucleus::createConstantInt(element + 20);
3780// pshufb[11] = Nucleus::createConstantInt(element + 20);
3781// pshufb[12] = Nucleus::createConstantInt(element + 24);
3782// pshufb[13] = Nucleus::createConstantInt(element + 24);
3783// pshufb[14] = Nucleus::createConstantInt(element + 28);
3784// pshufb[15] = Nucleus::createConstantInt(element + 28);
3785//
3786// Value *shuffle = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(pshufb, 16));
3787// Value *short8 = Nucleus::createBitCast(shuffle, UShort8::getType());
3788//
3789// return RValue<UShort8>(short8);
3790// }
3791
John Bauman19bac1e2014-05-06 15:23:49 -04003792 Type *UShort8::getType()
John Bauman89401822014-05-06 15:04:28 -04003793 {
Nicolas Capensac230122016-09-20 14:30:06 -04003794 return T(VectorType::get(UShort::getType(), 8));
John Bauman89401822014-05-06 15:04:28 -04003795 }
3796
Nicolas Capens81f18302016-01-14 09:32:35 -05003797 Int::Int(Argument<Int> argument)
John Bauman89401822014-05-06 15:04:28 -04003798 {
Nicolas Capens81f18302016-01-14 09:32:35 -05003799 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04003800 }
3801
John Bauman19bac1e2014-05-06 15:23:49 -04003802 Int::Int(RValue<Byte> cast)
John Bauman89401822014-05-06 15:04:28 -04003803 {
John Bauman89401822014-05-06 15:04:28 -04003804 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3805
John Bauman66b8ab22014-05-06 15:57:45 -04003806 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003807 }
3808
John Bauman19bac1e2014-05-06 15:23:49 -04003809 Int::Int(RValue<SByte> cast)
John Bauman89401822014-05-06 15:04:28 -04003810 {
John Bauman89401822014-05-06 15:04:28 -04003811 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3812
John Bauman66b8ab22014-05-06 15:57:45 -04003813 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003814 }
3815
John Bauman19bac1e2014-05-06 15:23:49 -04003816 Int::Int(RValue<Short> cast)
John Bauman89401822014-05-06 15:04:28 -04003817 {
John Bauman89401822014-05-06 15:04:28 -04003818 Value *integer = Nucleus::createSExt(cast.value, Int::getType());
3819
John Bauman66b8ab22014-05-06 15:57:45 -04003820 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003821 }
3822
John Bauman19bac1e2014-05-06 15:23:49 -04003823 Int::Int(RValue<UShort> cast)
John Bauman89401822014-05-06 15:04:28 -04003824 {
John Bauman89401822014-05-06 15:04:28 -04003825 Value *integer = Nucleus::createZExt(cast.value, Int::getType());
3826
John Bauman66b8ab22014-05-06 15:57:45 -04003827 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003828 }
3829
John Bauman19bac1e2014-05-06 15:23:49 -04003830 Int::Int(RValue<Int2> cast)
John Bauman89401822014-05-06 15:04:28 -04003831 {
John Bauman89401822014-05-06 15:04:28 -04003832 *this = Extract(cast, 0);
3833 }
3834
John Bauman19bac1e2014-05-06 15:23:49 -04003835 Int::Int(RValue<Long> cast)
John Bauman89401822014-05-06 15:04:28 -04003836 {
John Bauman89401822014-05-06 15:04:28 -04003837 Value *integer = Nucleus::createTrunc(cast.value, Int::getType());
3838
John Bauman66b8ab22014-05-06 15:57:45 -04003839 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003840 }
3841
John Bauman19bac1e2014-05-06 15:23:49 -04003842 Int::Int(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04003843 {
John Bauman89401822014-05-06 15:04:28 -04003844 Value *integer = Nucleus::createFPToSI(cast.value, Int::getType());
3845
John Bauman66b8ab22014-05-06 15:57:45 -04003846 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04003847 }
3848
3849 Int::Int()
3850 {
John Bauman89401822014-05-06 15:04:28 -04003851 }
3852
3853 Int::Int(int x)
3854 {
John Bauman66b8ab22014-05-06 15:57:45 -04003855 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04003856 }
3857
John Bauman19bac1e2014-05-06 15:23:49 -04003858 Int::Int(RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003859 {
John Bauman66b8ab22014-05-06 15:57:45 -04003860 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003861 }
3862
John Bauman19bac1e2014-05-06 15:23:49 -04003863 Int::Int(RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04003864 {
John Bauman66b8ab22014-05-06 15:57:45 -04003865 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003866 }
3867
3868 Int::Int(const Int &rhs)
3869 {
John Bauman66b8ab22014-05-06 15:57:45 -04003870 Value *value = rhs.loadValue();
3871 storeValue(value);
3872 }
John Bauman89401822014-05-06 15:04:28 -04003873
John Bauman66b8ab22014-05-06 15:57:45 -04003874 Int::Int(const Reference<Int> &rhs)
3875 {
3876 Value *value = rhs.loadValue();
3877 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003878 }
3879
3880 Int::Int(const UInt &rhs)
3881 {
John Bauman66b8ab22014-05-06 15:57:45 -04003882 Value *value = rhs.loadValue();
3883 storeValue(value);
3884 }
John Bauman89401822014-05-06 15:04:28 -04003885
John Bauman66b8ab22014-05-06 15:57:45 -04003886 Int::Int(const Reference<UInt> &rhs)
3887 {
3888 Value *value = rhs.loadValue();
3889 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003890 }
3891
3892 RValue<Int> Int::operator=(int rhs) const
3893 {
John Bauman66b8ab22014-05-06 15:57:45 -04003894 return RValue<Int>(storeValue(Nucleus::createConstantInt(rhs)));
John Bauman89401822014-05-06 15:04:28 -04003895 }
3896
John Bauman19bac1e2014-05-06 15:23:49 -04003897 RValue<Int> Int::operator=(RValue<Int> rhs) const
John Bauman89401822014-05-06 15:04:28 -04003898 {
John Bauman66b8ab22014-05-06 15:57:45 -04003899 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003900
3901 return rhs;
3902 }
3903
John Bauman19bac1e2014-05-06 15:23:49 -04003904 RValue<Int> Int::operator=(RValue<UInt> rhs) const
John Bauman89401822014-05-06 15:04:28 -04003905 {
John Bauman66b8ab22014-05-06 15:57:45 -04003906 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003907
John Bauman66b8ab22014-05-06 15:57:45 -04003908 return RValue<Int>(rhs);
John Bauman89401822014-05-06 15:04:28 -04003909 }
3910
3911 RValue<Int> Int::operator=(const Int &rhs) const
3912 {
John Bauman66b8ab22014-05-06 15:57:45 -04003913 Value *value = rhs.loadValue();
3914 storeValue(value);
3915
3916 return RValue<Int>(value);
3917 }
3918
3919 RValue<Int> Int::operator=(const Reference<Int> &rhs) const
3920 {
3921 Value *value = rhs.loadValue();
3922 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003923
3924 return RValue<Int>(value);
3925 }
3926
3927 RValue<Int> Int::operator=(const UInt &rhs) const
3928 {
John Bauman66b8ab22014-05-06 15:57:45 -04003929 Value *value = rhs.loadValue();
3930 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003931
3932 return RValue<Int>(value);
3933 }
3934
John Bauman66b8ab22014-05-06 15:57:45 -04003935 RValue<Int> Int::operator=(const Reference<UInt> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04003936 {
John Bauman66b8ab22014-05-06 15:57:45 -04003937 Value *value = rhs.loadValue();
3938 storeValue(value);
3939
3940 return RValue<Int>(value);
John Bauman89401822014-05-06 15:04:28 -04003941 }
3942
John Bauman19bac1e2014-05-06 15:23:49 -04003943 RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003944 {
3945 return RValue<Int>(Nucleus::createAdd(lhs.value, rhs.value));
3946 }
3947
John Bauman19bac1e2014-05-06 15:23:49 -04003948 RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003949 {
3950 return RValue<Int>(Nucleus::createSub(lhs.value, rhs.value));
3951 }
3952
John Bauman19bac1e2014-05-06 15:23:49 -04003953 RValue<Int> operator*(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003954 {
3955 return RValue<Int>(Nucleus::createMul(lhs.value, rhs.value));
3956 }
3957
John Bauman19bac1e2014-05-06 15:23:49 -04003958 RValue<Int> operator/(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003959 {
3960 return RValue<Int>(Nucleus::createSDiv(lhs.value, rhs.value));
3961 }
3962
John Bauman19bac1e2014-05-06 15:23:49 -04003963 RValue<Int> operator%(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003964 {
3965 return RValue<Int>(Nucleus::createSRem(lhs.value, rhs.value));
3966 }
3967
John Bauman19bac1e2014-05-06 15:23:49 -04003968 RValue<Int> operator&(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003969 {
3970 return RValue<Int>(Nucleus::createAnd(lhs.value, rhs.value));
3971 }
3972
John Bauman19bac1e2014-05-06 15:23:49 -04003973 RValue<Int> operator|(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003974 {
3975 return RValue<Int>(Nucleus::createOr(lhs.value, rhs.value));
3976 }
3977
John Bauman19bac1e2014-05-06 15:23:49 -04003978 RValue<Int> operator^(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003979 {
3980 return RValue<Int>(Nucleus::createXor(lhs.value, rhs.value));
3981 }
3982
John Bauman19bac1e2014-05-06 15:23:49 -04003983 RValue<Int> operator<<(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003984 {
3985 return RValue<Int>(Nucleus::createShl(lhs.value, rhs.value));
3986 }
3987
John Bauman19bac1e2014-05-06 15:23:49 -04003988 RValue<Int> operator>>(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003989 {
3990 return RValue<Int>(Nucleus::createAShr(lhs.value, rhs.value));
3991 }
3992
John Bauman19bac1e2014-05-06 15:23:49 -04003993 RValue<Int> operator+=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003994 {
3995 return lhs = lhs + rhs;
3996 }
3997
John Bauman19bac1e2014-05-06 15:23:49 -04003998 RValue<Int> operator-=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04003999 {
4000 return lhs = lhs - rhs;
4001 }
4002
John Bauman19bac1e2014-05-06 15:23:49 -04004003 RValue<Int> operator*=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004004 {
4005 return lhs = lhs * rhs;
4006 }
4007
John Bauman19bac1e2014-05-06 15:23:49 -04004008 RValue<Int> operator/=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004009 {
4010 return lhs = lhs / rhs;
4011 }
4012
John Bauman19bac1e2014-05-06 15:23:49 -04004013 RValue<Int> operator%=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004014 {
4015 return lhs = lhs % rhs;
4016 }
4017
John Bauman19bac1e2014-05-06 15:23:49 -04004018 RValue<Int> operator&=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004019 {
4020 return lhs = lhs & rhs;
4021 }
4022
John Bauman19bac1e2014-05-06 15:23:49 -04004023 RValue<Int> operator|=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004024 {
4025 return lhs = lhs | rhs;
4026 }
4027
John Bauman19bac1e2014-05-06 15:23:49 -04004028 RValue<Int> operator^=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004029 {
4030 return lhs = lhs ^ rhs;
4031 }
4032
John Bauman19bac1e2014-05-06 15:23:49 -04004033 RValue<Int> operator<<=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004034 {
4035 return lhs = lhs << rhs;
4036 }
4037
John Bauman19bac1e2014-05-06 15:23:49 -04004038 RValue<Int> operator>>=(const Int &lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004039 {
4040 return lhs = lhs >> rhs;
4041 }
4042
John Bauman19bac1e2014-05-06 15:23:49 -04004043 RValue<Int> operator+(RValue<Int> val)
John Bauman89401822014-05-06 15:04:28 -04004044 {
4045 return val;
4046 }
4047
John Bauman19bac1e2014-05-06 15:23:49 -04004048 RValue<Int> operator-(RValue<Int> val)
John Bauman89401822014-05-06 15:04:28 -04004049 {
4050 return RValue<Int>(Nucleus::createNeg(val.value));
4051 }
4052
John Bauman19bac1e2014-05-06 15:23:49 -04004053 RValue<Int> operator~(RValue<Int> val)
John Bauman89401822014-05-06 15:04:28 -04004054 {
4055 return RValue<Int>(Nucleus::createNot(val.value));
4056 }
4057
4058 RValue<Int> operator++(const Int &val, int) // Post-increment
4059 {
4060 RValue<Int> res = val;
4061
4062 Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantInt(1));
John Bauman66b8ab22014-05-06 15:57:45 -04004063 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004064
4065 return res;
4066 }
4067
4068 const Int &operator++(const Int &val) // Pre-increment
4069 {
John Bauman66b8ab22014-05-06 15:57:45 -04004070 Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantInt(1));
4071 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004072
4073 return val;
4074 }
4075
4076 RValue<Int> operator--(const Int &val, int) // Post-decrement
4077 {
4078 RValue<Int> res = val;
4079
4080 Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantInt(1));
John Bauman66b8ab22014-05-06 15:57:45 -04004081 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004082
4083 return res;
4084 }
4085
4086 const Int &operator--(const Int &val) // Pre-decrement
4087 {
John Bauman66b8ab22014-05-06 15:57:45 -04004088 Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantInt(1));
4089 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004090
4091 return val;
4092 }
4093
John Bauman19bac1e2014-05-06 15:23:49 -04004094 RValue<Bool> operator<(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004095 {
4096 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
4097 }
4098
John Bauman19bac1e2014-05-06 15:23:49 -04004099 RValue<Bool> operator<=(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004100 {
4101 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
4102 }
4103
John Bauman19bac1e2014-05-06 15:23:49 -04004104 RValue<Bool> operator>(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004105 {
4106 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
4107 }
4108
John Bauman19bac1e2014-05-06 15:23:49 -04004109 RValue<Bool> operator>=(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004110 {
4111 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
4112 }
4113
John Bauman19bac1e2014-05-06 15:23:49 -04004114 RValue<Bool> operator!=(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004115 {
4116 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
4117 }
4118
John Bauman19bac1e2014-05-06 15:23:49 -04004119 RValue<Bool> operator==(RValue<Int> lhs, RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004120 {
4121 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
4122 }
4123
John Bauman19bac1e2014-05-06 15:23:49 -04004124 RValue<Int> Max(RValue<Int> x, RValue<Int> y)
4125 {
4126 return IfThenElse(x > y, x, y);
4127 }
4128
4129 RValue<Int> Min(RValue<Int> x, RValue<Int> y)
4130 {
4131 return IfThenElse(x < y, x, y);
4132 }
4133
4134 RValue<Int> Clamp(RValue<Int> x, RValue<Int> min, RValue<Int> max)
4135 {
4136 return Min(Max(x, min), max);
4137 }
4138
4139 RValue<Int> RoundInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04004140 {
4141 return x86::cvtss2si(cast);
4142
John Bauman66b8ab22014-05-06 15:57:45 -04004143 // return IfThenElse(val > 0.0f, Int(val + 0.5f), Int(val - 0.5f));
John Bauman89401822014-05-06 15:04:28 -04004144 }
4145
John Bauman19bac1e2014-05-06 15:23:49 -04004146 Type *Int::getType()
John Bauman89401822014-05-06 15:04:28 -04004147 {
Nicolas Capensac230122016-09-20 14:30:06 -04004148 return T(llvm::Type::getInt32Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04004149 }
4150
John Bauman19bac1e2014-05-06 15:23:49 -04004151 Long::Long(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04004152 {
John Bauman89401822014-05-06 15:04:28 -04004153 Value *integer = Nucleus::createSExt(cast.value, Long::getType());
4154
John Bauman66b8ab22014-05-06 15:57:45 -04004155 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04004156 }
4157
John Bauman19bac1e2014-05-06 15:23:49 -04004158 Long::Long(RValue<UInt> cast)
John Bauman89401822014-05-06 15:04:28 -04004159 {
John Bauman89401822014-05-06 15:04:28 -04004160 Value *integer = Nucleus::createZExt(cast.value, Long::getType());
4161
John Bauman66b8ab22014-05-06 15:57:45 -04004162 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04004163 }
4164
4165 Long::Long()
4166 {
John Bauman89401822014-05-06 15:04:28 -04004167 }
4168
John Bauman19bac1e2014-05-06 15:23:49 -04004169 Long::Long(RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04004170 {
John Bauman66b8ab22014-05-06 15:57:45 -04004171 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004172 }
4173
4174 RValue<Long> Long::operator=(int64_t rhs) const
4175 {
John Bauman66b8ab22014-05-06 15:57:45 -04004176 return RValue<Long>(storeValue(Nucleus::createConstantInt(rhs)));
John Bauman89401822014-05-06 15:04:28 -04004177 }
4178
John Bauman19bac1e2014-05-06 15:23:49 -04004179 RValue<Long> Long::operator=(RValue<Long> rhs) const
John Bauman89401822014-05-06 15:04:28 -04004180 {
John Bauman66b8ab22014-05-06 15:57:45 -04004181 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004182
4183 return rhs;
4184 }
4185
4186 RValue<Long> Long::operator=(const Long &rhs) const
4187 {
John Bauman66b8ab22014-05-06 15:57:45 -04004188 Value *value = rhs.loadValue();
4189 storeValue(value);
4190
4191 return RValue<Long>(value);
4192 }
4193
4194 RValue<Long> Long::operator=(const Reference<Long> &rhs) const
4195 {
4196 Value *value = rhs.loadValue();
4197 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004198
4199 return RValue<Long>(value);
4200 }
4201
John Bauman19bac1e2014-05-06 15:23:49 -04004202 RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04004203 {
4204 return RValue<Long>(Nucleus::createAdd(lhs.value, rhs.value));
4205 }
4206
John Bauman19bac1e2014-05-06 15:23:49 -04004207 RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04004208 {
4209 return RValue<Long>(Nucleus::createSub(lhs.value, rhs.value));
4210 }
4211
John Bauman19bac1e2014-05-06 15:23:49 -04004212 RValue<Long> operator+=(const Long &lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04004213 {
4214 return lhs = lhs + rhs;
4215 }
4216
John Bauman19bac1e2014-05-06 15:23:49 -04004217 RValue<Long> operator-=(const Long &lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04004218 {
4219 return lhs = lhs - rhs;
4220 }
4221
John Bauman66b8ab22014-05-06 15:57:45 -04004222 RValue<Long> AddAtomic(RValue<Pointer<Long> > x, RValue<Long> y)
John Bauman89401822014-05-06 15:04:28 -04004223 {
John Bauman19bac1e2014-05-06 15:23:49 -04004224 return RValue<Long>(Nucleus::createAtomicAdd(x.value, y.value));
John Bauman89401822014-05-06 15:04:28 -04004225 }
4226
John Bauman19bac1e2014-05-06 15:23:49 -04004227 Type *Long::getType()
John Bauman89401822014-05-06 15:04:28 -04004228 {
Nicolas Capensac230122016-09-20 14:30:06 -04004229 return T(llvm::Type::getInt64Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04004230 }
4231
Nicolas Capens50c96362016-01-04 23:03:59 -05004232 Long1::Long1(const RValue<UInt> cast)
John Bauman89401822014-05-06 15:04:28 -04004233 {
Nicolas Capens50c96362016-01-04 23:03:59 -05004234 Value *undefCast = Nucleus::createInsertElement(UndefValue::get(VectorType::get(Int::getType(), 2)), cast.value, 0);
4235 Value *zeroCast = Nucleus::createInsertElement(undefCast, Nucleus::createConstantInt(0), 1);
John Bauman66b8ab22014-05-06 15:57:45 -04004236
Nicolas Capens50c96362016-01-04 23:03:59 -05004237 storeValue(Nucleus::createBitCast(zeroCast, Long1::getType()));
John Bauman89401822014-05-06 15:04:28 -04004238 }
4239
John Bauman19bac1e2014-05-06 15:23:49 -04004240 Long1::Long1(RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004241 {
John Bauman66b8ab22014-05-06 15:57:45 -04004242 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004243 }
4244
John Bauman19bac1e2014-05-06 15:23:49 -04004245 Type *Long1::getType()
John Bauman89401822014-05-06 15:04:28 -04004246 {
John Bauman19bac1e2014-05-06 15:23:49 -04004247 if(CPUID::supportsMMX2())
4248 {
4249 return MMX::getType();
4250 }
4251 else
4252 {
Nicolas Capensac230122016-09-20 14:30:06 -04004253 return T(VectorType::get(Long::getType(), 1));
John Bauman19bac1e2014-05-06 15:23:49 -04004254 }
John Bauman89401822014-05-06 15:04:28 -04004255 }
4256
John Bauman19bac1e2014-05-06 15:23:49 -04004257 RValue<Long2> UnpackHigh(RValue<Long2> x, RValue<Long2> y)
John Bauman89401822014-05-06 15:04:28 -04004258 {
4259 Constant *shuffle[2];
4260 shuffle[0] = Nucleus::createConstantInt(1);
4261 shuffle[1] = Nucleus::createConstantInt(3);
4262
4263 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 2));
4264
4265 return RValue<Long2>(packed);
4266 }
4267
John Bauman19bac1e2014-05-06 15:23:49 -04004268 Type *Long2::getType()
John Bauman89401822014-05-06 15:04:28 -04004269 {
Nicolas Capensac230122016-09-20 14:30:06 -04004270 return T(VectorType::get(Long::getType(), 2));
John Bauman89401822014-05-06 15:04:28 -04004271 }
4272
Nicolas Capens81f18302016-01-14 09:32:35 -05004273 UInt::UInt(Argument<UInt> argument)
John Bauman89401822014-05-06 15:04:28 -04004274 {
Nicolas Capens81f18302016-01-14 09:32:35 -05004275 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04004276 }
4277
John Bauman19bac1e2014-05-06 15:23:49 -04004278 UInt::UInt(RValue<UShort> cast)
John Bauman89401822014-05-06 15:04:28 -04004279 {
John Bauman89401822014-05-06 15:04:28 -04004280 Value *integer = Nucleus::createZExt(cast.value, UInt::getType());
4281
John Bauman66b8ab22014-05-06 15:57:45 -04004282 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04004283 }
4284
John Bauman19bac1e2014-05-06 15:23:49 -04004285 UInt::UInt(RValue<Long> cast)
John Bauman89401822014-05-06 15:04:28 -04004286 {
John Bauman89401822014-05-06 15:04:28 -04004287 Value *integer = Nucleus::createTrunc(cast.value, UInt::getType());
4288
John Bauman66b8ab22014-05-06 15:57:45 -04004289 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04004290 }
4291
John Bauman19bac1e2014-05-06 15:23:49 -04004292 UInt::UInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04004293 {
Alexis Hetu764d1422016-09-28 08:44:22 -04004294 // Note: createFPToUI is broken, must perform conversion using createFPtoSI
4295 // Value *integer = Nucleus::createFPToUI(cast.value, UInt::getType());
John Bauman89401822014-05-06 15:04:28 -04004296
Alexis Hetu764d1422016-09-28 08:44:22 -04004297 // Smallest positive value representable in UInt, but not in Int
4298 const unsigned int ustart = 0x80000000u;
4299 const float ustartf = float(ustart);
4300
4301 // If the value is negative, store 0, otherwise store the result of the conversion
4302 storeValue((~(As<Int>(cast) >> 31) &
4303 // Check if the value can be represented as an Int
4304 IfThenElse(cast >= ustartf,
4305 // If the value is too large, subtract ustart and re-add it after conversion.
4306 As<Int>(As<UInt>(Int(cast - Float(ustartf))) + UInt(ustart)),
4307 // Otherwise, just convert normally
4308 Int(cast))).value);
John Bauman89401822014-05-06 15:04:28 -04004309 }
4310
4311 UInt::UInt()
4312 {
John Bauman89401822014-05-06 15:04:28 -04004313 }
4314
4315 UInt::UInt(int x)
4316 {
John Bauman66b8ab22014-05-06 15:57:45 -04004317 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04004318 }
4319
4320 UInt::UInt(unsigned int x)
4321 {
John Bauman66b8ab22014-05-06 15:57:45 -04004322 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04004323 }
4324
John Bauman19bac1e2014-05-06 15:23:49 -04004325 UInt::UInt(RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004326 {
John Bauman66b8ab22014-05-06 15:57:45 -04004327 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004328 }
4329
John Bauman19bac1e2014-05-06 15:23:49 -04004330 UInt::UInt(RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004331 {
John Bauman66b8ab22014-05-06 15:57:45 -04004332 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004333 }
4334
4335 UInt::UInt(const UInt &rhs)
4336 {
John Bauman66b8ab22014-05-06 15:57:45 -04004337 Value *value = rhs.loadValue();
4338 storeValue(value);
4339 }
John Bauman89401822014-05-06 15:04:28 -04004340
John Bauman66b8ab22014-05-06 15:57:45 -04004341 UInt::UInt(const Reference<UInt> &rhs)
4342 {
4343 Value *value = rhs.loadValue();
4344 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004345 }
4346
4347 UInt::UInt(const Int &rhs)
4348 {
John Bauman66b8ab22014-05-06 15:57:45 -04004349 Value *value = rhs.loadValue();
4350 storeValue(value);
4351 }
John Bauman89401822014-05-06 15:04:28 -04004352
John Bauman66b8ab22014-05-06 15:57:45 -04004353 UInt::UInt(const Reference<Int> &rhs)
4354 {
4355 Value *value = rhs.loadValue();
4356 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004357 }
4358
4359 RValue<UInt> UInt::operator=(unsigned int rhs) const
4360 {
John Bauman66b8ab22014-05-06 15:57:45 -04004361 return RValue<UInt>(storeValue(Nucleus::createConstantInt(rhs)));
John Bauman89401822014-05-06 15:04:28 -04004362 }
4363
John Bauman19bac1e2014-05-06 15:23:49 -04004364 RValue<UInt> UInt::operator=(RValue<UInt> rhs) const
John Bauman89401822014-05-06 15:04:28 -04004365 {
John Bauman66b8ab22014-05-06 15:57:45 -04004366 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004367
4368 return rhs;
4369 }
4370
John Bauman19bac1e2014-05-06 15:23:49 -04004371 RValue<UInt> UInt::operator=(RValue<Int> rhs) const
John Bauman89401822014-05-06 15:04:28 -04004372 {
John Bauman66b8ab22014-05-06 15:57:45 -04004373 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004374
John Bauman66b8ab22014-05-06 15:57:45 -04004375 return RValue<UInt>(rhs);
John Bauman89401822014-05-06 15:04:28 -04004376 }
4377
4378 RValue<UInt> UInt::operator=(const UInt &rhs) const
4379 {
John Bauman66b8ab22014-05-06 15:57:45 -04004380 Value *value = rhs.loadValue();
4381 storeValue(value);
4382
4383 return RValue<UInt>(value);
4384 }
4385
4386 RValue<UInt> UInt::operator=(const Reference<UInt> &rhs) const
4387 {
4388 Value *value = rhs.loadValue();
4389 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004390
4391 return RValue<UInt>(value);
4392 }
4393
4394 RValue<UInt> UInt::operator=(const Int &rhs) const
4395 {
John Bauman66b8ab22014-05-06 15:57:45 -04004396 Value *value = rhs.loadValue();
4397 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004398
4399 return RValue<UInt>(value);
4400 }
4401
John Bauman66b8ab22014-05-06 15:57:45 -04004402 RValue<UInt> UInt::operator=(const Reference<Int> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04004403 {
John Bauman66b8ab22014-05-06 15:57:45 -04004404 Value *value = rhs.loadValue();
4405 storeValue(value);
4406
4407 return RValue<UInt>(value);
John Bauman89401822014-05-06 15:04:28 -04004408 }
4409
John Bauman19bac1e2014-05-06 15:23:49 -04004410 RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004411 {
4412 return RValue<UInt>(Nucleus::createAdd(lhs.value, rhs.value));
4413 }
4414
John Bauman19bac1e2014-05-06 15:23:49 -04004415 RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004416 {
4417 return RValue<UInt>(Nucleus::createSub(lhs.value, rhs.value));
4418 }
4419
John Bauman19bac1e2014-05-06 15:23:49 -04004420 RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004421 {
4422 return RValue<UInt>(Nucleus::createMul(lhs.value, rhs.value));
4423 }
4424
John Bauman19bac1e2014-05-06 15:23:49 -04004425 RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004426 {
4427 return RValue<UInt>(Nucleus::createUDiv(lhs.value, rhs.value));
4428 }
4429
John Bauman19bac1e2014-05-06 15:23:49 -04004430 RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004431 {
4432 return RValue<UInt>(Nucleus::createURem(lhs.value, rhs.value));
4433 }
4434
John Bauman19bac1e2014-05-06 15:23:49 -04004435 RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004436 {
4437 return RValue<UInt>(Nucleus::createAnd(lhs.value, rhs.value));
4438 }
4439
John Bauman19bac1e2014-05-06 15:23:49 -04004440 RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004441 {
4442 return RValue<UInt>(Nucleus::createOr(lhs.value, rhs.value));
4443 }
4444
John Bauman19bac1e2014-05-06 15:23:49 -04004445 RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004446 {
4447 return RValue<UInt>(Nucleus::createXor(lhs.value, rhs.value));
4448 }
4449
John Bauman19bac1e2014-05-06 15:23:49 -04004450 RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004451 {
4452 return RValue<UInt>(Nucleus::createShl(lhs.value, rhs.value));
4453 }
4454
John Bauman19bac1e2014-05-06 15:23:49 -04004455 RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004456 {
4457 return RValue<UInt>(Nucleus::createLShr(lhs.value, rhs.value));
4458 }
4459
John Bauman19bac1e2014-05-06 15:23:49 -04004460 RValue<UInt> operator+=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004461 {
4462 return lhs = lhs + rhs;
4463 }
4464
John Bauman19bac1e2014-05-06 15:23:49 -04004465 RValue<UInt> operator-=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004466 {
4467 return lhs = lhs - rhs;
4468 }
4469
John Bauman19bac1e2014-05-06 15:23:49 -04004470 RValue<UInt> operator*=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004471 {
4472 return lhs = lhs * rhs;
4473 }
4474
John Bauman19bac1e2014-05-06 15:23:49 -04004475 RValue<UInt> operator/=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004476 {
4477 return lhs = lhs / rhs;
4478 }
4479
John Bauman19bac1e2014-05-06 15:23:49 -04004480 RValue<UInt> operator%=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004481 {
4482 return lhs = lhs % rhs;
4483 }
4484
John Bauman19bac1e2014-05-06 15:23:49 -04004485 RValue<UInt> operator&=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004486 {
4487 return lhs = lhs & rhs;
4488 }
4489
John Bauman19bac1e2014-05-06 15:23:49 -04004490 RValue<UInt> operator|=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004491 {
4492 return lhs = lhs | rhs;
4493 }
4494
John Bauman19bac1e2014-05-06 15:23:49 -04004495 RValue<UInt> operator^=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004496 {
4497 return lhs = lhs ^ rhs;
4498 }
4499
John Bauman19bac1e2014-05-06 15:23:49 -04004500 RValue<UInt> operator<<=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004501 {
4502 return lhs = lhs << rhs;
4503 }
4504
John Bauman19bac1e2014-05-06 15:23:49 -04004505 RValue<UInt> operator>>=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004506 {
4507 return lhs = lhs >> rhs;
4508 }
4509
John Bauman19bac1e2014-05-06 15:23:49 -04004510 RValue<UInt> operator+(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004511 {
4512 return val;
4513 }
4514
John Bauman19bac1e2014-05-06 15:23:49 -04004515 RValue<UInt> operator-(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004516 {
4517 return RValue<UInt>(Nucleus::createNeg(val.value));
4518 }
4519
John Bauman19bac1e2014-05-06 15:23:49 -04004520 RValue<UInt> operator~(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004521 {
4522 return RValue<UInt>(Nucleus::createNot(val.value));
4523 }
4524
4525 RValue<UInt> operator++(const UInt &val, int) // Post-increment
4526 {
4527 RValue<UInt> res = val;
4528
4529 Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantInt(1));
John Bauman66b8ab22014-05-06 15:57:45 -04004530 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004531
4532 return res;
4533 }
4534
4535 const UInt &operator++(const UInt &val) // Pre-increment
4536 {
John Bauman66b8ab22014-05-06 15:57:45 -04004537 Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantInt(1));
4538 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004539
4540 return val;
4541 }
4542
4543 RValue<UInt> operator--(const UInt &val, int) // Post-decrement
4544 {
4545 RValue<UInt> res = val;
4546
4547 Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantInt(1));
John Bauman66b8ab22014-05-06 15:57:45 -04004548 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004549
4550 return res;
4551 }
4552
4553 const UInt &operator--(const UInt &val) // Pre-decrement
4554 {
John Bauman66b8ab22014-05-06 15:57:45 -04004555 Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantInt(1));
4556 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004557
4558 return val;
4559 }
4560
John Bauman19bac1e2014-05-06 15:23:49 -04004561 RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y)
4562 {
4563 return IfThenElse(x > y, x, y);
4564 }
4565
4566 RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y)
4567 {
4568 return IfThenElse(x < y, x, y);
4569 }
4570
4571 RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max)
4572 {
4573 return Min(Max(x, min), max);
4574 }
4575
4576 RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004577 {
4578 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
4579 }
4580
John Bauman19bac1e2014-05-06 15:23:49 -04004581 RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004582 {
4583 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
4584 }
4585
John Bauman19bac1e2014-05-06 15:23:49 -04004586 RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004587 {
4588 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
4589 }
4590
John Bauman19bac1e2014-05-06 15:23:49 -04004591 RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004592 {
4593 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
4594 }
4595
John Bauman19bac1e2014-05-06 15:23:49 -04004596 RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004597 {
4598 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
4599 }
4600
John Bauman19bac1e2014-05-06 15:23:49 -04004601 RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004602 {
4603 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
4604 }
4605
John Bauman19bac1e2014-05-06 15:23:49 -04004606// RValue<UInt> RoundUInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04004607// {
4608// return x86::cvtss2si(val); // FIXME: Unsigned
4609//
John Bauman66b8ab22014-05-06 15:57:45 -04004610// // return IfThenElse(val > 0.0f, Int(val + 0.5f), Int(val - 0.5f));
John Bauman89401822014-05-06 15:04:28 -04004611// }
4612
John Bauman19bac1e2014-05-06 15:23:49 -04004613 Type *UInt::getType()
John Bauman89401822014-05-06 15:04:28 -04004614 {
Nicolas Capensac230122016-09-20 14:30:06 -04004615 return T(llvm::Type::getInt32Ty(*::context));
John Bauman89401822014-05-06 15:04:28 -04004616 }
4617
John Bauman19bac1e2014-05-06 15:23:49 -04004618// Int2::Int2(RValue<Int> cast)
4619// {
John Bauman19bac1e2014-05-06 15:23:49 -04004620// Value *extend = Nucleus::createZExt(cast.value, Long::getType());
4621// Value *vector = Nucleus::createBitCast(extend, Int2::getType());
John Bauman66b8ab22014-05-06 15:57:45 -04004622//
John Bauman19bac1e2014-05-06 15:23:49 -04004623// Constant *shuffle[2];
4624// shuffle[0] = Nucleus::createConstantInt(0);
4625// shuffle[1] = Nucleus::createConstantInt(0);
4626//
4627// Value *replicate = Nucleus::createShuffleVector(vector, UndefValue::get(Int2::getType()), Nucleus::createConstantVector(shuffle, 2));
4628//
John Bauman66b8ab22014-05-06 15:57:45 -04004629// storeValue(replicate);
John Bauman19bac1e2014-05-06 15:23:49 -04004630// }
John Bauman89401822014-05-06 15:04:28 -04004631
John Bauman19bac1e2014-05-06 15:23:49 -04004632 Int2::Int2(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04004633 {
John Bauman89401822014-05-06 15:04:28 -04004634 Value *long2 = Nucleus::createBitCast(cast.value, Long2::getType());
4635 Value *element = Nucleus::createExtractElement(long2, 0);
4636 Value *int2 = Nucleus::createBitCast(element, Int2::getType());
4637
John Bauman66b8ab22014-05-06 15:57:45 -04004638 storeValue(int2);
John Bauman89401822014-05-06 15:04:28 -04004639 }
4640
4641 Int2::Int2()
4642 {
4643 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004644 }
4645
4646 Int2::Int2(int x, int y)
4647 {
4648 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004649
4650 Constant *constantVector[2];
4651 constantVector[0] = Nucleus::createConstantInt(x);
4652 constantVector[1] = Nucleus::createConstantInt(y);
John Bauman19bac1e2014-05-06 15:23:49 -04004653 Value *vector = Nucleus::createConstantVector(constantVector, 2);
John Bauman89401822014-05-06 15:04:28 -04004654
John Bauman66b8ab22014-05-06 15:57:45 -04004655 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04004656 }
4657
John Bauman19bac1e2014-05-06 15:23:49 -04004658 Int2::Int2(RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004659 {
4660 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004661
John Bauman66b8ab22014-05-06 15:57:45 -04004662 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004663 }
4664
4665 Int2::Int2(const Int2 &rhs)
4666 {
4667 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004668
John Bauman66b8ab22014-05-06 15:57:45 -04004669 Value *value = rhs.loadValue();
4670 storeValue(value);
4671 }
4672
4673 Int2::Int2(const Reference<Int2> &rhs)
4674 {
4675 // xy.parent = this;
4676
4677 Value *value = rhs.loadValue();
4678 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004679 }
4680
Nicolas Capens62abb552016-01-05 12:03:47 -05004681 Int2::Int2(RValue<Int> lo, RValue<Int> hi)
4682 {
Nicolas Capensb40a2562016-01-05 00:08:45 -05004683 if(CPUID::supportsMMX2())
4684 {
4685 // movd mm0, lo
4686 // movd mm1, hi
4687 // punpckldq mm0, mm1
4688 storeValue(As<Int2>(UnpackLow(As<Int2>(Long1(RValue<UInt>(lo))), As<Int2>(Long1(RValue<UInt>(hi))))).value);
4689 }
4690 else
4691 {
4692 Constant *shuffle[2];
4693 shuffle[0] = Nucleus::createConstantInt(0);
4694 shuffle[1] = Nucleus::createConstantInt(1);
Nicolas Capens05b3d662016-02-25 23:58:33 -05004695
Nicolas Capensac230122016-09-20 14:30:06 -04004696 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 -05004697
Nicolas Capensb40a2562016-01-05 00:08:45 -05004698 storeValue(Nucleus::createBitCast(packed, Int2::getType()));
4699 }
Nicolas Capens62abb552016-01-05 12:03:47 -05004700 }
4701
John Bauman19bac1e2014-05-06 15:23:49 -04004702 RValue<Int2> Int2::operator=(RValue<Int2> rhs) const
John Bauman89401822014-05-06 15:04:28 -04004703 {
John Bauman66b8ab22014-05-06 15:57:45 -04004704 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004705
4706 return rhs;
4707 }
4708
4709 RValue<Int2> Int2::operator=(const Int2 &rhs) const
4710 {
John Bauman66b8ab22014-05-06 15:57:45 -04004711 Value *value = rhs.loadValue();
4712 storeValue(value);
4713
4714 return RValue<Int2>(value);
4715 }
4716
4717 RValue<Int2> Int2::operator=(const Reference<Int2> &rhs) const
4718 {
4719 Value *value = rhs.loadValue();
4720 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004721
4722 return RValue<Int2>(value);
4723 }
4724
John Bauman19bac1e2014-05-06 15:23:49 -04004725 RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004726 {
John Bauman19bac1e2014-05-06 15:23:49 -04004727 if(CPUID::supportsMMX2())
4728 {
4729 return x86::paddd(lhs, rhs);
4730 }
4731 else
4732 {
4733 return RValue<Int2>(Nucleus::createAdd(lhs.value, rhs.value));
4734 }
John Bauman89401822014-05-06 15:04:28 -04004735 }
4736
John Bauman19bac1e2014-05-06 15:23:49 -04004737 RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004738 {
John Bauman19bac1e2014-05-06 15:23:49 -04004739 if(CPUID::supportsMMX2())
4740 {
4741 return x86::psubd(lhs, rhs);
4742 }
4743 else
4744 {
4745 return RValue<Int2>(Nucleus::createSub(lhs.value, rhs.value));
4746 }
John Bauman89401822014-05-06 15:04:28 -04004747 }
4748
John Bauman19bac1e2014-05-06 15:23:49 -04004749// RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs)
4750// {
4751// return RValue<Int2>(Nucleus::createMul(lhs.value, rhs.value));
4752// }
4753
4754// RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs)
4755// {
4756// return RValue<Int2>(Nucleus::createSDiv(lhs.value, rhs.value));
4757// }
4758
4759// RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs)
4760// {
4761// return RValue<Int2>(Nucleus::createSRem(lhs.value, rhs.value));
4762// }
4763
4764 RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004765 {
John Bauman19bac1e2014-05-06 15:23:49 -04004766 if(CPUID::supportsMMX2())
4767 {
4768 return As<Int2>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
4769 }
4770 else
4771 {
4772 return RValue<Int2>(Nucleus::createAnd(lhs.value, rhs.value));
4773 }
John Bauman89401822014-05-06 15:04:28 -04004774 }
4775
John Bauman19bac1e2014-05-06 15:23:49 -04004776 RValue<Int2> operator|(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004777 {
John Bauman19bac1e2014-05-06 15:23:49 -04004778 if(CPUID::supportsMMX2())
4779 {
4780 return As<Int2>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
4781 }
4782 else
4783 {
4784 return RValue<Int2>(Nucleus::createOr(lhs.value, rhs.value));
4785 }
John Bauman89401822014-05-06 15:04:28 -04004786 }
4787
John Bauman19bac1e2014-05-06 15:23:49 -04004788 RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004789 {
John Bauman19bac1e2014-05-06 15:23:49 -04004790 if(CPUID::supportsMMX2())
4791 {
4792 return As<Int2>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
4793 }
4794 else
4795 {
4796 return RValue<Int2>(Nucleus::createXor(lhs.value, rhs.value));
4797 }
John Bauman89401822014-05-06 15:04:28 -04004798 }
4799
John Bauman19bac1e2014-05-06 15:23:49 -04004800 RValue<Int2> operator<<(RValue<Int2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004801 {
4802 // return RValue<Int2>(Nucleus::createShl(lhs.value, rhs.value));
4803
4804 return x86::pslld(lhs, rhs);
4805 }
4806
John Bauman19bac1e2014-05-06 15:23:49 -04004807 RValue<Int2> operator>>(RValue<Int2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004808 {
4809 // return RValue<Int2>(Nucleus::createAShr(lhs.value, rhs.value));
4810
4811 return x86::psrad(lhs, rhs);
4812 }
4813
John Bauman19bac1e2014-05-06 15:23:49 -04004814 RValue<Int2> operator<<(RValue<Int2> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004815 {
4816 // return RValue<Int2>(Nucleus::createShl(lhs.value, rhs.value));
4817
4818 return x86::pslld(lhs, rhs);
4819 }
4820
John Bauman19bac1e2014-05-06 15:23:49 -04004821 RValue<Int2> operator>>(RValue<Int2> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004822 {
4823 // return RValue<Int2>(Nucleus::createAShr(lhs.value, rhs.value));
4824
4825 return x86::psrad(lhs, rhs);
4826 }
4827
John Bauman19bac1e2014-05-06 15:23:49 -04004828 RValue<Int2> operator+=(const Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004829 {
4830 return lhs = lhs + rhs;
4831 }
4832
John Bauman19bac1e2014-05-06 15:23:49 -04004833 RValue<Int2> operator-=(const Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004834 {
4835 return lhs = lhs - rhs;
4836 }
4837
John Bauman19bac1e2014-05-06 15:23:49 -04004838// RValue<Int2> operator*=(const Int2 &lhs, RValue<Int2> rhs)
4839// {
4840// return lhs = lhs * rhs;
4841// }
John Bauman89401822014-05-06 15:04:28 -04004842
John Bauman19bac1e2014-05-06 15:23:49 -04004843// RValue<Int2> operator/=(const Int2 &lhs, RValue<Int2> rhs)
4844// {
4845// return lhs = lhs / rhs;
4846// }
John Bauman89401822014-05-06 15:04:28 -04004847
John Bauman19bac1e2014-05-06 15:23:49 -04004848// RValue<Int2> operator%=(const Int2 &lhs, RValue<Int2> rhs)
4849// {
4850// return lhs = lhs % rhs;
4851// }
John Bauman89401822014-05-06 15:04:28 -04004852
John Bauman19bac1e2014-05-06 15:23:49 -04004853 RValue<Int2> operator&=(const Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004854 {
4855 return lhs = lhs & rhs;
4856 }
4857
John Bauman19bac1e2014-05-06 15:23:49 -04004858 RValue<Int2> operator|=(const Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004859 {
4860 return lhs = lhs | rhs;
4861 }
4862
John Bauman19bac1e2014-05-06 15:23:49 -04004863 RValue<Int2> operator^=(const Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004864 {
4865 return lhs = lhs ^ rhs;
4866 }
4867
4868 RValue<Int2> operator<<=(const Int2 &lhs, unsigned char rhs)
4869 {
4870 return lhs = lhs << rhs;
4871 }
4872
4873 RValue<Int2> operator>>=(const Int2 &lhs, unsigned char rhs)
4874 {
4875 return lhs = lhs >> rhs;
4876 }
4877
John Bauman19bac1e2014-05-06 15:23:49 -04004878 RValue<Int2> operator<<=(const Int2 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004879 {
4880 return lhs = lhs << rhs;
4881 }
4882
John Bauman19bac1e2014-05-06 15:23:49 -04004883 RValue<Int2> operator>>=(const Int2 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004884 {
4885 return lhs = lhs >> rhs;
4886 }
4887
John Bauman19bac1e2014-05-06 15:23:49 -04004888// RValue<Int2> operator+(RValue<Int2> val)
4889// {
4890// return val;
4891// }
4892
4893// RValue<Int2> operator-(RValue<Int2> val)
4894// {
4895// return RValue<Int2>(Nucleus::createNeg(val.value));
4896// }
4897
4898 RValue<Int2> operator~(RValue<Int2> val)
John Bauman89401822014-05-06 15:04:28 -04004899 {
John Bauman19bac1e2014-05-06 15:23:49 -04004900 if(CPUID::supportsMMX2())
4901 {
4902 return val ^ Int2(0xFFFFFFFF, 0xFFFFFFFF);
4903 }
4904 else
4905 {
4906 return RValue<Int2>(Nucleus::createNot(val.value));
4907 }
John Bauman89401822014-05-06 15:04:28 -04004908 }
4909
John Bauman19bac1e2014-05-06 15:23:49 -04004910 RValue<Long1> UnpackLow(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04004911 {
John Bauman19bac1e2014-05-06 15:23:49 -04004912 if(CPUID::supportsMMX2())
4913 {
4914 return x86::punpckldq(x, y);
4915 }
4916 else
4917 {
4918 Constant *shuffle[2];
4919 shuffle[0] = Nucleus::createConstantInt(0);
4920 shuffle[1] = Nucleus::createConstantInt(2);
John Bauman89401822014-05-06 15:04:28 -04004921
John Bauman19bac1e2014-05-06 15:23:49 -04004922 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 2));
John Bauman89401822014-05-06 15:04:28 -04004923
John Bauman19bac1e2014-05-06 15:23:49 -04004924 return RValue<Long1>(Nucleus::createBitCast(packed, Long1::getType()));
4925 }
John Bauman89401822014-05-06 15:04:28 -04004926 }
John Bauman66b8ab22014-05-06 15:57:45 -04004927
John Bauman19bac1e2014-05-06 15:23:49 -04004928 RValue<Long1> UnpackHigh(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04004929 {
John Bauman19bac1e2014-05-06 15:23:49 -04004930 if(CPUID::supportsMMX2())
4931 {
4932 return x86::punpckhdq(x, y);
4933 }
4934 else
4935 {
4936 Constant *shuffle[2];
4937 shuffle[0] = Nucleus::createConstantInt(1);
4938 shuffle[1] = Nucleus::createConstantInt(3);
John Bauman89401822014-05-06 15:04:28 -04004939
John Bauman19bac1e2014-05-06 15:23:49 -04004940 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 2));
John Bauman89401822014-05-06 15:04:28 -04004941
John Bauman19bac1e2014-05-06 15:23:49 -04004942 return RValue<Long1>(Nucleus::createBitCast(packed, Long1::getType()));
4943 }
John Bauman89401822014-05-06 15:04:28 -04004944 }
4945
John Bauman19bac1e2014-05-06 15:23:49 -04004946 RValue<Int> Extract(RValue<Int2> val, int i)
John Bauman89401822014-05-06 15:04:28 -04004947 {
4948 if(false) // FIXME: LLVM does not generate optimal code
4949 {
4950 return RValue<Int>(Nucleus::createExtractElement(val.value, i));
4951 }
4952 else
4953 {
4954 if(i == 0)
4955 {
Nicolas Capensac230122016-09-20 14:30:06 -04004956 return RValue<Int>(Nucleus::createExtractElement(Nucleus::createBitCast(val.value, T(VectorType::get(Int::getType(), 2))), 0));
John Bauman89401822014-05-06 15:04:28 -04004957 }
4958 else
4959 {
4960 Int2 val2 = As<Int2>(UnpackHigh(val, val));
4961
4962 return Extract(val2, 0);
4963 }
4964 }
4965 }
4966
Nicolas Capensfff3c9b2015-05-13 23:40:44 -04004967 RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i)
4968 {
Nicolas Capensac230122016-09-20 14:30:06 -04004969 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 -04004970 }
John Bauman89401822014-05-06 15:04:28 -04004971
John Bauman19bac1e2014-05-06 15:23:49 -04004972 Type *Int2::getType()
John Bauman89401822014-05-06 15:04:28 -04004973 {
John Bauman19bac1e2014-05-06 15:23:49 -04004974 if(CPUID::supportsMMX2())
4975 {
4976 return MMX::getType();
4977 }
4978 else
4979 {
Nicolas Capensac230122016-09-20 14:30:06 -04004980 return T(VectorType::get(Int::getType(), 2));
John Bauman19bac1e2014-05-06 15:23:49 -04004981 }
John Bauman89401822014-05-06 15:04:28 -04004982 }
4983
4984 UInt2::UInt2()
4985 {
4986 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004987 }
4988
4989 UInt2::UInt2(unsigned int x, unsigned int y)
4990 {
4991 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004992
4993 Constant *constantVector[2];
4994 constantVector[0] = Nucleus::createConstantInt(x);
4995 constantVector[1] = Nucleus::createConstantInt(y);
John Bauman19bac1e2014-05-06 15:23:49 -04004996 Value *vector = Nucleus::createConstantVector(constantVector, 2);
John Bauman89401822014-05-06 15:04:28 -04004997
John Bauman66b8ab22014-05-06 15:57:45 -04004998 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04004999 }
5000
John Bauman19bac1e2014-05-06 15:23:49 -04005001 UInt2::UInt2(RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005002 {
5003 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005004
John Bauman66b8ab22014-05-06 15:57:45 -04005005 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005006 }
5007
5008 UInt2::UInt2(const UInt2 &rhs)
5009 {
5010 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005011
John Bauman66b8ab22014-05-06 15:57:45 -04005012 Value *value = rhs.loadValue();
5013 storeValue(value);
5014 }
5015
5016 UInt2::UInt2(const Reference<UInt2> &rhs)
5017 {
5018 // xy.parent = this;
5019
5020 Value *value = rhs.loadValue();
5021 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005022 }
5023
John Bauman19bac1e2014-05-06 15:23:49 -04005024 RValue<UInt2> UInt2::operator=(RValue<UInt2> rhs) const
John Bauman89401822014-05-06 15:04:28 -04005025 {
John Bauman66b8ab22014-05-06 15:57:45 -04005026 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005027
5028 return rhs;
5029 }
5030
5031 RValue<UInt2> UInt2::operator=(const UInt2 &rhs) const
5032 {
John Bauman66b8ab22014-05-06 15:57:45 -04005033 Value *value = rhs.loadValue();
5034 storeValue(value);
5035
5036 return RValue<UInt2>(value);
5037 }
5038
5039 RValue<UInt2> UInt2::operator=(const Reference<UInt2> &rhs) const
5040 {
5041 Value *value = rhs.loadValue();
5042 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005043
5044 return RValue<UInt2>(value);
5045 }
5046
John Bauman19bac1e2014-05-06 15:23:49 -04005047 RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005048 {
John Bauman19bac1e2014-05-06 15:23:49 -04005049 if(CPUID::supportsMMX2())
5050 {
5051 return As<UInt2>(x86::paddd(As<Int2>(lhs), As<Int2>(rhs)));
5052 }
5053 else
5054 {
5055 return RValue<UInt2>(Nucleus::createAdd(lhs.value, rhs.value));
5056 }
John Bauman89401822014-05-06 15:04:28 -04005057 }
5058
John Bauman19bac1e2014-05-06 15:23:49 -04005059 RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005060 {
John Bauman19bac1e2014-05-06 15:23:49 -04005061 if(CPUID::supportsMMX2())
5062 {
5063 return As<UInt2>(x86::psubd(As<Int2>(lhs), As<Int2>(rhs)));
5064 }
5065 else
5066 {
5067 return RValue<UInt2>(Nucleus::createSub(lhs.value, rhs.value));
5068 }
John Bauman89401822014-05-06 15:04:28 -04005069 }
5070
John Bauman19bac1e2014-05-06 15:23:49 -04005071// RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs)
5072// {
5073// return RValue<UInt2>(Nucleus::createMul(lhs.value, rhs.value));
5074// }
5075
5076// RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs)
5077// {
5078// return RValue<UInt2>(Nucleus::createUDiv(lhs.value, rhs.value));
5079// }
5080
5081// RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs)
5082// {
5083// return RValue<UInt2>(Nucleus::createURem(lhs.value, rhs.value));
5084// }
5085
5086 RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005087 {
John Bauman19bac1e2014-05-06 15:23:49 -04005088 if(CPUID::supportsMMX2())
5089 {
5090 return As<UInt2>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
5091 }
5092 else
5093 {
5094 return RValue<UInt2>(Nucleus::createAnd(lhs.value, rhs.value));
5095 }
John Bauman89401822014-05-06 15:04:28 -04005096 }
5097
John Bauman19bac1e2014-05-06 15:23:49 -04005098 RValue<UInt2> operator|(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005099 {
John Bauman19bac1e2014-05-06 15:23:49 -04005100 if(CPUID::supportsMMX2())
5101 {
5102 return As<UInt2>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
5103 }
5104 else
5105 {
5106 return RValue<UInt2>(Nucleus::createOr(lhs.value, rhs.value));
5107 }
John Bauman89401822014-05-06 15:04:28 -04005108 }
5109
John Bauman19bac1e2014-05-06 15:23:49 -04005110 RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005111 {
John Bauman19bac1e2014-05-06 15:23:49 -04005112 if(CPUID::supportsMMX2())
5113 {
5114 return As<UInt2>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
5115 }
5116 else
5117 {
5118 return RValue<UInt2>(Nucleus::createXor(lhs.value, rhs.value));
5119 }
John Bauman89401822014-05-06 15:04:28 -04005120 }
5121
John Bauman19bac1e2014-05-06 15:23:49 -04005122 RValue<UInt2> operator<<(RValue<UInt2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005123 {
5124 // return RValue<UInt2>(Nucleus::createShl(lhs.value, rhs.value));
5125
5126 return As<UInt2>(x86::pslld(As<Int2>(lhs), rhs));
5127 }
5128
John Bauman19bac1e2014-05-06 15:23:49 -04005129 RValue<UInt2> operator>>(RValue<UInt2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005130 {
5131 // return RValue<UInt2>(Nucleus::createLShr(lhs.value, rhs.value));
5132
5133 return x86::psrld(lhs, rhs);
5134 }
5135
John Bauman19bac1e2014-05-06 15:23:49 -04005136 RValue<UInt2> operator<<(RValue<UInt2> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04005137 {
5138 // return RValue<UInt2>(Nucleus::createShl(lhs.value, rhs.value));
5139
5140 return As<UInt2>(x86::pslld(As<Int2>(lhs), rhs));
5141 }
5142
John Bauman19bac1e2014-05-06 15:23:49 -04005143 RValue<UInt2> operator>>(RValue<UInt2> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04005144 {
5145 // return RValue<UInt2>(Nucleus::createLShr(lhs.value, rhs.value));
5146
5147 return x86::psrld(lhs, rhs);
5148 }
5149
John Bauman19bac1e2014-05-06 15:23:49 -04005150 RValue<UInt2> operator+=(const UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005151 {
5152 return lhs = lhs + rhs;
5153 }
5154
John Bauman19bac1e2014-05-06 15:23:49 -04005155 RValue<UInt2> operator-=(const UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005156 {
5157 return lhs = lhs - rhs;
5158 }
5159
John Bauman19bac1e2014-05-06 15:23:49 -04005160// RValue<UInt2> operator*=(const UInt2 &lhs, RValue<UInt2> rhs)
5161// {
5162// return lhs = lhs * rhs;
5163// }
John Bauman89401822014-05-06 15:04:28 -04005164
John Bauman19bac1e2014-05-06 15:23:49 -04005165// RValue<UInt2> operator/=(const UInt2 &lhs, RValue<UInt2> rhs)
5166// {
5167// return lhs = lhs / rhs;
5168// }
John Bauman89401822014-05-06 15:04:28 -04005169
John Bauman19bac1e2014-05-06 15:23:49 -04005170// RValue<UInt2> operator%=(const UInt2 &lhs, RValue<UInt2> rhs)
5171// {
5172// return lhs = lhs % rhs;
5173// }
John Bauman89401822014-05-06 15:04:28 -04005174
John Bauman19bac1e2014-05-06 15:23:49 -04005175 RValue<UInt2> operator&=(const UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005176 {
5177 return lhs = lhs & rhs;
5178 }
5179
John Bauman19bac1e2014-05-06 15:23:49 -04005180 RValue<UInt2> operator|=(const UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005181 {
5182 return lhs = lhs | rhs;
5183 }
5184
John Bauman19bac1e2014-05-06 15:23:49 -04005185 RValue<UInt2> operator^=(const UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005186 {
5187 return lhs = lhs ^ rhs;
5188 }
5189
5190 RValue<UInt2> operator<<=(const UInt2 &lhs, unsigned char rhs)
5191 {
5192 return lhs = lhs << rhs;
5193 }
5194
5195 RValue<UInt2> operator>>=(const UInt2 &lhs, unsigned char rhs)
5196 {
5197 return lhs = lhs >> rhs;
5198 }
5199
John Bauman19bac1e2014-05-06 15:23:49 -04005200 RValue<UInt2> operator<<=(const UInt2 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04005201 {
5202 return lhs = lhs << rhs;
5203 }
5204
John Bauman19bac1e2014-05-06 15:23:49 -04005205 RValue<UInt2> operator>>=(const UInt2 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04005206 {
5207 return lhs = lhs >> rhs;
5208 }
5209
John Bauman19bac1e2014-05-06 15:23:49 -04005210// RValue<UInt2> operator+(RValue<UInt2> val)
5211// {
5212// return val;
5213// }
5214
5215// RValue<UInt2> operator-(RValue<UInt2> val)
5216// {
5217// return RValue<UInt2>(Nucleus::createNeg(val.value));
5218// }
5219
5220 RValue<UInt2> operator~(RValue<UInt2> val)
John Bauman89401822014-05-06 15:04:28 -04005221 {
John Bauman19bac1e2014-05-06 15:23:49 -04005222 if(CPUID::supportsMMX2())
5223 {
5224 return val ^ UInt2(0xFFFFFFFF, 0xFFFFFFFF);
5225 }
5226 else
5227 {
5228 return RValue<UInt2>(Nucleus::createNot(val.value));
5229 }
John Bauman89401822014-05-06 15:04:28 -04005230 }
5231
John Bauman19bac1e2014-05-06 15:23:49 -04005232 Type *UInt2::getType()
John Bauman89401822014-05-06 15:04:28 -04005233 {
John Bauman19bac1e2014-05-06 15:23:49 -04005234 if(CPUID::supportsMMX2())
5235 {
5236 return MMX::getType();
5237 }
5238 else
5239 {
Nicolas Capensac230122016-09-20 14:30:06 -04005240 return T(VectorType::get(UInt::getType(), 2));
John Bauman19bac1e2014-05-06 15:23:49 -04005241 }
John Bauman89401822014-05-06 15:04:28 -04005242 }
5243
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005244 Int4::Int4(RValue<Byte4> cast)
5245 {
5246 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
5247 Value *a = Nucleus::createInsertElement(UndefValue::get(Int4::getType()), x, 0);
5248
5249 Value *e;
5250
5251 if (CPUID::supportsSSE4_1())
5252 {
5253 e = x86::pmovzxbd(RValue<Int4>(a)).value;
5254 }
5255 else
5256 {
5257 Constant *swizzle[16];
5258 swizzle[0] = Nucleus::createConstantInt(0);
5259 swizzle[1] = Nucleus::createConstantInt(16);
5260 swizzle[2] = Nucleus::createConstantInt(1);
5261 swizzle[3] = Nucleus::createConstantInt(17);
5262 swizzle[4] = Nucleus::createConstantInt(2);
5263 swizzle[5] = Nucleus::createConstantInt(18);
5264 swizzle[6] = Nucleus::createConstantInt(3);
5265 swizzle[7] = Nucleus::createConstantInt(19);
5266 swizzle[8] = Nucleus::createConstantInt(4);
5267 swizzle[9] = Nucleus::createConstantInt(20);
5268 swizzle[10] = Nucleus::createConstantInt(5);
5269 swizzle[11] = Nucleus::createConstantInt(21);
5270 swizzle[12] = Nucleus::createConstantInt(6);
5271 swizzle[13] = Nucleus::createConstantInt(22);
5272 swizzle[14] = Nucleus::createConstantInt(7);
5273 swizzle[15] = Nucleus::createConstantInt(23);
5274
5275 Value *b = Nucleus::createBitCast(a, Byte16::getType());
5276 Value *c = Nucleus::createShuffleVector(b, Nucleus::createNullValue(Byte16::getType()), Nucleus::createConstantVector(swizzle, 16));
5277
5278 Constant *swizzle2[8];
5279 swizzle2[0] = Nucleus::createConstantInt(0);
5280 swizzle2[1] = Nucleus::createConstantInt(8);
5281 swizzle2[2] = Nucleus::createConstantInt(1);
5282 swizzle2[3] = Nucleus::createConstantInt(9);
5283 swizzle2[4] = Nucleus::createConstantInt(2);
5284 swizzle2[5] = Nucleus::createConstantInt(10);
5285 swizzle2[6] = Nucleus::createConstantInt(3);
5286 swizzle2[7] = Nucleus::createConstantInt(11);
5287
5288 Value *d = Nucleus::createBitCast(c, Short8::getType());
5289 e = Nucleus::createShuffleVector(d, Nucleus::createNullValue(Short8::getType()), Nucleus::createConstantVector(swizzle2, 8));
5290 }
5291
5292 Value *f = Nucleus::createBitCast(e, Int4::getType());
5293 storeValue(f);
5294 }
5295
5296 Int4::Int4(RValue<SByte4> cast)
5297 {
5298 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
5299 Value *a = Nucleus::createInsertElement(UndefValue::get(Int4::getType()), x, 0);
5300
5301 Value *g;
5302
5303 if (CPUID::supportsSSE4_1())
5304 {
5305 g = x86::pmovsxbd(RValue<Int4>(a)).value;
5306 }
5307 else
5308 {
5309 Constant *swizzle[16];
5310 swizzle[0] = Nucleus::createConstantInt(0);
5311 swizzle[1] = Nucleus::createConstantInt(0);
5312 swizzle[2] = Nucleus::createConstantInt(1);
5313 swizzle[3] = Nucleus::createConstantInt(1);
5314 swizzle[4] = Nucleus::createConstantInt(2);
5315 swizzle[5] = Nucleus::createConstantInt(2);
5316 swizzle[6] = Nucleus::createConstantInt(3);
5317 swizzle[7] = Nucleus::createConstantInt(3);
5318 swizzle[8] = Nucleus::createConstantInt(4);
5319 swizzle[9] = Nucleus::createConstantInt(4);
5320 swizzle[10] = Nucleus::createConstantInt(5);
5321 swizzle[11] = Nucleus::createConstantInt(5);
5322 swizzle[12] = Nucleus::createConstantInt(6);
5323 swizzle[13] = Nucleus::createConstantInt(6);
5324 swizzle[14] = Nucleus::createConstantInt(7);
5325 swizzle[15] = Nucleus::createConstantInt(7);
5326
5327 Value *b = Nucleus::createBitCast(a, Byte16::getType());
5328 Value *c = Nucleus::createShuffleVector(b, b, Nucleus::createConstantVector(swizzle, 16));
5329
5330 Constant *swizzle2[8];
5331 swizzle2[0] = Nucleus::createConstantInt(0);
5332 swizzle2[1] = Nucleus::createConstantInt(0);
5333 swizzle2[2] = Nucleus::createConstantInt(1);
5334 swizzle2[3] = Nucleus::createConstantInt(1);
5335 swizzle2[4] = Nucleus::createConstantInt(2);
5336 swizzle2[5] = Nucleus::createConstantInt(2);
5337 swizzle2[6] = Nucleus::createConstantInt(3);
5338 swizzle2[7] = Nucleus::createConstantInt(3);
5339
5340 Value *d = Nucleus::createBitCast(c, Short8::getType());
5341 Value *e = Nucleus::createShuffleVector(d, d, Nucleus::createConstantVector(swizzle2, 8));
5342
5343 Value *f = Nucleus::createBitCast(e, Int4::getType());
5344 // g = Nucleus::createAShr(f, Nucleus::createConstantInt(24));
5345 g = x86::psrad(RValue<Int4>(f), 24).value;
5346 }
5347
5348 storeValue(g);
5349 }
5350
John Bauman19bac1e2014-05-06 15:23:49 -04005351 Int4::Int4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005352 {
5353 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005354
5355 Value *xyzw = Nucleus::createFPToSI(cast.value, Int4::getType());
John Bauman89401822014-05-06 15:04:28 -04005356
John Bauman66b8ab22014-05-06 15:57:45 -04005357 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04005358 }
5359
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005360 Int4::Int4(RValue<Short4> cast)
5361 {
5362 Value *long2 = UndefValue::get(Long2::getType());
5363 Value *element = Nucleus::createBitCast(cast.value, Long::getType());
5364 long2 = Nucleus::createInsertElement(long2, element, 0);
5365 RValue<Int4> vector = RValue<Int4>(Nucleus::createBitCast(long2, Int4::getType()));
Nicolas Capens05b3d662016-02-25 23:58:33 -05005366
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005367 if(CPUID::supportsSSE4_1())
5368 {
5369 storeValue(x86::pmovsxwd(vector).value);
5370 }
5371 else
5372 {
5373 Value *b = Nucleus::createBitCast(vector.value, Short8::getType());
5374
5375 Constant *swizzle[8];
5376 swizzle[0] = Nucleus::createConstantInt(0);
5377 swizzle[1] = Nucleus::createConstantInt(0);
5378 swizzle[2] = Nucleus::createConstantInt(1);
5379 swizzle[3] = Nucleus::createConstantInt(1);
5380 swizzle[4] = Nucleus::createConstantInt(2);
5381 swizzle[5] = Nucleus::createConstantInt(2);
5382 swizzle[6] = Nucleus::createConstantInt(3);
5383 swizzle[7] = Nucleus::createConstantInt(3);
5384
Nicolas Capens6ce5c332015-10-28 01:58:18 -04005385 Value *c = Nucleus::createShuffleVector(b, b, Nucleus::createConstantVector(swizzle, 8));
5386 Value *d = Nucleus::createBitCast(c, Int4::getType());
5387 storeValue(d);
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005388
5389 // Each Short is packed into each Int in the (Short | Short) format.
5390 // Shifting by 16 will retrieve the original Short value.
5391 // Shitfing an Int will propagate the sign bit, which will work
5392 // for both positive and negative values of a Short.
5393 *this >>= 16;
5394 }
5395 }
5396
5397 Int4::Int4(RValue<UShort4> cast)
5398 {
5399 Value *long2 = UndefValue::get(Long2::getType());
5400 Value *element = Nucleus::createBitCast(cast.value, Long::getType());
5401 long2 = Nucleus::createInsertElement(long2, element, 0);
5402 RValue<Int4> vector = RValue<Int4>(Nucleus::createBitCast(long2, Int4::getType()));
5403
5404 if(CPUID::supportsSSE4_1())
5405 {
5406 storeValue(x86::pmovzxwd(RValue<Int4>(vector)).value);
5407 }
5408 else
5409 {
5410 Value *b = Nucleus::createBitCast(vector.value, Short8::getType());
5411
5412 Constant *swizzle[8];
5413 swizzle[0] = Nucleus::createConstantInt(0);
5414 swizzle[1] = Nucleus::createConstantInt(8);
5415 swizzle[2] = Nucleus::createConstantInt(1);
5416 swizzle[3] = Nucleus::createConstantInt(9);
5417 swizzle[4] = Nucleus::createConstantInt(2);
5418 swizzle[5] = Nucleus::createConstantInt(10);
5419 swizzle[6] = Nucleus::createConstantInt(3);
5420 swizzle[7] = Nucleus::createConstantInt(11);
5421
Nicolas Capens6ce5c332015-10-28 01:58:18 -04005422 Value *c = Nucleus::createShuffleVector(b, Nucleus::createNullValue(Short8::getType()), Nucleus::createConstantVector(swizzle, 8));
5423 Value *d = Nucleus::createBitCast(c, Int4::getType());
5424 storeValue(d);
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005425 }
5426 }
5427
John Bauman89401822014-05-06 15:04:28 -04005428 Int4::Int4()
5429 {
5430 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005431 }
5432
5433 Int4::Int4(int xyzw)
5434 {
5435 constant(xyzw, xyzw, xyzw, xyzw);
5436 }
5437
5438 Int4::Int4(int x, int yzw)
5439 {
5440 constant(x, yzw, yzw, yzw);
5441 }
5442
5443 Int4::Int4(int x, int y, int zw)
5444 {
5445 constant(x, y, zw, zw);
5446 }
5447
5448 Int4::Int4(int x, int y, int z, int w)
5449 {
5450 constant(x, y, z, w);
5451 }
5452
5453 void Int4::constant(int x, int y, int z, int w)
5454 {
5455 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005456
5457 Constant *constantVector[4];
5458 constantVector[0] = Nucleus::createConstantInt(x);
5459 constantVector[1] = Nucleus::createConstantInt(y);
5460 constantVector[2] = Nucleus::createConstantInt(z);
5461 constantVector[3] = Nucleus::createConstantInt(w);
5462
John Bauman66b8ab22014-05-06 15:57:45 -04005463 storeValue(Nucleus::createConstantVector(constantVector, 4));
John Bauman89401822014-05-06 15:04:28 -04005464 }
5465
John Bauman19bac1e2014-05-06 15:23:49 -04005466 Int4::Int4(RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005467 {
5468 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005469
John Bauman66b8ab22014-05-06 15:57:45 -04005470 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005471 }
5472
5473 Int4::Int4(const Int4 &rhs)
5474 {
5475 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005476
John Bauman66b8ab22014-05-06 15:57:45 -04005477 Value *value = rhs.loadValue();
5478 storeValue(value);
5479 }
5480
5481 Int4::Int4(const Reference<Int4> &rhs)
5482 {
5483 // xyzw.parent = this;
5484
5485 Value *value = rhs.loadValue();
5486 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005487 }
5488
John Bauman19bac1e2014-05-06 15:23:49 -04005489 Int4::Int4(RValue<UInt4> rhs)
5490 {
5491 // xyzw.parent = this;
John Bauman19bac1e2014-05-06 15:23:49 -04005492
John Bauman66b8ab22014-05-06 15:57:45 -04005493 storeValue(rhs.value);
John Bauman19bac1e2014-05-06 15:23:49 -04005494 }
5495
5496 Int4::Int4(const UInt4 &rhs)
5497 {
5498 // xyzw.parent = this;
John Bauman19bac1e2014-05-06 15:23:49 -04005499
John Bauman66b8ab22014-05-06 15:57:45 -04005500 Value *value = rhs.loadValue();
5501 storeValue(value);
5502 }
5503
5504 Int4::Int4(const Reference<UInt4> &rhs)
5505 {
5506 // xyzw.parent = this;
5507
5508 Value *value = rhs.loadValue();
5509 storeValue(value);
John Bauman19bac1e2014-05-06 15:23:49 -04005510 }
5511
Nicolas Capens62abb552016-01-05 12:03:47 -05005512 Int4::Int4(RValue<Int2> lo, RValue<Int2> hi)
5513 {
Nicolas Capens24c8cf02016-08-15 15:33:14 -04005514 // xyzw.parent = this;
5515
Nicolas Capens62abb552016-01-05 12:03:47 -05005516 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
5517 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
5518
5519 Value *long2 = UndefValue::get(Long2::getType());
5520 long2 = Nucleus::createInsertElement(long2, loLong, 0);
5521 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
5522 Value *int4 = Nucleus::createBitCast(long2, Int4::getType());
5523
5524 storeValue(int4);
5525 }
5526
Nicolas Capens24c8cf02016-08-15 15:33:14 -04005527 Int4::Int4(RValue<Int> rhs)
5528 {
5529 // xyzw.parent = this;
5530
5531 Value *vector = loadValue();
5532 Value *insert = Nucleus::createInsertElement(vector, rhs.value, 0);
5533
5534 Constant *swizzle[4];
5535 swizzle[0] = Nucleus::createConstantInt(0);
5536 swizzle[1] = Nucleus::createConstantInt(0);
5537 swizzle[2] = Nucleus::createConstantInt(0);
5538 swizzle[3] = Nucleus::createConstantInt(0);
5539
5540 Value *replicate = Nucleus::createShuffleVector(insert, UndefValue::get(Int4::getType()), Nucleus::createConstantVector(swizzle, 4));
5541
5542 storeValue(replicate);
5543 }
5544
5545 Int4::Int4(const Int &rhs)
5546 {
5547 // xyzw.parent = this;
5548
5549 *this = RValue<Int>(rhs.loadValue());
5550 }
5551
5552 Int4::Int4(const Reference<Int> &rhs)
5553 {
5554 // xyzw.parent = this;
5555
5556 *this = RValue<Int>(rhs.loadValue());
5557 }
5558
John Bauman19bac1e2014-05-06 15:23:49 -04005559 RValue<Int4> Int4::operator=(RValue<Int4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04005560 {
John Bauman66b8ab22014-05-06 15:57:45 -04005561 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005562
5563 return rhs;
5564 }
5565
5566 RValue<Int4> Int4::operator=(const Int4 &rhs) const
5567 {
John Bauman66b8ab22014-05-06 15:57:45 -04005568 Value *value = rhs.loadValue();
5569 storeValue(value);
5570
5571 return RValue<Int4>(value);
5572 }
5573
5574 RValue<Int4> Int4::operator=(const Reference<Int4> &rhs) const
5575 {
5576 Value *value = rhs.loadValue();
5577 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005578
5579 return RValue<Int4>(value);
5580 }
5581
John Bauman19bac1e2014-05-06 15:23:49 -04005582 RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005583 {
5584 return RValue<Int4>(Nucleus::createAdd(lhs.value, rhs.value));
5585 }
5586
John Bauman19bac1e2014-05-06 15:23:49 -04005587 RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005588 {
5589 return RValue<Int4>(Nucleus::createSub(lhs.value, rhs.value));
5590 }
5591
John Bauman19bac1e2014-05-06 15:23:49 -04005592 RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005593 {
5594 return RValue<Int4>(Nucleus::createMul(lhs.value, rhs.value));
5595 }
5596
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005597 RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs)
5598 {
5599 return RValue<Int4>(Nucleus::createSDiv(lhs.value, rhs.value));
5600 }
John Bauman89401822014-05-06 15:04:28 -04005601
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005602 RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs)
5603 {
5604 return RValue<Int4>(Nucleus::createSRem(lhs.value, rhs.value));
5605 }
John Bauman89401822014-05-06 15:04:28 -04005606
John Bauman19bac1e2014-05-06 15:23:49 -04005607 RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005608 {
5609 return RValue<Int4>(Nucleus::createAnd(lhs.value, rhs.value));
5610 }
5611
John Bauman19bac1e2014-05-06 15:23:49 -04005612 RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005613 {
5614 return RValue<Int4>(Nucleus::createOr(lhs.value, rhs.value));
5615 }
5616
John Bauman19bac1e2014-05-06 15:23:49 -04005617 RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005618 {
5619 return RValue<Int4>(Nucleus::createXor(lhs.value, rhs.value));
5620 }
5621
John Bauman19bac1e2014-05-06 15:23:49 -04005622 RValue<Int4> operator<<(RValue<Int4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005623 {
John Bauman89401822014-05-06 15:04:28 -04005624 return x86::pslld(lhs, rhs);
5625 }
5626
John Bauman19bac1e2014-05-06 15:23:49 -04005627 RValue<Int4> operator>>(RValue<Int4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005628 {
John Bauman89401822014-05-06 15:04:28 -04005629 return x86::psrad(lhs, rhs);
5630 }
5631
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005632 RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs)
5633 {
5634 return RValue<Int4>(Nucleus::createShl(lhs.value, rhs.value));
5635 }
5636
5637 RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs)
5638 {
5639 return RValue<Int4>(Nucleus::createAShr(lhs.value, rhs.value));
5640 }
5641
John Bauman19bac1e2014-05-06 15:23:49 -04005642 RValue<Int4> operator+=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005643 {
5644 return lhs = lhs + rhs;
5645 }
5646
John Bauman19bac1e2014-05-06 15:23:49 -04005647 RValue<Int4> operator-=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005648 {
5649 return lhs = lhs - rhs;
5650 }
5651
John Bauman19bac1e2014-05-06 15:23:49 -04005652 RValue<Int4> operator*=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005653 {
5654 return lhs = lhs * rhs;
5655 }
5656
John Bauman19bac1e2014-05-06 15:23:49 -04005657// RValue<Int4> operator/=(const Int4 &lhs, RValue<Int4> rhs)
5658// {
5659// return lhs = lhs / rhs;
5660// }
John Bauman89401822014-05-06 15:04:28 -04005661
John Bauman19bac1e2014-05-06 15:23:49 -04005662// RValue<Int4> operator%=(const Int4 &lhs, RValue<Int4> rhs)
5663// {
5664// return lhs = lhs % rhs;
5665// }
John Bauman89401822014-05-06 15:04:28 -04005666
John Bauman19bac1e2014-05-06 15:23:49 -04005667 RValue<Int4> operator&=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005668 {
5669 return lhs = lhs & rhs;
5670 }
5671
John Bauman19bac1e2014-05-06 15:23:49 -04005672 RValue<Int4> operator|=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005673 {
5674 return lhs = lhs | rhs;
5675 }
5676
John Bauman19bac1e2014-05-06 15:23:49 -04005677 RValue<Int4> operator^=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005678 {
5679 return lhs = lhs ^ rhs;
5680 }
5681
5682 RValue<Int4> operator<<=(const Int4 &lhs, unsigned char rhs)
5683 {
5684 return lhs = lhs << rhs;
5685 }
5686
5687 RValue<Int4> operator>>=(const Int4 &lhs, unsigned char rhs)
5688 {
5689 return lhs = lhs >> rhs;
5690 }
5691
John Bauman19bac1e2014-05-06 15:23:49 -04005692 RValue<Int4> operator+(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005693 {
5694 return val;
5695 }
5696
John Bauman19bac1e2014-05-06 15:23:49 -04005697 RValue<Int4> operator-(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005698 {
5699 return RValue<Int4>(Nucleus::createNeg(val.value));
5700 }
5701
John Bauman19bac1e2014-05-06 15:23:49 -04005702 RValue<Int4> operator~(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005703 {
5704 return RValue<Int4>(Nucleus::createNot(val.value));
5705 }
5706
John Bauman19bac1e2014-05-06 15:23:49 -04005707 RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y)
5708 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005709 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
Alexis Hetufb603992016-04-26 11:50:40 -04005710 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5711 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
5712 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005713 }
5714
5715 RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y)
5716 {
5717 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLT(x.value, y.value), Int4::getType()));
5718 }
5719
5720 RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y)
5721 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005722 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5723 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5724 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLE(x.value, y.value), Int4::getType()));
5725 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGT(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005726 }
5727
5728 RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y)
5729 {
5730 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
5731 }
5732
5733 RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y)
5734 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005735 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5736 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5737 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGE(x.value, y.value), Int4::getType()));
5738 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLT(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005739 }
5740
5741 RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y)
5742 {
5743 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGT(x.value, y.value), Int4::getType()));
5744 }
5745
5746 RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y)
5747 {
5748 if(CPUID::supportsSSE4_1())
5749 {
5750 return x86::pmaxsd(x, y);
5751 }
5752 else
5753 {
5754 RValue<Int4> greater = CmpNLE(x, y);
5755 return x & greater | y & ~greater;
5756 }
5757 }
5758
5759 RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y)
5760 {
5761 if(CPUID::supportsSSE4_1())
5762 {
5763 return x86::pminsd(x, y);
5764 }
5765 else
5766 {
5767 RValue<Int4> less = CmpLT(x, y);
5768 return x & less | y & ~less;
5769 }
5770 }
5771
5772 RValue<Int4> RoundInt(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005773 {
5774 return x86::cvtps2dq(cast);
5775 }
5776
John Bauman19bac1e2014-05-06 15:23:49 -04005777 RValue<Short8> Pack(RValue<Int4> x, RValue<Int4> y)
John Bauman89401822014-05-06 15:04:28 -04005778 {
5779 return x86::packssdw(x, y);
5780 }
5781
John Bauman19bac1e2014-05-06 15:23:49 -04005782 RValue<Int> Extract(RValue<Int4> x, int i)
John Bauman89401822014-05-06 15:04:28 -04005783 {
5784 return RValue<Int>(Nucleus::createExtractElement(x.value, i));
5785 }
5786
John Bauman19bac1e2014-05-06 15:23:49 -04005787 RValue<Int4> Insert(RValue<Int4> x, RValue<Int> element, int i)
John Bauman89401822014-05-06 15:04:28 -04005788 {
5789 return RValue<Int4>(Nucleus::createInsertElement(x.value, element.value, i));
5790 }
5791
John Bauman19bac1e2014-05-06 15:23:49 -04005792 RValue<Int> SignMask(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04005793 {
5794 return x86::movmskps(As<Float4>(x));
5795 }
5796
John Bauman19bac1e2014-05-06 15:23:49 -04005797 RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04005798 {
5799 return RValue<Int4>(Nucleus::createSwizzle(x.value, select));
5800 }
5801
John Bauman19bac1e2014-05-06 15:23:49 -04005802 Type *Int4::getType()
John Bauman89401822014-05-06 15:04:28 -04005803 {
Nicolas Capensac230122016-09-20 14:30:06 -04005804 return T(VectorType::get(Int::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04005805 }
5806
John Bauman19bac1e2014-05-06 15:23:49 -04005807 UInt4::UInt4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005808 {
5809 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005810
Alexis Hetu764d1422016-09-28 08:44:22 -04005811 // Note: createFPToUI is broken, must perform conversion using createFPtoSI
5812 // Value *xyzw = Nucleus::createFPToUI(cast.value, UInt4::getType());
John Bauman89401822014-05-06 15:04:28 -04005813
Alexis Hetu764d1422016-09-28 08:44:22 -04005814 // Smallest positive value representable in UInt, but not in Int
5815 const unsigned int ustart = 0x80000000u;
5816 const float ustartf = float(ustart);
5817
5818 // Check if the value can be represented as an Int
5819 Int4 uiValue = CmpNLT(cast, Float4(ustartf));
5820 // If the value is too large, subtract ustart and re-add it after conversion.
5821 uiValue = (uiValue & As<Int4>(As<UInt4>(Int4(cast - Float4(ustartf))) + UInt4(ustart))) |
5822 // Otherwise, just convert normally
5823 (~uiValue & Int4(cast));
5824 // If the value is negative, store 0, otherwise store the result of the conversion
5825 storeValue((~(As<Int4>(cast) >> 31) & uiValue).value);
John Bauman89401822014-05-06 15:04:28 -04005826 }
5827
5828 UInt4::UInt4()
5829 {
5830 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005831 }
5832
John Bauman19bac1e2014-05-06 15:23:49 -04005833 UInt4::UInt4(int xyzw)
5834 {
5835 constant(xyzw, xyzw, xyzw, xyzw);
5836 }
5837
5838 UInt4::UInt4(int x, int yzw)
5839 {
5840 constant(x, yzw, yzw, yzw);
5841 }
5842
5843 UInt4::UInt4(int x, int y, int zw)
5844 {
5845 constant(x, y, zw, zw);
5846 }
5847
5848 UInt4::UInt4(int x, int y, int z, int w)
5849 {
5850 constant(x, y, z, w);
5851 }
5852
5853 void UInt4::constant(int x, int y, int z, int w)
John Bauman89401822014-05-06 15:04:28 -04005854 {
5855 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005856
5857 Constant *constantVector[4];
5858 constantVector[0] = Nucleus::createConstantInt(x);
5859 constantVector[1] = Nucleus::createConstantInt(y);
5860 constantVector[2] = Nucleus::createConstantInt(z);
5861 constantVector[3] = Nucleus::createConstantInt(w);
5862
John Bauman66b8ab22014-05-06 15:57:45 -04005863 storeValue(Nucleus::createConstantVector(constantVector, 4));
John Bauman89401822014-05-06 15:04:28 -04005864 }
5865
John Bauman19bac1e2014-05-06 15:23:49 -04005866 UInt4::UInt4(RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005867 {
5868 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005869
John Bauman66b8ab22014-05-06 15:57:45 -04005870 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005871 }
5872
5873 UInt4::UInt4(const UInt4 &rhs)
5874 {
5875 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005876
John Bauman66b8ab22014-05-06 15:57:45 -04005877 Value *value = rhs.loadValue();
5878 storeValue(value);
5879 }
5880
5881 UInt4::UInt4(const Reference<UInt4> &rhs)
5882 {
5883 // xyzw.parent = this;
5884
5885 Value *value = rhs.loadValue();
5886 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005887 }
5888
John Bauman19bac1e2014-05-06 15:23:49 -04005889 UInt4::UInt4(RValue<Int4> rhs)
5890 {
5891 // xyzw.parent = this;
John Bauman19bac1e2014-05-06 15:23:49 -04005892
John Bauman66b8ab22014-05-06 15:57:45 -04005893 storeValue(rhs.value);
John Bauman19bac1e2014-05-06 15:23:49 -04005894 }
5895
5896 UInt4::UInt4(const Int4 &rhs)
5897 {
5898 // xyzw.parent = this;
John Bauman19bac1e2014-05-06 15:23:49 -04005899
John Bauman66b8ab22014-05-06 15:57:45 -04005900 Value *value = rhs.loadValue();
5901 storeValue(value);
5902 }
5903
5904 UInt4::UInt4(const Reference<Int4> &rhs)
5905 {
5906 // xyzw.parent = this;
5907
5908 Value *value = rhs.loadValue();
5909 storeValue(value);
John Bauman19bac1e2014-05-06 15:23:49 -04005910 }
5911
Nicolas Capens62abb552016-01-05 12:03:47 -05005912 UInt4::UInt4(RValue<UInt2> lo, RValue<UInt2> hi)
5913 {
5914 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
5915 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
5916
5917 Value *long2 = UndefValue::get(Long2::getType());
5918 long2 = Nucleus::createInsertElement(long2, loLong, 0);
5919 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
5920 Value *uint4 = Nucleus::createBitCast(long2, Int4::getType());
5921
5922 storeValue(uint4);
5923 }
5924
John Bauman19bac1e2014-05-06 15:23:49 -04005925 RValue<UInt4> UInt4::operator=(RValue<UInt4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04005926 {
John Bauman66b8ab22014-05-06 15:57:45 -04005927 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005928
5929 return rhs;
5930 }
5931
5932 RValue<UInt4> UInt4::operator=(const UInt4 &rhs) const
5933 {
John Bauman66b8ab22014-05-06 15:57:45 -04005934 Value *value = rhs.loadValue();
5935 storeValue(value);
5936
5937 return RValue<UInt4>(value);
5938 }
5939
5940 RValue<UInt4> UInt4::operator=(const Reference<UInt4> &rhs) const
5941 {
5942 Value *value = rhs.loadValue();
5943 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005944
5945 return RValue<UInt4>(value);
5946 }
5947
John Bauman19bac1e2014-05-06 15:23:49 -04005948 RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005949 {
5950 return RValue<UInt4>(Nucleus::createAdd(lhs.value, rhs.value));
5951 }
5952
John Bauman19bac1e2014-05-06 15:23:49 -04005953 RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005954 {
5955 return RValue<UInt4>(Nucleus::createSub(lhs.value, rhs.value));
5956 }
5957
John Bauman19bac1e2014-05-06 15:23:49 -04005958 RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005959 {
5960 return RValue<UInt4>(Nucleus::createMul(lhs.value, rhs.value));
5961 }
5962
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005963 RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs)
5964 {
5965 return RValue<UInt4>(Nucleus::createUDiv(lhs.value, rhs.value));
5966 }
John Bauman89401822014-05-06 15:04:28 -04005967
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005968 RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs)
5969 {
5970 return RValue<UInt4>(Nucleus::createURem(lhs.value, rhs.value));
5971 }
John Bauman89401822014-05-06 15:04:28 -04005972
John Bauman19bac1e2014-05-06 15:23:49 -04005973 RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005974 {
5975 return RValue<UInt4>(Nucleus::createAnd(lhs.value, rhs.value));
5976 }
5977
John Bauman19bac1e2014-05-06 15:23:49 -04005978 RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005979 {
5980 return RValue<UInt4>(Nucleus::createOr(lhs.value, rhs.value));
5981 }
5982
John Bauman19bac1e2014-05-06 15:23:49 -04005983 RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005984 {
5985 return RValue<UInt4>(Nucleus::createXor(lhs.value, rhs.value));
5986 }
5987
John Bauman19bac1e2014-05-06 15:23:49 -04005988 RValue<UInt4> operator<<(RValue<UInt4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005989 {
John Bauman89401822014-05-06 15:04:28 -04005990 return As<UInt4>(x86::pslld(As<Int4>(lhs), rhs));
5991 }
5992
John Bauman19bac1e2014-05-06 15:23:49 -04005993 RValue<UInt4> operator>>(RValue<UInt4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005994 {
John Bauman89401822014-05-06 15:04:28 -04005995 return x86::psrld(lhs, rhs);
5996 }
5997
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005998 RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs)
5999 {
6000 return RValue<UInt4>(Nucleus::createShl(lhs.value, rhs.value));
6001 }
6002
6003 RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs)
6004 {
6005 return RValue<UInt4>(Nucleus::createLShr(lhs.value, rhs.value));
6006 }
6007
John Bauman19bac1e2014-05-06 15:23:49 -04006008 RValue<UInt4> operator+=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006009 {
6010 return lhs = lhs + rhs;
6011 }
6012
John Bauman19bac1e2014-05-06 15:23:49 -04006013 RValue<UInt4> operator-=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006014 {
6015 return lhs = lhs - rhs;
6016 }
6017
John Bauman19bac1e2014-05-06 15:23:49 -04006018 RValue<UInt4> operator*=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006019 {
6020 return lhs = lhs * rhs;
6021 }
6022
John Bauman19bac1e2014-05-06 15:23:49 -04006023// RValue<UInt4> operator/=(const UInt4 &lhs, RValue<UInt4> rhs)
6024// {
6025// return lhs = lhs / rhs;
6026// }
John Bauman89401822014-05-06 15:04:28 -04006027
John Bauman19bac1e2014-05-06 15:23:49 -04006028// RValue<UInt4> operator%=(const UInt4 &lhs, RValue<UInt4> rhs)
6029// {
6030// return lhs = lhs % rhs;
6031// }
John Bauman89401822014-05-06 15:04:28 -04006032
John Bauman19bac1e2014-05-06 15:23:49 -04006033 RValue<UInt4> operator&=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006034 {
6035 return lhs = lhs & rhs;
6036 }
6037
John Bauman19bac1e2014-05-06 15:23:49 -04006038 RValue<UInt4> operator|=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006039 {
6040 return lhs = lhs | rhs;
6041 }
6042
John Bauman19bac1e2014-05-06 15:23:49 -04006043 RValue<UInt4> operator^=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006044 {
6045 return lhs = lhs ^ rhs;
6046 }
6047
6048 RValue<UInt4> operator<<=(const UInt4 &lhs, unsigned char rhs)
6049 {
6050 return lhs = lhs << rhs;
6051 }
6052
6053 RValue<UInt4> operator>>=(const UInt4 &lhs, unsigned char rhs)
6054 {
6055 return lhs = lhs >> rhs;
6056 }
6057
John Bauman19bac1e2014-05-06 15:23:49 -04006058 RValue<UInt4> operator+(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04006059 {
6060 return val;
6061 }
6062
John Bauman19bac1e2014-05-06 15:23:49 -04006063 RValue<UInt4> operator-(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04006064 {
6065 return RValue<UInt4>(Nucleus::createNeg(val.value));
6066 }
6067
John Bauman19bac1e2014-05-06 15:23:49 -04006068 RValue<UInt4> operator~(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04006069 {
6070 return RValue<UInt4>(Nucleus::createNot(val.value));
6071 }
6072
John Bauman19bac1e2014-05-06 15:23:49 -04006073 RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y)
6074 {
Nicolas Capens197226a2016-04-27 23:08:50 -04006075 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
Alexis Hetufb603992016-04-26 11:50:40 -04006076 // Restore the following line when LLVM is updated to a version where this issue is fixed.
6077 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
6078 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04006079 }
6080
6081 RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y)
6082 {
6083 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULT(x.value, y.value), Int4::getType()));
6084 }
6085
6086 RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y)
6087 {
Nicolas Capens197226a2016-04-27 23:08:50 -04006088 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
6089 // Restore the following line when LLVM is updated to a version where this issue is fixed.
6090 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULE(x.value, y.value), Int4::getType()));
6091 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGT(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04006092 }
6093
6094 RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y)
6095 {
6096 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
6097 }
6098
6099 RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y)
6100 {
Nicolas Capens197226a2016-04-27 23:08:50 -04006101 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
6102 // Restore the following line when LLVM is updated to a version where this issue is fixed.
6103 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGE(x.value, y.value), Int4::getType()));
6104 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULT(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04006105 }
6106
6107 RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y)
6108 {
6109 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGT(x.value, y.value), Int4::getType()));
6110 }
6111
6112 RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y)
6113 {
6114 if(CPUID::supportsSSE4_1())
6115 {
6116 return x86::pmaxud(x, y);
6117 }
6118 else
6119 {
6120 RValue<UInt4> greater = CmpNLE(x, y);
6121 return x & greater | y & ~greater;
6122 }
6123 }
6124
6125 RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y)
6126 {
6127 if(CPUID::supportsSSE4_1())
6128 {
6129 return x86::pminud(x, y);
6130 }
6131 else
6132 {
6133 RValue<UInt4> less = CmpLT(x, y);
6134 return x & less | y & ~less;
6135 }
6136 }
6137
6138 RValue<UShort8> Pack(RValue<UInt4> x, RValue<UInt4> y)
John Bauman89401822014-05-06 15:04:28 -04006139 {
6140 return x86::packusdw(x, y); // FIXME: Fallback required
6141 }
6142
John Bauman19bac1e2014-05-06 15:23:49 -04006143 Type *UInt4::getType()
John Bauman89401822014-05-06 15:04:28 -04006144 {
Nicolas Capensac230122016-09-20 14:30:06 -04006145 return T(VectorType::get(UInt::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04006146 }
6147
John Bauman19bac1e2014-05-06 15:23:49 -04006148 Float::Float(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04006149 {
John Bauman89401822014-05-06 15:04:28 -04006150 Value *integer = Nucleus::createSIToFP(cast.value, Float::getType());
6151
John Bauman66b8ab22014-05-06 15:57:45 -04006152 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04006153 }
6154
6155 Float::Float()
6156 {
John Bauman66b8ab22014-05-06 15:57:45 -04006157
John Bauman89401822014-05-06 15:04:28 -04006158 }
6159
6160 Float::Float(float x)
6161 {
John Bauman66b8ab22014-05-06 15:57:45 -04006162 storeValue(Nucleus::createConstantFloat(x));
John Bauman89401822014-05-06 15:04:28 -04006163 }
6164
John Bauman19bac1e2014-05-06 15:23:49 -04006165 Float::Float(RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006166 {
John Bauman66b8ab22014-05-06 15:57:45 -04006167 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04006168 }
6169
6170 Float::Float(const Float &rhs)
6171 {
John Bauman66b8ab22014-05-06 15:57:45 -04006172 Value *value = rhs.loadValue();
6173 storeValue(value);
6174 }
John Bauman89401822014-05-06 15:04:28 -04006175
John Bauman66b8ab22014-05-06 15:57:45 -04006176 Float::Float(const Reference<Float> &rhs)
6177 {
6178 Value *value = rhs.loadValue();
6179 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04006180 }
6181
John Bauman19bac1e2014-05-06 15:23:49 -04006182 RValue<Float> Float::operator=(RValue<Float> rhs) const
John Bauman89401822014-05-06 15:04:28 -04006183 {
John Bauman66b8ab22014-05-06 15:57:45 -04006184 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04006185
6186 return rhs;
6187 }
6188
6189 RValue<Float> Float::operator=(const Float &rhs) const
6190 {
John Bauman66b8ab22014-05-06 15:57:45 -04006191 Value *value = rhs.loadValue();
6192 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04006193
6194 return RValue<Float>(value);
6195 }
6196
John Bauman66b8ab22014-05-06 15:57:45 -04006197 RValue<Float> Float::operator=(const Reference<Float> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04006198 {
John Bauman66b8ab22014-05-06 15:57:45 -04006199 Value *value = rhs.loadValue();
6200 storeValue(value);
6201
6202 return RValue<Float>(value);
John Bauman89401822014-05-06 15:04:28 -04006203 }
6204
John Bauman19bac1e2014-05-06 15:23:49 -04006205 RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006206 {
6207 return RValue<Float>(Nucleus::createFAdd(lhs.value, rhs.value));
6208 }
6209
John Bauman19bac1e2014-05-06 15:23:49 -04006210 RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006211 {
6212 return RValue<Float>(Nucleus::createFSub(lhs.value, rhs.value));
6213 }
6214
John Bauman19bac1e2014-05-06 15:23:49 -04006215 RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006216 {
6217 return RValue<Float>(Nucleus::createFMul(lhs.value, rhs.value));
6218 }
6219
John Bauman19bac1e2014-05-06 15:23:49 -04006220 RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006221 {
6222 return RValue<Float>(Nucleus::createFDiv(lhs.value, rhs.value));
6223 }
6224
John Bauman19bac1e2014-05-06 15:23:49 -04006225 RValue<Float> operator+=(const Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006226 {
6227 return lhs = lhs + rhs;
6228 }
6229
John Bauman19bac1e2014-05-06 15:23:49 -04006230 RValue<Float> operator-=(const Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006231 {
6232 return lhs = lhs - rhs;
6233 }
6234
John Bauman19bac1e2014-05-06 15:23:49 -04006235 RValue<Float> operator*=(const Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006236 {
6237 return lhs = lhs * rhs;
6238 }
6239
John Bauman19bac1e2014-05-06 15:23:49 -04006240 RValue<Float> operator/=(const Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006241 {
6242 return lhs = lhs / rhs;
6243 }
6244
John Bauman19bac1e2014-05-06 15:23:49 -04006245 RValue<Float> operator+(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006246 {
6247 return val;
6248 }
6249
John Bauman19bac1e2014-05-06 15:23:49 -04006250 RValue<Float> operator-(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006251 {
6252 return RValue<Float>(Nucleus::createFNeg(val.value));
6253 }
6254
John Bauman19bac1e2014-05-06 15:23:49 -04006255 RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006256 {
6257 return RValue<Bool>(Nucleus::createFCmpOLT(lhs.value, rhs.value));
6258 }
6259
John Bauman19bac1e2014-05-06 15:23:49 -04006260 RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006261 {
6262 return RValue<Bool>(Nucleus::createFCmpOLE(lhs.value, rhs.value));
6263 }
6264
John Bauman19bac1e2014-05-06 15:23:49 -04006265 RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006266 {
6267 return RValue<Bool>(Nucleus::createFCmpOGT(lhs.value, rhs.value));
6268 }
6269
John Bauman19bac1e2014-05-06 15:23:49 -04006270 RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006271 {
6272 return RValue<Bool>(Nucleus::createFCmpOGE(lhs.value, rhs.value));
6273 }
6274
John Bauman19bac1e2014-05-06 15:23:49 -04006275 RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006276 {
6277 return RValue<Bool>(Nucleus::createFCmpONE(lhs.value, rhs.value));
6278 }
6279
John Bauman19bac1e2014-05-06 15:23:49 -04006280 RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006281 {
6282 return RValue<Bool>(Nucleus::createFCmpOEQ(lhs.value, rhs.value));
6283 }
6284
John Bauman19bac1e2014-05-06 15:23:49 -04006285 RValue<Float> Abs(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006286 {
John Bauman66b8ab22014-05-06 15:57:45 -04006287 return IfThenElse(x > 0.0f, x, -x);
John Bauman89401822014-05-06 15:04:28 -04006288 }
6289
John Bauman19bac1e2014-05-06 15:23:49 -04006290 RValue<Float> Max(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006291 {
6292 return IfThenElse(x > y, x, y);
6293 }
6294
John Bauman19bac1e2014-05-06 15:23:49 -04006295 RValue<Float> Min(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006296 {
6297 return IfThenElse(x < y, x, y);
6298 }
6299
Nicolas Capens05b3d662016-02-25 23:58:33 -05006300 RValue<Float> Rcp_pp(RValue<Float> x, bool exactAtPow2)
John Bauman89401822014-05-06 15:04:28 -04006301 {
Nicolas Capens05b3d662016-02-25 23:58:33 -05006302 if(exactAtPow2)
6303 {
6304 // rcpss uses a piecewise-linear approximation which minimizes the relative error
6305 // but is not exact at power-of-two values. Rectify by multiplying by the inverse.
6306 return x86::rcpss(x) * Float(1.0f / _mm_cvtss_f32(_mm_rcp_ss(_mm_set_ps1(1.0f))));
6307 }
6308 else
6309 {
6310 return x86::rcpss(x);
6311 }
John Bauman89401822014-05-06 15:04:28 -04006312 }
John Bauman66b8ab22014-05-06 15:57:45 -04006313
John Bauman19bac1e2014-05-06 15:23:49 -04006314 RValue<Float> RcpSqrt_pp(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006315 {
6316 return x86::rsqrtss(x);
6317 }
6318
John Bauman19bac1e2014-05-06 15:23:49 -04006319 RValue<Float> Sqrt(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006320 {
6321 return x86::sqrtss(x);
6322 }
6323
John Bauman19bac1e2014-05-06 15:23:49 -04006324 RValue<Float> Round(RValue<Float> x)
6325 {
6326 if(CPUID::supportsSSE4_1())
6327 {
6328 return x86::roundss(x, 0);
6329 }
6330 else
6331 {
6332 return Float4(Round(Float4(x))).x;
6333 }
6334 }
6335
6336 RValue<Float> Trunc(RValue<Float> x)
6337 {
6338 if(CPUID::supportsSSE4_1())
6339 {
6340 return x86::roundss(x, 3);
6341 }
6342 else
6343 {
6344 return Float(Int(x)); // Rounded toward zero
6345 }
6346 }
6347
6348 RValue<Float> Frac(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006349 {
6350 if(CPUID::supportsSSE4_1())
6351 {
6352 return x - x86::floorss(x);
6353 }
6354 else
6355 {
John Bauman19bac1e2014-05-06 15:23:49 -04006356 return Float4(Frac(Float4(x))).x;
John Bauman89401822014-05-06 15:04:28 -04006357 }
6358 }
6359
John Bauman19bac1e2014-05-06 15:23:49 -04006360 RValue<Float> Floor(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006361 {
6362 if(CPUID::supportsSSE4_1())
6363 {
6364 return x86::floorss(x);
6365 }
6366 else
6367 {
6368 return Float4(Floor(Float4(x))).x;
6369 }
6370 }
6371
John Bauman19bac1e2014-05-06 15:23:49 -04006372 RValue<Float> Ceil(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006373 {
John Bauman19bac1e2014-05-06 15:23:49 -04006374 if(CPUID::supportsSSE4_1())
6375 {
6376 return x86::ceilss(x);
6377 }
6378 else
6379 {
6380 return Float4(Ceil(Float4(x))).x;
6381 }
John Bauman89401822014-05-06 15:04:28 -04006382 }
6383
John Bauman19bac1e2014-05-06 15:23:49 -04006384 Type *Float::getType()
John Bauman89401822014-05-06 15:04:28 -04006385 {
Nicolas Capensac230122016-09-20 14:30:06 -04006386 return T(llvm::Type::getFloatTy(*::context));
John Bauman89401822014-05-06 15:04:28 -04006387 }
6388
John Bauman19bac1e2014-05-06 15:23:49 -04006389 Float2::Float2(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04006390 {
6391 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006392
6393 Value *int64x2 = Nucleus::createBitCast(cast.value, Long2::getType());
6394 Value *int64 = Nucleus::createExtractElement(int64x2, 0);
6395 Value *float2 = Nucleus::createBitCast(int64, Float2::getType());
6396
John Bauman66b8ab22014-05-06 15:57:45 -04006397 storeValue(float2);
John Bauman89401822014-05-06 15:04:28 -04006398 }
6399
John Bauman19bac1e2014-05-06 15:23:49 -04006400 Type *Float2::getType()
John Bauman89401822014-05-06 15:04:28 -04006401 {
Nicolas Capensac230122016-09-20 14:30:06 -04006402 return T(VectorType::get(Float::getType(), 2));
John Bauman89401822014-05-06 15:04:28 -04006403 }
6404
John Bauman19bac1e2014-05-06 15:23:49 -04006405 Float4::Float4(RValue<Byte4> cast)
John Bauman89401822014-05-06 15:04:28 -04006406 {
6407 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006408
6409 #if 0
6410 Value *xyzw = Nucleus::createUIToFP(cast.value, Float4::getType()); // FIXME: Crashes
6411 #elif 0
John Bauman66b8ab22014-05-06 15:57:45 -04006412 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04006413
6414 Value *i8x = Nucleus::createExtractElement(cast.value, 0);
6415 Value *f32x = Nucleus::createUIToFP(i8x, Float::getType());
6416 Value *x = Nucleus::createInsertElement(vector, f32x, 0);
6417
6418 Value *i8y = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(1));
6419 Value *f32y = Nucleus::createUIToFP(i8y, Float::getType());
6420 Value *xy = Nucleus::createInsertElement(x, f32y, Nucleus::createConstantInt(1));
6421
6422 Value *i8z = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(2));
6423 Value *f32z = Nucleus::createUIToFP(i8z, Float::getType());
6424 Value *xyz = Nucleus::createInsertElement(xy, f32z, Nucleus::createConstantInt(2));
6425
6426 Value *i8w = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(3));
6427 Value *f32w = Nucleus::createUIToFP(i8w, Float::getType());
6428 Value *xyzw = Nucleus::createInsertElement(xyz, f32w, Nucleus::createConstantInt(3));
6429 #else
Meng-Lin Wu601d0052016-06-10 14:18:41 -04006430 Value *a = Int4(cast).loadValue();
6431 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04006432 #endif
John Bauman66b8ab22014-05-06 15:57:45 -04006433
6434 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04006435 }
6436
John Bauman19bac1e2014-05-06 15:23:49 -04006437 Float4::Float4(RValue<SByte4> cast)
John Bauman89401822014-05-06 15:04:28 -04006438 {
6439 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006440
6441 #if 0
6442 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType()); // FIXME: Crashes
6443 #elif 0
John Bauman66b8ab22014-05-06 15:57:45 -04006444 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04006445
6446 Value *i8x = Nucleus::createExtractElement(cast.value, 0);
6447 Value *f32x = Nucleus::createSIToFP(i8x, Float::getType());
6448 Value *x = Nucleus::createInsertElement(vector, f32x, 0);
6449
6450 Value *i8y = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(1));
6451 Value *f32y = Nucleus::createSIToFP(i8y, Float::getType());
6452 Value *xy = Nucleus::createInsertElement(x, f32y, Nucleus::createConstantInt(1));
6453
6454 Value *i8z = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(2));
6455 Value *f32z = Nucleus::createSIToFP(i8z, Float::getType());
6456 Value *xyz = Nucleus::createInsertElement(xy, f32z, Nucleus::createConstantInt(2));
6457
6458 Value *i8w = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(3));
6459 Value *f32w = Nucleus::createSIToFP(i8w, Float::getType());
6460 Value *xyzw = Nucleus::createInsertElement(xyz, f32w, Nucleus::createConstantInt(3));
6461 #else
Meng-Lin Wu601d0052016-06-10 14:18:41 -04006462 Value *a = Int4(cast).loadValue();
6463 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04006464 #endif
John Bauman66b8ab22014-05-06 15:57:45 -04006465
6466 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04006467 }
6468
John Bauman19bac1e2014-05-06 15:23:49 -04006469 Float4::Float4(RValue<Short4> cast)
John Bauman89401822014-05-06 15:04:28 -04006470 {
6471 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006472
Alexis Hetu2aa852f2015-10-14 16:32:39 -04006473 Int4 c(cast);
6474 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
John Bauman89401822014-05-06 15:04:28 -04006475 }
6476
John Bauman19bac1e2014-05-06 15:23:49 -04006477 Float4::Float4(RValue<UShort4> cast)
John Bauman89401822014-05-06 15:04:28 -04006478 {
6479 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006480
Alexis Hetu2aa852f2015-10-14 16:32:39 -04006481 Int4 c(cast);
6482 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
John Bauman89401822014-05-06 15:04:28 -04006483 }
6484
John Bauman19bac1e2014-05-06 15:23:49 -04006485 Float4::Float4(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04006486 {
6487 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006488
6489 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04006490
John Bauman66b8ab22014-05-06 15:57:45 -04006491 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04006492 }
6493
John Bauman19bac1e2014-05-06 15:23:49 -04006494 Float4::Float4(RValue<UInt4> cast)
John Bauman89401822014-05-06 15:04:28 -04006495 {
6496 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006497
6498 Value *xyzw = Nucleus::createUIToFP(cast.value, Float4::getType());
6499
John Bauman66b8ab22014-05-06 15:57:45 -04006500 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04006501 }
6502
6503 Float4::Float4()
6504 {
6505 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006506 }
John Bauman66b8ab22014-05-06 15:57:45 -04006507
John Bauman89401822014-05-06 15:04:28 -04006508 Float4::Float4(float xyzw)
6509 {
6510 constant(xyzw, xyzw, xyzw, xyzw);
6511 }
6512
6513 Float4::Float4(float x, float yzw)
6514 {
6515 constant(x, yzw, yzw, yzw);
6516 }
6517
6518 Float4::Float4(float x, float y, float zw)
6519 {
6520 constant(x, y, zw, zw);
6521 }
6522
6523 Float4::Float4(float x, float y, float z, float w)
6524 {
6525 constant(x, y, z, w);
6526 }
6527
6528 void Float4::constant(float x, float y, float z, float w)
6529 {
6530 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006531
6532 Constant *constantVector[4];
6533 constantVector[0] = Nucleus::createConstantFloat(x);
6534 constantVector[1] = Nucleus::createConstantFloat(y);
6535 constantVector[2] = Nucleus::createConstantFloat(z);
6536 constantVector[3] = Nucleus::createConstantFloat(w);
6537
John Bauman66b8ab22014-05-06 15:57:45 -04006538 storeValue(Nucleus::createConstantVector(constantVector, 4));
John Bauman89401822014-05-06 15:04:28 -04006539 }
6540
John Bauman19bac1e2014-05-06 15:23:49 -04006541 Float4::Float4(RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006542 {
6543 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006544
John Bauman66b8ab22014-05-06 15:57:45 -04006545 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04006546 }
6547
6548 Float4::Float4(const Float4 &rhs)
6549 {
6550 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006551
John Bauman66b8ab22014-05-06 15:57:45 -04006552 Value *value = rhs.loadValue();
6553 storeValue(value);
6554 }
6555
6556 Float4::Float4(const Reference<Float4> &rhs)
6557 {
6558 xyzw.parent = this;
6559
6560 Value *value = rhs.loadValue();
6561 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04006562 }
6563
John Bauman19bac1e2014-05-06 15:23:49 -04006564 Float4::Float4(RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006565 {
6566 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006567
John Bauman66b8ab22014-05-06 15:57:45 -04006568 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04006569 Value *insert = Nucleus::createInsertElement(vector, rhs.value, 0);
6570
6571 Constant *swizzle[4];
6572 swizzle[0] = Nucleus::createConstantInt(0);
6573 swizzle[1] = Nucleus::createConstantInt(0);
6574 swizzle[2] = Nucleus::createConstantInt(0);
6575 swizzle[3] = Nucleus::createConstantInt(0);
6576
6577 Value *replicate = Nucleus::createShuffleVector(insert, UndefValue::get(Float4::getType()), Nucleus::createConstantVector(swizzle, 4));
6578
John Bauman66b8ab22014-05-06 15:57:45 -04006579 storeValue(replicate);
John Bauman89401822014-05-06 15:04:28 -04006580 }
6581
6582 Float4::Float4(const Float &rhs)
6583 {
6584 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006585
John Bauman66b8ab22014-05-06 15:57:45 -04006586 *this = RValue<Float>(rhs.loadValue());
6587 }
John Bauman89401822014-05-06 15:04:28 -04006588
John Bauman66b8ab22014-05-06 15:57:45 -04006589 Float4::Float4(const Reference<Float> &rhs)
6590 {
6591 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006592
John Bauman66b8ab22014-05-06 15:57:45 -04006593 *this = RValue<Float>(rhs.loadValue());
John Bauman89401822014-05-06 15:04:28 -04006594 }
6595
6596 RValue<Float4> Float4::operator=(float x) const
6597 {
6598 return *this = Float4(x, x, x, x);
6599 }
6600
John Bauman19bac1e2014-05-06 15:23:49 -04006601 RValue<Float4> Float4::operator=(RValue<Float4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04006602 {
John Bauman66b8ab22014-05-06 15:57:45 -04006603 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04006604
6605 return rhs;
6606 }
6607
6608 RValue<Float4> Float4::operator=(const Float4 &rhs) const
6609 {
John Bauman66b8ab22014-05-06 15:57:45 -04006610 Value *value = rhs.loadValue();
6611 storeValue(value);
6612
6613 return RValue<Float4>(value);
6614 }
6615
6616 RValue<Float4> Float4::operator=(const Reference<Float4> &rhs) const
6617 {
6618 Value *value = rhs.loadValue();
6619 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04006620
6621 return RValue<Float4>(value);
6622 }
6623
John Bauman19bac1e2014-05-06 15:23:49 -04006624 RValue<Float4> Float4::operator=(RValue<Float> rhs) const
John Bauman89401822014-05-06 15:04:28 -04006625 {
6626 return *this = Float4(rhs);
6627 }
6628
6629 RValue<Float4> Float4::operator=(const Float &rhs) const
6630 {
6631 return *this = Float4(rhs);
6632 }
6633
John Bauman66b8ab22014-05-06 15:57:45 -04006634 RValue<Float4> Float4::operator=(const Reference<Float> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04006635 {
John Bauman66b8ab22014-05-06 15:57:45 -04006636 return *this = Float4(rhs);
John Bauman89401822014-05-06 15:04:28 -04006637 }
6638
John Bauman19bac1e2014-05-06 15:23:49 -04006639 RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006640 {
6641 return RValue<Float4>(Nucleus::createFAdd(lhs.value, rhs.value));
6642 }
6643
John Bauman19bac1e2014-05-06 15:23:49 -04006644 RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006645 {
6646 return RValue<Float4>(Nucleus::createFSub(lhs.value, rhs.value));
6647 }
6648
John Bauman19bac1e2014-05-06 15:23:49 -04006649 RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006650 {
6651 return RValue<Float4>(Nucleus::createFMul(lhs.value, rhs.value));
6652 }
6653
John Bauman19bac1e2014-05-06 15:23:49 -04006654 RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006655 {
6656 return RValue<Float4>(Nucleus::createFDiv(lhs.value, rhs.value));
6657 }
6658
John Bauman19bac1e2014-05-06 15:23:49 -04006659 RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006660 {
6661 return RValue<Float4>(Nucleus::createFRem(lhs.value, rhs.value));
6662 }
6663
John Bauman19bac1e2014-05-06 15:23:49 -04006664 RValue<Float4> operator+=(const Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006665 {
6666 return lhs = lhs + rhs;
6667 }
6668
John Bauman19bac1e2014-05-06 15:23:49 -04006669 RValue<Float4> operator-=(const Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006670 {
6671 return lhs = lhs - rhs;
6672 }
6673
John Bauman19bac1e2014-05-06 15:23:49 -04006674 RValue<Float4> operator*=(const Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006675 {
6676 return lhs = lhs * rhs;
6677 }
6678
John Bauman19bac1e2014-05-06 15:23:49 -04006679 RValue<Float4> operator/=(const Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006680 {
6681 return lhs = lhs / rhs;
6682 }
6683
John Bauman19bac1e2014-05-06 15:23:49 -04006684 RValue<Float4> operator%=(const Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006685 {
6686 return lhs = lhs % rhs;
6687 }
6688
John Bauman19bac1e2014-05-06 15:23:49 -04006689 RValue<Float4> operator+(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006690 {
6691 return val;
6692 }
6693
John Bauman19bac1e2014-05-06 15:23:49 -04006694 RValue<Float4> operator-(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006695 {
6696 return RValue<Float4>(Nucleus::createFNeg(val.value));
6697 }
6698
John Bauman19bac1e2014-05-06 15:23:49 -04006699 RValue<Float4> Abs(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006700 {
6701 Value *vector = Nucleus::createBitCast(x.value, Int4::getType());
6702
6703 Constant *constantVector[4];
6704 constantVector[0] = Nucleus::createConstantInt(0x7FFFFFFF);
6705 constantVector[1] = Nucleus::createConstantInt(0x7FFFFFFF);
6706 constantVector[2] = Nucleus::createConstantInt(0x7FFFFFFF);
6707 constantVector[3] = Nucleus::createConstantInt(0x7FFFFFFF);
6708
6709 Value *result = Nucleus::createAnd(vector, Nucleus::createConstantVector(constantVector, 4));
6710
6711 return RValue<Float4>(Nucleus::createBitCast(result, Float4::getType()));
6712 }
6713
John Bauman19bac1e2014-05-06 15:23:49 -04006714 RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006715 {
6716 return x86::maxps(x, y);
6717 }
6718
John Bauman19bac1e2014-05-06 15:23:49 -04006719 RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006720 {
6721 return x86::minps(x, y);
6722 }
6723
Nicolas Capens05b3d662016-02-25 23:58:33 -05006724 RValue<Float4> Rcp_pp(RValue<Float4> x, bool exactAtPow2)
John Bauman89401822014-05-06 15:04:28 -04006725 {
Nicolas Capens05b3d662016-02-25 23:58:33 -05006726 if(exactAtPow2)
6727 {
6728 // rcpps uses a piecewise-linear approximation which minimizes the relative error
6729 // but is not exact at power-of-two values. Rectify by multiplying by the inverse.
6730 return x86::rcpps(x) * Float4(1.0f / _mm_cvtss_f32(_mm_rcp_ss(_mm_set_ps1(1.0f))));
6731 }
6732 else
6733 {
6734 return x86::rcpps(x);
6735 }
John Bauman89401822014-05-06 15:04:28 -04006736 }
John Bauman66b8ab22014-05-06 15:57:45 -04006737
John Bauman19bac1e2014-05-06 15:23:49 -04006738 RValue<Float4> RcpSqrt_pp(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006739 {
6740 return x86::rsqrtps(x);
6741 }
6742
John Bauman19bac1e2014-05-06 15:23:49 -04006743 RValue<Float4> Sqrt(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006744 {
6745 return x86::sqrtps(x);
6746 }
6747
John Bauman19bac1e2014-05-06 15:23:49 -04006748 RValue<Float4> Insert(const Float4 &val, RValue<Float> element, int i)
John Bauman89401822014-05-06 15:04:28 -04006749 {
John Bauman66b8ab22014-05-06 15:57:45 -04006750 llvm::Value *value = val.loadValue();
John Bauman89401822014-05-06 15:04:28 -04006751 llvm::Value *insert = Nucleus::createInsertElement(value, element.value, i);
6752
6753 val = RValue<Float4>(insert);
6754
6755 return val;
6756 }
6757
John Bauman19bac1e2014-05-06 15:23:49 -04006758 RValue<Float> Extract(RValue<Float4> x, int i)
John Bauman89401822014-05-06 15:04:28 -04006759 {
6760 return RValue<Float>(Nucleus::createExtractElement(x.value, i));
6761 }
6762
John Bauman19bac1e2014-05-06 15:23:49 -04006763 RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04006764 {
6765 return RValue<Float4>(Nucleus::createSwizzle(x.value, select));
6766 }
6767
John Bauman19bac1e2014-05-06 15:23:49 -04006768 RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006769 {
6770 Constant *shuffle[4];
6771 shuffle[0] = Nucleus::createConstantInt(((imm >> 0) & 0x03) + 0);
6772 shuffle[1] = Nucleus::createConstantInt(((imm >> 2) & 0x03) + 0);
6773 shuffle[2] = Nucleus::createConstantInt(((imm >> 4) & 0x03) + 4);
6774 shuffle[3] = Nucleus::createConstantInt(((imm >> 6) & 0x03) + 4);
6775
6776 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 4)));
6777 }
6778
John Bauman19bac1e2014-05-06 15:23:49 -04006779 RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006780 {
6781 Constant *shuffle[4];
6782 shuffle[0] = Nucleus::createConstantInt(0);
6783 shuffle[1] = Nucleus::createConstantInt(4);
6784 shuffle[2] = Nucleus::createConstantInt(1);
6785 shuffle[3] = Nucleus::createConstantInt(5);
6786
6787 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 4)));
6788 }
6789
John Bauman19bac1e2014-05-06 15:23:49 -04006790 RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006791 {
6792 Constant *shuffle[4];
6793 shuffle[0] = Nucleus::createConstantInt(2);
6794 shuffle[1] = Nucleus::createConstantInt(6);
6795 shuffle[2] = Nucleus::createConstantInt(3);
6796 shuffle[3] = Nucleus::createConstantInt(7);
6797
6798 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 4)));
6799 }
John Bauman66b8ab22014-05-06 15:57:45 -04006800
John Bauman19bac1e2014-05-06 15:23:49 -04006801 RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04006802 {
John Bauman66b8ab22014-05-06 15:57:45 -04006803 Value *vector = lhs.loadValue();
John Bauman89401822014-05-06 15:04:28 -04006804 Value *shuffle = Nucleus::createMask(vector, rhs.value, select);
John Bauman66b8ab22014-05-06 15:57:45 -04006805 lhs.storeValue(shuffle);
John Bauman89401822014-05-06 15:04:28 -04006806
6807 return RValue<Float4>(shuffle);
6808 }
6809
John Bauman19bac1e2014-05-06 15:23:49 -04006810 RValue<Int> SignMask(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006811 {
6812 return x86::movmskps(x);
6813 }
6814
John Bauman19bac1e2014-05-06 15:23:49 -04006815 RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006816 {
6817 // return As<Int4>(x86::cmpeqps(x, y));
6818 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOEQ(x.value, y.value), Int4::getType()));
6819 }
6820
John Bauman19bac1e2014-05-06 15:23:49 -04006821 RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006822 {
6823 // return As<Int4>(x86::cmpltps(x, y));
6824 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOLT(x.value, y.value), Int4::getType()));
6825 }
6826
John Bauman19bac1e2014-05-06 15:23:49 -04006827 RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006828 {
6829 // return As<Int4>(x86::cmpleps(x, y));
6830 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOLE(x.value, y.value), Int4::getType()));
6831 }
6832
John Bauman19bac1e2014-05-06 15:23:49 -04006833 RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006834 {
6835 // return As<Int4>(x86::cmpneqps(x, y));
6836 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpONE(x.value, y.value), Int4::getType()));
6837 }
6838
John Bauman19bac1e2014-05-06 15:23:49 -04006839 RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006840 {
6841 // return As<Int4>(x86::cmpnltps(x, y));
6842 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOGE(x.value, y.value), Int4::getType()));
6843 }
6844
John Bauman19bac1e2014-05-06 15:23:49 -04006845 RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006846 {
6847 // return As<Int4>(x86::cmpnleps(x, y));
6848 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOGT(x.value, y.value), Int4::getType()));
6849 }
6850
John Bauman19bac1e2014-05-06 15:23:49 -04006851 RValue<Float4> Round(RValue<Float4> x)
6852 {
6853 if(CPUID::supportsSSE4_1())
6854 {
6855 return x86::roundps(x, 0);
6856 }
6857 else
6858 {
6859 return Float4(RoundInt(x));
6860 }
6861 }
6862
6863 RValue<Float4> Trunc(RValue<Float4> x)
6864 {
6865 if(CPUID::supportsSSE4_1())
6866 {
6867 return x86::roundps(x, 3);
6868 }
6869 else
6870 {
6871 return Float4(Int4(x)); // Rounded toward zero
6872 }
6873 }
6874
6875 RValue<Float4> Frac(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006876 {
6877 if(CPUID::supportsSSE4_1())
6878 {
6879 return x - x86::floorps(x);
6880 }
6881 else
6882 {
John Bauman19bac1e2014-05-06 15:23:49 -04006883 Float4 frc = x - Float4(Int4(x)); // Signed fractional part
John Bauman89401822014-05-06 15:04:28 -04006884
John Bauman19bac1e2014-05-06 15:23:49 -04006885 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 -04006886 }
6887 }
6888
John Bauman19bac1e2014-05-06 15:23:49 -04006889 RValue<Float4> Floor(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006890 {
6891 if(CPUID::supportsSSE4_1())
6892 {
6893 return x86::floorps(x);
6894 }
6895 else
6896 {
John Bauman19bac1e2014-05-06 15:23:49 -04006897 return x - Frac(x);
John Bauman89401822014-05-06 15:04:28 -04006898 }
6899 }
6900
John Bauman19bac1e2014-05-06 15:23:49 -04006901 RValue<Float4> Ceil(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006902 {
John Bauman19bac1e2014-05-06 15:23:49 -04006903 if(CPUID::supportsSSE4_1())
6904 {
6905 return x86::ceilps(x);
6906 }
6907 else
6908 {
6909 return -Floor(-x);
6910 }
John Bauman89401822014-05-06 15:04:28 -04006911 }
6912
John Bauman19bac1e2014-05-06 15:23:49 -04006913 Type *Float4::getType()
John Bauman89401822014-05-06 15:04:28 -04006914 {
Nicolas Capensac230122016-09-20 14:30:06 -04006915 return T(VectorType::get(Float::getType(), 4));
John Bauman89401822014-05-06 15:04:28 -04006916 }
6917
Nicolas Capens81f18302016-01-14 09:32:35 -05006918 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006919 {
Nicolas Capens81f18302016-01-14 09:32:35 -05006920 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Nucleus::createConstantInt(offset)));
John Bauman89401822014-05-06 15:04:28 -04006921 }
6922
Nicolas Capens81f18302016-01-14 09:32:35 -05006923 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006924 {
Nicolas Capens81f18302016-01-14 09:32:35 -05006925 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, offset.value));
John Bauman89401822014-05-06 15:04:28 -04006926 }
6927
Nicolas Capens81f18302016-01-14 09:32:35 -05006928 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006929 {
Nicolas Capens81f18302016-01-14 09:32:35 -05006930 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, offset.value));
John Bauman89401822014-05-06 15:04:28 -04006931 }
6932
Nicolas Capens81f18302016-01-14 09:32:35 -05006933 RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006934 {
6935 return lhs = lhs + offset;
6936 }
6937
Nicolas Capens81f18302016-01-14 09:32:35 -05006938 RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006939 {
6940 return lhs = lhs + offset;
6941 }
6942
Nicolas Capens81f18302016-01-14 09:32:35 -05006943 RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006944 {
6945 return lhs = lhs + offset;
6946 }
6947
Nicolas Capens81f18302016-01-14 09:32:35 -05006948 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006949 {
6950 return lhs + -offset;
6951 }
6952
Nicolas Capens81f18302016-01-14 09:32:35 -05006953 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006954 {
6955 return lhs + -offset;
6956 }
6957
Nicolas Capens81f18302016-01-14 09:32:35 -05006958 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006959 {
6960 return lhs + -offset;
6961 }
6962
Nicolas Capens81f18302016-01-14 09:32:35 -05006963 RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006964 {
6965 return lhs = lhs - offset;
6966 }
6967
Nicolas Capens81f18302016-01-14 09:32:35 -05006968 RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006969 {
6970 return lhs = lhs - offset;
6971 }
6972
Nicolas Capens81f18302016-01-14 09:32:35 -05006973 RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006974 {
6975 return lhs = lhs - offset;
6976 }
6977
6978 void Return()
6979 {
John Bauman89401822014-05-06 15:04:28 -04006980 Nucleus::createRetVoid();
6981 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
John Bauman19bac1e2014-05-06 15:23:49 -04006982 Nucleus::createUnreachable();
6983 }
6984
6985 void Return(bool ret)
6986 {
John Bauman19bac1e2014-05-06 15:23:49 -04006987 Nucleus::createRet(Nucleus::createConstantBool(ret));
6988 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
6989 Nucleus::createUnreachable();
John Bauman89401822014-05-06 15:04:28 -04006990 }
6991
6992 void Return(const Int &ret)
6993 {
John Bauman66b8ab22014-05-06 15:57:45 -04006994 Nucleus::createRet(ret.loadValue());
John Bauman89401822014-05-06 15:04:28 -04006995 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
John Bauman19bac1e2014-05-06 15:23:49 -04006996 Nucleus::createUnreachable();
John Bauman89401822014-05-06 15:04:28 -04006997 }
6998
6999 BasicBlock *beginLoop()
7000 {
7001 BasicBlock *loopBB = Nucleus::createBasicBlock();
7002
7003 Nucleus::createBr(loopBB);
John Bauman66b8ab22014-05-06 15:57:45 -04007004 Nucleus::setInsertBlock(loopBB);
John Bauman89401822014-05-06 15:04:28 -04007005
7006 return loopBB;
7007 }
7008
John Bauman19bac1e2014-05-06 15:23:49 -04007009 bool branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB)
John Bauman89401822014-05-06 15:04:28 -04007010 {
7011 Nucleus::createCondBr(cmp.value, bodyBB, endBB);
John Bauman66b8ab22014-05-06 15:57:45 -04007012 Nucleus::setInsertBlock(bodyBB);
7013
John Bauman89401822014-05-06 15:04:28 -04007014 return true;
7015 }
7016
7017 bool elseBlock(BasicBlock *falseBB)
7018 {
7019 falseBB->back().eraseFromParent();
John Bauman66b8ab22014-05-06 15:57:45 -04007020 Nucleus::setInsertBlock(falseBB);
John Bauman89401822014-05-06 15:04:28 -04007021
7022 return true;
7023 }
7024
7025 RValue<Long> Ticks()
7026 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007027 llvm::Function *rdtsc = Intrinsic::getDeclaration(::module, Intrinsic::readcyclecounter);
John Bauman89401822014-05-06 15:04:28 -04007028
7029 return RValue<Long>(Nucleus::createCall(rdtsc));
7030 }
John Bauman89401822014-05-06 15:04:28 -04007031}
7032
7033namespace sw
7034{
7035 namespace x86
7036 {
John Bauman19bac1e2014-05-06 15:23:49 -04007037 RValue<Int> cvtss2si(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04007038 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007039 llvm::Function *cvtss2si = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cvtss2si);
John Bauman66b8ab22014-05-06 15:57:45 -04007040
John Bauman89401822014-05-06 15:04:28 -04007041 Float4 vector;
7042 vector.x = val;
7043
7044 return RValue<Int>(Nucleus::createCall(cvtss2si, RValue<Float4>(vector).value));
7045 }
7046
John Bauman19bac1e2014-05-06 15:23:49 -04007047 RValue<Int2> cvtps2pi(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04007048 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007049 llvm::Function *cvtps2pi = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cvtps2pi);
John Bauman89401822014-05-06 15:04:28 -04007050
7051 return RValue<Int2>(Nucleus::createCall(cvtps2pi, val.value));
7052 }
7053
John Bauman19bac1e2014-05-06 15:23:49 -04007054 RValue<Int2> cvttps2pi(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04007055 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007056 llvm::Function *cvttps2pi = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cvttps2pi);
John Bauman89401822014-05-06 15:04:28 -04007057
7058 return RValue<Int2>(Nucleus::createCall(cvttps2pi, val.value));
7059 }
7060
John Bauman19bac1e2014-05-06 15:23:49 -04007061 RValue<Int4> cvtps2dq(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04007062 {
7063 if(CPUID::supportsSSE2())
7064 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007065 llvm::Function *cvtps2dq = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_cvtps2dq);
John Bauman89401822014-05-06 15:04:28 -04007066
7067 return RValue<Int4>(Nucleus::createCall(cvtps2dq, val.value));
7068 }
7069 else
7070 {
7071 Int2 lo = x86::cvtps2pi(val);
7072 Int2 hi = x86::cvtps2pi(Swizzle(val, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04007073
Nicolas Capens62abb552016-01-05 12:03:47 -05007074 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007075 }
7076 }
7077
John Bauman19bac1e2014-05-06 15:23:49 -04007078 RValue<Float> rcpss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04007079 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007080 llvm::Function *rcpss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rcp_ss);
John Bauman89401822014-05-06 15:04:28 -04007081
7082 Value *vector = Nucleus::createInsertElement(UndefValue::get(Float4::getType()), val.value, 0);
John Bauman66b8ab22014-05-06 15:57:45 -04007083
John Bauman89401822014-05-06 15:04:28 -04007084 return RValue<Float>(Nucleus::createExtractElement(Nucleus::createCall(rcpss, vector), 0));
7085 }
7086
John Bauman19bac1e2014-05-06 15:23:49 -04007087 RValue<Float> sqrtss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04007088 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007089 llvm::Function *sqrtss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_sqrt_ss);
John Bauman89401822014-05-06 15:04:28 -04007090
7091 Value *vector = Nucleus::createInsertElement(UndefValue::get(Float4::getType()), val.value, 0);
John Bauman66b8ab22014-05-06 15:57:45 -04007092
John Bauman89401822014-05-06 15:04:28 -04007093 return RValue<Float>(Nucleus::createExtractElement(Nucleus::createCall(sqrtss, vector), 0));
7094 }
7095
John Bauman19bac1e2014-05-06 15:23:49 -04007096 RValue<Float> rsqrtss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04007097 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007098 llvm::Function *rsqrtss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rsqrt_ss);
John Bauman66b8ab22014-05-06 15:57:45 -04007099
John Bauman89401822014-05-06 15:04:28 -04007100 Value *vector = Nucleus::createInsertElement(UndefValue::get(Float4::getType()), val.value, 0);
7101
7102 return RValue<Float>(Nucleus::createExtractElement(Nucleus::createCall(rsqrtss, vector), 0));
7103 }
7104
John Bauman19bac1e2014-05-06 15:23:49 -04007105 RValue<Float4> rcpps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04007106 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007107 llvm::Function *rcpps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rcp_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04007108
John Bauman89401822014-05-06 15:04:28 -04007109 return RValue<Float4>(Nucleus::createCall(rcpps, val.value));
7110 }
7111
John Bauman19bac1e2014-05-06 15:23:49 -04007112 RValue<Float4> sqrtps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04007113 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007114 llvm::Function *sqrtps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_sqrt_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04007115
John Bauman89401822014-05-06 15:04:28 -04007116 return RValue<Float4>(Nucleus::createCall(sqrtps, val.value));
7117 }
7118
John Bauman19bac1e2014-05-06 15:23:49 -04007119 RValue<Float4> rsqrtps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04007120 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007121 llvm::Function *rsqrtps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_rsqrt_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04007122
John Bauman89401822014-05-06 15:04:28 -04007123 return RValue<Float4>(Nucleus::createCall(rsqrtps, val.value));
7124 }
7125
John Bauman19bac1e2014-05-06 15:23:49 -04007126 RValue<Float4> maxps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007127 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007128 llvm::Function *maxps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_max_ps);
John Bauman89401822014-05-06 15:04:28 -04007129
7130 return RValue<Float4>(Nucleus::createCall(maxps, x.value, y.value));
7131 }
7132
John Bauman19bac1e2014-05-06 15:23:49 -04007133 RValue<Float4> minps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007134 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007135 llvm::Function *minps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_min_ps);
John Bauman89401822014-05-06 15:04:28 -04007136
7137 return RValue<Float4>(Nucleus::createCall(minps, x.value, y.value));
7138 }
7139
John Bauman19bac1e2014-05-06 15:23:49 -04007140 RValue<Float> roundss(RValue<Float> val, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04007141 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007142 llvm::Function *roundss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_round_ss);
John Bauman89401822014-05-06 15:04:28 -04007143
7144 Value *undef = UndefValue::get(Float4::getType());
7145 Value *vector = Nucleus::createInsertElement(undef, val.value, 0);
7146
7147 return RValue<Float>(Nucleus::createExtractElement(Nucleus::createCall(roundss, undef, vector, Nucleus::createConstantInt(imm)), 0));
7148 }
7149
John Bauman19bac1e2014-05-06 15:23:49 -04007150 RValue<Float> floorss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04007151 {
7152 return roundss(val, 1);
7153 }
7154
John Bauman19bac1e2014-05-06 15:23:49 -04007155 RValue<Float> ceilss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04007156 {
7157 return roundss(val, 2);
7158 }
7159
John Bauman19bac1e2014-05-06 15:23:49 -04007160 RValue<Float4> roundps(RValue<Float4> val, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04007161 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007162 llvm::Function *roundps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_round_ps);
John Bauman89401822014-05-06 15:04:28 -04007163
7164 return RValue<Float4>(Nucleus::createCall(roundps, val.value, Nucleus::createConstantInt(imm)));
7165 }
7166
John Bauman19bac1e2014-05-06 15:23:49 -04007167 RValue<Float4> floorps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04007168 {
7169 return roundps(val, 1);
7170 }
7171
John Bauman19bac1e2014-05-06 15:23:49 -04007172 RValue<Float4> ceilps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04007173 {
7174 return roundps(val, 2);
7175 }
7176
John Bauman19bac1e2014-05-06 15:23:49 -04007177 RValue<Float4> cmpps(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04007178 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007179 llvm::Function *cmpps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cmp_ps);
John Bauman89401822014-05-06 15:04:28 -04007180
7181 return RValue<Float4>(Nucleus::createCall(cmpps, x.value, y.value, Nucleus::createConstantByte(imm)));
7182 }
7183
John Bauman19bac1e2014-05-06 15:23:49 -04007184 RValue<Float4> cmpeqps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007185 {
7186 return cmpps(x, y, 0);
7187 }
7188
John Bauman19bac1e2014-05-06 15:23:49 -04007189 RValue<Float4> cmpltps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007190 {
7191 return cmpps(x, y, 1);
7192 }
7193
John Bauman19bac1e2014-05-06 15:23:49 -04007194 RValue<Float4> cmpleps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007195 {
7196 return cmpps(x, y, 2);
7197 }
7198
John Bauman19bac1e2014-05-06 15:23:49 -04007199 RValue<Float4> cmpunordps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007200 {
7201 return cmpps(x, y, 3);
7202 }
7203
John Bauman19bac1e2014-05-06 15:23:49 -04007204 RValue<Float4> cmpneqps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007205 {
7206 return cmpps(x, y, 4);
7207 }
7208
John Bauman19bac1e2014-05-06 15:23:49 -04007209 RValue<Float4> cmpnltps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007210 {
7211 return cmpps(x, y, 5);
7212 }
7213
John Bauman19bac1e2014-05-06 15:23:49 -04007214 RValue<Float4> cmpnleps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007215 {
7216 return cmpps(x, y, 6);
7217 }
7218
John Bauman19bac1e2014-05-06 15:23:49 -04007219 RValue<Float4> cmpordps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007220 {
7221 return cmpps(x, y, 7);
7222 }
7223
John Bauman19bac1e2014-05-06 15:23:49 -04007224 RValue<Float> cmpss(RValue<Float> x, RValue<Float> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04007225 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007226 llvm::Function *cmpss = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_cmp_ss);
John Bauman89401822014-05-06 15:04:28 -04007227
7228 Value *vector1 = Nucleus::createInsertElement(UndefValue::get(Float4::getType()), x.value, 0);
7229 Value *vector2 = Nucleus::createInsertElement(UndefValue::get(Float4::getType()), y.value, 0);
7230
7231 return RValue<Float>(Nucleus::createExtractElement(Nucleus::createCall(cmpss, vector1, vector2, Nucleus::createConstantByte(imm)), 0));
7232 }
7233
John Bauman19bac1e2014-05-06 15:23:49 -04007234 RValue<Float> cmpeqss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007235 {
7236 return cmpss(x, y, 0);
7237 }
7238
John Bauman19bac1e2014-05-06 15:23:49 -04007239 RValue<Float> cmpltss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007240 {
7241 return cmpss(x, y, 1);
7242 }
7243
John Bauman19bac1e2014-05-06 15:23:49 -04007244 RValue<Float> cmpless(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007245 {
7246 return cmpss(x, y, 2);
7247 }
7248
John Bauman19bac1e2014-05-06 15:23:49 -04007249 RValue<Float> cmpunordss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007250 {
7251 return cmpss(x, y, 3);
7252 }
7253
John Bauman19bac1e2014-05-06 15:23:49 -04007254 RValue<Float> cmpneqss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007255 {
7256 return cmpss(x, y, 4);
7257 }
7258
John Bauman19bac1e2014-05-06 15:23:49 -04007259 RValue<Float> cmpnltss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007260 {
7261 return cmpss(x, y, 5);
7262 }
7263
John Bauman19bac1e2014-05-06 15:23:49 -04007264 RValue<Float> cmpnless(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007265 {
7266 return cmpss(x, y, 6);
7267 }
7268
John Bauman19bac1e2014-05-06 15:23:49 -04007269 RValue<Float> cmpordss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007270 {
7271 return cmpss(x, y, 7);
7272 }
7273
Alexis Hetu0f448072016-03-18 10:56:08 -04007274 RValue<Int4> pabsd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007275 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007276 llvm::Function *pabsd = Intrinsic::getDeclaration(::module, Intrinsic::x86_ssse3_pabs_d_128);
John Bauman89401822014-05-06 15:04:28 -04007277
Alexis Hetu0f448072016-03-18 10:56:08 -04007278 return RValue<Int4>(Nucleus::createCall(pabsd, x.value));
John Bauman89401822014-05-06 15:04:28 -04007279 }
7280
John Bauman19bac1e2014-05-06 15:23:49 -04007281 RValue<Short4> paddsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007282 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007283 llvm::Function *paddsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padds_w);
John Bauman89401822014-05-06 15:04:28 -04007284
John Bauman19bac1e2014-05-06 15:23:49 -04007285 return As<Short4>(RValue<MMX>(Nucleus::createCall(paddsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007286 }
John Bauman66b8ab22014-05-06 15:57:45 -04007287
John Bauman19bac1e2014-05-06 15:23:49 -04007288 RValue<Short4> psubsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007289 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007290 llvm::Function *psubsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubs_w);
John Bauman89401822014-05-06 15:04:28 -04007291
John Bauman19bac1e2014-05-06 15:23:49 -04007292 return As<Short4>(RValue<MMX>(Nucleus::createCall(psubsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007293 }
7294
John Bauman19bac1e2014-05-06 15:23:49 -04007295 RValue<UShort4> paddusw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007296 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007297 llvm::Function *paddusw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_paddus_w);
John Bauman89401822014-05-06 15:04:28 -04007298
John Bauman19bac1e2014-05-06 15:23:49 -04007299 return As<UShort4>(RValue<MMX>(Nucleus::createCall(paddusw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007300 }
John Bauman66b8ab22014-05-06 15:57:45 -04007301
John Bauman19bac1e2014-05-06 15:23:49 -04007302 RValue<UShort4> psubusw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007303 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007304 llvm::Function *psubusw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubus_w);
John Bauman89401822014-05-06 15:04:28 -04007305
John Bauman19bac1e2014-05-06 15:23:49 -04007306 return As<UShort4>(RValue<MMX>(Nucleus::createCall(psubusw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007307 }
7308
John Bauman19bac1e2014-05-06 15:23:49 -04007309 RValue<SByte8> paddsb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04007310 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007311 llvm::Function *paddsb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padds_b);
John Bauman89401822014-05-06 15:04:28 -04007312
John Bauman19bac1e2014-05-06 15:23:49 -04007313 return As<SByte8>(RValue<MMX>(Nucleus::createCall(paddsb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007314 }
John Bauman66b8ab22014-05-06 15:57:45 -04007315
John Bauman19bac1e2014-05-06 15:23:49 -04007316 RValue<SByte8> psubsb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04007317 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007318 llvm::Function *psubsb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubs_b);
John Bauman89401822014-05-06 15:04:28 -04007319
John Bauman19bac1e2014-05-06 15:23:49 -04007320 return As<SByte8>(RValue<MMX>(Nucleus::createCall(psubsb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007321 }
John Bauman66b8ab22014-05-06 15:57:45 -04007322
John Bauman19bac1e2014-05-06 15:23:49 -04007323 RValue<Byte8> paddusb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04007324 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007325 llvm::Function *paddusb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_paddus_b);
John Bauman89401822014-05-06 15:04:28 -04007326
John Bauman19bac1e2014-05-06 15:23:49 -04007327 return As<Byte8>(RValue<MMX>(Nucleus::createCall(paddusb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007328 }
John Bauman66b8ab22014-05-06 15:57:45 -04007329
John Bauman19bac1e2014-05-06 15:23:49 -04007330 RValue<Byte8> psubusb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04007331 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007332 llvm::Function *psubusb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psubus_b);
John Bauman89401822014-05-06 15:04:28 -04007333
John Bauman19bac1e2014-05-06 15:23:49 -04007334 return As<Byte8>(RValue<MMX>(Nucleus::createCall(psubusb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007335 }
7336
John Bauman19bac1e2014-05-06 15:23:49 -04007337 RValue<Short4> paddw(RValue<Short4> x, RValue<Short4> y)
7338 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007339 llvm::Function *paddw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padd_w);
John Bauman19bac1e2014-05-06 15:23:49 -04007340
7341 return As<Short4>(RValue<MMX>(Nucleus::createCall(paddw, As<MMX>(x).value, As<MMX>(y).value)));
7342 }
7343
7344 RValue<Short4> psubw(RValue<Short4> x, RValue<Short4> y)
7345 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007346 llvm::Function *psubw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psub_w);
John Bauman19bac1e2014-05-06 15:23:49 -04007347
7348 return As<Short4>(RValue<MMX>(Nucleus::createCall(psubw, As<MMX>(x).value, As<MMX>(y).value)));
7349 }
7350
7351 RValue<Short4> pmullw(RValue<Short4> x, RValue<Short4> y)
7352 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007353 llvm::Function *pmullw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmull_w);
John Bauman19bac1e2014-05-06 15:23:49 -04007354
7355 return As<Short4>(RValue<MMX>(Nucleus::createCall(pmullw, As<MMX>(x).value, As<MMX>(y).value)));
7356 }
7357
7358 RValue<Short4> pand(RValue<Short4> x, RValue<Short4> y)
7359 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007360 llvm::Function *pand = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pand);
John Bauman19bac1e2014-05-06 15:23:49 -04007361
7362 return As<Short4>(RValue<MMX>(Nucleus::createCall(pand, As<MMX>(x).value, As<MMX>(y).value)));
7363 }
7364
7365 RValue<Short4> por(RValue<Short4> x, RValue<Short4> y)
7366 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007367 llvm::Function *por = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_por);
John Bauman19bac1e2014-05-06 15:23:49 -04007368
7369 return As<Short4>(RValue<MMX>(Nucleus::createCall(por, As<MMX>(x).value, As<MMX>(y).value)));
7370 }
7371
7372 RValue<Short4> pxor(RValue<Short4> x, RValue<Short4> y)
7373 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007374 llvm::Function *pxor = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pxor);
John Bauman19bac1e2014-05-06 15:23:49 -04007375
7376 return As<Short4>(RValue<MMX>(Nucleus::createCall(pxor, As<MMX>(x).value, As<MMX>(y).value)));
7377 }
7378
7379 RValue<Short4> pshufw(RValue<Short4> x, unsigned char y)
7380 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007381 llvm::Function *pshufw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_pshuf_w);
John Bauman19bac1e2014-05-06 15:23:49 -04007382
7383 return As<Short4>(RValue<MMX>(Nucleus::createCall(pshufw, As<MMX>(x).value, Nucleus::createConstantByte(y))));
7384 }
7385
7386 RValue<Int2> punpcklwd(RValue<Short4> x, RValue<Short4> y)
7387 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007388 llvm::Function *punpcklwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpcklwd);
John Bauman19bac1e2014-05-06 15:23:49 -04007389
7390 return As<Int2>(RValue<MMX>(Nucleus::createCall(punpcklwd, As<MMX>(x).value, As<MMX>(y).value)));
7391 }
7392
7393 RValue<Int2> punpckhwd(RValue<Short4> x, RValue<Short4> y)
7394 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007395 llvm::Function *punpckhwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckhwd);
John Bauman19bac1e2014-05-06 15:23:49 -04007396
7397 return As<Int2>(RValue<MMX>(Nucleus::createCall(punpckhwd, As<MMX>(x).value, As<MMX>(y).value)));
7398 }
7399
7400 RValue<Short4> pinsrw(RValue<Short4> x, RValue<Int> y, unsigned int i)
7401 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007402 llvm::Function *pinsrw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pinsr_w);
John Bauman19bac1e2014-05-06 15:23:49 -04007403
7404 return As<Short4>(RValue<MMX>(Nucleus::createCall(pinsrw, As<MMX>(x).value, y.value, Nucleus::createConstantInt(i))));
7405 }
7406
7407 RValue<Int> pextrw(RValue<Short4> x, unsigned int i)
7408 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007409 llvm::Function *pextrw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pextr_w);
John Bauman19bac1e2014-05-06 15:23:49 -04007410
7411 return RValue<Int>(Nucleus::createCall(pextrw, As<MMX>(x).value, Nucleus::createConstantInt(i)));
7412 }
7413
7414 RValue<Long1> punpckldq(RValue<Int2> x, RValue<Int2> y)
7415 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007416 llvm::Function *punpckldq = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckldq);
John Bauman19bac1e2014-05-06 15:23:49 -04007417
7418 return As<Long1>(RValue<MMX>(Nucleus::createCall(punpckldq, As<MMX>(x).value, As<MMX>(y).value)));
7419 }
7420
7421 RValue<Long1> punpckhdq(RValue<Int2> x, RValue<Int2> y)
7422 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007423 llvm::Function *punpckhdq = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckhdq);
John Bauman19bac1e2014-05-06 15:23:49 -04007424
7425 return As<Long1>(RValue<MMX>(Nucleus::createCall(punpckhdq, As<MMX>(x).value, As<MMX>(y).value)));
7426 }
7427
7428 RValue<Short4> punpcklbw(RValue<Byte8> x, RValue<Byte8> y)
7429 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007430 llvm::Function *punpcklbw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpcklbw);
John Bauman19bac1e2014-05-06 15:23:49 -04007431
7432 return As<Short4>(RValue<MMX>(Nucleus::createCall(punpcklbw, As<MMX>(x).value, As<MMX>(y).value)));
7433 }
7434
7435 RValue<Short4> punpckhbw(RValue<Byte8> x, RValue<Byte8> y)
7436 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007437 llvm::Function *punpckhbw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_punpckhbw);
John Bauman19bac1e2014-05-06 15:23:49 -04007438
7439 return As<Short4>(RValue<MMX>(Nucleus::createCall(punpckhbw, As<MMX>(x).value, As<MMX>(y).value)));
7440 }
7441
7442 RValue<Byte8> paddb(RValue<Byte8> x, RValue<Byte8> y)
7443 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007444 llvm::Function *paddb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padd_b);
John Bauman19bac1e2014-05-06 15:23:49 -04007445
7446 return As<Byte8>(RValue<MMX>(Nucleus::createCall(paddb, As<MMX>(x).value, As<MMX>(y).value)));
7447 }
7448
7449 RValue<Byte8> psubb(RValue<Byte8> x, RValue<Byte8> y)
7450 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007451 llvm::Function *psubb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psub_b);
John Bauman19bac1e2014-05-06 15:23:49 -04007452
7453 return As<Byte8>(RValue<MMX>(Nucleus::createCall(psubb, As<MMX>(x).value, As<MMX>(y).value)));
7454 }
7455
7456 RValue<Int2> paddd(RValue<Int2> x, RValue<Int2> y)
7457 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007458 llvm::Function *paddd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_padd_d);
John Bauman19bac1e2014-05-06 15:23:49 -04007459
7460 return As<Int2>(RValue<MMX>(Nucleus::createCall(paddd, As<MMX>(x).value, As<MMX>(y).value)));
7461 }
7462
7463 RValue<Int2> psubd(RValue<Int2> x, RValue<Int2> y)
7464 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007465 llvm::Function *psubd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psub_d);
John Bauman19bac1e2014-05-06 15:23:49 -04007466
7467 return As<Int2>(RValue<MMX>(Nucleus::createCall(psubd, As<MMX>(x).value, As<MMX>(y).value)));
7468 }
7469
7470 RValue<UShort4> pavgw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007471 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007472 llvm::Function *pavgw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pavg_w);
John Bauman89401822014-05-06 15:04:28 -04007473
John Bauman19bac1e2014-05-06 15:23:49 -04007474 return As<UShort4>(RValue<MMX>(Nucleus::createCall(pavgw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007475 }
7476
John Bauman19bac1e2014-05-06 15:23:49 -04007477 RValue<Short4> pmaxsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007478 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007479 llvm::Function *pmaxsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmaxs_w);
John Bauman89401822014-05-06 15:04:28 -04007480
John Bauman19bac1e2014-05-06 15:23:49 -04007481 return As<Short4>(RValue<MMX>(Nucleus::createCall(pmaxsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007482 }
7483
John Bauman19bac1e2014-05-06 15:23:49 -04007484 RValue<Short4> pminsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007485 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007486 llvm::Function *pminsw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmins_w);
John Bauman89401822014-05-06 15:04:28 -04007487
John Bauman19bac1e2014-05-06 15:23:49 -04007488 return As<Short4>(RValue<MMX>(Nucleus::createCall(pminsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007489 }
7490
John Bauman19bac1e2014-05-06 15:23:49 -04007491 RValue<Short4> pcmpgtw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007492 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007493 llvm::Function *pcmpgtw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpgt_w);
John Bauman89401822014-05-06 15:04:28 -04007494
John Bauman19bac1e2014-05-06 15:23:49 -04007495 return As<Short4>(RValue<MMX>(Nucleus::createCall(pcmpgtw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007496 }
7497
John Bauman19bac1e2014-05-06 15:23:49 -04007498 RValue<Short4> pcmpeqw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007499 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007500 llvm::Function *pcmpeqw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpeq_w);
John Bauman89401822014-05-06 15:04:28 -04007501
John Bauman19bac1e2014-05-06 15:23:49 -04007502 return As<Short4>(RValue<MMX>(Nucleus::createCall(pcmpeqw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007503 }
7504
John Bauman19bac1e2014-05-06 15:23:49 -04007505 RValue<Byte8> pcmpgtb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04007506 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007507 llvm::Function *pcmpgtb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpgt_b);
John Bauman89401822014-05-06 15:04:28 -04007508
John Bauman19bac1e2014-05-06 15:23:49 -04007509 return As<Byte8>(RValue<MMX>(Nucleus::createCall(pcmpgtb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007510 }
7511
John Bauman19bac1e2014-05-06 15:23:49 -04007512 RValue<Byte8> pcmpeqb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04007513 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007514 llvm::Function *pcmpeqb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pcmpeq_b);
John Bauman89401822014-05-06 15:04:28 -04007515
John Bauman19bac1e2014-05-06 15:23:49 -04007516 return As<Byte8>(RValue<MMX>(Nucleus::createCall(pcmpeqb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007517 }
7518
John Bauman19bac1e2014-05-06 15:23:49 -04007519 RValue<Short4> packssdw(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04007520 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007521 llvm::Function *packssdw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_packssdw);
John Bauman89401822014-05-06 15:04:28 -04007522
John Bauman19bac1e2014-05-06 15:23:49 -04007523 return As<Short4>(RValue<MMX>(Nucleus::createCall(packssdw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007524 }
7525
John Bauman19bac1e2014-05-06 15:23:49 -04007526 RValue<Short8> packssdw(RValue<Int4> x, RValue<Int4> y)
John Bauman89401822014-05-06 15:04:28 -04007527 {
7528 if(CPUID::supportsSSE2())
7529 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007530 llvm::Function *packssdw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_packssdw_128);
John Bauman89401822014-05-06 15:04:28 -04007531
7532 return RValue<Short8>(Nucleus::createCall(packssdw, x.value, y.value));
7533 }
7534 else
7535 {
7536 Int2 loX = Int2(x);
7537 Int2 hiX = Int2(Swizzle(x, 0xEE));
7538
7539 Int2 loY = Int2(y);
7540 Int2 hiY = Int2(Swizzle(y, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04007541
John Bauman89401822014-05-06 15:04:28 -04007542 Short4 lo = x86::packssdw(loX, hiX);
7543 Short4 hi = x86::packssdw(loY, hiY);
John Bauman66b8ab22014-05-06 15:57:45 -04007544
Nicolas Capens62abb552016-01-05 12:03:47 -05007545 return Short8(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007546 }
7547 }
7548
John Bauman19bac1e2014-05-06 15:23:49 -04007549 RValue<SByte8> packsswb(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007550 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007551 llvm::Function *packsswb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_packsswb);
John Bauman89401822014-05-06 15:04:28 -04007552
John Bauman19bac1e2014-05-06 15:23:49 -04007553 return As<SByte8>(RValue<MMX>(Nucleus::createCall(packsswb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007554 }
7555
John Bauman19bac1e2014-05-06 15:23:49 -04007556 RValue<Byte8> packuswb(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007557 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007558 llvm::Function *packuswb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_packuswb);
John Bauman89401822014-05-06 15:04:28 -04007559
John Bauman19bac1e2014-05-06 15:23:49 -04007560 return As<Byte8>(RValue<MMX>(Nucleus::createCall(packuswb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007561 }
7562
John Bauman19bac1e2014-05-06 15:23:49 -04007563 RValue<UShort8> packusdw(RValue<UInt4> x, RValue<UInt4> y)
John Bauman89401822014-05-06 15:04:28 -04007564 {
7565 if(CPUID::supportsSSE4_1())
7566 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007567 llvm::Function *packusdw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_packusdw);
John Bauman66b8ab22014-05-06 15:57:45 -04007568
John Bauman89401822014-05-06 15:04:28 -04007569 return RValue<UShort8>(Nucleus::createCall(packusdw, x.value, y.value));
7570 }
7571 else
7572 {
7573 // FIXME: Not an exact replacement!
John Bauman19bac1e2014-05-06 15:23:49 -04007574 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 -04007575 }
7576 }
7577
John Bauman19bac1e2014-05-06 15:23:49 -04007578 RValue<UShort4> psrlw(RValue<UShort4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007579 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007580 llvm::Function *psrlw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrli_w);
John Bauman89401822014-05-06 15:04:28 -04007581
John Bauman19bac1e2014-05-06 15:23:49 -04007582 return As<UShort4>(RValue<MMX>(Nucleus::createCall(psrlw, As<MMX>(x).value, Nucleus::createConstantInt(y))));
John Bauman89401822014-05-06 15:04:28 -04007583 }
7584
John Bauman19bac1e2014-05-06 15:23:49 -04007585 RValue<UShort8> psrlw(RValue<UShort8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007586 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007587 llvm::Function *psrlw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrli_w);
John Bauman89401822014-05-06 15:04:28 -04007588
7589 return RValue<UShort8>(Nucleus::createCall(psrlw, x.value, Nucleus::createConstantInt(y)));
7590 }
7591
John Bauman19bac1e2014-05-06 15:23:49 -04007592 RValue<Short4> psraw(RValue<Short4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007593 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007594 llvm::Function *psraw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrai_w);
John Bauman89401822014-05-06 15:04:28 -04007595
John Bauman19bac1e2014-05-06 15:23:49 -04007596 return As<Short4>(RValue<MMX>(Nucleus::createCall(psraw, As<MMX>(x).value, Nucleus::createConstantInt(y))));
John Bauman89401822014-05-06 15:04:28 -04007597 }
7598
John Bauman19bac1e2014-05-06 15:23:49 -04007599 RValue<Short8> psraw(RValue<Short8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007600 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007601 llvm::Function *psraw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrai_w);
John Bauman89401822014-05-06 15:04:28 -04007602
7603 return RValue<Short8>(Nucleus::createCall(psraw, x.value, Nucleus::createConstantInt(y)));
7604 }
7605
John Bauman19bac1e2014-05-06 15:23:49 -04007606 RValue<Short4> psllw(RValue<Short4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007607 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007608 llvm::Function *psllw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pslli_w);
John Bauman89401822014-05-06 15:04:28 -04007609
John Bauman19bac1e2014-05-06 15:23:49 -04007610 return As<Short4>(RValue<MMX>(Nucleus::createCall(psllw, As<MMX>(x).value, Nucleus::createConstantInt(y))));
John Bauman89401822014-05-06 15:04:28 -04007611 }
7612
John Bauman19bac1e2014-05-06 15:23:49 -04007613 RValue<Short8> psllw(RValue<Short8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007614 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007615 llvm::Function *psllw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pslli_w);
John Bauman89401822014-05-06 15:04:28 -04007616
7617 return RValue<Short8>(Nucleus::createCall(psllw, x.value, Nucleus::createConstantInt(y)));
7618 }
7619
John Bauman19bac1e2014-05-06 15:23:49 -04007620 RValue<Int2> pslld(RValue<Int2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007621 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007622 llvm::Function *pslld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pslli_d);
John Bauman89401822014-05-06 15:04:28 -04007623
John Bauman19bac1e2014-05-06 15:23:49 -04007624 return As<Int2>(RValue<MMX>(Nucleus::createCall(pslld, As<MMX>(x).value, Nucleus::createConstantInt(y))));
John Bauman89401822014-05-06 15:04:28 -04007625 }
7626
John Bauman19bac1e2014-05-06 15:23:49 -04007627 RValue<Int4> pslld(RValue<Int4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007628 {
7629 if(CPUID::supportsSSE2())
7630 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007631 llvm::Function *pslld = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pslli_d);
John Bauman89401822014-05-06 15:04:28 -04007632
7633 return RValue<Int4>(Nucleus::createCall(pslld, x.value, Nucleus::createConstantInt(y)));
7634 }
7635 else
7636 {
7637 Int2 lo = Int2(x);
7638 Int2 hi = Int2(Swizzle(x, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04007639
John Bauman89401822014-05-06 15:04:28 -04007640 lo = x86::pslld(lo, y);
7641 hi = x86::pslld(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04007642
Nicolas Capens62abb552016-01-05 12:03:47 -05007643 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007644 }
7645 }
7646
John Bauman19bac1e2014-05-06 15:23:49 -04007647 RValue<Int2> psrad(RValue<Int2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007648 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007649 llvm::Function *psrad = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrai_d);
John Bauman89401822014-05-06 15:04:28 -04007650
John Bauman19bac1e2014-05-06 15:23:49 -04007651 return As<Int2>(RValue<MMX>(Nucleus::createCall(psrad, As<MMX>(x).value, Nucleus::createConstantInt(y))));
John Bauman89401822014-05-06 15:04:28 -04007652 }
7653
John Bauman19bac1e2014-05-06 15:23:49 -04007654 RValue<Int4> psrad(RValue<Int4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007655 {
7656 if(CPUID::supportsSSE2())
7657 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007658 llvm::Function *psrad = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrai_d);
John Bauman89401822014-05-06 15:04:28 -04007659
7660 return RValue<Int4>(Nucleus::createCall(psrad, x.value, Nucleus::createConstantInt(y)));
7661 }
7662 else
7663 {
7664 Int2 lo = Int2(x);
7665 Int2 hi = Int2(Swizzle(x, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04007666
John Bauman89401822014-05-06 15:04:28 -04007667 lo = x86::psrad(lo, y);
7668 hi = x86::psrad(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04007669
Nicolas Capens62abb552016-01-05 12:03:47 -05007670 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007671 }
7672 }
7673
John Bauman19bac1e2014-05-06 15:23:49 -04007674 RValue<UInt2> psrld(RValue<UInt2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007675 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007676 llvm::Function *psrld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrli_d);
John Bauman89401822014-05-06 15:04:28 -04007677
John Bauman19bac1e2014-05-06 15:23:49 -04007678 return As<UInt2>(RValue<MMX>(Nucleus::createCall(psrld, As<MMX>(x).value, Nucleus::createConstantInt(y))));
John Bauman89401822014-05-06 15:04:28 -04007679 }
7680
John Bauman19bac1e2014-05-06 15:23:49 -04007681 RValue<UInt4> psrld(RValue<UInt4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007682 {
7683 if(CPUID::supportsSSE2())
7684 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007685 llvm::Function *psrld = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_psrli_d);
John Bauman89401822014-05-06 15:04:28 -04007686
7687 return RValue<UInt4>(Nucleus::createCall(psrld, x.value, Nucleus::createConstantInt(y)));
7688 }
7689 else
7690 {
7691 UInt2 lo = As<UInt2>(Int2(As<Int4>(x)));
7692 UInt2 hi = As<UInt2>(Int2(Swizzle(As<Int4>(x), 0xEE)));
John Bauman66b8ab22014-05-06 15:57:45 -04007693
John Bauman89401822014-05-06 15:04:28 -04007694 lo = x86::psrld(lo, y);
7695 hi = x86::psrld(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04007696
Nicolas Capens62abb552016-01-05 12:03:47 -05007697 return UInt4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007698 }
7699 }
7700
John Bauman19bac1e2014-05-06 15:23:49 -04007701 RValue<UShort4> psrlw(RValue<UShort4> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007702 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007703 llvm::Function *psrlw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrl_w);
John Bauman89401822014-05-06 15:04:28 -04007704
John Bauman19bac1e2014-05-06 15:23:49 -04007705 return As<UShort4>(RValue<MMX>(Nucleus::createCall(psrlw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007706 }
7707
John Bauman19bac1e2014-05-06 15:23:49 -04007708 RValue<Short4> psraw(RValue<Short4> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007709 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007710 llvm::Function *psraw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psra_w);
John Bauman89401822014-05-06 15:04:28 -04007711
John Bauman19bac1e2014-05-06 15:23:49 -04007712 return As<Short4>(RValue<MMX>(Nucleus::createCall(psraw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007713 }
7714
John Bauman19bac1e2014-05-06 15:23:49 -04007715 RValue<Short4> psllw(RValue<Short4> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007716 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007717 llvm::Function *psllw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psll_w);
John Bauman89401822014-05-06 15:04:28 -04007718
John Bauman19bac1e2014-05-06 15:23:49 -04007719 return As<Short4>(RValue<MMX>(Nucleus::createCall(psllw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007720 }
7721
John Bauman19bac1e2014-05-06 15:23:49 -04007722 RValue<Int2> pslld(RValue<Int2> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007723 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007724 llvm::Function *pslld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psll_d);
John Bauman89401822014-05-06 15:04:28 -04007725
John Bauman19bac1e2014-05-06 15:23:49 -04007726 return As<Int2>(RValue<MMX>(Nucleus::createCall(pslld, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007727 }
7728
John Bauman19bac1e2014-05-06 15:23:49 -04007729 RValue<UInt2> psrld(RValue<UInt2> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007730 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007731 llvm::Function *psrld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psrl_d);
John Bauman89401822014-05-06 15:04:28 -04007732
John Bauman19bac1e2014-05-06 15:23:49 -04007733 return As<UInt2>(RValue<MMX>(Nucleus::createCall(psrld, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007734 }
7735
John Bauman19bac1e2014-05-06 15:23:49 -04007736 RValue<Int2> psrad(RValue<Int2> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007737 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007738 llvm::Function *psrld = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_psra_d);
John Bauman89401822014-05-06 15:04:28 -04007739
John Bauman19bac1e2014-05-06 15:23:49 -04007740 return As<Int2>(RValue<MMX>(Nucleus::createCall(psrld, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007741 }
7742
John Bauman19bac1e2014-05-06 15:23:49 -04007743 RValue<Int4> pmaxsd(RValue<Int4> x, RValue<Int4> y)
7744 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007745 llvm::Function *pmaxsd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmaxsd);
John Bauman19bac1e2014-05-06 15:23:49 -04007746
7747 return RValue<Int4>(Nucleus::createCall(pmaxsd, x.value, y.value));
7748 }
7749
7750 RValue<Int4> pminsd(RValue<Int4> x, RValue<Int4> y)
7751 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007752 llvm::Function *pminsd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pminsd);
John Bauman19bac1e2014-05-06 15:23:49 -04007753
7754 return RValue<Int4>(Nucleus::createCall(pminsd, x.value, y.value));
7755 }
7756
7757 RValue<UInt4> pmaxud(RValue<UInt4> x, RValue<UInt4> y)
7758 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007759 llvm::Function *pmaxud = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmaxud);
John Bauman19bac1e2014-05-06 15:23:49 -04007760
John Bauman66b8ab22014-05-06 15:57:45 -04007761 return RValue<UInt4>(Nucleus::createCall(pmaxud, x.value, y.value));
John Bauman19bac1e2014-05-06 15:23:49 -04007762 }
7763
7764 RValue<UInt4> pminud(RValue<UInt4> x, RValue<UInt4> y)
7765 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007766 llvm::Function *pminud = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pminud);
John Bauman19bac1e2014-05-06 15:23:49 -04007767
John Bauman66b8ab22014-05-06 15:57:45 -04007768 return RValue<UInt4>(Nucleus::createCall(pminud, x.value, y.value));
John Bauman19bac1e2014-05-06 15:23:49 -04007769 }
7770
7771 RValue<Short4> pmulhw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007772 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007773 llvm::Function *pmulhw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmulh_w);
John Bauman89401822014-05-06 15:04:28 -04007774
John Bauman19bac1e2014-05-06 15:23:49 -04007775 return As<Short4>(RValue<MMX>(Nucleus::createCall(pmulhw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007776 }
7777
John Bauman19bac1e2014-05-06 15:23:49 -04007778 RValue<UShort4> pmulhuw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007779 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007780 llvm::Function *pmulhuw = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmulhu_w);
John Bauman89401822014-05-06 15:04:28 -04007781
John Bauman19bac1e2014-05-06 15:23:49 -04007782 return As<UShort4>(RValue<MMX>(Nucleus::createCall(pmulhuw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007783 }
7784
John Bauman19bac1e2014-05-06 15:23:49 -04007785 RValue<Int2> pmaddwd(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007786 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007787 llvm::Function *pmaddwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmadd_wd);
John Bauman89401822014-05-06 15:04:28 -04007788
John Bauman19bac1e2014-05-06 15:23:49 -04007789 return As<Int2>(RValue<MMX>(Nucleus::createCall(pmaddwd, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007790 }
7791
John Bauman19bac1e2014-05-06 15:23:49 -04007792 RValue<Short8> pmulhw(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04007793 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007794 llvm::Function *pmulhw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pmulh_w);
John Bauman89401822014-05-06 15:04:28 -04007795
7796 return RValue<Short8>(Nucleus::createCall(pmulhw, x.value, y.value));
7797 }
7798
John Bauman19bac1e2014-05-06 15:23:49 -04007799 RValue<UShort8> pmulhuw(RValue<UShort8> x, RValue<UShort8> y)
John Bauman89401822014-05-06 15:04:28 -04007800 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007801 llvm::Function *pmulhuw = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pmulhu_w);
John Bauman89401822014-05-06 15:04:28 -04007802
7803 return RValue<UShort8>(Nucleus::createCall(pmulhuw, x.value, y.value));
7804 }
7805
John Bauman19bac1e2014-05-06 15:23:49 -04007806 RValue<Int4> pmaddwd(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04007807 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007808 llvm::Function *pmaddwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse2_pmadd_wd);
John Bauman89401822014-05-06 15:04:28 -04007809
7810 return RValue<Int4>(Nucleus::createCall(pmaddwd, x.value, y.value));
7811 }
7812
John Bauman19bac1e2014-05-06 15:23:49 -04007813 RValue<Int> movmskps(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04007814 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007815 llvm::Function *movmskps = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse_movmsk_ps);
John Bauman89401822014-05-06 15:04:28 -04007816
7817 return RValue<Int>(Nucleus::createCall(movmskps, x.value));
7818 }
7819
John Bauman19bac1e2014-05-06 15:23:49 -04007820 RValue<Int> pmovmskb(RValue<Byte8> x)
John Bauman89401822014-05-06 15:04:28 -04007821 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007822 llvm::Function *pmovmskb = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_pmovmskb);
John Bauman89401822014-05-06 15:04:28 -04007823
John Bauman19bac1e2014-05-06 15:23:49 -04007824 return RValue<Int>(Nucleus::createCall(pmovmskb, As<MMX>(x).value));
John Bauman89401822014-05-06 15:04:28 -04007825 }
7826
Nicolas Capens81f18302016-01-14 09:32:35 -05007827 //RValue<Int2> movd(RValue<Pointer<Int>> x)
John Bauman89401822014-05-06 15:04:28 -04007828 //{
7829 // Value *element = Nucleus::createLoad(x.value);
7830
7831 //// Value *int2 = UndefValue::get(Int2::getType());
7832 //// int2 = Nucleus::createInsertElement(int2, element, ConstantInt::get(Int::getType(), 0));
7833
7834 // Value *int2 = Nucleus::createBitCast(Nucleus::createZExt(element, Long::getType()), Int2::getType());
7835
7836 // return RValue<Int2>(int2);
7837 //}
7838
John Bauman19bac1e2014-05-06 15:23:49 -04007839 //RValue<Int2> movdq2q(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007840 //{
7841 // Value *long2 = Nucleus::createBitCast(x.value, Long2::getType());
7842 // Value *element = Nucleus::createExtractElement(long2, ConstantInt::get(Int::getType(), 0));
7843
7844 // return RValue<Int2>(Nucleus::createBitCast(element, Int2::getType()));
7845 //}
7846
John Bauman19bac1e2014-05-06 15:23:49 -04007847 RValue<Int4> pmovzxbd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007848 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007849 llvm::Function *pmovzxbd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovzxbd);
John Bauman66b8ab22014-05-06 15:57:45 -04007850
John Bauman89401822014-05-06 15:04:28 -04007851 return RValue<Int4>(Nucleus::createCall(pmovzxbd, Nucleus::createBitCast(x.value, Byte16::getType())));
7852 }
7853
John Bauman19bac1e2014-05-06 15:23:49 -04007854 RValue<Int4> pmovsxbd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007855 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007856 llvm::Function *pmovsxbd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovsxbd);
John Bauman66b8ab22014-05-06 15:57:45 -04007857
John Bauman89401822014-05-06 15:04:28 -04007858 return RValue<Int4>(Nucleus::createCall(pmovsxbd, Nucleus::createBitCast(x.value, SByte16::getType())));
7859 }
7860
John Bauman19bac1e2014-05-06 15:23:49 -04007861 RValue<Int4> pmovzxwd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007862 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007863 llvm::Function *pmovzxwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovzxwd);
John Bauman66b8ab22014-05-06 15:57:45 -04007864
John Bauman89401822014-05-06 15:04:28 -04007865 return RValue<Int4>(Nucleus::createCall(pmovzxwd, Nucleus::createBitCast(x.value, UShort8::getType())));
7866 }
7867
John Bauman19bac1e2014-05-06 15:23:49 -04007868 RValue<Int4> pmovsxwd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007869 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007870 llvm::Function *pmovsxwd = Intrinsic::getDeclaration(::module, Intrinsic::x86_sse41_pmovsxwd);
John Bauman66b8ab22014-05-06 15:57:45 -04007871
John Bauman89401822014-05-06 15:04:28 -04007872 return RValue<Int4>(Nucleus::createCall(pmovsxwd, Nucleus::createBitCast(x.value, Short8::getType())));
7873 }
7874
7875 void emms()
7876 {
Nicolas Capens5c1f5cc2016-09-23 16:45:13 -04007877 llvm::Function *emms = Intrinsic::getDeclaration(::module, Intrinsic::x86_mmx_emms);
John Bauman89401822014-05-06 15:04:28 -04007878
7879 Nucleus::createCall(emms);
7880 }
7881 }
7882}