blob: 0a648bd100b2d0548a96c60348af193dbc174552 [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
61namespace sw
62{
63 Optimization optimization[10] = {InstructionCombining, Disabled};
64
65 using namespace llvm;
66
Nicolas Capens2fb41102014-06-26 10:11:50 -040067 RoutineManager *Nucleus::routineManager = 0;
John Bauman89401822014-05-06 15:04:28 -040068 ExecutionEngine *Nucleus::executionEngine = 0;
69 Builder *Nucleus::builder = 0;
70 LLVMContext *Nucleus::context = 0;
71 Module *Nucleus::module = 0;
72 llvm::Function *Nucleus::function = 0;
Nicolas Capensb7ea9842015-04-01 10:54:59 -040073 BackoffLock Nucleus::codegenMutex;
John Bauman89401822014-05-06 15:04:28 -040074
75 class Builder : public IRBuilder<>
76 {
77 };
78
John Bauman89401822014-05-06 15:04:28 -040079 Nucleus::Nucleus()
80 {
Nicolas Capensb7ea9842015-04-01 10:54:59 -040081 codegenMutex.lock(); // Reactor and LLVM are currently not thread safe
82
John Bauman19bac1e2014-05-06 15:23:49 -040083 InitializeNativeTarget();
John Bauman89401822014-05-06 15:04:28 -040084 JITEmitDebugInfo = false;
85
86 if(!context)
87 {
88 context = new LLVMContext();
89 }
90
91 module = new Module("", *context);
Nicolas Capens2fb41102014-06-26 10:11:50 -040092 routineManager = new RoutineManager();
John Bauman66b8ab22014-05-06 15:57:45 -040093
John Bauman89401822014-05-06 15:04:28 -040094 #if defined(__x86_64__)
95 const char *architecture = "x86-64";
96 #else
97 const char *architecture = "x86";
98 #endif
99
100 SmallVector<std::string, 1> MAttrs;
101 MAttrs.push_back(CPUID::supportsMMX() ? "+mmx" : "-mmx");
102 MAttrs.push_back(CPUID::supportsCMOV() ? "+cmov" : "-cmov");
103 MAttrs.push_back(CPUID::supportsSSE() ? "+sse" : "-sse");
104 MAttrs.push_back(CPUID::supportsSSE2() ? "+sse2" : "-sse2");
105 MAttrs.push_back(CPUID::supportsSSE3() ? "+sse3" : "-sse3");
106 MAttrs.push_back(CPUID::supportsSSSE3() ? "+ssse3" : "-ssse3");
107 MAttrs.push_back(CPUID::supportsSSE4_1() ? "+sse41" : "-sse41");
108
John Bauman19bac1e2014-05-06 15:23:49 -0400109 std::string error;
110 TargetMachine *targetMachine = EngineBuilder::selectTarget(module, architecture, "", MAttrs, Reloc::Default, CodeModel::JITDefault, &error);
Nicolas Capens2fb41102014-06-26 10:11:50 -0400111 executionEngine = JIT::createJIT(module, 0, routineManager, CodeGenOpt::Aggressive, true, targetMachine);
John Bauman89401822014-05-06 15:04:28 -0400112
113 if(!builder)
114 {
115 builder = static_cast<Builder*>(new IRBuilder<>(*context));
116
John Bauman66b8ab22014-05-06 15:57:45 -0400117 #if defined(_WIN32)
118 HMODULE CodeAnalyst = LoadLibrary("CAJitNtfyLib.dll");
119 if(CodeAnalyst)
120 {
121 CodeAnalystInitialize = (bool(*)())GetProcAddress(CodeAnalyst, "CAJIT_Initialize");
122 CodeAnalystCompleteJITLog = (void(*)())GetProcAddress(CodeAnalyst, "CAJIT_CompleteJITLog");
123 CodeAnalystLogJITCode = (bool(*)(const void*, unsigned int, const wchar_t*))GetProcAddress(CodeAnalyst, "CAJIT_LogJITCode");
124
125 CodeAnalystInitialize();
126 }
127 #endif
John Bauman89401822014-05-06 15:04:28 -0400128 }
129 }
130
131 Nucleus::~Nucleus()
132 {
133 delete executionEngine;
134 executionEngine = 0;
135
Nicolas Capens2fb41102014-06-26 10:11:50 -0400136 routineManager = 0;
John Bauman89401822014-05-06 15:04:28 -0400137 function = 0;
138 module = 0;
Nicolas Capensb7ea9842015-04-01 10:54:59 -0400139
140 codegenMutex.unlock();
John Bauman89401822014-05-06 15:04:28 -0400141 }
142
143 Routine *Nucleus::acquireRoutine(const wchar_t *name, bool runOptimizations)
144 {
John Bauman19bac1e2014-05-06 15:23:49 -0400145 if(builder->GetInsertBlock()->empty() || !builder->GetInsertBlock()->back().isTerminator())
146 {
John Bauman19bac1e2014-05-06 15:23:49 -0400147 Type *type = function->getReturnType();
148
149 if(type->isVoidTy())
150 {
151 createRetVoid();
152 }
153 else
154 {
155 createRet(UndefValue::get(type));
156 }
157 }
John Bauman89401822014-05-06 15:04:28 -0400158
159 if(false)
160 {
John Bauman66b8ab22014-05-06 15:57:45 -0400161 std::string error;
162 raw_fd_ostream file("llvm-dump-unopt.txt", error);
163 module->print(file, 0);
John Bauman89401822014-05-06 15:04:28 -0400164 }
165
166 if(runOptimizations)
167 {
168 optimize();
169 }
170
171 if(false)
172 {
John Bauman66b8ab22014-05-06 15:57:45 -0400173 std::string error;
174 raw_fd_ostream file("llvm-dump-opt.txt", error);
175 module->print(file, 0);
John Bauman89401822014-05-06 15:04:28 -0400176 }
177
178 void *entry = executionEngine->getPointerToFunction(function);
Nicolas Capensd946e0a2014-06-26 11:31:08 -0400179 Routine *routine = routineManager->acquireRoutine(entry);
John Bauman89401822014-05-06 15:04:28 -0400180
181 if(CodeAnalystLogJITCode)
182 {
Nicolas Capensd946e0a2014-06-26 11:31:08 -0400183 CodeAnalystLogJITCode(routine->getEntry(), routine->getCodeSize(), name);
John Bauman89401822014-05-06 15:04:28 -0400184 }
185
186 return routine;
187 }
188
189 void Nucleus::optimize()
190 {
191 static PassManager *passManager = 0;
John Bauman66b8ab22014-05-06 15:57:45 -0400192
John Bauman89401822014-05-06 15:04:28 -0400193 if(!passManager)
194 {
195 passManager = new PassManager();
196
197 UnsafeFPMath = true;
198 // NoInfsFPMath = true;
199 // NoNaNsFPMath = true;
200
201 passManager->add(new TargetData(*executionEngine->getTargetData()));
202 passManager->add(createScalarReplAggregatesPass());
203
204 for(int pass = 0; pass < 10 && optimization[pass] != Disabled; pass++)
205 {
206 switch(optimization[pass])
207 {
208 case Disabled: break;
209 case CFGSimplification: passManager->add(createCFGSimplificationPass()); break;
210 case LICM: passManager->add(createLICMPass()); break;
211 case AggressiveDCE: passManager->add(createAggressiveDCEPass()); break;
212 case GVN: passManager->add(createGVNPass()); break;
213 case InstructionCombining: passManager->add(createInstructionCombiningPass()); break;
214 case Reassociate: passManager->add(createReassociatePass()); break;
215 case DeadStoreElimination: passManager->add(createDeadStoreEliminationPass()); break;
216 case SCCP: passManager->add(createSCCPPass()); break;
John Bauman19bac1e2014-05-06 15:23:49 -0400217 case ScalarReplAggregates: passManager->add(createScalarReplAggregatesPass()); break;
John Bauman89401822014-05-06 15:04:28 -0400218 default:
219 assert(false);
220 }
221 }
222 }
223
224 passManager->run(*module);
225 }
226
227 void Nucleus::setFunction(llvm::Function *function)
228 {
229 Nucleus::function = function;
230
John Bauman19bac1e2014-05-06 15:23:49 -0400231 builder->SetInsertPoint(BasicBlock::Create(*context, "", function));
John Bauman89401822014-05-06 15:04:28 -0400232 }
233
234 Module *Nucleus::getModule()
235 {
236 return module;
237 }
238
John Bauman89401822014-05-06 15:04:28 -0400239 llvm::Function *Nucleus::getFunction()
240 {
241 return function;
242 }
243
244 llvm::LLVMContext *Nucleus::getContext()
245 {
246 return context;
247 }
248
John Bauman19bac1e2014-05-06 15:23:49 -0400249 Value *Nucleus::allocateStackVariable(Type *type, int arraySize)
John Bauman89401822014-05-06 15:04:28 -0400250 {
251 // Need to allocate it in the entry block for mem2reg to work
252 llvm::Function *function = getFunction();
253 BasicBlock &entryBlock = function->getEntryBlock();
254
255 Instruction *declaration;
256
257 if(arraySize)
258 {
259 declaration = new AllocaInst(type, Nucleus::createConstantInt(arraySize));
260 }
261 else
262 {
263 declaration = new AllocaInst(type, (Value*)0);
264 }
265
266 entryBlock.getInstList().push_front(declaration);
267
268 return declaration;
269 }
270
271 BasicBlock *Nucleus::createBasicBlock()
272 {
John Bauman19bac1e2014-05-06 15:23:49 -0400273 return BasicBlock::Create(*context, "", Nucleus::getFunction());
John Bauman89401822014-05-06 15:04:28 -0400274 }
275
276 BasicBlock *Nucleus::getInsertBlock()
277 {
278 return builder->GetInsertBlock();
279 }
280
281 void Nucleus::setInsertBlock(BasicBlock *basicBlock)
282 {
John Bauman19bac1e2014-05-06 15:23:49 -0400283 // assert(builder->GetInsertBlock()->back().isTerminator());
John Bauman89401822014-05-06 15:04:28 -0400284 return builder->SetInsertPoint(basicBlock);
285 }
286
287 BasicBlock *Nucleus::getPredecessor(BasicBlock *basicBlock)
288 {
289 return *pred_begin(basicBlock);
290 }
291
John Bauman19bac1e2014-05-06 15:23:49 -0400292 llvm::Function *Nucleus::createFunction(llvm::Type *ReturnType, std::vector<llvm::Type*> &Params)
John Bauman89401822014-05-06 15:04:28 -0400293 {
294 llvm::FunctionType *functionType = llvm::FunctionType::get(ReturnType, Params, false);
295 llvm::Function *function = llvm::Function::Create(functionType, llvm::GlobalValue::InternalLinkage, "", Nucleus::getModule());
296 function->setCallingConv(llvm::CallingConv::C);
297
298 return function;
299 }
300
Nicolas Capens81f18302016-01-14 09:32:35 -0500301 llvm::Value *Nucleus::getArgument(llvm::Function *function, unsigned int index)
John Bauman89401822014-05-06 15:04:28 -0400302 {
303 llvm::Function::arg_iterator args = function->arg_begin();
304
305 while(index)
306 {
307 args++;
308 index--;
309 }
310
311 return &*args;
312 }
313
314 Value *Nucleus::createRetVoid()
315 {
John Bauman66b8ab22014-05-06 15:57:45 -0400316 x86::emms();
317
John Bauman89401822014-05-06 15:04:28 -0400318 return builder->CreateRetVoid();
319 }
320
321 Value *Nucleus::createRet(Value *V)
322 {
John Bauman66b8ab22014-05-06 15:57:45 -0400323 x86::emms();
324
John Bauman89401822014-05-06 15:04:28 -0400325 return builder->CreateRet(V);
326 }
327
328 Value *Nucleus::createBr(BasicBlock *dest)
329 {
330 return builder->CreateBr(dest);
331 }
332
333 Value *Nucleus::createCondBr(Value *cond, BasicBlock *ifTrue, BasicBlock *ifFalse)
334 {
335 return builder->CreateCondBr(cond, ifTrue, ifFalse);
336 }
337
338 Value *Nucleus::createAdd(Value *lhs, Value *rhs)
339 {
340 return builder->CreateAdd(lhs, rhs);
341 }
342
343 Value *Nucleus::createSub(Value *lhs, Value *rhs)
344 {
345 return builder->CreateSub(lhs, rhs);
346 }
347
348 Value *Nucleus::createMul(Value *lhs, Value *rhs)
349 {
350 return builder->CreateMul(lhs, rhs);
351 }
352
353 Value *Nucleus::createUDiv(Value *lhs, Value *rhs)
354 {
355 return builder->CreateUDiv(lhs, rhs);
356 }
357
358 Value *Nucleus::createSDiv(Value *lhs, Value *rhs)
359 {
360 return builder->CreateSDiv(lhs, rhs);
361 }
362
363 Value *Nucleus::createFAdd(Value *lhs, Value *rhs)
364 {
365 return builder->CreateFAdd(lhs, rhs);
366 }
367
368 Value *Nucleus::createFSub(Value *lhs, Value *rhs)
369 {
370 return builder->CreateFSub(lhs, rhs);
371 }
372
373 Value *Nucleus::createFMul(Value *lhs, Value *rhs)
374 {
375 return builder->CreateFMul(lhs, rhs);
376 }
377
378 Value *Nucleus::createFDiv(Value *lhs, Value *rhs)
379 {
380 return builder->CreateFDiv(lhs, rhs);
381 }
382
383 Value *Nucleus::createURem(Value *lhs, Value *rhs)
384 {
385 return builder->CreateURem(lhs, rhs);
386 }
387
388 Value *Nucleus::createSRem(Value *lhs, Value *rhs)
389 {
390 return builder->CreateSRem(lhs, rhs);
391 }
392
393 Value *Nucleus::createFRem(Value *lhs, Value *rhs)
394 {
395 return builder->CreateFRem(lhs, rhs);
396 }
397
398 Value *Nucleus::createShl(Value *lhs, Value *rhs)
399 {
400 return builder->CreateShl(lhs, rhs);
401 }
402
403 Value *Nucleus::createLShr(Value *lhs, Value *rhs)
404 {
405 return builder->CreateLShr(lhs, rhs);
406 }
407
408 Value *Nucleus::createAShr(Value *lhs, Value *rhs)
409 {
410 return builder->CreateAShr(lhs, rhs);
411 }
412
413 Value *Nucleus::createAnd(Value *lhs, Value *rhs)
414 {
415 return builder->CreateAnd(lhs, rhs);
416 }
417
418 Value *Nucleus::createOr(Value *lhs, Value *rhs)
419 {
420 return builder->CreateOr(lhs, rhs);
421 }
422
423 Value *Nucleus::createXor(Value *lhs, Value *rhs)
424 {
425 return builder->CreateXor(lhs, rhs);
426 }
427
428 Value *Nucleus::createNeg(Value *V)
429 {
430 return builder->CreateNeg(V);
431 }
432
433 Value *Nucleus::createFNeg(Value *V)
434 {
435 return builder->CreateFNeg(V);
436 }
437
438 Value *Nucleus::createNot(Value *V)
439 {
440 return builder->CreateNot(V);
441 }
442
443 Value *Nucleus::createLoad(Value *ptr, bool isVolatile, unsigned int align)
444 {
John Bauman19bac1e2014-05-06 15:23:49 -0400445 return builder->Insert(new LoadInst(ptr, "", isVolatile, align));
John Bauman89401822014-05-06 15:04:28 -0400446 }
447
448 Value *Nucleus::createStore(Value *value, Value *ptr, bool isVolatile, unsigned int align)
449 {
450 return builder->Insert(new StoreInst(value, ptr, isVolatile, align));
451 }
452
453 Value *Nucleus::createGEP(Value *ptr, Value *index)
454 {
455 return builder->CreateGEP(ptr, index);
456 }
457
John Bauman19bac1e2014-05-06 15:23:49 -0400458 Value *Nucleus::createAtomicAdd(Value *ptr, Value *value)
459 {
460 return builder->CreateAtomicRMW(AtomicRMWInst::Add, ptr, value, SequentiallyConsistent);
461 }
462
463 Value *Nucleus::createTrunc(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400464 {
465 return builder->CreateTrunc(V, destType);
466 }
467
John Bauman19bac1e2014-05-06 15:23:49 -0400468 Value *Nucleus::createZExt(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400469 {
470 return builder->CreateZExt(V, destType);
471 }
472
John Bauman19bac1e2014-05-06 15:23:49 -0400473 Value *Nucleus::createSExt(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400474 {
475 return builder->CreateSExt(V, destType);
476 }
477
Alexis Hetu764d1422016-09-28 08:44:22 -0400478// Value *Nucleus::createFPToUI(Value *V, Type *destType)
479// {
480// return builder->CreateFPToUI(V, destType);
481// }
John Bauman89401822014-05-06 15:04:28 -0400482
John Bauman19bac1e2014-05-06 15:23:49 -0400483 Value *Nucleus::createFPToSI(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400484 {
485 return builder->CreateFPToSI(V, destType);
486 }
487
John Bauman19bac1e2014-05-06 15:23:49 -0400488 Value *Nucleus::createUIToFP(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400489 {
490 return builder->CreateUIToFP(V, destType);
491 }
492
John Bauman19bac1e2014-05-06 15:23:49 -0400493 Value *Nucleus::createSIToFP(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400494 {
495 return builder->CreateSIToFP(V, destType);
496 }
497
John Bauman19bac1e2014-05-06 15:23:49 -0400498 Value *Nucleus::createFPTrunc(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400499 {
500 return builder->CreateFPTrunc(V, destType);
501 }
502
John Bauman19bac1e2014-05-06 15:23:49 -0400503 Value *Nucleus::createFPExt(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400504 {
505 return builder->CreateFPExt(V, destType);
506 }
507
John Bauman19bac1e2014-05-06 15:23:49 -0400508 Value *Nucleus::createPtrToInt(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400509 {
510 return builder->CreatePtrToInt(V, destType);
511 }
512
John Bauman19bac1e2014-05-06 15:23:49 -0400513 Value *Nucleus::createIntToPtr(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400514 {
515 return builder->CreateIntToPtr(V, destType);
516 }
517
John Bauman19bac1e2014-05-06 15:23:49 -0400518 Value *Nucleus::createBitCast(Value *V, Type *destType)
John Bauman89401822014-05-06 15:04:28 -0400519 {
520 return builder->CreateBitCast(V, destType);
521 }
522
John Bauman19bac1e2014-05-06 15:23:49 -0400523 Value *Nucleus::createIntCast(Value *V, Type *destType, bool isSigned)
John Bauman89401822014-05-06 15:04:28 -0400524 {
525 return builder->CreateIntCast(V, destType, isSigned);
526 }
527
528 Value *Nucleus::createICmpEQ(Value *lhs, Value *rhs)
529 {
530 return builder->CreateICmpEQ(lhs, rhs);
531 }
532
533 Value *Nucleus::createICmpNE(Value *lhs, Value *rhs)
534 {
535 return builder->CreateICmpNE(lhs, rhs);
536 }
537
538 Value *Nucleus::createICmpUGT(Value *lhs, Value *rhs)
539 {
540 return builder->CreateICmpUGT(lhs, rhs);
541 }
542
543 Value *Nucleus::createICmpUGE(Value *lhs, Value *rhs)
544 {
545 return builder->CreateICmpUGE(lhs, rhs);
546 }
547
548 Value *Nucleus::createICmpULT(Value *lhs, Value *rhs)
549 {
550 return builder->CreateICmpULT(lhs, rhs);
551 }
552
553 Value *Nucleus::createICmpULE(Value *lhs, Value *rhs)
554 {
555 return builder->CreateICmpULE(lhs, rhs);
556 }
557
558 Value *Nucleus::createICmpSGT(Value *lhs, Value *rhs)
559 {
560 return builder->CreateICmpSGT(lhs, rhs);
561 }
562
563 Value *Nucleus::createICmpSGE(Value *lhs, Value *rhs)
564 {
565 return builder->CreateICmpSGE(lhs, rhs);
566 }
567
568 Value *Nucleus::createICmpSLT(Value *lhs, Value *rhs)
569 {
570 return builder->CreateICmpSLT(lhs, rhs);
571 }
572
573 Value *Nucleus::createICmpSLE(Value *lhs, Value *rhs)
574 {
575 return builder->CreateICmpSLE(lhs, rhs);
576 }
577
578 Value *Nucleus::createFCmpOEQ(Value *lhs, Value *rhs)
579 {
580 return builder->CreateFCmpOEQ(lhs, rhs);
581 }
582
583 Value *Nucleus::createFCmpOGT(Value *lhs, Value *rhs)
584 {
585 return builder->CreateFCmpOGT(lhs, rhs);
586 }
587
588 Value *Nucleus::createFCmpOGE(Value *lhs, Value *rhs)
589 {
590 return builder->CreateFCmpOGE(lhs, rhs);
591 }
592
593 Value *Nucleus::createFCmpOLT(Value *lhs, Value *rhs)
594 {
595 return builder->CreateFCmpOLT(lhs, rhs);
596 }
597
598 Value *Nucleus::createFCmpOLE(Value *lhs, Value *rhs)
599 {
600 return builder->CreateFCmpOLE(lhs, rhs);
601 }
602
603 Value *Nucleus::createFCmpONE(Value *lhs, Value *rhs)
604 {
605 return builder->CreateFCmpONE(lhs, rhs);
606 }
607
608 Value *Nucleus::createFCmpORD(Value *lhs, Value *rhs)
609 {
610 return builder->CreateFCmpORD(lhs, rhs);
611 }
612
613 Value *Nucleus::createFCmpUNO(Value *lhs, Value *rhs)
614 {
615 return builder->CreateFCmpUNO(lhs, rhs);
616 }
617
618 Value *Nucleus::createFCmpUEQ(Value *lhs, Value *rhs)
619 {
620 return builder->CreateFCmpUEQ(lhs, rhs);
621 }
622
623 Value *Nucleus::createFCmpUGT(Value *lhs, Value *rhs)
624 {
625 return builder->CreateFCmpUGT(lhs, rhs);
626 }
627
628 Value *Nucleus::createFCmpUGE(Value *lhs, Value *rhs)
629 {
630 return builder->CreateFCmpUGE(lhs, rhs);
631 }
632
633 Value *Nucleus::createFCmpULT(Value *lhs, Value *rhs)
634 {
635 return builder->CreateFCmpULT(lhs, rhs);
636 }
637
638 Value *Nucleus::createFCmpULE(Value *lhs, Value *rhs)
639 {
640 return builder->CreateFCmpULE(lhs, rhs);
641 }
642
643 Value *Nucleus::createFCmpUNE(Value *lhs, Value *rhs)
644 {
645 return builder->CreateFCmpULE(lhs, rhs);
646 }
647
648 Value *Nucleus::createCall(Value *callee)
649 {
650 return builder->CreateCall(callee);
651 }
652
653 Value *Nucleus::createCall(Value *callee, Value *arg)
654 {
655 return builder->CreateCall(callee, arg);
656 }
657
658 Value *Nucleus::createCall(Value *callee, Value *arg1, Value *arg2)
659 {
660 return builder->CreateCall2(callee, arg1, arg2);
661 }
662
663 Value *Nucleus::createCall(Value *callee, Value *arg1, Value *arg2, Value *arg3)
664 {
665 return builder->CreateCall3(callee, arg1, arg2, arg3);
666 }
667
668 Value *Nucleus::createCall(Value *callee, Value *arg1, Value *arg2, Value *arg3, Value *arg4)
669 {
670 return builder->CreateCall4(callee, arg1, arg2, arg3, arg4);
671 }
672
673 Value *Nucleus::createExtractElement(Value *vector, int index)
674 {
675 return builder->CreateExtractElement(vector, createConstantInt(index));
676 }
677
678 Value *Nucleus::createInsertElement(Value *vector, Value *element, int index)
679 {
680 return builder->CreateInsertElement(vector, element, createConstantInt(index));
681 }
682
683 Value *Nucleus::createShuffleVector(Value *V1, Value *V2, Value *mask)
684 {
685 return builder->CreateShuffleVector(V1, V2, mask);
686 }
687
688 Value *Nucleus::createSelect(Value *C, Value *ifTrue, Value *ifFalse)
689 {
690 return builder->CreateSelect(C, ifTrue, ifFalse);
691 }
692
693 Value *Nucleus::createSwitch(llvm::Value *V, llvm::BasicBlock *Dest, unsigned NumCases)
694 {
695 return builder->CreateSwitch(V, Dest, NumCases);
696 }
697
698 void Nucleus::addSwitchCase(llvm::Value *Switch, int Case, llvm::BasicBlock *Branch)
699 {
700 static_cast<SwitchInst*>(Switch)->addCase(Nucleus::createConstantInt(Case), Branch);
701 }
702
703 Value *Nucleus::createUnreachable()
704 {
705 return builder->CreateUnreachable();
706 }
707
708 Value *Nucleus::createSwizzle(Value *val, unsigned char select)
709 {
710 Constant *swizzle[4];
711 swizzle[0] = Nucleus::createConstantInt((select >> 0) & 0x03);
712 swizzle[1] = Nucleus::createConstantInt((select >> 2) & 0x03);
713 swizzle[2] = Nucleus::createConstantInt((select >> 4) & 0x03);
714 swizzle[3] = Nucleus::createConstantInt((select >> 6) & 0x03);
715
716 Value *shuffle = Nucleus::createShuffleVector(val, UndefValue::get(val->getType()), Nucleus::createConstantVector(swizzle, 4));
717
718 return shuffle;
719 }
720
721 Value *Nucleus::createMask(Value *lhs, Value *rhs, unsigned char select)
722 {
723 bool mask[4] = {false, false, false, false};
724
725 mask[(select >> 0) & 0x03] = true;
726 mask[(select >> 2) & 0x03] = true;
727 mask[(select >> 4) & 0x03] = true;
728 mask[(select >> 6) & 0x03] = true;
729
730 Constant *swizzle[4];
731 swizzle[0] = Nucleus::createConstantInt(mask[0] ? 4 : 0);
732 swizzle[1] = Nucleus::createConstantInt(mask[1] ? 5 : 1);
733 swizzle[2] = Nucleus::createConstantInt(mask[2] ? 6 : 2);
734 swizzle[3] = Nucleus::createConstantInt(mask[3] ? 7 : 3);
735
736 Value *shuffle = Nucleus::createShuffleVector(lhs, rhs, Nucleus::createConstantVector(swizzle, 4));
737
738 return shuffle;
739 }
740
741 const llvm::GlobalValue *Nucleus::getGlobalValueAtAddress(void *Addr)
742 {
743 return executionEngine->getGlobalValueAtAddress(Addr);
744 }
745
746 void Nucleus::addGlobalMapping(const llvm::GlobalValue *GV, void *Addr)
747 {
748 executionEngine->addGlobalMapping(GV, Addr);
749 }
750
John Bauman19bac1e2014-05-06 15:23:49 -0400751 llvm::GlobalValue *Nucleus::createGlobalValue(llvm::Type *Ty, bool isConstant, unsigned int Align)
John Bauman89401822014-05-06 15:04:28 -0400752 {
John Bauman19bac1e2014-05-06 15:23:49 -0400753 llvm::GlobalValue *global = new llvm::GlobalVariable(*Nucleus::getModule(), Ty, isConstant, llvm::GlobalValue::ExternalLinkage, 0, "");
John Bauman89401822014-05-06 15:04:28 -0400754 global->setAlignment(Align);
755
756 return global;
757 }
758
John Bauman19bac1e2014-05-06 15:23:49 -0400759 llvm::Type *Nucleus::getPointerType(llvm::Type *ElementType)
John Bauman89401822014-05-06 15:04:28 -0400760 {
761 return llvm::PointerType::get(ElementType, 0);
762 }
763
John Bauman19bac1e2014-05-06 15:23:49 -0400764 llvm::Constant *Nucleus::createNullValue(llvm::Type *Ty)
John Bauman89401822014-05-06 15:04:28 -0400765 {
766 return llvm::Constant::getNullValue(Ty);
767 }
768
John Bauman66b8ab22014-05-06 15:57:45 -0400769 llvm::ConstantInt *Nucleus::createConstantInt(int64_t i)
John Bauman89401822014-05-06 15:04:28 -0400770 {
771 return llvm::ConstantInt::get(Type::getInt64Ty(*context), i, true);
772 }
773
774 llvm::ConstantInt *Nucleus::createConstantInt(int i)
775 {
776 return llvm::ConstantInt::get(Type::getInt32Ty(*context), i, true);
777 }
778
779 llvm::ConstantInt *Nucleus::createConstantInt(unsigned int i)
780 {
781 return llvm::ConstantInt::get(Type::getInt32Ty(*context), i, false);
782 }
783
784 llvm::ConstantInt *Nucleus::createConstantBool(bool b)
785 {
786 return llvm::ConstantInt::get(Type::getInt1Ty(*context), b);
787 }
788
789 llvm::ConstantInt *Nucleus::createConstantByte(signed char i)
790 {
791 return llvm::ConstantInt::get(Type::getInt8Ty(*context), i, true);
792 }
793
794 llvm::ConstantInt *Nucleus::createConstantByte(unsigned char i)
795 {
796 return llvm::ConstantInt::get(Type::getInt8Ty(*context), i, false);
797 }
798
799 llvm::ConstantInt *Nucleus::createConstantShort(short i)
800 {
801 return llvm::ConstantInt::get(Type::getInt16Ty(*context), i, true);
802 }
803
804 llvm::ConstantInt *Nucleus::createConstantShort(unsigned short i)
805 {
806 return llvm::ConstantInt::get(Type::getInt16Ty(*context), i, false);
807 }
808
809 llvm::Constant *Nucleus::createConstantFloat(float x)
810 {
811 return ConstantFP::get(Float::getType(), x);
812 }
813
John Bauman19bac1e2014-05-06 15:23:49 -0400814 llvm::Value *Nucleus::createNullPointer(llvm::Type *Ty)
John Bauman89401822014-05-06 15:04:28 -0400815 {
816 return llvm::ConstantPointerNull::get(llvm::PointerType::get(Ty, 0));
817 }
818
John Bauman19bac1e2014-05-06 15:23:49 -0400819 llvm::Value *Nucleus::createConstantVector(llvm::Constant *const *Vals, unsigned NumVals)
John Bauman89401822014-05-06 15:04:28 -0400820 {
John Bauman19bac1e2014-05-06 15:23:49 -0400821 return llvm::ConstantVector::get(llvm::ArrayRef<llvm::Constant*>(Vals, NumVals));
John Bauman89401822014-05-06 15:04:28 -0400822 }
823
John Bauman19bac1e2014-05-06 15:23:49 -0400824 Type *Void::getType()
John Bauman89401822014-05-06 15:04:28 -0400825 {
826 return Type::getVoidTy(*Nucleus::getContext());
827 }
828
John Bauman66b8ab22014-05-06 15:57:45 -0400829 LValue::LValue(llvm::Type *type, int arraySize)
830 {
831 address = Nucleus::allocateStackVariable(type, arraySize);
832 }
833
834 llvm::Value *LValue::loadValue(unsigned int alignment) const
835 {
836 return Nucleus::createLoad(address, false, alignment);
837 }
838
839 llvm::Value *LValue::storeValue(llvm::Value *value, unsigned int alignment) const
840 {
841 return Nucleus::createStore(value, address, false, alignment);
842 }
843
844 llvm::Value *LValue::getAddress(llvm::Value *index) const
845 {
846 return Nucleus::createGEP(address, index);
847 }
848
John Bauman19bac1e2014-05-06 15:23:49 -0400849 Type *MMX::getType()
850 {
851 return Type::getX86_MMXTy(*Nucleus::getContext());
852 }
853
Nicolas Capens81f18302016-01-14 09:32:35 -0500854 Bool::Bool(Argument<Bool> argument)
John Bauman89401822014-05-06 15:04:28 -0400855 {
Nicolas Capens81f18302016-01-14 09:32:35 -0500856 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -0400857 }
858
859 Bool::Bool()
860 {
John Bauman89401822014-05-06 15:04:28 -0400861 }
862
863 Bool::Bool(bool x)
864 {
John Bauman66b8ab22014-05-06 15:57:45 -0400865 storeValue(Nucleus::createConstantBool(x));
John Bauman89401822014-05-06 15:04:28 -0400866 }
867
John Bauman19bac1e2014-05-06 15:23:49 -0400868 Bool::Bool(RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400869 {
John Bauman66b8ab22014-05-06 15:57:45 -0400870 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400871 }
872
873 Bool::Bool(const Bool &rhs)
874 {
John Bauman66b8ab22014-05-06 15:57:45 -0400875 Value *value = rhs.loadValue();
876 storeValue(value);
877 }
John Bauman89401822014-05-06 15:04:28 -0400878
John Bauman66b8ab22014-05-06 15:57:45 -0400879 Bool::Bool(const Reference<Bool> &rhs)
880 {
881 Value *value = rhs.loadValue();
882 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400883 }
884
John Bauman19bac1e2014-05-06 15:23:49 -0400885 RValue<Bool> Bool::operator=(RValue<Bool> rhs) const
John Bauman89401822014-05-06 15:04:28 -0400886 {
John Bauman66b8ab22014-05-06 15:57:45 -0400887 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400888
889 return rhs;
890 }
891
892 RValue<Bool> Bool::operator=(const Bool &rhs) const
893 {
John Bauman66b8ab22014-05-06 15:57:45 -0400894 Value *value = rhs.loadValue();
895 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400896
897 return RValue<Bool>(value);
898 }
899
John Bauman66b8ab22014-05-06 15:57:45 -0400900 RValue<Bool> Bool::operator=(const Reference<Bool> &rhs) const
John Bauman89401822014-05-06 15:04:28 -0400901 {
John Bauman66b8ab22014-05-06 15:57:45 -0400902 Value *value = rhs.loadValue();
903 storeValue(value);
904
905 return RValue<Bool>(value);
John Bauman89401822014-05-06 15:04:28 -0400906 }
907
John Bauman19bac1e2014-05-06 15:23:49 -0400908 RValue<Bool> operator!(RValue<Bool> val)
John Bauman89401822014-05-06 15:04:28 -0400909 {
910 return RValue<Bool>(Nucleus::createNot(val.value));
911 }
912
John Bauman19bac1e2014-05-06 15:23:49 -0400913 RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400914 {
915 return RValue<Bool>(Nucleus::createAnd(lhs.value, rhs.value));
916 }
917
John Bauman19bac1e2014-05-06 15:23:49 -0400918 RValue<Bool> operator||(RValue<Bool> lhs, RValue<Bool> rhs)
John Bauman89401822014-05-06 15:04:28 -0400919 {
920 return RValue<Bool>(Nucleus::createOr(lhs.value, rhs.value));
921 }
922
John Bauman19bac1e2014-05-06 15:23:49 -0400923 Type *Bool::getType()
John Bauman89401822014-05-06 15:04:28 -0400924 {
925 return Type::getInt1Ty(*Nucleus::getContext());
926 }
927
Nicolas Capens81f18302016-01-14 09:32:35 -0500928 Byte::Byte(Argument<Byte> argument)
John Bauman89401822014-05-06 15:04:28 -0400929 {
Nicolas Capens81f18302016-01-14 09:32:35 -0500930 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -0400931 }
932
John Bauman19bac1e2014-05-06 15:23:49 -0400933 Byte::Byte(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -0400934 {
John Bauman89401822014-05-06 15:04:28 -0400935 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
936
John Bauman66b8ab22014-05-06 15:57:45 -0400937 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -0400938 }
939
Alexis Hetu77dfab42015-11-23 13:31:22 -0500940 Byte::Byte(RValue<UInt> cast)
941 {
942 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
943
944 storeValue(integer);
945 }
946
947 Byte::Byte(RValue<UShort> cast)
948 {
949 Value *integer = Nucleus::createTrunc(cast.value, Byte::getType());
950
951 storeValue(integer);
952 }
953
John Bauman89401822014-05-06 15:04:28 -0400954 Byte::Byte()
955 {
John Bauman89401822014-05-06 15:04:28 -0400956 }
957
958 Byte::Byte(int x)
959 {
John Bauman66b8ab22014-05-06 15:57:45 -0400960 storeValue(Nucleus::createConstantByte((unsigned char)x));
John Bauman89401822014-05-06 15:04:28 -0400961 }
962
963 Byte::Byte(unsigned char x)
964 {
John Bauman66b8ab22014-05-06 15:57:45 -0400965 storeValue(Nucleus::createConstantByte(x));
John Bauman89401822014-05-06 15:04:28 -0400966 }
967
John Bauman19bac1e2014-05-06 15:23:49 -0400968 Byte::Byte(RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -0400969 {
John Bauman66b8ab22014-05-06 15:57:45 -0400970 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400971 }
972
973 Byte::Byte(const Byte &rhs)
974 {
John Bauman66b8ab22014-05-06 15:57:45 -0400975 Value *value = rhs.loadValue();
976 storeValue(value);
977 }
John Bauman89401822014-05-06 15:04:28 -0400978
John Bauman66b8ab22014-05-06 15:57:45 -0400979 Byte::Byte(const Reference<Byte> &rhs)
980 {
981 Value *value = rhs.loadValue();
982 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400983 }
984
John Bauman19bac1e2014-05-06 15:23:49 -0400985 RValue<Byte> Byte::operator=(RValue<Byte> rhs) const
John Bauman89401822014-05-06 15:04:28 -0400986 {
John Bauman66b8ab22014-05-06 15:57:45 -0400987 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -0400988
989 return rhs;
990 }
991
992 RValue<Byte> Byte::operator=(const Byte &rhs) const
993 {
John Bauman66b8ab22014-05-06 15:57:45 -0400994 Value *value = rhs.loadValue();
995 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -0400996
997 return RValue<Byte>(value);
998 }
999
John Bauman66b8ab22014-05-06 15:57:45 -04001000 RValue<Byte> Byte::operator=(const Reference<Byte> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04001001 {
John Bauman66b8ab22014-05-06 15:57:45 -04001002 Value *value = rhs.loadValue();
1003 storeValue(value);
1004
1005 return RValue<Byte>(value);
John Bauman89401822014-05-06 15:04:28 -04001006 }
1007
John Bauman19bac1e2014-05-06 15:23:49 -04001008 RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001009 {
1010 return RValue<Byte>(Nucleus::createAdd(lhs.value, rhs.value));
1011 }
1012
John Bauman19bac1e2014-05-06 15:23:49 -04001013 RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001014 {
1015 return RValue<Byte>(Nucleus::createSub(lhs.value, rhs.value));
1016 }
1017
John Bauman19bac1e2014-05-06 15:23:49 -04001018 RValue<Byte> operator*(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001019 {
1020 return RValue<Byte>(Nucleus::createMul(lhs.value, rhs.value));
1021 }
1022
John Bauman19bac1e2014-05-06 15:23:49 -04001023 RValue<Byte> operator/(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001024 {
1025 return RValue<Byte>(Nucleus::createUDiv(lhs.value, rhs.value));
1026 }
1027
John Bauman19bac1e2014-05-06 15:23:49 -04001028 RValue<Byte> operator%(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001029 {
1030 return RValue<Byte>(Nucleus::createURem(lhs.value, rhs.value));
1031 }
1032
John Bauman19bac1e2014-05-06 15:23:49 -04001033 RValue<Byte> operator&(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001034 {
1035 return RValue<Byte>(Nucleus::createAnd(lhs.value, rhs.value));
1036 }
1037
John Bauman19bac1e2014-05-06 15:23:49 -04001038 RValue<Byte> operator|(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001039 {
1040 return RValue<Byte>(Nucleus::createOr(lhs.value, rhs.value));
1041 }
1042
John Bauman19bac1e2014-05-06 15:23:49 -04001043 RValue<Byte> operator^(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001044 {
1045 return RValue<Byte>(Nucleus::createXor(lhs.value, rhs.value));
1046 }
1047
John Bauman19bac1e2014-05-06 15:23:49 -04001048 RValue<Byte> operator<<(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001049 {
1050 return RValue<Byte>(Nucleus::createShl(lhs.value, rhs.value));
1051 }
1052
John Bauman19bac1e2014-05-06 15:23:49 -04001053 RValue<Byte> operator>>(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001054 {
1055 return RValue<Byte>(Nucleus::createLShr(lhs.value, rhs.value));
1056 }
1057
John Bauman19bac1e2014-05-06 15:23:49 -04001058 RValue<Byte> operator+=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001059 {
1060 return lhs = lhs + rhs;
1061 }
1062
John Bauman19bac1e2014-05-06 15:23:49 -04001063 RValue<Byte> operator-=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001064 {
1065 return lhs = lhs - rhs;
1066 }
1067
John Bauman19bac1e2014-05-06 15:23:49 -04001068 RValue<Byte> operator*=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001069 {
1070 return lhs = lhs * rhs;
1071 }
1072
John Bauman19bac1e2014-05-06 15:23:49 -04001073 RValue<Byte> operator/=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001074 {
1075 return lhs = lhs / rhs;
1076 }
1077
John Bauman19bac1e2014-05-06 15:23:49 -04001078 RValue<Byte> operator%=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001079 {
1080 return lhs = lhs % rhs;
1081 }
1082
John Bauman19bac1e2014-05-06 15:23:49 -04001083 RValue<Byte> operator&=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001084 {
1085 return lhs = lhs & rhs;
1086 }
1087
John Bauman19bac1e2014-05-06 15:23:49 -04001088 RValue<Byte> operator|=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001089 {
1090 return lhs = lhs | rhs;
1091 }
1092
John Bauman19bac1e2014-05-06 15:23:49 -04001093 RValue<Byte> operator^=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001094 {
1095 return lhs = lhs ^ rhs;
1096 }
1097
John Bauman19bac1e2014-05-06 15:23:49 -04001098 RValue<Byte> operator<<=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001099 {
1100 return lhs = lhs << rhs;
1101 }
1102
John Bauman19bac1e2014-05-06 15:23:49 -04001103 RValue<Byte> operator>>=(const Byte &lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001104 {
1105 return lhs = lhs >> rhs;
1106 }
1107
John Bauman19bac1e2014-05-06 15:23:49 -04001108 RValue<Byte> operator+(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001109 {
1110 return val;
1111 }
1112
John Bauman19bac1e2014-05-06 15:23:49 -04001113 RValue<Byte> operator-(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001114 {
1115 return RValue<Byte>(Nucleus::createNeg(val.value));
1116 }
1117
John Bauman19bac1e2014-05-06 15:23:49 -04001118 RValue<Byte> operator~(RValue<Byte> val)
John Bauman89401822014-05-06 15:04:28 -04001119 {
1120 return RValue<Byte>(Nucleus::createNot(val.value));
1121 }
1122
1123 RValue<Byte> operator++(const Byte &val, int) // Post-increment
1124 {
1125 RValue<Byte> res = val;
1126
1127 Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantByte((unsigned char)1));
John Bauman66b8ab22014-05-06 15:57:45 -04001128 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001129
1130 return res;
1131 }
1132
1133 const Byte &operator++(const Byte &val) // Pre-increment
1134 {
John Bauman66b8ab22014-05-06 15:57:45 -04001135 Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantByte((unsigned char)1));
1136 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001137
1138 return val;
1139 }
1140
1141 RValue<Byte> operator--(const Byte &val, int) // Post-decrement
1142 {
1143 RValue<Byte> res = val;
1144
1145 Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantByte((unsigned char)1));
John Bauman66b8ab22014-05-06 15:57:45 -04001146 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001147
1148 return res;
1149 }
1150
1151 const Byte &operator--(const Byte &val) // Pre-decrement
1152 {
John Bauman66b8ab22014-05-06 15:57:45 -04001153 Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantByte((unsigned char)1));
1154 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001155
1156 return val;
1157 }
1158
John Bauman19bac1e2014-05-06 15:23:49 -04001159 RValue<Bool> operator<(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001160 {
1161 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1162 }
1163
John Bauman19bac1e2014-05-06 15:23:49 -04001164 RValue<Bool> operator<=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001165 {
1166 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1167 }
1168
John Bauman19bac1e2014-05-06 15:23:49 -04001169 RValue<Bool> operator>(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001170 {
1171 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1172 }
1173
John Bauman19bac1e2014-05-06 15:23:49 -04001174 RValue<Bool> operator>=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001175 {
1176 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1177 }
1178
John Bauman19bac1e2014-05-06 15:23:49 -04001179 RValue<Bool> operator!=(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001180 {
1181 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1182 }
1183
John Bauman19bac1e2014-05-06 15:23:49 -04001184 RValue<Bool> operator==(RValue<Byte> lhs, RValue<Byte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001185 {
1186 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1187 }
1188
John Bauman19bac1e2014-05-06 15:23:49 -04001189 Type *Byte::getType()
John Bauman89401822014-05-06 15:04:28 -04001190 {
1191 return Type::getInt8Ty(*Nucleus::getContext());
1192 }
1193
Nicolas Capens81f18302016-01-14 09:32:35 -05001194 SByte::SByte(Argument<SByte> argument)
John Bauman89401822014-05-06 15:04:28 -04001195 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001196 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001197 }
1198
Alexis Hetu77dfab42015-11-23 13:31:22 -05001199 SByte::SByte(RValue<Int> cast)
1200 {
1201 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1202
1203 storeValue(integer);
1204 }
1205
1206 SByte::SByte(RValue<Short> cast)
1207 {
1208 Value *integer = Nucleus::createTrunc(cast.value, SByte::getType());
1209
1210 storeValue(integer);
1211 }
1212
John Bauman89401822014-05-06 15:04:28 -04001213 SByte::SByte()
1214 {
John Bauman89401822014-05-06 15:04:28 -04001215 }
1216
1217 SByte::SByte(signed char x)
1218 {
John Bauman66b8ab22014-05-06 15:57:45 -04001219 storeValue(Nucleus::createConstantByte(x));
John Bauman89401822014-05-06 15:04:28 -04001220 }
1221
John Bauman19bac1e2014-05-06 15:23:49 -04001222 SByte::SByte(RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001223 {
John Bauman66b8ab22014-05-06 15:57:45 -04001224 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001225 }
1226
1227 SByte::SByte(const SByte &rhs)
1228 {
John Bauman66b8ab22014-05-06 15:57:45 -04001229 Value *value = rhs.loadValue();
1230 storeValue(value);
1231 }
John Bauman89401822014-05-06 15:04:28 -04001232
John Bauman66b8ab22014-05-06 15:57:45 -04001233 SByte::SByte(const Reference<SByte> &rhs)
1234 {
1235 Value *value = rhs.loadValue();
1236 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001237 }
1238
John Bauman19bac1e2014-05-06 15:23:49 -04001239 RValue<SByte> SByte::operator=(RValue<SByte> rhs) const
John Bauman89401822014-05-06 15:04:28 -04001240 {
John Bauman66b8ab22014-05-06 15:57:45 -04001241 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001242
1243 return rhs;
1244 }
1245
1246 RValue<SByte> SByte::operator=(const SByte &rhs) const
1247 {
John Bauman66b8ab22014-05-06 15:57:45 -04001248 Value *value = rhs.loadValue();
1249 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001250
1251 return RValue<SByte>(value);
1252 }
1253
John Bauman66b8ab22014-05-06 15:57:45 -04001254 RValue<SByte> SByte::operator=(const Reference<SByte> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04001255 {
John Bauman66b8ab22014-05-06 15:57:45 -04001256 Value *value = rhs.loadValue();
1257 storeValue(value);
1258
1259 return RValue<SByte>(value);
John Bauman89401822014-05-06 15:04:28 -04001260 }
1261
John Bauman19bac1e2014-05-06 15:23:49 -04001262 RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001263 {
1264 return RValue<SByte>(Nucleus::createAdd(lhs.value, rhs.value));
1265 }
1266
John Bauman19bac1e2014-05-06 15:23:49 -04001267 RValue<SByte> operator-(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001268 {
1269 return RValue<SByte>(Nucleus::createSub(lhs.value, rhs.value));
1270 }
1271
John Bauman19bac1e2014-05-06 15:23:49 -04001272 RValue<SByte> operator*(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001273 {
1274 return RValue<SByte>(Nucleus::createMul(lhs.value, rhs.value));
1275 }
1276
John Bauman19bac1e2014-05-06 15:23:49 -04001277 RValue<SByte> operator/(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001278 {
1279 return RValue<SByte>(Nucleus::createSDiv(lhs.value, rhs.value));
1280 }
1281
John Bauman19bac1e2014-05-06 15:23:49 -04001282 RValue<SByte> operator%(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001283 {
1284 return RValue<SByte>(Nucleus::createSRem(lhs.value, rhs.value));
1285 }
1286
John Bauman19bac1e2014-05-06 15:23:49 -04001287 RValue<SByte> operator&(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001288 {
1289 return RValue<SByte>(Nucleus::createAnd(lhs.value, rhs.value));
1290 }
1291
John Bauman19bac1e2014-05-06 15:23:49 -04001292 RValue<SByte> operator|(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001293 {
1294 return RValue<SByte>(Nucleus::createOr(lhs.value, rhs.value));
1295 }
1296
John Bauman19bac1e2014-05-06 15:23:49 -04001297 RValue<SByte> operator^(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001298 {
1299 return RValue<SByte>(Nucleus::createXor(lhs.value, rhs.value));
1300 }
1301
John Bauman19bac1e2014-05-06 15:23:49 -04001302 RValue<SByte> operator<<(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001303 {
1304 return RValue<SByte>(Nucleus::createShl(lhs.value, rhs.value));
1305 }
1306
John Bauman19bac1e2014-05-06 15:23:49 -04001307 RValue<SByte> operator>>(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001308 {
1309 return RValue<SByte>(Nucleus::createAShr(lhs.value, rhs.value));
1310 }
1311
John Bauman19bac1e2014-05-06 15:23:49 -04001312 RValue<SByte> operator+=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001313 {
1314 return lhs = lhs + rhs;
1315 }
1316
John Bauman19bac1e2014-05-06 15:23:49 -04001317 RValue<SByte> operator-=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001318 {
1319 return lhs = lhs - rhs;
1320 }
1321
John Bauman19bac1e2014-05-06 15:23:49 -04001322 RValue<SByte> operator*=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001323 {
1324 return lhs = lhs * rhs;
1325 }
1326
John Bauman19bac1e2014-05-06 15:23:49 -04001327 RValue<SByte> operator/=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001328 {
1329 return lhs = lhs / rhs;
1330 }
1331
John Bauman19bac1e2014-05-06 15:23:49 -04001332 RValue<SByte> operator%=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001333 {
1334 return lhs = lhs % rhs;
1335 }
1336
John Bauman19bac1e2014-05-06 15:23:49 -04001337 RValue<SByte> operator&=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001338 {
1339 return lhs = lhs & rhs;
1340 }
1341
John Bauman19bac1e2014-05-06 15:23:49 -04001342 RValue<SByte> operator|=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001343 {
1344 return lhs = lhs | rhs;
1345 }
1346
John Bauman19bac1e2014-05-06 15:23:49 -04001347 RValue<SByte> operator^=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001348 {
1349 return lhs = lhs ^ rhs;
1350 }
1351
John Bauman19bac1e2014-05-06 15:23:49 -04001352 RValue<SByte> operator<<=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001353 {
1354 return lhs = lhs << rhs;
1355 }
1356
John Bauman19bac1e2014-05-06 15:23:49 -04001357 RValue<SByte> operator>>=(const SByte &lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001358 {
1359 return lhs = lhs >> rhs;
1360 }
1361
John Bauman19bac1e2014-05-06 15:23:49 -04001362 RValue<SByte> operator+(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001363 {
1364 return val;
1365 }
1366
John Bauman19bac1e2014-05-06 15:23:49 -04001367 RValue<SByte> operator-(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001368 {
1369 return RValue<SByte>(Nucleus::createNeg(val.value));
1370 }
1371
John Bauman19bac1e2014-05-06 15:23:49 -04001372 RValue<SByte> operator~(RValue<SByte> val)
John Bauman89401822014-05-06 15:04:28 -04001373 {
1374 return RValue<SByte>(Nucleus::createNot(val.value));
1375 }
1376
1377 RValue<SByte> operator++(const SByte &val, int) // Post-increment
1378 {
1379 RValue<SByte> res = val;
1380
1381 Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantByte((signed char)1));
John Bauman66b8ab22014-05-06 15:57:45 -04001382 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001383
1384 return res;
1385 }
1386
1387 const SByte &operator++(const SByte &val) // Pre-increment
1388 {
John Bauman66b8ab22014-05-06 15:57:45 -04001389 Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantByte((signed char)1));
1390 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001391
1392 return val;
1393 }
1394
1395 RValue<SByte> operator--(const SByte &val, int) // Post-decrement
1396 {
1397 RValue<SByte> res = val;
1398
1399 Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantByte((signed char)1));
John Bauman66b8ab22014-05-06 15:57:45 -04001400 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001401
1402 return res;
1403 }
1404
1405 const SByte &operator--(const SByte &val) // Pre-decrement
1406 {
John Bauman66b8ab22014-05-06 15:57:45 -04001407 Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantByte((signed char)1));
1408 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001409
1410 return val;
1411 }
1412
John Bauman19bac1e2014-05-06 15:23:49 -04001413 RValue<Bool> operator<(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001414 {
1415 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
1416 }
1417
John Bauman19bac1e2014-05-06 15:23:49 -04001418 RValue<Bool> operator<=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001419 {
1420 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
1421 }
1422
John Bauman19bac1e2014-05-06 15:23:49 -04001423 RValue<Bool> operator>(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001424 {
1425 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
1426 }
1427
John Bauman19bac1e2014-05-06 15:23:49 -04001428 RValue<Bool> operator>=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001429 {
1430 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
1431 }
1432
John Bauman19bac1e2014-05-06 15:23:49 -04001433 RValue<Bool> operator!=(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001434 {
1435 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1436 }
1437
John Bauman19bac1e2014-05-06 15:23:49 -04001438 RValue<Bool> operator==(RValue<SByte> lhs, RValue<SByte> rhs)
John Bauman89401822014-05-06 15:04:28 -04001439 {
1440 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1441 }
1442
John Bauman19bac1e2014-05-06 15:23:49 -04001443 Type *SByte::getType()
John Bauman89401822014-05-06 15:04:28 -04001444 {
1445 return Type::getInt8Ty(*Nucleus::getContext());
1446 }
1447
Nicolas Capens81f18302016-01-14 09:32:35 -05001448 Short::Short(Argument<Short> argument)
John Bauman89401822014-05-06 15:04:28 -04001449 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001450 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001451 }
1452
John Bauman19bac1e2014-05-06 15:23:49 -04001453 Short::Short(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04001454 {
John Bauman89401822014-05-06 15:04:28 -04001455 Value *integer = Nucleus::createTrunc(cast.value, Short::getType());
1456
John Bauman66b8ab22014-05-06 15:57:45 -04001457 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04001458 }
1459
1460 Short::Short()
1461 {
John Bauman89401822014-05-06 15:04:28 -04001462 }
1463
1464 Short::Short(short x)
1465 {
John Bauman66b8ab22014-05-06 15:57:45 -04001466 storeValue(Nucleus::createConstantShort(x));
John Bauman89401822014-05-06 15:04:28 -04001467 }
1468
John Bauman19bac1e2014-05-06 15:23:49 -04001469 Short::Short(RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001470 {
John Bauman66b8ab22014-05-06 15:57:45 -04001471 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001472 }
1473
1474 Short::Short(const Short &rhs)
1475 {
John Bauman66b8ab22014-05-06 15:57:45 -04001476 Value *value = rhs.loadValue();
1477 storeValue(value);
1478 }
John Bauman89401822014-05-06 15:04:28 -04001479
John Bauman66b8ab22014-05-06 15:57:45 -04001480 Short::Short(const Reference<Short> &rhs)
1481 {
1482 Value *value = rhs.loadValue();
1483 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001484 }
1485
John Bauman19bac1e2014-05-06 15:23:49 -04001486 RValue<Short> Short::operator=(RValue<Short> rhs) const
John Bauman89401822014-05-06 15:04:28 -04001487 {
John Bauman66b8ab22014-05-06 15:57:45 -04001488 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001489
1490 return rhs;
1491 }
1492
1493 RValue<Short> Short::operator=(const Short &rhs) const
1494 {
John Bauman66b8ab22014-05-06 15:57:45 -04001495 Value *value = rhs.loadValue();
1496 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001497
1498 return RValue<Short>(value);
1499 }
1500
John Bauman66b8ab22014-05-06 15:57:45 -04001501 RValue<Short> Short::operator=(const Reference<Short> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04001502 {
John Bauman66b8ab22014-05-06 15:57:45 -04001503 Value *value = rhs.loadValue();
1504 storeValue(value);
1505
1506 return RValue<Short>(value);
John Bauman89401822014-05-06 15:04:28 -04001507 }
1508
John Bauman19bac1e2014-05-06 15:23:49 -04001509 RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001510 {
1511 return RValue<Short>(Nucleus::createAdd(lhs.value, rhs.value));
1512 }
1513
John Bauman19bac1e2014-05-06 15:23:49 -04001514 RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001515 {
1516 return RValue<Short>(Nucleus::createSub(lhs.value, rhs.value));
1517 }
1518
John Bauman19bac1e2014-05-06 15:23:49 -04001519 RValue<Short> operator*(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001520 {
1521 return RValue<Short>(Nucleus::createMul(lhs.value, rhs.value));
1522 }
1523
John Bauman19bac1e2014-05-06 15:23:49 -04001524 RValue<Short> operator/(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001525 {
1526 return RValue<Short>(Nucleus::createSDiv(lhs.value, rhs.value));
1527 }
1528
John Bauman19bac1e2014-05-06 15:23:49 -04001529 RValue<Short> operator%(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001530 {
1531 return RValue<Short>(Nucleus::createSRem(lhs.value, rhs.value));
1532 }
1533
John Bauman19bac1e2014-05-06 15:23:49 -04001534 RValue<Short> operator&(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001535 {
1536 return RValue<Short>(Nucleus::createAnd(lhs.value, rhs.value));
1537 }
1538
John Bauman19bac1e2014-05-06 15:23:49 -04001539 RValue<Short> operator|(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001540 {
1541 return RValue<Short>(Nucleus::createOr(lhs.value, rhs.value));
1542 }
1543
John Bauman19bac1e2014-05-06 15:23:49 -04001544 RValue<Short> operator^(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001545 {
1546 return RValue<Short>(Nucleus::createXor(lhs.value, rhs.value));
1547 }
1548
John Bauman19bac1e2014-05-06 15:23:49 -04001549 RValue<Short> operator<<(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001550 {
1551 return RValue<Short>(Nucleus::createShl(lhs.value, rhs.value));
1552 }
1553
John Bauman19bac1e2014-05-06 15:23:49 -04001554 RValue<Short> operator>>(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001555 {
1556 return RValue<Short>(Nucleus::createAShr(lhs.value, rhs.value));
1557 }
1558
John Bauman19bac1e2014-05-06 15:23:49 -04001559 RValue<Short> operator+=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001560 {
1561 return lhs = lhs + rhs;
1562 }
1563
John Bauman19bac1e2014-05-06 15:23:49 -04001564 RValue<Short> operator-=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001565 {
1566 return lhs = lhs - rhs;
1567 }
1568
John Bauman19bac1e2014-05-06 15:23:49 -04001569 RValue<Short> operator*=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001570 {
1571 return lhs = lhs * rhs;
1572 }
1573
John Bauman19bac1e2014-05-06 15:23:49 -04001574 RValue<Short> operator/=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001575 {
1576 return lhs = lhs / rhs;
1577 }
1578
John Bauman19bac1e2014-05-06 15:23:49 -04001579 RValue<Short> operator%=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001580 {
1581 return lhs = lhs % rhs;
1582 }
1583
John Bauman19bac1e2014-05-06 15:23:49 -04001584 RValue<Short> operator&=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001585 {
1586 return lhs = lhs & rhs;
1587 }
1588
John Bauman19bac1e2014-05-06 15:23:49 -04001589 RValue<Short> operator|=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001590 {
1591 return lhs = lhs | rhs;
1592 }
1593
John Bauman19bac1e2014-05-06 15:23:49 -04001594 RValue<Short> operator^=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001595 {
1596 return lhs = lhs ^ rhs;
1597 }
1598
John Bauman19bac1e2014-05-06 15:23:49 -04001599 RValue<Short> operator<<=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001600 {
1601 return lhs = lhs << rhs;
1602 }
1603
John Bauman19bac1e2014-05-06 15:23:49 -04001604 RValue<Short> operator>>=(const Short &lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001605 {
1606 return lhs = lhs >> rhs;
1607 }
1608
John Bauman19bac1e2014-05-06 15:23:49 -04001609 RValue<Short> operator+(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001610 {
1611 return val;
1612 }
1613
John Bauman19bac1e2014-05-06 15:23:49 -04001614 RValue<Short> operator-(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001615 {
1616 return RValue<Short>(Nucleus::createNeg(val.value));
1617 }
1618
John Bauman19bac1e2014-05-06 15:23:49 -04001619 RValue<Short> operator~(RValue<Short> val)
John Bauman89401822014-05-06 15:04:28 -04001620 {
1621 return RValue<Short>(Nucleus::createNot(val.value));
1622 }
1623
1624 RValue<Short> operator++(const Short &val, int) // Post-increment
1625 {
1626 RValue<Short> res = val;
1627
1628 Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantShort((short)1));
John Bauman66b8ab22014-05-06 15:57:45 -04001629 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001630
1631 return res;
1632 }
1633
1634 const Short &operator++(const Short &val) // Pre-increment
1635 {
John Bauman66b8ab22014-05-06 15:57:45 -04001636 Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantShort((short)1));
1637 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001638
1639 return val;
1640 }
1641
1642 RValue<Short> operator--(const Short &val, int) // Post-decrement
1643 {
1644 RValue<Short> res = val;
1645
1646 Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantShort((short)1));
John Bauman66b8ab22014-05-06 15:57:45 -04001647 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001648
1649 return res;
1650 }
1651
1652 const Short &operator--(const Short &val) // Pre-decrement
1653 {
John Bauman66b8ab22014-05-06 15:57:45 -04001654 Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantShort((short)1));
1655 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001656
1657 return val;
1658 }
1659
John Bauman19bac1e2014-05-06 15:23:49 -04001660 RValue<Bool> operator<(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001661 {
1662 return RValue<Bool>(Nucleus::createICmpSLT(lhs.value, rhs.value));
1663 }
1664
John Bauman19bac1e2014-05-06 15:23:49 -04001665 RValue<Bool> operator<=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001666 {
1667 return RValue<Bool>(Nucleus::createICmpSLE(lhs.value, rhs.value));
1668 }
1669
John Bauman19bac1e2014-05-06 15:23:49 -04001670 RValue<Bool> operator>(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001671 {
1672 return RValue<Bool>(Nucleus::createICmpSGT(lhs.value, rhs.value));
1673 }
1674
John Bauman19bac1e2014-05-06 15:23:49 -04001675 RValue<Bool> operator>=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001676 {
1677 return RValue<Bool>(Nucleus::createICmpSGE(lhs.value, rhs.value));
1678 }
1679
John Bauman19bac1e2014-05-06 15:23:49 -04001680 RValue<Bool> operator!=(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001681 {
1682 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1683 }
1684
John Bauman19bac1e2014-05-06 15:23:49 -04001685 RValue<Bool> operator==(RValue<Short> lhs, RValue<Short> rhs)
John Bauman89401822014-05-06 15:04:28 -04001686 {
1687 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1688 }
1689
John Bauman19bac1e2014-05-06 15:23:49 -04001690 Type *Short::getType()
John Bauman89401822014-05-06 15:04:28 -04001691 {
1692 return Type::getInt16Ty(*Nucleus::getContext());
1693 }
1694
Nicolas Capens81f18302016-01-14 09:32:35 -05001695 UShort::UShort(Argument<UShort> argument)
John Bauman89401822014-05-06 15:04:28 -04001696 {
Nicolas Capens81f18302016-01-14 09:32:35 -05001697 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04001698 }
1699
Alexis Hetu77dfab42015-11-23 13:31:22 -05001700 UShort::UShort(RValue<UInt> cast)
1701 {
1702 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
1703
1704 storeValue(integer);
1705 }
1706
Alexis Hetu75b650f2015-11-19 17:40:15 -05001707 UShort::UShort(RValue<Int> cast)
1708 {
1709 Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
1710
1711 storeValue(integer);
1712 }
1713
John Bauman89401822014-05-06 15:04:28 -04001714 UShort::UShort()
1715 {
John Bauman89401822014-05-06 15:04:28 -04001716 }
1717
1718 UShort::UShort(unsigned short x)
1719 {
John Bauman66b8ab22014-05-06 15:57:45 -04001720 storeValue(Nucleus::createConstantShort(x));
John Bauman89401822014-05-06 15:04:28 -04001721 }
1722
John Bauman19bac1e2014-05-06 15:23:49 -04001723 UShort::UShort(RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001724 {
John Bauman66b8ab22014-05-06 15:57:45 -04001725 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001726 }
1727
1728 UShort::UShort(const UShort &rhs)
1729 {
John Bauman66b8ab22014-05-06 15:57:45 -04001730 Value *value = rhs.loadValue();
1731 storeValue(value);
1732 }
John Bauman89401822014-05-06 15:04:28 -04001733
John Bauman66b8ab22014-05-06 15:57:45 -04001734 UShort::UShort(const Reference<UShort> &rhs)
1735 {
1736 Value *value = rhs.loadValue();
1737 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001738 }
1739
John Bauman19bac1e2014-05-06 15:23:49 -04001740 RValue<UShort> UShort::operator=(RValue<UShort> rhs) const
John Bauman89401822014-05-06 15:04:28 -04001741 {
John Bauman66b8ab22014-05-06 15:57:45 -04001742 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04001743
1744 return rhs;
1745 }
1746
1747 RValue<UShort> UShort::operator=(const UShort &rhs) const
1748 {
John Bauman66b8ab22014-05-06 15:57:45 -04001749 Value *value = rhs.loadValue();
1750 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04001751
1752 return RValue<UShort>(value);
1753 }
1754
John Bauman66b8ab22014-05-06 15:57:45 -04001755 RValue<UShort> UShort::operator=(const Reference<UShort> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04001756 {
John Bauman66b8ab22014-05-06 15:57:45 -04001757 Value *value = rhs.loadValue();
1758 storeValue(value);
1759
1760 return RValue<UShort>(value);
John Bauman89401822014-05-06 15:04:28 -04001761 }
1762
John Bauman19bac1e2014-05-06 15:23:49 -04001763 RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001764 {
1765 return RValue<UShort>(Nucleus::createAdd(lhs.value, rhs.value));
1766 }
1767
John Bauman19bac1e2014-05-06 15:23:49 -04001768 RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001769 {
1770 return RValue<UShort>(Nucleus::createSub(lhs.value, rhs.value));
1771 }
1772
John Bauman19bac1e2014-05-06 15:23:49 -04001773 RValue<UShort> operator*(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001774 {
1775 return RValue<UShort>(Nucleus::createMul(lhs.value, rhs.value));
1776 }
1777
John Bauman19bac1e2014-05-06 15:23:49 -04001778 RValue<UShort> operator/(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001779 {
1780 return RValue<UShort>(Nucleus::createUDiv(lhs.value, rhs.value));
1781 }
1782
John Bauman19bac1e2014-05-06 15:23:49 -04001783 RValue<UShort> operator%(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001784 {
1785 return RValue<UShort>(Nucleus::createURem(lhs.value, rhs.value));
1786 }
1787
John Bauman19bac1e2014-05-06 15:23:49 -04001788 RValue<UShort> operator&(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001789 {
1790 return RValue<UShort>(Nucleus::createAnd(lhs.value, rhs.value));
1791 }
1792
John Bauman19bac1e2014-05-06 15:23:49 -04001793 RValue<UShort> operator|(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001794 {
1795 return RValue<UShort>(Nucleus::createOr(lhs.value, rhs.value));
1796 }
1797
John Bauman19bac1e2014-05-06 15:23:49 -04001798 RValue<UShort> operator^(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001799 {
1800 return RValue<UShort>(Nucleus::createXor(lhs.value, rhs.value));
1801 }
1802
John Bauman19bac1e2014-05-06 15:23:49 -04001803 RValue<UShort> operator<<(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001804 {
1805 return RValue<UShort>(Nucleus::createShl(lhs.value, rhs.value));
1806 }
1807
John Bauman19bac1e2014-05-06 15:23:49 -04001808 RValue<UShort> operator>>(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001809 {
1810 return RValue<UShort>(Nucleus::createLShr(lhs.value, rhs.value));
1811 }
1812
John Bauman19bac1e2014-05-06 15:23:49 -04001813 RValue<UShort> operator+=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001814 {
1815 return lhs = lhs + rhs;
1816 }
1817
John Bauman19bac1e2014-05-06 15:23:49 -04001818 RValue<UShort> operator-=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001819 {
1820 return lhs = lhs - rhs;
1821 }
1822
John Bauman19bac1e2014-05-06 15:23:49 -04001823 RValue<UShort> operator*=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001824 {
1825 return lhs = lhs * rhs;
1826 }
1827
John Bauman19bac1e2014-05-06 15:23:49 -04001828 RValue<UShort> operator/=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001829 {
1830 return lhs = lhs / rhs;
1831 }
1832
John Bauman19bac1e2014-05-06 15:23:49 -04001833 RValue<UShort> operator%=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001834 {
1835 return lhs = lhs % rhs;
1836 }
1837
John Bauman19bac1e2014-05-06 15:23:49 -04001838 RValue<UShort> operator&=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001839 {
1840 return lhs = lhs & rhs;
1841 }
1842
John Bauman19bac1e2014-05-06 15:23:49 -04001843 RValue<UShort> operator|=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001844 {
1845 return lhs = lhs | rhs;
1846 }
1847
John Bauman19bac1e2014-05-06 15:23:49 -04001848 RValue<UShort> operator^=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001849 {
1850 return lhs = lhs ^ rhs;
1851 }
1852
John Bauman19bac1e2014-05-06 15:23:49 -04001853 RValue<UShort> operator<<=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001854 {
1855 return lhs = lhs << rhs;
1856 }
1857
John Bauman19bac1e2014-05-06 15:23:49 -04001858 RValue<UShort> operator>>=(const UShort &lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001859 {
1860 return lhs = lhs >> rhs;
1861 }
1862
John Bauman19bac1e2014-05-06 15:23:49 -04001863 RValue<UShort> operator+(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001864 {
1865 return val;
1866 }
1867
John Bauman19bac1e2014-05-06 15:23:49 -04001868 RValue<UShort> operator-(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001869 {
1870 return RValue<UShort>(Nucleus::createNeg(val.value));
1871 }
1872
John Bauman19bac1e2014-05-06 15:23:49 -04001873 RValue<UShort> operator~(RValue<UShort> val)
John Bauman89401822014-05-06 15:04:28 -04001874 {
1875 return RValue<UShort>(Nucleus::createNot(val.value));
1876 }
1877
1878 RValue<UShort> operator++(const UShort &val, int) // Post-increment
1879 {
1880 RValue<UShort> res = val;
1881
1882 Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantShort((unsigned short)1));
John Bauman66b8ab22014-05-06 15:57:45 -04001883 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001884
1885 return res;
1886 }
1887
1888 const UShort &operator++(const UShort &val) // Pre-increment
1889 {
John Bauman66b8ab22014-05-06 15:57:45 -04001890 Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantShort((unsigned short)1));
1891 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001892
1893 return val;
1894 }
1895
1896 RValue<UShort> operator--(const UShort &val, int) // Post-decrement
1897 {
1898 RValue<UShort> res = val;
1899
1900 Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantShort((unsigned short)1));
John Bauman66b8ab22014-05-06 15:57:45 -04001901 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001902
1903 return res;
1904 }
1905
1906 const UShort &operator--(const UShort &val) // Pre-decrement
1907 {
John Bauman66b8ab22014-05-06 15:57:45 -04001908 Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantShort((unsigned short)1));
1909 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04001910
1911 return val;
1912 }
1913
John Bauman19bac1e2014-05-06 15:23:49 -04001914 RValue<Bool> operator<(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001915 {
1916 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
1917 }
1918
John Bauman19bac1e2014-05-06 15:23:49 -04001919 RValue<Bool> operator<=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001920 {
1921 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
1922 }
1923
John Bauman19bac1e2014-05-06 15:23:49 -04001924 RValue<Bool> operator>(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001925 {
1926 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
1927 }
1928
John Bauman19bac1e2014-05-06 15:23:49 -04001929 RValue<Bool> operator>=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001930 {
1931 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
1932 }
1933
John Bauman19bac1e2014-05-06 15:23:49 -04001934 RValue<Bool> operator!=(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001935 {
1936 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
1937 }
1938
John Bauman19bac1e2014-05-06 15:23:49 -04001939 RValue<Bool> operator==(RValue<UShort> lhs, RValue<UShort> rhs)
John Bauman89401822014-05-06 15:04:28 -04001940 {
1941 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
1942 }
1943
John Bauman19bac1e2014-05-06 15:23:49 -04001944 Type *UShort::getType()
John Bauman89401822014-05-06 15:04:28 -04001945 {
1946 return Type::getInt16Ty(*Nucleus::getContext());
1947 }
1948
John Bauman19bac1e2014-05-06 15:23:49 -04001949 Type *Byte4::getType()
John Bauman89401822014-05-06 15:04:28 -04001950 {
1951 #if 0
1952 return VectorType::get(Byte::getType(), 4);
1953 #else
1954 return UInt::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
1955 #endif
1956 }
1957
John Bauman19bac1e2014-05-06 15:23:49 -04001958 Type *SByte4::getType()
John Bauman89401822014-05-06 15:04:28 -04001959 {
1960 #if 0
1961 return VectorType::get(SByte::getType(), 4);
1962 #else
1963 return Int::getType(); // FIXME: LLVM doesn't manipulate it as one 32-bit block
1964 #endif
1965 }
1966
1967 Byte8::Byte8()
1968 {
1969 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04001970 }
1971
1972 Byte8::Byte8(byte x0, byte x1, byte x2, byte x3, byte x4, byte x5, byte x6, byte x7)
1973 {
1974 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04001975
1976 Constant *constantVector[8];
1977 constantVector[0] = Nucleus::createConstantByte(x0);
1978 constantVector[1] = Nucleus::createConstantByte(x1);
1979 constantVector[2] = Nucleus::createConstantByte(x2);
1980 constantVector[3] = Nucleus::createConstantByte(x3);
1981 constantVector[4] = Nucleus::createConstantByte(x4);
1982 constantVector[5] = Nucleus::createConstantByte(x5);
1983 constantVector[6] = Nucleus::createConstantByte(x6);
1984 constantVector[7] = Nucleus::createConstantByte(x7);
John Bauman19bac1e2014-05-06 15:23:49 -04001985 Value *vector = Nucleus::createConstantVector(constantVector, 8);
John Bauman89401822014-05-06 15:04:28 -04001986
John Bauman66b8ab22014-05-06 15:57:45 -04001987 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04001988 }
1989
1990 Byte8::Byte8(int64_t x)
1991 {
1992 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04001993
1994 Constant *constantVector[8];
1995 constantVector[0] = Nucleus::createConstantByte((unsigned char)(x >> 0));
1996 constantVector[1] = Nucleus::createConstantByte((unsigned char)(x >> 8));
1997 constantVector[2] = Nucleus::createConstantByte((unsigned char)(x >> 16));
1998 constantVector[3] = Nucleus::createConstantByte((unsigned char)(x >> 24));
1999 constantVector[4] = Nucleus::createConstantByte((unsigned char)(x >> 32));
2000 constantVector[5] = Nucleus::createConstantByte((unsigned char)(x >> 40));
2001 constantVector[6] = Nucleus::createConstantByte((unsigned char)(x >> 48));
2002 constantVector[7] = Nucleus::createConstantByte((unsigned char)(x >> 56));
John Bauman19bac1e2014-05-06 15:23:49 -04002003 Value *vector = Nucleus::createConstantVector(constantVector, 8);
John Bauman89401822014-05-06 15:04:28 -04002004
John Bauman66b8ab22014-05-06 15:57:45 -04002005 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04002006 }
2007
John Bauman19bac1e2014-05-06 15:23:49 -04002008 Byte8::Byte8(RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002009 {
2010 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002011
John Bauman66b8ab22014-05-06 15:57:45 -04002012 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002013 }
2014
2015 Byte8::Byte8(const Byte8 &rhs)
2016 {
2017 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002018
John Bauman66b8ab22014-05-06 15:57:45 -04002019 Value *value = rhs.loadValue();
2020 storeValue(value);
2021 }
2022
2023 Byte8::Byte8(const Reference<Byte8> &rhs)
2024 {
2025 // xyzw.parent = this;
2026
2027 Value *value = rhs.loadValue();
2028 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002029 }
2030
John Bauman19bac1e2014-05-06 15:23:49 -04002031 RValue<Byte8> Byte8::operator=(RValue<Byte8> rhs) const
John Bauman89401822014-05-06 15:04:28 -04002032 {
John Bauman66b8ab22014-05-06 15:57:45 -04002033 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002034
2035 return rhs;
2036 }
2037
2038 RValue<Byte8> Byte8::operator=(const Byte8 &rhs) const
2039 {
John Bauman66b8ab22014-05-06 15:57:45 -04002040 Value *value = rhs.loadValue();
2041 storeValue(value);
2042
2043 return RValue<Byte8>(value);
2044 }
2045
2046 RValue<Byte8> Byte8::operator=(const Reference<Byte8> &rhs) const
2047 {
2048 Value *value = rhs.loadValue();
2049 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002050
2051 return RValue<Byte8>(value);
2052 }
2053
John Bauman19bac1e2014-05-06 15:23:49 -04002054 RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002055 {
John Bauman19bac1e2014-05-06 15:23:49 -04002056 if(CPUID::supportsMMX2())
2057 {
2058 return x86::paddb(lhs, rhs);
2059 }
2060 else
2061 {
2062 return RValue<Byte8>(Nucleus::createAdd(lhs.value, rhs.value));
2063 }
John Bauman89401822014-05-06 15:04:28 -04002064 }
2065
John Bauman19bac1e2014-05-06 15:23:49 -04002066 RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002067 {
John Bauman19bac1e2014-05-06 15:23:49 -04002068 if(CPUID::supportsMMX2())
2069 {
2070 return x86::psubb(lhs, rhs);
2071 }
2072 else
2073 {
2074 return RValue<Byte8>(Nucleus::createSub(lhs.value, rhs.value));
2075 }
John Bauman89401822014-05-06 15:04:28 -04002076 }
2077
John Bauman19bac1e2014-05-06 15:23:49 -04002078// RValue<Byte8> operator*(RValue<Byte8> lhs, RValue<Byte8> rhs)
2079// {
2080// return RValue<Byte8>(Nucleus::createMul(lhs.value, rhs.value));
2081// }
2082
2083// RValue<Byte8> operator/(RValue<Byte8> lhs, RValue<Byte8> rhs)
2084// {
2085// return RValue<Byte8>(Nucleus::createUDiv(lhs.value, rhs.value));
2086// }
2087
2088// RValue<Byte8> operator%(RValue<Byte8> lhs, RValue<Byte8> rhs)
2089// {
2090// return RValue<Byte8>(Nucleus::createURem(lhs.value, rhs.value));
2091// }
2092
2093 RValue<Byte8> operator&(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002094 {
John Bauman19bac1e2014-05-06 15:23:49 -04002095 if(CPUID::supportsMMX2())
2096 {
2097 return As<Byte8>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
2098 }
2099 else
2100 {
2101 return RValue<Byte8>(Nucleus::createAnd(lhs.value, rhs.value));
2102 }
John Bauman89401822014-05-06 15:04:28 -04002103 }
2104
John Bauman19bac1e2014-05-06 15:23:49 -04002105 RValue<Byte8> operator|(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002106 {
John Bauman19bac1e2014-05-06 15:23:49 -04002107 if(CPUID::supportsMMX2())
2108 {
2109 return As<Byte8>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
2110 }
2111 else
2112 {
2113 return RValue<Byte8>(Nucleus::createOr(lhs.value, rhs.value));
2114 }
John Bauman89401822014-05-06 15:04:28 -04002115 }
2116
John Bauman19bac1e2014-05-06 15:23:49 -04002117 RValue<Byte8> operator^(RValue<Byte8> lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002118 {
John Bauman19bac1e2014-05-06 15:23:49 -04002119 if(CPUID::supportsMMX2())
2120 {
2121 return As<Byte8>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
2122 }
2123 else
John Bauman66b8ab22014-05-06 15:57:45 -04002124 {
John Bauman19bac1e2014-05-06 15:23:49 -04002125 return RValue<Byte8>(Nucleus::createXor(lhs.value, rhs.value));
2126 }
John Bauman89401822014-05-06 15:04:28 -04002127 }
2128
John Bauman19bac1e2014-05-06 15:23:49 -04002129// RValue<Byte8> operator<<(RValue<Byte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002130// {
2131// return RValue<Byte8>(Nucleus::createShl(lhs.value, rhs.value));
2132// }
2133
John Bauman19bac1e2014-05-06 15:23:49 -04002134// RValue<Byte8> operator>>(RValue<Byte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002135// {
2136// return RValue<Byte8>(Nucleus::createLShr(lhs.value, rhs.value));
2137// }
2138
John Bauman19bac1e2014-05-06 15:23:49 -04002139 RValue<Byte8> operator+=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002140 {
2141 return lhs = lhs + rhs;
2142 }
2143
John Bauman19bac1e2014-05-06 15:23:49 -04002144 RValue<Byte8> operator-=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002145 {
2146 return lhs = lhs - rhs;
2147 }
2148
John Bauman19bac1e2014-05-06 15:23:49 -04002149// RValue<Byte8> operator*=(const Byte8 &lhs, RValue<Byte8> rhs)
2150// {
2151// return lhs = lhs * rhs;
2152// }
John Bauman89401822014-05-06 15:04:28 -04002153
John Bauman19bac1e2014-05-06 15:23:49 -04002154// RValue<Byte8> operator/=(const Byte8 &lhs, RValue<Byte8> rhs)
2155// {
2156// return lhs = lhs / rhs;
2157// }
John Bauman89401822014-05-06 15:04:28 -04002158
John Bauman19bac1e2014-05-06 15:23:49 -04002159// RValue<Byte8> operator%=(const Byte8 &lhs, RValue<Byte8> rhs)
2160// {
2161// return lhs = lhs % rhs;
2162// }
John Bauman89401822014-05-06 15:04:28 -04002163
John Bauman19bac1e2014-05-06 15:23:49 -04002164 RValue<Byte8> operator&=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002165 {
2166 return lhs = lhs & rhs;
2167 }
2168
John Bauman19bac1e2014-05-06 15:23:49 -04002169 RValue<Byte8> operator|=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002170 {
2171 return lhs = lhs | rhs;
2172 }
2173
John Bauman19bac1e2014-05-06 15:23:49 -04002174 RValue<Byte8> operator^=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002175 {
2176 return lhs = lhs ^ rhs;
2177 }
2178
John Bauman19bac1e2014-05-06 15:23:49 -04002179// RValue<Byte8> operator<<=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002180// {
2181// return lhs = lhs << rhs;
2182// }
2183
John Bauman19bac1e2014-05-06 15:23:49 -04002184// RValue<Byte8> operator>>=(const Byte8 &lhs, RValue<Byte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002185// {
2186// return lhs = lhs >> rhs;
2187// }
2188
John Bauman19bac1e2014-05-06 15:23:49 -04002189// RValue<Byte8> operator+(RValue<Byte8> val)
2190// {
2191// return val;
2192// }
2193
2194// RValue<Byte8> operator-(RValue<Byte8> val)
2195// {
2196// return RValue<Byte8>(Nucleus::createNeg(val.value));
2197// }
2198
2199 RValue<Byte8> operator~(RValue<Byte8> val)
John Bauman89401822014-05-06 15:04:28 -04002200 {
John Bauman19bac1e2014-05-06 15:23:49 -04002201 if(CPUID::supportsMMX2())
2202 {
2203 return val ^ Byte8(0xFFFFFFFFFFFFFFFF);
2204 }
2205 else
2206 {
2207 return RValue<Byte8>(Nucleus::createNot(val.value));
2208 }
John Bauman89401822014-05-06 15:04:28 -04002209 }
2210
John Bauman19bac1e2014-05-06 15:23:49 -04002211 RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002212 {
2213 return x86::paddusb(x, y);
2214 }
John Bauman66b8ab22014-05-06 15:57:45 -04002215
John Bauman19bac1e2014-05-06 15:23:49 -04002216 RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002217 {
2218 return x86::psubusb(x, y);
2219 }
2220
John Bauman19bac1e2014-05-06 15:23:49 -04002221 RValue<Short4> Unpack(RValue<Byte4> x)
John Bauman89401822014-05-06 15:04:28 -04002222 {
John Bauman19bac1e2014-05-06 15:23:49 -04002223 Value *int2 = Nucleus::createInsertElement(UndefValue::get(VectorType::get(Int::getType(), 2)), x.value, 0);
2224 Value *byte8 = Nucleus::createBitCast(int2, Byte8::getType());
John Bauman89401822014-05-06 15:04:28 -04002225
John Bauman19bac1e2014-05-06 15:23:49 -04002226 return UnpackLow(RValue<Byte8>(byte8), RValue<Byte8>(byte8));
2227 }
John Bauman89401822014-05-06 15:04:28 -04002228
John Bauman19bac1e2014-05-06 15:23:49 -04002229 RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y)
2230 {
2231 if(CPUID::supportsMMX2())
2232 {
2233 return x86::punpcklbw(x, y);
2234 }
2235 else
2236 {
2237 Constant *shuffle[8];
2238 shuffle[0] = Nucleus::createConstantInt(0);
2239 shuffle[1] = Nucleus::createConstantInt(8);
2240 shuffle[2] = Nucleus::createConstantInt(1);
2241 shuffle[3] = Nucleus::createConstantInt(9);
2242 shuffle[4] = Nucleus::createConstantInt(2);
2243 shuffle[5] = Nucleus::createConstantInt(10);
2244 shuffle[6] = Nucleus::createConstantInt(3);
2245 shuffle[7] = Nucleus::createConstantInt(11);
2246
2247 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 8));
2248
2249 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2250 }
John Bauman89401822014-05-06 15:04:28 -04002251 }
John Bauman66b8ab22014-05-06 15:57:45 -04002252
John Bauman19bac1e2014-05-06 15:23:49 -04002253 RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002254 {
John Bauman19bac1e2014-05-06 15:23:49 -04002255 if(CPUID::supportsMMX2())
2256 {
2257 return x86::punpckhbw(x, y);
2258 }
2259 else
2260 {
2261 Constant *shuffle[8];
2262 shuffle[0] = Nucleus::createConstantInt(4);
2263 shuffle[1] = Nucleus::createConstantInt(12);
2264 shuffle[2] = Nucleus::createConstantInt(5);
2265 shuffle[3] = Nucleus::createConstantInt(13);
2266 shuffle[4] = Nucleus::createConstantInt(6);
2267 shuffle[5] = Nucleus::createConstantInt(14);
2268 shuffle[6] = Nucleus::createConstantInt(7);
2269 shuffle[7] = Nucleus::createConstantInt(15);
John Bauman89401822014-05-06 15:04:28 -04002270
John Bauman19bac1e2014-05-06 15:23:49 -04002271 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 8));
John Bauman89401822014-05-06 15:04:28 -04002272
John Bauman19bac1e2014-05-06 15:23:49 -04002273 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2274 }
John Bauman89401822014-05-06 15:04:28 -04002275 }
2276
John Bauman19bac1e2014-05-06 15:23:49 -04002277 RValue<Int> SignMask(RValue<Byte8> x)
John Bauman89401822014-05-06 15:04:28 -04002278 {
2279 return x86::pmovmskb(x);
2280 }
2281
John Bauman19bac1e2014-05-06 15:23:49 -04002282// RValue<Byte8> CmpGT(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002283// {
2284// return x86::pcmpgtb(x, y); // FIXME: Signedness
2285// }
John Bauman66b8ab22014-05-06 15:57:45 -04002286
John Bauman19bac1e2014-05-06 15:23:49 -04002287 RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04002288 {
2289 return x86::pcmpeqb(x, y);
2290 }
2291
John Bauman19bac1e2014-05-06 15:23:49 -04002292 Type *Byte8::getType()
John Bauman89401822014-05-06 15:04:28 -04002293 {
John Bauman19bac1e2014-05-06 15:23:49 -04002294 if(CPUID::supportsMMX2())
2295 {
2296 return MMX::getType();
2297 }
2298 else
2299 {
2300 return VectorType::get(Byte::getType(), 8);
2301 }
John Bauman89401822014-05-06 15:04:28 -04002302 }
2303
2304 SByte8::SByte8()
2305 {
2306 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002307 }
2308
2309 SByte8::SByte8(byte x0, byte x1, byte x2, byte x3, byte x4, byte x5, byte x6, byte x7)
2310 {
2311 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002312
2313 Constant *constantVector[8];
2314 constantVector[0] = Nucleus::createConstantByte(x0);
2315 constantVector[1] = Nucleus::createConstantByte(x1);
2316 constantVector[2] = Nucleus::createConstantByte(x2);
2317 constantVector[3] = Nucleus::createConstantByte(x3);
2318 constantVector[4] = Nucleus::createConstantByte(x4);
2319 constantVector[5] = Nucleus::createConstantByte(x5);
2320 constantVector[6] = Nucleus::createConstantByte(x6);
2321 constantVector[7] = Nucleus::createConstantByte(x7);
John Bauman19bac1e2014-05-06 15:23:49 -04002322 Value *vector = Nucleus::createConstantVector(constantVector, 8);
John Bauman89401822014-05-06 15:04:28 -04002323
John Bauman66b8ab22014-05-06 15:57:45 -04002324 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04002325 }
2326
2327 SByte8::SByte8(int64_t x)
2328 {
2329 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002330
2331 Constant *constantVector[8];
2332 constantVector[0] = Nucleus::createConstantByte((unsigned char)(x >> 0));
2333 constantVector[1] = Nucleus::createConstantByte((unsigned char)(x >> 8));
2334 constantVector[2] = Nucleus::createConstantByte((unsigned char)(x >> 16));
2335 constantVector[3] = Nucleus::createConstantByte((unsigned char)(x >> 24));
2336 constantVector[4] = Nucleus::createConstantByte((unsigned char)(x >> 32));
2337 constantVector[5] = Nucleus::createConstantByte((unsigned char)(x >> 40));
2338 constantVector[6] = Nucleus::createConstantByte((unsigned char)(x >> 48));
2339 constantVector[7] = Nucleus::createConstantByte((unsigned char)(x >> 56));
John Bauman19bac1e2014-05-06 15:23:49 -04002340 Value *vector = Nucleus::createConstantVector(constantVector, 8);
John Bauman89401822014-05-06 15:04:28 -04002341
John Bauman66b8ab22014-05-06 15:57:45 -04002342 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04002343 }
2344
John Bauman19bac1e2014-05-06 15:23:49 -04002345 SByte8::SByte8(RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002346 {
2347 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002348
John Bauman66b8ab22014-05-06 15:57:45 -04002349 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002350 }
2351
2352 SByte8::SByte8(const SByte8 &rhs)
2353 {
2354 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002355
John Bauman66b8ab22014-05-06 15:57:45 -04002356 Value *value = rhs.loadValue();
2357 storeValue(value);
2358 }
2359
2360 SByte8::SByte8(const Reference<SByte8> &rhs)
2361 {
2362 // xyzw.parent = this;
2363
2364 Value *value = rhs.loadValue();
2365 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002366 }
2367
John Bauman19bac1e2014-05-06 15:23:49 -04002368 RValue<SByte8> SByte8::operator=(RValue<SByte8> rhs) const
John Bauman89401822014-05-06 15:04:28 -04002369 {
John Bauman66b8ab22014-05-06 15:57:45 -04002370 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002371
2372 return rhs;
2373 }
2374
2375 RValue<SByte8> SByte8::operator=(const SByte8 &rhs) const
2376 {
John Bauman66b8ab22014-05-06 15:57:45 -04002377 Value *value = rhs.loadValue();
2378 storeValue(value);
2379
2380 return RValue<SByte8>(value);
2381 }
2382
2383 RValue<SByte8> SByte8::operator=(const Reference<SByte8> &rhs) const
2384 {
2385 Value *value = rhs.loadValue();
2386 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002387
2388 return RValue<SByte8>(value);
2389 }
2390
John Bauman19bac1e2014-05-06 15:23:49 -04002391 RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002392 {
John Bauman19bac1e2014-05-06 15:23:49 -04002393 if(CPUID::supportsMMX2())
2394 {
2395 return As<SByte8>(x86::paddb(As<Byte8>(lhs), As<Byte8>(rhs)));
2396 }
2397 else
2398 {
2399 return RValue<SByte8>(Nucleus::createAdd(lhs.value, rhs.value));
2400 }
John Bauman89401822014-05-06 15:04:28 -04002401 }
2402
John Bauman19bac1e2014-05-06 15:23:49 -04002403 RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002404 {
John Bauman19bac1e2014-05-06 15:23:49 -04002405 if(CPUID::supportsMMX2())
2406 {
2407 return As<SByte8>(x86::psubb(As<Byte8>(lhs), As<Byte8>(rhs)));
2408 }
2409 else
2410 {
2411 return RValue<SByte8>(Nucleus::createSub(lhs.value, rhs.value));
2412 }
John Bauman89401822014-05-06 15:04:28 -04002413 }
2414
John Bauman19bac1e2014-05-06 15:23:49 -04002415// RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs)
2416// {
2417// return RValue<SByte8>(Nucleus::createMul(lhs.value, rhs.value));
2418// }
John Bauman89401822014-05-06 15:04:28 -04002419
John Bauman19bac1e2014-05-06 15:23:49 -04002420// RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs)
2421// {
2422// return RValue<SByte8>(Nucleus::createSDiv(lhs.value, rhs.value));
2423// }
John Bauman89401822014-05-06 15:04:28 -04002424
John Bauman19bac1e2014-05-06 15:23:49 -04002425// RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs)
2426// {
2427// return RValue<SByte8>(Nucleus::createSRem(lhs.value, rhs.value));
2428// }
John Bauman89401822014-05-06 15:04:28 -04002429
John Bauman19bac1e2014-05-06 15:23:49 -04002430 RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002431 {
2432 return RValue<SByte8>(Nucleus::createAnd(lhs.value, rhs.value));
2433 }
2434
John Bauman19bac1e2014-05-06 15:23:49 -04002435 RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002436 {
2437 return RValue<SByte8>(Nucleus::createOr(lhs.value, rhs.value));
2438 }
2439
John Bauman19bac1e2014-05-06 15:23:49 -04002440 RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002441 {
2442 return RValue<SByte8>(Nucleus::createXor(lhs.value, rhs.value));
2443 }
2444
John Bauman19bac1e2014-05-06 15:23:49 -04002445// RValue<SByte8> operator<<(RValue<SByte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002446// {
2447// return RValue<SByte8>(Nucleus::createShl(lhs.value, rhs.value));
2448// }
2449
John Bauman19bac1e2014-05-06 15:23:49 -04002450// RValue<SByte8> operator>>(RValue<SByte8> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002451// {
2452// return RValue<SByte8>(Nucleus::createAShr(lhs.value, rhs.value));
2453// }
2454
John Bauman19bac1e2014-05-06 15:23:49 -04002455 RValue<SByte8> operator+=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002456 {
2457 return lhs = lhs + rhs;
2458 }
2459
John Bauman19bac1e2014-05-06 15:23:49 -04002460 RValue<SByte8> operator-=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002461 {
2462 return lhs = lhs - rhs;
2463 }
2464
John Bauman19bac1e2014-05-06 15:23:49 -04002465// RValue<SByte8> operator*=(const SByte8 &lhs, RValue<SByte8> rhs)
2466// {
2467// return lhs = lhs * rhs;
2468// }
John Bauman89401822014-05-06 15:04:28 -04002469
John Bauman19bac1e2014-05-06 15:23:49 -04002470// RValue<SByte8> operator/=(const SByte8 &lhs, RValue<SByte8> rhs)
2471// {
2472// return lhs = lhs / rhs;
2473// }
John Bauman89401822014-05-06 15:04:28 -04002474
John Bauman19bac1e2014-05-06 15:23:49 -04002475// RValue<SByte8> operator%=(const SByte8 &lhs, RValue<SByte8> rhs)
2476// {
2477// return lhs = lhs % rhs;
2478// }
John Bauman89401822014-05-06 15:04:28 -04002479
John Bauman19bac1e2014-05-06 15:23:49 -04002480 RValue<SByte8> operator&=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002481 {
2482 return lhs = lhs & rhs;
2483 }
2484
John Bauman19bac1e2014-05-06 15:23:49 -04002485 RValue<SByte8> operator|=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002486 {
2487 return lhs = lhs | rhs;
2488 }
2489
John Bauman19bac1e2014-05-06 15:23:49 -04002490 RValue<SByte8> operator^=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002491 {
2492 return lhs = lhs ^ rhs;
2493 }
2494
John Bauman19bac1e2014-05-06 15:23:49 -04002495// RValue<SByte8> operator<<=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002496// {
2497// return lhs = lhs << rhs;
2498// }
2499
John Bauman19bac1e2014-05-06 15:23:49 -04002500// RValue<SByte8> operator>>=(const SByte8 &lhs, RValue<SByte8> rhs)
John Bauman89401822014-05-06 15:04:28 -04002501// {
2502// return lhs = lhs >> rhs;
2503// }
2504
John Bauman19bac1e2014-05-06 15:23:49 -04002505// RValue<SByte8> operator+(RValue<SByte8> val)
2506// {
2507// return val;
2508// }
2509
2510// RValue<SByte8> operator-(RValue<SByte8> val)
2511// {
2512// return RValue<SByte8>(Nucleus::createNeg(val.value));
2513// }
2514
2515 RValue<SByte8> operator~(RValue<SByte8> val)
John Bauman89401822014-05-06 15:04:28 -04002516 {
John Bauman19bac1e2014-05-06 15:23:49 -04002517 if(CPUID::supportsMMX2())
2518 {
2519 return val ^ SByte8(0xFFFFFFFFFFFFFFFF);
2520 }
2521 else
2522 {
2523 return RValue<SByte8>(Nucleus::createNot(val.value));
2524 }
John Bauman89401822014-05-06 15:04:28 -04002525 }
2526
John Bauman19bac1e2014-05-06 15:23:49 -04002527 RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002528 {
2529 return x86::paddsb(x, y);
2530 }
John Bauman66b8ab22014-05-06 15:57:45 -04002531
John Bauman19bac1e2014-05-06 15:23:49 -04002532 RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002533 {
2534 return x86::psubsb(x, y);
2535 }
2536
John Bauman19bac1e2014-05-06 15:23:49 -04002537 RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002538 {
John Bauman19bac1e2014-05-06 15:23:49 -04002539 if(CPUID::supportsMMX2())
2540 {
2541 return As<Short4>(x86::punpcklbw(As<Byte8>(x), As<Byte8>(y)));
2542 }
2543 else
2544 {
2545 Constant *shuffle[8];
2546 shuffle[0] = Nucleus::createConstantInt(0);
2547 shuffle[1] = Nucleus::createConstantInt(8);
2548 shuffle[2] = Nucleus::createConstantInt(1);
2549 shuffle[3] = Nucleus::createConstantInt(9);
2550 shuffle[4] = Nucleus::createConstantInt(2);
2551 shuffle[5] = Nucleus::createConstantInt(10);
2552 shuffle[6] = Nucleus::createConstantInt(3);
2553 shuffle[7] = Nucleus::createConstantInt(11);
John Bauman89401822014-05-06 15:04:28 -04002554
John Bauman19bac1e2014-05-06 15:23:49 -04002555 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 8));
John Bauman89401822014-05-06 15:04:28 -04002556
John Bauman19bac1e2014-05-06 15:23:49 -04002557 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2558 }
John Bauman89401822014-05-06 15:04:28 -04002559 }
John Bauman66b8ab22014-05-06 15:57:45 -04002560
John Bauman19bac1e2014-05-06 15:23:49 -04002561 RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002562 {
John Bauman19bac1e2014-05-06 15:23:49 -04002563 if(CPUID::supportsMMX2())
2564 {
2565 return As<Short4>(x86::punpckhbw(As<Byte8>(x), As<Byte8>(y)));
2566 }
2567 else
2568 {
2569 Constant *shuffle[8];
2570 shuffle[0] = Nucleus::createConstantInt(4);
2571 shuffle[1] = Nucleus::createConstantInt(12);
2572 shuffle[2] = Nucleus::createConstantInt(5);
2573 shuffle[3] = Nucleus::createConstantInt(13);
2574 shuffle[4] = Nucleus::createConstantInt(6);
2575 shuffle[5] = Nucleus::createConstantInt(14);
2576 shuffle[6] = Nucleus::createConstantInt(7);
2577 shuffle[7] = Nucleus::createConstantInt(15);
John Bauman89401822014-05-06 15:04:28 -04002578
John Bauman19bac1e2014-05-06 15:23:49 -04002579 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 8));
John Bauman89401822014-05-06 15:04:28 -04002580
John Bauman19bac1e2014-05-06 15:23:49 -04002581 return RValue<Short4>(Nucleus::createBitCast(packed, Short4::getType()));
2582 }
John Bauman89401822014-05-06 15:04:28 -04002583 }
2584
John Bauman19bac1e2014-05-06 15:23:49 -04002585 RValue<Int> SignMask(RValue<SByte8> x)
John Bauman89401822014-05-06 15:04:28 -04002586 {
2587 return x86::pmovmskb(As<Byte8>(x));
2588 }
2589
John Bauman19bac1e2014-05-06 15:23:49 -04002590 RValue<Byte8> CmpGT(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002591 {
2592 return x86::pcmpgtb(x, y);
2593 }
John Bauman66b8ab22014-05-06 15:57:45 -04002594
John Bauman19bac1e2014-05-06 15:23:49 -04002595 RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04002596 {
2597 return x86::pcmpeqb(As<Byte8>(x), As<Byte8>(y));
2598 }
2599
John Bauman19bac1e2014-05-06 15:23:49 -04002600 Type *SByte8::getType()
John Bauman89401822014-05-06 15:04:28 -04002601 {
John Bauman19bac1e2014-05-06 15:23:49 -04002602 if(CPUID::supportsMMX2())
2603 {
2604 return MMX::getType();
2605 }
2606 else
2607 {
2608 return VectorType::get(SByte::getType(), 8);
2609 }
John Bauman89401822014-05-06 15:04:28 -04002610 }
2611
John Bauman19bac1e2014-05-06 15:23:49 -04002612 Byte16::Byte16(RValue<Byte16> rhs)
John Bauman89401822014-05-06 15:04:28 -04002613 {
2614 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002615
John Bauman66b8ab22014-05-06 15:57:45 -04002616 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002617 }
2618
2619 Byte16::Byte16(const Byte16 &rhs)
2620 {
2621 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002622
John Bauman66b8ab22014-05-06 15:57:45 -04002623 Value *value = rhs.loadValue();
2624 storeValue(value);
2625 }
2626
2627 Byte16::Byte16(const Reference<Byte16> &rhs)
2628 {
2629 // xyzw.parent = this;
2630
2631 Value *value = rhs.loadValue();
2632 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002633 }
2634
John Bauman19bac1e2014-05-06 15:23:49 -04002635 RValue<Byte16> Byte16::operator=(RValue<Byte16> rhs) const
John Bauman89401822014-05-06 15:04:28 -04002636 {
John Bauman66b8ab22014-05-06 15:57:45 -04002637 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002638
2639 return rhs;
2640 }
2641
2642 RValue<Byte16> Byte16::operator=(const Byte16 &rhs) const
2643 {
John Bauman66b8ab22014-05-06 15:57:45 -04002644 Value *value = rhs.loadValue();
2645 storeValue(value);
2646
2647 return RValue<Byte16>(value);
2648 }
2649
2650 RValue<Byte16> Byte16::operator=(const Reference<Byte16> &rhs) const
2651 {
2652 Value *value = rhs.loadValue();
2653 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002654
2655 return RValue<Byte16>(value);
2656 }
2657
John Bauman19bac1e2014-05-06 15:23:49 -04002658 Type *Byte16::getType()
John Bauman89401822014-05-06 15:04:28 -04002659 {
2660 return VectorType::get(Byte::getType(), 16);
2661 }
2662
John Bauman19bac1e2014-05-06 15:23:49 -04002663 Type *SByte16::getType()
John Bauman89401822014-05-06 15:04:28 -04002664 {
2665 return VectorType::get(SByte::getType(), 16);
2666 }
2667
John Bauman19bac1e2014-05-06 15:23:49 -04002668 Short4::Short4(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04002669 {
John Bauman89401822014-05-06 15:04:28 -04002670 Value *extend = Nucleus::createZExt(cast.value, Long::getType());
John Bauman19bac1e2014-05-06 15:23:49 -04002671 Value *swizzle = Swizzle(RValue<Short4>(extend), 0x00).value;
John Bauman66b8ab22014-05-06 15:57:45 -04002672
2673 storeValue(swizzle);
John Bauman89401822014-05-06 15:04:28 -04002674 }
2675
John Bauman19bac1e2014-05-06 15:23:49 -04002676 Short4::Short4(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04002677 {
John Bauman89401822014-05-06 15:04:28 -04002678 Value *short8 = Nucleus::createBitCast(cast.value, Short8::getType());
2679
2680 #if 0 // FIXME: Check codegen (pshuflw phshufhw pshufd)
2681 Constant *pack[8];
2682 pack[0] = Nucleus::createConstantInt(0);
2683 pack[1] = Nucleus::createConstantInt(2);
2684 pack[2] = Nucleus::createConstantInt(4);
2685 pack[3] = Nucleus::createConstantInt(6);
2686
2687 Value *short4 = Nucleus::createShuffleVector(short8, short8, Nucleus::createConstantVector(pack, 4));
2688 #else
2689 Value *packed;
2690
2691 // FIXME: Use Swizzle<Short8>
2692 if(!CPUID::supportsSSSE3())
2693 {
2694 Constant *pshuflw[8];
2695 pshuflw[0] = Nucleus::createConstantInt(0);
2696 pshuflw[1] = Nucleus::createConstantInt(2);
2697 pshuflw[2] = Nucleus::createConstantInt(0);
2698 pshuflw[3] = Nucleus::createConstantInt(2);
2699 pshuflw[4] = Nucleus::createConstantInt(4);
2700 pshuflw[5] = Nucleus::createConstantInt(5);
2701 pshuflw[6] = Nucleus::createConstantInt(6);
2702 pshuflw[7] = Nucleus::createConstantInt(7);
2703
2704 Constant *pshufhw[8];
2705 pshufhw[0] = Nucleus::createConstantInt(0);
2706 pshufhw[1] = Nucleus::createConstantInt(1);
2707 pshufhw[2] = Nucleus::createConstantInt(2);
2708 pshufhw[3] = Nucleus::createConstantInt(3);
2709 pshufhw[4] = Nucleus::createConstantInt(4);
2710 pshufhw[5] = Nucleus::createConstantInt(6);
2711 pshufhw[6] = Nucleus::createConstantInt(4);
2712 pshufhw[7] = Nucleus::createConstantInt(6);
2713
2714 Value *shuffle1 = Nucleus::createShuffleVector(short8, UndefValue::get(Short8::getType()), Nucleus::createConstantVector(pshuflw, 8));
2715 Value *shuffle2 = Nucleus::createShuffleVector(shuffle1, UndefValue::get(Short8::getType()), Nucleus::createConstantVector(pshufhw, 8));
2716 Value *int4 = Nucleus::createBitCast(shuffle2, Int4::getType());
2717 packed = Nucleus::createSwizzle(int4, 0x88);
2718 }
2719 else
2720 {
2721 Constant *pshufb[16];
2722 pshufb[0] = Nucleus::createConstantInt(0);
2723 pshufb[1] = Nucleus::createConstantInt(1);
2724 pshufb[2] = Nucleus::createConstantInt(4);
2725 pshufb[3] = Nucleus::createConstantInt(5);
2726 pshufb[4] = Nucleus::createConstantInt(8);
2727 pshufb[5] = Nucleus::createConstantInt(9);
2728 pshufb[6] = Nucleus::createConstantInt(12);
2729 pshufb[7] = Nucleus::createConstantInt(13);
2730 pshufb[8] = Nucleus::createConstantInt(0);
2731 pshufb[9] = Nucleus::createConstantInt(1);
2732 pshufb[10] = Nucleus::createConstantInt(4);
2733 pshufb[11] = Nucleus::createConstantInt(5);
2734 pshufb[12] = Nucleus::createConstantInt(8);
2735 pshufb[13] = Nucleus::createConstantInt(9);
2736 pshufb[14] = Nucleus::createConstantInt(12);
2737 pshufb[15] = Nucleus::createConstantInt(13);
2738
2739 Value *byte16 = Nucleus::createBitCast(cast.value, Byte16::getType());
2740 packed = Nucleus::createShuffleVector(byte16, UndefValue::get(Byte16::getType()), Nucleus::createConstantVector(pshufb, 16));
2741 }
2742
2743 #if 0 // FIXME: No optimal instruction selection
2744 Value *qword2 = Nucleus::createBitCast(packed, Long2::getType());
2745 Value *element = Nucleus::createExtractElement(qword2, 0);
2746 Value *short4 = Nucleus::createBitCast(element, Short4::getType());
2747 #else // FIXME: Requires SSE
2748 Value *int2 = RValue<Int2>(Int2(RValue<Int4>(packed))).value;
2749 Value *short4 = Nucleus::createBitCast(int2, Short4::getType());
2750 #endif
2751 #endif
2752
John Bauman66b8ab22014-05-06 15:57:45 -04002753 storeValue(short4);
John Bauman89401822014-05-06 15:04:28 -04002754 }
2755
John Bauman19bac1e2014-05-06 15:23:49 -04002756// Short4::Short4(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04002757// {
2758// }
2759
John Bauman19bac1e2014-05-06 15:23:49 -04002760 Short4::Short4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04002761 {
John Bauman89401822014-05-06 15:04:28 -04002762 Int4 v4i32 = Int4(cast);
2763 v4i32 = As<Int4>(x86::packssdw(v4i32, v4i32));
John Bauman66b8ab22014-05-06 15:57:45 -04002764
2765 storeValue(As<Short4>(Int2(v4i32)).value);
John Bauman89401822014-05-06 15:04:28 -04002766 }
2767
2768 Short4::Short4()
2769 {
2770 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002771 }
2772
John Bauman19bac1e2014-05-06 15:23:49 -04002773 Short4::Short4(short xyzw)
2774 {
2775 // xyzw.parent = this;
John Bauman19bac1e2014-05-06 15:23:49 -04002776
2777 Constant *constantVector[4];
2778 constantVector[0] = Nucleus::createConstantShort(xyzw);
2779 constantVector[1] = Nucleus::createConstantShort(xyzw);
2780 constantVector[2] = Nucleus::createConstantShort(xyzw);
2781 constantVector[3] = Nucleus::createConstantShort(xyzw);
2782 Value *vector = Nucleus::createConstantVector(constantVector, 4);
2783
John Bauman66b8ab22014-05-06 15:57:45 -04002784 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman19bac1e2014-05-06 15:23:49 -04002785 }
2786
John Bauman89401822014-05-06 15:04:28 -04002787 Short4::Short4(short x, short y, short z, short w)
2788 {
2789 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002790
2791 Constant *constantVector[4];
2792 constantVector[0] = Nucleus::createConstantShort(x);
2793 constantVector[1] = Nucleus::createConstantShort(y);
2794 constantVector[2] = Nucleus::createConstantShort(z);
2795 constantVector[3] = Nucleus::createConstantShort(w);
John Bauman19bac1e2014-05-06 15:23:49 -04002796 Value *vector = Nucleus::createConstantVector(constantVector, 4);
2797
John Bauman66b8ab22014-05-06 15:57:45 -04002798 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04002799 }
2800
John Bauman19bac1e2014-05-06 15:23:49 -04002801 Short4::Short4(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002802 {
2803 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002804
John Bauman66b8ab22014-05-06 15:57:45 -04002805 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002806 }
2807
2808 Short4::Short4(const Short4 &rhs)
2809 {
2810 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002811
John Bauman66b8ab22014-05-06 15:57:45 -04002812 Value *value = rhs.loadValue();
2813 storeValue(value);
2814 }
2815
2816 Short4::Short4(const Reference<Short4> &rhs)
2817 {
2818 // xyzw.parent = this;
2819
2820 Value *value = rhs.loadValue();
2821 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002822 }
2823
John Bauman19bac1e2014-05-06 15:23:49 -04002824 Short4::Short4(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002825 {
2826 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002827
John Bauman66b8ab22014-05-06 15:57:45 -04002828 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002829 }
2830
2831 Short4::Short4(const UShort4 &rhs)
2832 {
2833 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04002834
John Bauman66b8ab22014-05-06 15:57:45 -04002835 storeValue(rhs.loadValue());
2836 }
2837
2838 Short4::Short4(const Reference<UShort4> &rhs)
2839 {
2840 // xyzw.parent = this;
2841
2842 storeValue(rhs.loadValue());
John Bauman89401822014-05-06 15:04:28 -04002843 }
2844
John Bauman19bac1e2014-05-06 15:23:49 -04002845 RValue<Short4> Short4::operator=(RValue<Short4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04002846 {
John Bauman66b8ab22014-05-06 15:57:45 -04002847 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002848
2849 return rhs;
2850 }
2851
2852 RValue<Short4> Short4::operator=(const Short4 &rhs) const
2853 {
John Bauman66b8ab22014-05-06 15:57:45 -04002854 Value *value = rhs.loadValue();
2855 storeValue(value);
2856
2857 return RValue<Short4>(value);
2858 }
2859
2860 RValue<Short4> Short4::operator=(const Reference<Short4> &rhs) const
2861 {
2862 Value *value = rhs.loadValue();
2863 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002864
2865 return RValue<Short4>(value);
2866 }
2867
John Bauman19bac1e2014-05-06 15:23:49 -04002868 RValue<Short4> Short4::operator=(RValue<UShort4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04002869 {
John Bauman66b8ab22014-05-06 15:57:45 -04002870 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04002871
John Bauman66b8ab22014-05-06 15:57:45 -04002872 return RValue<Short4>(rhs);
John Bauman89401822014-05-06 15:04:28 -04002873 }
2874
2875 RValue<Short4> Short4::operator=(const UShort4 &rhs) const
2876 {
John Bauman66b8ab22014-05-06 15:57:45 -04002877 Value *value = rhs.loadValue();
2878 storeValue(value);
2879
2880 return RValue<Short4>(value);
2881 }
2882
2883 RValue<Short4> Short4::operator=(const Reference<UShort4> &rhs) const
2884 {
2885 Value *value = rhs.loadValue();
2886 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04002887
2888 return RValue<Short4>(value);
2889 }
2890
John Bauman19bac1e2014-05-06 15:23:49 -04002891 RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002892 {
John Bauman19bac1e2014-05-06 15:23:49 -04002893 if(CPUID::supportsMMX2())
2894 {
2895 return x86::paddw(lhs, rhs);
2896 }
2897 else
2898 {
2899 return RValue<Short4>(Nucleus::createAdd(lhs.value, rhs.value));
2900 }
John Bauman89401822014-05-06 15:04:28 -04002901 }
2902
John Bauman19bac1e2014-05-06 15:23:49 -04002903 RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002904 {
John Bauman19bac1e2014-05-06 15:23:49 -04002905 if(CPUID::supportsMMX2())
2906 {
2907 return x86::psubw(lhs, rhs);
2908 }
2909 else
2910 {
2911 return RValue<Short4>(Nucleus::createSub(lhs.value, rhs.value));
2912 }
John Bauman89401822014-05-06 15:04:28 -04002913 }
2914
John Bauman19bac1e2014-05-06 15:23:49 -04002915 RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002916 {
John Bauman19bac1e2014-05-06 15:23:49 -04002917 if(CPUID::supportsMMX2())
2918 {
2919 return x86::pmullw(lhs, rhs);
2920 }
2921 else
2922 {
2923 return RValue<Short4>(Nucleus::createMul(lhs.value, rhs.value));
2924 }
John Bauman89401822014-05-06 15:04:28 -04002925 }
2926
John Bauman19bac1e2014-05-06 15:23:49 -04002927// RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs)
2928// {
2929// return RValue<Short4>(Nucleus::createSDiv(lhs.value, rhs.value));
2930// }
2931
2932// RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs)
2933// {
2934// return RValue<Short4>(Nucleus::createSRem(lhs.value, rhs.value));
2935// }
2936
2937 RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002938 {
John Bauman19bac1e2014-05-06 15:23:49 -04002939 if(CPUID::supportsMMX2())
2940 {
2941 return x86::pand(lhs, rhs);
2942 }
2943 else
2944 {
2945 return RValue<Short4>(Nucleus::createAnd(lhs.value, rhs.value));
2946 }
John Bauman89401822014-05-06 15:04:28 -04002947 }
2948
John Bauman19bac1e2014-05-06 15:23:49 -04002949 RValue<Short4> operator|(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002950 {
John Bauman19bac1e2014-05-06 15:23:49 -04002951 if(CPUID::supportsMMX2())
2952 {
2953 return x86::por(lhs, rhs);
2954 }
2955 else
2956 {
2957 return RValue<Short4>(Nucleus::createOr(lhs.value, rhs.value));
2958 }
John Bauman89401822014-05-06 15:04:28 -04002959 }
2960
John Bauman19bac1e2014-05-06 15:23:49 -04002961 RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04002962 {
John Bauman19bac1e2014-05-06 15:23:49 -04002963 if(CPUID::supportsMMX2())
2964 {
2965 return x86::pxor(lhs, rhs);
2966 }
2967 else
2968 {
2969 return RValue<Short4>(Nucleus::createXor(lhs.value, rhs.value));
2970 }
John Bauman89401822014-05-06 15:04:28 -04002971 }
2972
John Bauman19bac1e2014-05-06 15:23:49 -04002973 RValue<Short4> operator<<(RValue<Short4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002974 {
2975 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
2976
2977 return x86::psllw(lhs, rhs);
2978 }
2979
John Bauman19bac1e2014-05-06 15:23:49 -04002980 RValue<Short4> operator>>(RValue<Short4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04002981 {
2982 // return RValue<Short4>(Nucleus::createAShr(lhs.value, rhs.value));
2983
2984 return x86::psraw(lhs, rhs);
2985 }
2986
John Bauman19bac1e2014-05-06 15:23:49 -04002987 RValue<Short4> operator<<(RValue<Short4> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04002988 {
2989 // return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
2990
2991 return x86::psllw(lhs, rhs);
2992 }
2993
John Bauman19bac1e2014-05-06 15:23:49 -04002994 RValue<Short4> operator>>(RValue<Short4> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04002995 {
2996 // return RValue<Short4>(Nucleus::createAShr(lhs.value, rhs.value));
2997
2998 return x86::psraw(lhs, rhs);
2999 }
3000
John Bauman19bac1e2014-05-06 15:23:49 -04003001 RValue<Short4> operator+=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003002 {
3003 return lhs = lhs + rhs;
3004 }
3005
John Bauman19bac1e2014-05-06 15:23:49 -04003006 RValue<Short4> operator-=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003007 {
3008 return lhs = lhs - rhs;
3009 }
3010
John Bauman19bac1e2014-05-06 15:23:49 -04003011 RValue<Short4> operator*=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003012 {
3013 return lhs = lhs * rhs;
3014 }
3015
John Bauman19bac1e2014-05-06 15:23:49 -04003016// RValue<Short4> operator/=(const Short4 &lhs, RValue<Short4> rhs)
3017// {
3018// return lhs = lhs / rhs;
3019// }
John Bauman89401822014-05-06 15:04:28 -04003020
John Bauman19bac1e2014-05-06 15:23:49 -04003021// RValue<Short4> operator%=(const Short4 &lhs, RValue<Short4> rhs)
3022// {
3023// return lhs = lhs % rhs;
3024// }
John Bauman89401822014-05-06 15:04:28 -04003025
John Bauman19bac1e2014-05-06 15:23:49 -04003026 RValue<Short4> operator&=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003027 {
3028 return lhs = lhs & rhs;
3029 }
3030
John Bauman19bac1e2014-05-06 15:23:49 -04003031 RValue<Short4> operator|=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003032 {
3033 return lhs = lhs | rhs;
3034 }
3035
John Bauman19bac1e2014-05-06 15:23:49 -04003036 RValue<Short4> operator^=(const Short4 &lhs, RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003037 {
3038 return lhs = lhs ^ rhs;
3039 }
3040
3041 RValue<Short4> operator<<=(const Short4 &lhs, unsigned char rhs)
3042 {
3043 return lhs = lhs << rhs;
3044 }
3045
3046 RValue<Short4> operator>>=(const Short4 &lhs, unsigned char rhs)
3047 {
3048 return lhs = lhs >> rhs;
3049 }
3050
John Bauman19bac1e2014-05-06 15:23:49 -04003051 RValue<Short4> operator<<=(const Short4 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04003052 {
3053 return lhs = lhs << rhs;
3054 }
3055
John Bauman19bac1e2014-05-06 15:23:49 -04003056 RValue<Short4> operator>>=(const Short4 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04003057 {
3058 return lhs = lhs >> rhs;
3059 }
3060
John Bauman19bac1e2014-05-06 15:23:49 -04003061// RValue<Short4> operator+(RValue<Short4> val)
3062// {
3063// return val;
3064// }
3065
3066 RValue<Short4> operator-(RValue<Short4> val)
John Bauman89401822014-05-06 15:04:28 -04003067 {
John Bauman19bac1e2014-05-06 15:23:49 -04003068 if(CPUID::supportsMMX2())
3069 {
3070 return Short4(0, 0, 0, 0) - val;
3071 }
3072 else
3073 {
3074 return RValue<Short4>(Nucleus::createNeg(val.value));
3075 }
John Bauman89401822014-05-06 15:04:28 -04003076 }
3077
John Bauman19bac1e2014-05-06 15:23:49 -04003078 RValue<Short4> operator~(RValue<Short4> val)
John Bauman89401822014-05-06 15:04:28 -04003079 {
John Bauman19bac1e2014-05-06 15:23:49 -04003080 if(CPUID::supportsMMX2())
3081 {
3082 return val ^ Short4(0xFFFFu, 0xFFFFu, 0xFFFFu, 0xFFFFu);
3083 }
3084 else
3085 {
3086 return RValue<Short4>(Nucleus::createNot(val.value));
3087 }
John Bauman89401822014-05-06 15:04:28 -04003088 }
3089
John Bauman19bac1e2014-05-06 15:23:49 -04003090 RValue<Short4> RoundShort4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04003091 {
3092 RValue<Int4> v4i32 = x86::cvtps2dq(cast);
Nicolas Capens698633a2015-02-04 00:16:13 -05003093 RValue<Short8> v8i16 = x86::packssdw(v4i32, v4i32);
John Bauman66b8ab22014-05-06 15:57:45 -04003094
Nicolas Capens698633a2015-02-04 00:16:13 -05003095 return As<Short4>(Int2(As<Int4>(v8i16)));
John Bauman89401822014-05-06 15:04:28 -04003096 }
3097
John Bauman19bac1e2014-05-06 15:23:49 -04003098 RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003099 {
3100 return x86::pmaxsw(x, y);
3101 }
3102
John Bauman19bac1e2014-05-06 15:23:49 -04003103 RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003104 {
3105 return x86::pminsw(x, y);
3106 }
3107
John Bauman19bac1e2014-05-06 15:23:49 -04003108 RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003109 {
3110 return x86::paddsw(x, y);
3111 }
3112
John Bauman19bac1e2014-05-06 15:23:49 -04003113 RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003114 {
3115 return x86::psubsw(x, y);
3116 }
3117
John Bauman19bac1e2014-05-06 15:23:49 -04003118 RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003119 {
3120 return x86::pmulhw(x, y);
3121 }
3122
John Bauman19bac1e2014-05-06 15:23:49 -04003123 RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003124 {
3125 return x86::pmaddwd(x, y);
3126 }
3127
John Bauman19bac1e2014-05-06 15:23:49 -04003128 RValue<SByte8> Pack(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003129 {
3130 return x86::packsswb(x, y);
3131 }
3132
John Bauman19bac1e2014-05-06 15:23:49 -04003133 RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003134 {
John Bauman19bac1e2014-05-06 15:23:49 -04003135 if(CPUID::supportsMMX2())
3136 {
3137 return x86::punpcklwd(x, y);
3138 }
3139 else
3140 {
3141 Constant *shuffle[4];
3142 shuffle[0] = Nucleus::createConstantInt(0);
3143 shuffle[1] = Nucleus::createConstantInt(4);
3144 shuffle[2] = Nucleus::createConstantInt(1);
3145 shuffle[3] = Nucleus::createConstantInt(5);
John Bauman89401822014-05-06 15:04:28 -04003146
John Bauman19bac1e2014-05-06 15:23:49 -04003147 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 4));
John Bauman89401822014-05-06 15:04:28 -04003148
John Bauman19bac1e2014-05-06 15:23:49 -04003149 return RValue<Int2>(Nucleus::createBitCast(packed, Int2::getType()));
3150 }
John Bauman89401822014-05-06 15:04:28 -04003151 }
3152
John Bauman19bac1e2014-05-06 15:23:49 -04003153 RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003154 {
John Bauman19bac1e2014-05-06 15:23:49 -04003155 if(CPUID::supportsMMX2())
3156 {
3157 return x86::punpckhwd(x, y);
3158 }
3159 else
3160 {
3161 Constant *shuffle[4];
3162 shuffle[0] = Nucleus::createConstantInt(2);
3163 shuffle[1] = Nucleus::createConstantInt(6);
3164 shuffle[2] = Nucleus::createConstantInt(3);
3165 shuffle[3] = Nucleus::createConstantInt(7);
John Bauman89401822014-05-06 15:04:28 -04003166
John Bauman19bac1e2014-05-06 15:23:49 -04003167 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 4));
John Bauman89401822014-05-06 15:04:28 -04003168
John Bauman19bac1e2014-05-06 15:23:49 -04003169 return RValue<Int2>(Nucleus::createBitCast(packed, Int2::getType()));
3170 }
John Bauman89401822014-05-06 15:04:28 -04003171 }
3172
John Bauman19bac1e2014-05-06 15:23:49 -04003173 RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04003174 {
John Bauman19bac1e2014-05-06 15:23:49 -04003175 if(CPUID::supportsMMX2())
3176 {
3177 return x86::pshufw(x, select);
3178 }
3179 else
3180 {
3181 return RValue<Short4>(Nucleus::createSwizzle(x.value, select));
3182 }
John Bauman89401822014-05-06 15:04:28 -04003183 }
3184
John Bauman19bac1e2014-05-06 15:23:49 -04003185 RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i)
John Bauman89401822014-05-06 15:04:28 -04003186 {
John Bauman19bac1e2014-05-06 15:23:49 -04003187 if(CPUID::supportsMMX2())
3188 {
3189 return x86::pinsrw(val, Int(element), i);
3190 }
3191 else
3192 {
3193 return RValue<Short4>(Nucleus::createInsertElement(val.value, element.value, i));
3194 }
John Bauman89401822014-05-06 15:04:28 -04003195 }
3196
John Bauman19bac1e2014-05-06 15:23:49 -04003197 RValue<Short> Extract(RValue<Short4> val, int i)
John Bauman89401822014-05-06 15:04:28 -04003198 {
John Bauman19bac1e2014-05-06 15:23:49 -04003199 if(CPUID::supportsMMX2())
3200 {
3201 return Short(x86::pextrw(val, i));
3202 }
3203 else
3204 {
3205 return RValue<Short>(Nucleus::createExtractElement(val.value, i));
3206 }
John Bauman89401822014-05-06 15:04:28 -04003207 }
3208
John Bauman19bac1e2014-05-06 15:23:49 -04003209 RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003210 {
3211 return x86::pcmpgtw(x, y);
3212 }
3213
John Bauman19bac1e2014-05-06 15:23:49 -04003214 RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04003215 {
3216 return x86::pcmpeqw(x, y);
3217 }
3218
John Bauman19bac1e2014-05-06 15:23:49 -04003219 Type *Short4::getType()
John Bauman89401822014-05-06 15:04:28 -04003220 {
John Bauman19bac1e2014-05-06 15:23:49 -04003221 if(CPUID::supportsMMX2())
3222 {
3223 return MMX::getType();
3224 }
3225 else
3226 {
3227 return VectorType::get(Short::getType(), 4);
3228 }
John Bauman89401822014-05-06 15:04:28 -04003229 }
3230
John Bauman19bac1e2014-05-06 15:23:49 -04003231 UShort4::UShort4(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04003232 {
John Bauman89401822014-05-06 15:04:28 -04003233 *this = Short4(cast);
3234 }
3235
John Bauman19bac1e2014-05-06 15:23:49 -04003236 UShort4::UShort4(RValue<Float4> cast, bool saturate)
John Bauman89401822014-05-06 15:04:28 -04003237 {
John Bauman89401822014-05-06 15:04:28 -04003238 Float4 sat;
3239
3240 if(saturate)
3241 {
3242 if(CPUID::supportsSSE4_1())
3243 {
3244 sat = Min(cast, Float4(0xFFFF)); // packusdw takes care of 0x0000 saturation
3245 }
3246 else
3247 {
3248 sat = Max(Min(cast, Float4(0xFFFF)), Float4(0x0000));
3249 }
3250 }
3251 else
3252 {
3253 sat = cast;
3254 }
3255
3256 Int4 int4(sat);
3257
3258 if(!saturate || !CPUID::supportsSSE4_1())
3259 {
3260 *this = Short4(Int4(int4));
3261 }
3262 else
3263 {
3264 *this = As<Short4>(Int2(As<Int4>(x86::packusdw(As<UInt4>(int4), As<UInt4>(int4)))));
3265 }
3266 }
3267
3268 UShort4::UShort4()
3269 {
3270 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003271 }
3272
Alexis Hetu90c7ad62016-06-27 11:50:40 -04003273 UShort4::UShort4(unsigned short xyzw)
3274 {
3275 // xyzw.parent = this;
3276
3277 Constant *constantVector[4];
3278 constantVector[0] = Nucleus::createConstantShort(xyzw);
3279 constantVector[1] = Nucleus::createConstantShort(xyzw);
3280 constantVector[2] = Nucleus::createConstantShort(xyzw);
3281 constantVector[3] = Nucleus::createConstantShort(xyzw);
3282 Value *vector = Nucleus::createConstantVector(constantVector, 4);
3283
3284 storeValue(Nucleus::createBitCast(vector, getType()));
3285 }
3286
John Bauman89401822014-05-06 15:04:28 -04003287 UShort4::UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w)
3288 {
3289 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003290
3291 Constant *constantVector[4];
3292 constantVector[0] = Nucleus::createConstantShort(x);
3293 constantVector[1] = Nucleus::createConstantShort(y);
3294 constantVector[2] = Nucleus::createConstantShort(z);
3295 constantVector[3] = Nucleus::createConstantShort(w);
John Bauman19bac1e2014-05-06 15:23:49 -04003296 Value *vector = Nucleus::createConstantVector(constantVector, 4);
John Bauman89401822014-05-06 15:04:28 -04003297
John Bauman66b8ab22014-05-06 15:57:45 -04003298 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04003299 }
3300
John Bauman19bac1e2014-05-06 15:23:49 -04003301 UShort4::UShort4(RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003302 {
3303 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003304
John Bauman66b8ab22014-05-06 15:57:45 -04003305 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003306 }
3307
3308 UShort4::UShort4(const UShort4 &rhs)
3309 {
3310 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003311
John Bauman66b8ab22014-05-06 15:57:45 -04003312 Value *value = rhs.loadValue();
3313 storeValue(value);
3314 }
3315
3316 UShort4::UShort4(const Reference<UShort4> &rhs)
3317 {
3318 // xyzw.parent = this;
3319
3320 Value *value = rhs.loadValue();
3321 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003322 }
3323
John Bauman19bac1e2014-05-06 15:23:49 -04003324 UShort4::UShort4(RValue<Short4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003325 {
3326 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003327
John Bauman66b8ab22014-05-06 15:57:45 -04003328 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003329 }
3330
3331 UShort4::UShort4(const Short4 &rhs)
3332 {
3333 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04003334
John Bauman66b8ab22014-05-06 15:57:45 -04003335 Value *value = rhs.loadValue();
3336 storeValue(value);
3337 }
3338
3339 UShort4::UShort4(const Reference<Short4> &rhs)
3340 {
3341 // xyzw.parent = this;
3342
3343 Value *value = rhs.loadValue();
3344 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003345 }
3346
John Bauman19bac1e2014-05-06 15:23:49 -04003347 RValue<UShort4> UShort4::operator=(RValue<UShort4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04003348 {
John Bauman66b8ab22014-05-06 15:57:45 -04003349 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003350
3351 return rhs;
3352 }
3353
3354 RValue<UShort4> UShort4::operator=(const UShort4 &rhs) const
3355 {
John Bauman66b8ab22014-05-06 15:57:45 -04003356 Value *value = rhs.loadValue();
3357 storeValue(value);
3358
3359 return RValue<UShort4>(value);
3360 }
3361
3362 RValue<UShort4> UShort4::operator=(const Reference<UShort4> &rhs) const
3363 {
3364 Value *value = rhs.loadValue();
3365 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003366
3367 return RValue<UShort4>(value);
3368 }
3369
John Bauman19bac1e2014-05-06 15:23:49 -04003370 RValue<UShort4> UShort4::operator=(RValue<Short4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04003371 {
John Bauman66b8ab22014-05-06 15:57:45 -04003372 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04003373
John Bauman66b8ab22014-05-06 15:57:45 -04003374 return RValue<UShort4>(rhs);
John Bauman89401822014-05-06 15:04:28 -04003375 }
3376
3377 RValue<UShort4> UShort4::operator=(const Short4 &rhs) const
3378 {
John Bauman66b8ab22014-05-06 15:57:45 -04003379 Value *value = rhs.loadValue();
3380 storeValue(value);
3381
3382 return RValue<UShort4>(value);
3383 }
3384
3385 RValue<UShort4> UShort4::operator=(const Reference<Short4> &rhs) const
3386 {
3387 Value *value = rhs.loadValue();
3388 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04003389
3390 return RValue<UShort4>(value);
3391 }
3392
John Bauman19bac1e2014-05-06 15:23:49 -04003393 RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003394 {
John Bauman19bac1e2014-05-06 15:23:49 -04003395 if(CPUID::supportsMMX2())
3396 {
3397 return As<UShort4>(x86::paddw(As<Short4>(lhs), As<Short4>(rhs)));
3398 }
3399 else
3400 {
3401 return RValue<UShort4>(Nucleus::createAdd(lhs.value, rhs.value));
3402 }
John Bauman89401822014-05-06 15:04:28 -04003403 }
3404
John Bauman19bac1e2014-05-06 15:23:49 -04003405 RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs)
John Bauman89401822014-05-06 15:04:28 -04003406 {
John Bauman19bac1e2014-05-06 15:23:49 -04003407 if(CPUID::supportsMMX2())
3408 {
3409 return As<UShort4>(x86::psubw(As<Short4>(lhs), As<Short4>(rhs)));
3410 }
3411 else
3412 {
3413 return RValue<UShort4>(Nucleus::createSub(lhs.value, rhs.value));
3414 }
John Bauman89401822014-05-06 15:04:28 -04003415 }
3416
John Bauman19bac1e2014-05-06 15:23:49 -04003417
3418 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 {
3533 return VectorType::get(UShort::getType(), 4);
3534 }
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 {
3627 return VectorType::get(Short::getType(), 8);
3628 }
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 {
3794 return VectorType::get(UShort::getType(), 8);
3795 }
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 {
4148 return Type::getInt32Ty(*Nucleus::getContext());
4149 }
4150
John Bauman19bac1e2014-05-06 15:23:49 -04004151 Long::Long(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04004152 {
John Bauman66b8ab22014-05-06 15:57:45 -04004153
John Bauman89401822014-05-06 15:04:28 -04004154
4155 Value *integer = Nucleus::createSExt(cast.value, Long::getType());
4156
John Bauman66b8ab22014-05-06 15:57:45 -04004157 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04004158 }
4159
John Bauman19bac1e2014-05-06 15:23:49 -04004160 Long::Long(RValue<UInt> cast)
John Bauman89401822014-05-06 15:04:28 -04004161 {
John Bauman89401822014-05-06 15:04:28 -04004162 Value *integer = Nucleus::createZExt(cast.value, Long::getType());
4163
John Bauman66b8ab22014-05-06 15:57:45 -04004164 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04004165 }
4166
4167 Long::Long()
4168 {
John Bauman89401822014-05-06 15:04:28 -04004169 }
4170
John Bauman19bac1e2014-05-06 15:23:49 -04004171 Long::Long(RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04004172 {
John Bauman66b8ab22014-05-06 15:57:45 -04004173 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004174 }
4175
4176 RValue<Long> Long::operator=(int64_t rhs) const
4177 {
John Bauman66b8ab22014-05-06 15:57:45 -04004178 return RValue<Long>(storeValue(Nucleus::createConstantInt(rhs)));
John Bauman89401822014-05-06 15:04:28 -04004179 }
4180
John Bauman19bac1e2014-05-06 15:23:49 -04004181 RValue<Long> Long::operator=(RValue<Long> rhs) const
John Bauman89401822014-05-06 15:04:28 -04004182 {
John Bauman66b8ab22014-05-06 15:57:45 -04004183 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004184
4185 return rhs;
4186 }
4187
4188 RValue<Long> Long::operator=(const Long &rhs) const
4189 {
John Bauman66b8ab22014-05-06 15:57:45 -04004190 Value *value = rhs.loadValue();
4191 storeValue(value);
4192
4193 return RValue<Long>(value);
4194 }
4195
4196 RValue<Long> Long::operator=(const Reference<Long> &rhs) const
4197 {
4198 Value *value = rhs.loadValue();
4199 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004200
4201 return RValue<Long>(value);
4202 }
4203
John Bauman19bac1e2014-05-06 15:23:49 -04004204 RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04004205 {
4206 return RValue<Long>(Nucleus::createAdd(lhs.value, rhs.value));
4207 }
4208
John Bauman19bac1e2014-05-06 15:23:49 -04004209 RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04004210 {
4211 return RValue<Long>(Nucleus::createSub(lhs.value, rhs.value));
4212 }
4213
John Bauman19bac1e2014-05-06 15:23:49 -04004214 RValue<Long> operator+=(const Long &lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04004215 {
4216 return lhs = lhs + rhs;
4217 }
4218
John Bauman19bac1e2014-05-06 15:23:49 -04004219 RValue<Long> operator-=(const Long &lhs, RValue<Long> rhs)
John Bauman89401822014-05-06 15:04:28 -04004220 {
4221 return lhs = lhs - rhs;
4222 }
4223
John Bauman66b8ab22014-05-06 15:57:45 -04004224 RValue<Long> AddAtomic(RValue<Pointer<Long> > x, RValue<Long> y)
John Bauman89401822014-05-06 15:04:28 -04004225 {
John Bauman19bac1e2014-05-06 15:23:49 -04004226 return RValue<Long>(Nucleus::createAtomicAdd(x.value, y.value));
John Bauman89401822014-05-06 15:04:28 -04004227 }
4228
John Bauman19bac1e2014-05-06 15:23:49 -04004229 Type *Long::getType()
John Bauman89401822014-05-06 15:04:28 -04004230 {
4231 return Type::getInt64Ty(*Nucleus::getContext());
4232 }
4233
Nicolas Capens50c96362016-01-04 23:03:59 -05004234 Long1::Long1(const RValue<UInt> cast)
John Bauman89401822014-05-06 15:04:28 -04004235 {
Nicolas Capens50c96362016-01-04 23:03:59 -05004236 Value *undefCast = Nucleus::createInsertElement(UndefValue::get(VectorType::get(Int::getType(), 2)), cast.value, 0);
4237 Value *zeroCast = Nucleus::createInsertElement(undefCast, Nucleus::createConstantInt(0), 1);
John Bauman66b8ab22014-05-06 15:57:45 -04004238
Nicolas Capens50c96362016-01-04 23:03:59 -05004239 storeValue(Nucleus::createBitCast(zeroCast, Long1::getType()));
John Bauman89401822014-05-06 15:04:28 -04004240 }
4241
John Bauman19bac1e2014-05-06 15:23:49 -04004242 Long1::Long1(RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004243 {
John Bauman66b8ab22014-05-06 15:57:45 -04004244 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004245 }
4246
John Bauman19bac1e2014-05-06 15:23:49 -04004247 Type *Long1::getType()
John Bauman89401822014-05-06 15:04:28 -04004248 {
John Bauman19bac1e2014-05-06 15:23:49 -04004249 if(CPUID::supportsMMX2())
4250 {
4251 return MMX::getType();
4252 }
4253 else
4254 {
4255 return VectorType::get(Long::getType(), 1);
4256 }
John Bauman89401822014-05-06 15:04:28 -04004257 }
4258
John Bauman19bac1e2014-05-06 15:23:49 -04004259 RValue<Long2> UnpackHigh(RValue<Long2> x, RValue<Long2> y)
John Bauman89401822014-05-06 15:04:28 -04004260 {
4261 Constant *shuffle[2];
4262 shuffle[0] = Nucleus::createConstantInt(1);
4263 shuffle[1] = Nucleus::createConstantInt(3);
4264
4265 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 2));
4266
4267 return RValue<Long2>(packed);
4268 }
4269
John Bauman19bac1e2014-05-06 15:23:49 -04004270 Type *Long2::getType()
John Bauman89401822014-05-06 15:04:28 -04004271 {
4272 return VectorType::get(Long::getType(), 2);
4273 }
4274
Nicolas Capens81f18302016-01-14 09:32:35 -05004275 UInt::UInt(Argument<UInt> argument)
John Bauman89401822014-05-06 15:04:28 -04004276 {
Nicolas Capens81f18302016-01-14 09:32:35 -05004277 storeValue(argument.value);
John Bauman89401822014-05-06 15:04:28 -04004278 }
4279
John Bauman19bac1e2014-05-06 15:23:49 -04004280 UInt::UInt(RValue<UShort> cast)
John Bauman89401822014-05-06 15:04:28 -04004281 {
John Bauman89401822014-05-06 15:04:28 -04004282 Value *integer = Nucleus::createZExt(cast.value, UInt::getType());
4283
John Bauman66b8ab22014-05-06 15:57:45 -04004284 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04004285 }
4286
John Bauman19bac1e2014-05-06 15:23:49 -04004287 UInt::UInt(RValue<Long> cast)
John Bauman89401822014-05-06 15:04:28 -04004288 {
John Bauman89401822014-05-06 15:04:28 -04004289 Value *integer = Nucleus::createTrunc(cast.value, UInt::getType());
4290
John Bauman66b8ab22014-05-06 15:57:45 -04004291 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04004292 }
4293
John Bauman19bac1e2014-05-06 15:23:49 -04004294 UInt::UInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04004295 {
Alexis Hetu764d1422016-09-28 08:44:22 -04004296 // Note: createFPToUI is broken, must perform conversion using createFPtoSI
4297 // Value *integer = Nucleus::createFPToUI(cast.value, UInt::getType());
John Bauman89401822014-05-06 15:04:28 -04004298
Alexis Hetu764d1422016-09-28 08:44:22 -04004299 // Smallest positive value representable in UInt, but not in Int
4300 const unsigned int ustart = 0x80000000u;
4301 const float ustartf = float(ustart);
4302
4303 // If the value is negative, store 0, otherwise store the result of the conversion
4304 storeValue((~(As<Int>(cast) >> 31) &
4305 // Check if the value can be represented as an Int
4306 IfThenElse(cast >= ustartf,
4307 // If the value is too large, subtract ustart and re-add it after conversion.
4308 As<Int>(As<UInt>(Int(cast - Float(ustartf))) + UInt(ustart)),
4309 // Otherwise, just convert normally
4310 Int(cast))).value);
John Bauman89401822014-05-06 15:04:28 -04004311 }
4312
4313 UInt::UInt()
4314 {
John Bauman89401822014-05-06 15:04:28 -04004315 }
4316
4317 UInt::UInt(int x)
4318 {
John Bauman66b8ab22014-05-06 15:57:45 -04004319 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04004320 }
4321
4322 UInt::UInt(unsigned int x)
4323 {
John Bauman66b8ab22014-05-06 15:57:45 -04004324 storeValue(Nucleus::createConstantInt(x));
John Bauman89401822014-05-06 15:04:28 -04004325 }
4326
John Bauman19bac1e2014-05-06 15:23:49 -04004327 UInt::UInt(RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004328 {
John Bauman66b8ab22014-05-06 15:57:45 -04004329 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004330 }
4331
John Bauman19bac1e2014-05-06 15:23:49 -04004332 UInt::UInt(RValue<Int> rhs)
John Bauman89401822014-05-06 15:04:28 -04004333 {
John Bauman66b8ab22014-05-06 15:57:45 -04004334 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004335 }
4336
4337 UInt::UInt(const UInt &rhs)
4338 {
John Bauman66b8ab22014-05-06 15:57:45 -04004339 Value *value = rhs.loadValue();
4340 storeValue(value);
4341 }
John Bauman89401822014-05-06 15:04:28 -04004342
John Bauman66b8ab22014-05-06 15:57:45 -04004343 UInt::UInt(const Reference<UInt> &rhs)
4344 {
4345 Value *value = rhs.loadValue();
4346 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004347 }
4348
4349 UInt::UInt(const Int &rhs)
4350 {
John Bauman66b8ab22014-05-06 15:57:45 -04004351 Value *value = rhs.loadValue();
4352 storeValue(value);
4353 }
John Bauman89401822014-05-06 15:04:28 -04004354
John Bauman66b8ab22014-05-06 15:57:45 -04004355 UInt::UInt(const Reference<Int> &rhs)
4356 {
4357 Value *value = rhs.loadValue();
4358 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004359 }
4360
4361 RValue<UInt> UInt::operator=(unsigned int rhs) const
4362 {
John Bauman66b8ab22014-05-06 15:57:45 -04004363 return RValue<UInt>(storeValue(Nucleus::createConstantInt(rhs)));
John Bauman89401822014-05-06 15:04:28 -04004364 }
4365
John Bauman19bac1e2014-05-06 15:23:49 -04004366 RValue<UInt> UInt::operator=(RValue<UInt> rhs) const
John Bauman89401822014-05-06 15:04:28 -04004367 {
John Bauman66b8ab22014-05-06 15:57:45 -04004368 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004369
4370 return rhs;
4371 }
4372
John Bauman19bac1e2014-05-06 15:23:49 -04004373 RValue<UInt> UInt::operator=(RValue<Int> rhs) const
John Bauman89401822014-05-06 15:04:28 -04004374 {
John Bauman66b8ab22014-05-06 15:57:45 -04004375 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004376
John Bauman66b8ab22014-05-06 15:57:45 -04004377 return RValue<UInt>(rhs);
John Bauman89401822014-05-06 15:04:28 -04004378 }
4379
4380 RValue<UInt> UInt::operator=(const UInt &rhs) const
4381 {
John Bauman66b8ab22014-05-06 15:57:45 -04004382 Value *value = rhs.loadValue();
4383 storeValue(value);
4384
4385 return RValue<UInt>(value);
4386 }
4387
4388 RValue<UInt> UInt::operator=(const Reference<UInt> &rhs) const
4389 {
4390 Value *value = rhs.loadValue();
4391 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004392
4393 return RValue<UInt>(value);
4394 }
4395
4396 RValue<UInt> UInt::operator=(const Int &rhs) const
4397 {
John Bauman66b8ab22014-05-06 15:57:45 -04004398 Value *value = rhs.loadValue();
4399 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004400
4401 return RValue<UInt>(value);
4402 }
4403
John Bauman66b8ab22014-05-06 15:57:45 -04004404 RValue<UInt> UInt::operator=(const Reference<Int> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04004405 {
John Bauman66b8ab22014-05-06 15:57:45 -04004406 Value *value = rhs.loadValue();
4407 storeValue(value);
4408
4409 return RValue<UInt>(value);
John Bauman89401822014-05-06 15:04:28 -04004410 }
4411
John Bauman19bac1e2014-05-06 15:23:49 -04004412 RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004413 {
4414 return RValue<UInt>(Nucleus::createAdd(lhs.value, rhs.value));
4415 }
4416
John Bauman19bac1e2014-05-06 15:23:49 -04004417 RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004418 {
4419 return RValue<UInt>(Nucleus::createSub(lhs.value, rhs.value));
4420 }
4421
John Bauman19bac1e2014-05-06 15:23:49 -04004422 RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004423 {
4424 return RValue<UInt>(Nucleus::createMul(lhs.value, rhs.value));
4425 }
4426
John Bauman19bac1e2014-05-06 15:23:49 -04004427 RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004428 {
4429 return RValue<UInt>(Nucleus::createUDiv(lhs.value, rhs.value));
4430 }
4431
John Bauman19bac1e2014-05-06 15:23:49 -04004432 RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004433 {
4434 return RValue<UInt>(Nucleus::createURem(lhs.value, rhs.value));
4435 }
4436
John Bauman19bac1e2014-05-06 15:23:49 -04004437 RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004438 {
4439 return RValue<UInt>(Nucleus::createAnd(lhs.value, rhs.value));
4440 }
4441
John Bauman19bac1e2014-05-06 15:23:49 -04004442 RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004443 {
4444 return RValue<UInt>(Nucleus::createOr(lhs.value, rhs.value));
4445 }
4446
John Bauman19bac1e2014-05-06 15:23:49 -04004447 RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004448 {
4449 return RValue<UInt>(Nucleus::createXor(lhs.value, rhs.value));
4450 }
4451
John Bauman19bac1e2014-05-06 15:23:49 -04004452 RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004453 {
4454 return RValue<UInt>(Nucleus::createShl(lhs.value, rhs.value));
4455 }
4456
John Bauman19bac1e2014-05-06 15:23:49 -04004457 RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004458 {
4459 return RValue<UInt>(Nucleus::createLShr(lhs.value, rhs.value));
4460 }
4461
John Bauman19bac1e2014-05-06 15:23:49 -04004462 RValue<UInt> operator+=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004463 {
4464 return lhs = lhs + rhs;
4465 }
4466
John Bauman19bac1e2014-05-06 15:23:49 -04004467 RValue<UInt> operator-=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004468 {
4469 return lhs = lhs - rhs;
4470 }
4471
John Bauman19bac1e2014-05-06 15:23:49 -04004472 RValue<UInt> operator*=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004473 {
4474 return lhs = lhs * rhs;
4475 }
4476
John Bauman19bac1e2014-05-06 15:23:49 -04004477 RValue<UInt> operator/=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004478 {
4479 return lhs = lhs / rhs;
4480 }
4481
John Bauman19bac1e2014-05-06 15:23:49 -04004482 RValue<UInt> operator%=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004483 {
4484 return lhs = lhs % rhs;
4485 }
4486
John Bauman19bac1e2014-05-06 15:23:49 -04004487 RValue<UInt> operator&=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004488 {
4489 return lhs = lhs & rhs;
4490 }
4491
John Bauman19bac1e2014-05-06 15:23:49 -04004492 RValue<UInt> operator|=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004493 {
4494 return lhs = lhs | rhs;
4495 }
4496
John Bauman19bac1e2014-05-06 15:23:49 -04004497 RValue<UInt> operator^=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004498 {
4499 return lhs = lhs ^ rhs;
4500 }
4501
John Bauman19bac1e2014-05-06 15:23:49 -04004502 RValue<UInt> operator<<=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004503 {
4504 return lhs = lhs << rhs;
4505 }
4506
John Bauman19bac1e2014-05-06 15:23:49 -04004507 RValue<UInt> operator>>=(const UInt &lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004508 {
4509 return lhs = lhs >> rhs;
4510 }
4511
John Bauman19bac1e2014-05-06 15:23:49 -04004512 RValue<UInt> operator+(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004513 {
4514 return val;
4515 }
4516
John Bauman19bac1e2014-05-06 15:23:49 -04004517 RValue<UInt> operator-(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004518 {
4519 return RValue<UInt>(Nucleus::createNeg(val.value));
4520 }
4521
John Bauman19bac1e2014-05-06 15:23:49 -04004522 RValue<UInt> operator~(RValue<UInt> val)
John Bauman89401822014-05-06 15:04:28 -04004523 {
4524 return RValue<UInt>(Nucleus::createNot(val.value));
4525 }
4526
4527 RValue<UInt> operator++(const UInt &val, int) // Post-increment
4528 {
4529 RValue<UInt> res = val;
4530
4531 Value *inc = Nucleus::createAdd(res.value, Nucleus::createConstantInt(1));
John Bauman66b8ab22014-05-06 15:57:45 -04004532 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004533
4534 return res;
4535 }
4536
4537 const UInt &operator++(const UInt &val) // Pre-increment
4538 {
John Bauman66b8ab22014-05-06 15:57:45 -04004539 Value *inc = Nucleus::createAdd(val.loadValue(), Nucleus::createConstantInt(1));
4540 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004541
4542 return val;
4543 }
4544
4545 RValue<UInt> operator--(const UInt &val, int) // Post-decrement
4546 {
4547 RValue<UInt> res = val;
4548
4549 Value *inc = Nucleus::createSub(res.value, Nucleus::createConstantInt(1));
John Bauman66b8ab22014-05-06 15:57:45 -04004550 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004551
4552 return res;
4553 }
4554
4555 const UInt &operator--(const UInt &val) // Pre-decrement
4556 {
John Bauman66b8ab22014-05-06 15:57:45 -04004557 Value *inc = Nucleus::createSub(val.loadValue(), Nucleus::createConstantInt(1));
4558 val.storeValue(inc);
John Bauman89401822014-05-06 15:04:28 -04004559
4560 return val;
4561 }
4562
John Bauman19bac1e2014-05-06 15:23:49 -04004563 RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y)
4564 {
4565 return IfThenElse(x > y, x, y);
4566 }
4567
4568 RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y)
4569 {
4570 return IfThenElse(x < y, x, y);
4571 }
4572
4573 RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max)
4574 {
4575 return Min(Max(x, min), max);
4576 }
4577
4578 RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004579 {
4580 return RValue<Bool>(Nucleus::createICmpULT(lhs.value, rhs.value));
4581 }
4582
John Bauman19bac1e2014-05-06 15:23:49 -04004583 RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004584 {
4585 return RValue<Bool>(Nucleus::createICmpULE(lhs.value, rhs.value));
4586 }
4587
John Bauman19bac1e2014-05-06 15:23:49 -04004588 RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004589 {
4590 return RValue<Bool>(Nucleus::createICmpUGT(lhs.value, rhs.value));
4591 }
4592
John Bauman19bac1e2014-05-06 15:23:49 -04004593 RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004594 {
4595 return RValue<Bool>(Nucleus::createICmpUGE(lhs.value, rhs.value));
4596 }
4597
John Bauman19bac1e2014-05-06 15:23:49 -04004598 RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004599 {
4600 return RValue<Bool>(Nucleus::createICmpNE(lhs.value, rhs.value));
4601 }
4602
John Bauman19bac1e2014-05-06 15:23:49 -04004603 RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs)
John Bauman89401822014-05-06 15:04:28 -04004604 {
4605 return RValue<Bool>(Nucleus::createICmpEQ(lhs.value, rhs.value));
4606 }
4607
John Bauman19bac1e2014-05-06 15:23:49 -04004608// RValue<UInt> RoundUInt(RValue<Float> cast)
John Bauman89401822014-05-06 15:04:28 -04004609// {
4610// return x86::cvtss2si(val); // FIXME: Unsigned
4611//
John Bauman66b8ab22014-05-06 15:57:45 -04004612// // return IfThenElse(val > 0.0f, Int(val + 0.5f), Int(val - 0.5f));
John Bauman89401822014-05-06 15:04:28 -04004613// }
4614
John Bauman19bac1e2014-05-06 15:23:49 -04004615 Type *UInt::getType()
John Bauman89401822014-05-06 15:04:28 -04004616 {
4617 return Type::getInt32Ty(*Nucleus::getContext());
4618 }
4619
John Bauman19bac1e2014-05-06 15:23:49 -04004620// Int2::Int2(RValue<Int> cast)
4621// {
John Bauman19bac1e2014-05-06 15:23:49 -04004622// Value *extend = Nucleus::createZExt(cast.value, Long::getType());
4623// Value *vector = Nucleus::createBitCast(extend, Int2::getType());
John Bauman66b8ab22014-05-06 15:57:45 -04004624//
John Bauman19bac1e2014-05-06 15:23:49 -04004625// Constant *shuffle[2];
4626// shuffle[0] = Nucleus::createConstantInt(0);
4627// shuffle[1] = Nucleus::createConstantInt(0);
4628//
4629// Value *replicate = Nucleus::createShuffleVector(vector, UndefValue::get(Int2::getType()), Nucleus::createConstantVector(shuffle, 2));
4630//
John Bauman66b8ab22014-05-06 15:57:45 -04004631// storeValue(replicate);
John Bauman19bac1e2014-05-06 15:23:49 -04004632// }
John Bauman89401822014-05-06 15:04:28 -04004633
John Bauman19bac1e2014-05-06 15:23:49 -04004634 Int2::Int2(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04004635 {
John Bauman89401822014-05-06 15:04:28 -04004636 Value *long2 = Nucleus::createBitCast(cast.value, Long2::getType());
4637 Value *element = Nucleus::createExtractElement(long2, 0);
4638 Value *int2 = Nucleus::createBitCast(element, Int2::getType());
4639
John Bauman66b8ab22014-05-06 15:57:45 -04004640 storeValue(int2);
John Bauman89401822014-05-06 15:04:28 -04004641 }
4642
4643 Int2::Int2()
4644 {
4645 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004646 }
4647
4648 Int2::Int2(int x, int y)
4649 {
4650 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004651
4652 Constant *constantVector[2];
4653 constantVector[0] = Nucleus::createConstantInt(x);
4654 constantVector[1] = Nucleus::createConstantInt(y);
John Bauman19bac1e2014-05-06 15:23:49 -04004655 Value *vector = Nucleus::createConstantVector(constantVector, 2);
John Bauman89401822014-05-06 15:04:28 -04004656
John Bauman66b8ab22014-05-06 15:57:45 -04004657 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04004658 }
4659
John Bauman19bac1e2014-05-06 15:23:49 -04004660 Int2::Int2(RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004661 {
4662 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004663
John Bauman66b8ab22014-05-06 15:57:45 -04004664 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004665 }
4666
4667 Int2::Int2(const Int2 &rhs)
4668 {
4669 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004670
John Bauman66b8ab22014-05-06 15:57:45 -04004671 Value *value = rhs.loadValue();
4672 storeValue(value);
4673 }
4674
4675 Int2::Int2(const Reference<Int2> &rhs)
4676 {
4677 // xy.parent = this;
4678
4679 Value *value = rhs.loadValue();
4680 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004681 }
4682
Nicolas Capens62abb552016-01-05 12:03:47 -05004683 Int2::Int2(RValue<Int> lo, RValue<Int> hi)
4684 {
Nicolas Capensb40a2562016-01-05 00:08:45 -05004685 if(CPUID::supportsMMX2())
4686 {
4687 // movd mm0, lo
4688 // movd mm1, hi
4689 // punpckldq mm0, mm1
4690 storeValue(As<Int2>(UnpackLow(As<Int2>(Long1(RValue<UInt>(lo))), As<Int2>(Long1(RValue<UInt>(hi))))).value);
4691 }
4692 else
4693 {
4694 Constant *shuffle[2];
4695 shuffle[0] = Nucleus::createConstantInt(0);
4696 shuffle[1] = Nucleus::createConstantInt(1);
Nicolas Capens05b3d662016-02-25 23:58:33 -05004697
Nicolas Capensb40a2562016-01-05 00:08:45 -05004698 Value *packed = Nucleus::createShuffleVector(Nucleus::createBitCast(lo.value, VectorType::get(Int::getType(), 1)), Nucleus::createBitCast(hi.value, VectorType::get(Int::getType(), 1)), Nucleus::createConstantVector(shuffle, 2));
Nicolas Capens05b3d662016-02-25 23:58:33 -05004699
Nicolas Capensb40a2562016-01-05 00:08:45 -05004700 storeValue(Nucleus::createBitCast(packed, Int2::getType()));
4701 }
Nicolas Capens62abb552016-01-05 12:03:47 -05004702 }
4703
John Bauman19bac1e2014-05-06 15:23:49 -04004704 RValue<Int2> Int2::operator=(RValue<Int2> rhs) const
John Bauman89401822014-05-06 15:04:28 -04004705 {
John Bauman66b8ab22014-05-06 15:57:45 -04004706 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04004707
4708 return rhs;
4709 }
4710
4711 RValue<Int2> Int2::operator=(const Int2 &rhs) const
4712 {
John Bauman66b8ab22014-05-06 15:57:45 -04004713 Value *value = rhs.loadValue();
4714 storeValue(value);
4715
4716 return RValue<Int2>(value);
4717 }
4718
4719 RValue<Int2> Int2::operator=(const Reference<Int2> &rhs) const
4720 {
4721 Value *value = rhs.loadValue();
4722 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04004723
4724 return RValue<Int2>(value);
4725 }
4726
John Bauman19bac1e2014-05-06 15:23:49 -04004727 RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004728 {
John Bauman19bac1e2014-05-06 15:23:49 -04004729 if(CPUID::supportsMMX2())
4730 {
4731 return x86::paddd(lhs, rhs);
4732 }
4733 else
4734 {
4735 return RValue<Int2>(Nucleus::createAdd(lhs.value, rhs.value));
4736 }
John Bauman89401822014-05-06 15:04:28 -04004737 }
4738
John Bauman19bac1e2014-05-06 15:23:49 -04004739 RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004740 {
John Bauman19bac1e2014-05-06 15:23:49 -04004741 if(CPUID::supportsMMX2())
4742 {
4743 return x86::psubd(lhs, rhs);
4744 }
4745 else
4746 {
4747 return RValue<Int2>(Nucleus::createSub(lhs.value, rhs.value));
4748 }
John Bauman89401822014-05-06 15:04:28 -04004749 }
4750
John Bauman19bac1e2014-05-06 15:23:49 -04004751// RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs)
4752// {
4753// return RValue<Int2>(Nucleus::createMul(lhs.value, rhs.value));
4754// }
4755
4756// RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs)
4757// {
4758// return RValue<Int2>(Nucleus::createSDiv(lhs.value, rhs.value));
4759// }
4760
4761// RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs)
4762// {
4763// return RValue<Int2>(Nucleus::createSRem(lhs.value, rhs.value));
4764// }
4765
4766 RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004767 {
John Bauman19bac1e2014-05-06 15:23:49 -04004768 if(CPUID::supportsMMX2())
4769 {
4770 return As<Int2>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
4771 }
4772 else
4773 {
4774 return RValue<Int2>(Nucleus::createAnd(lhs.value, rhs.value));
4775 }
John Bauman89401822014-05-06 15:04:28 -04004776 }
4777
John Bauman19bac1e2014-05-06 15:23:49 -04004778 RValue<Int2> operator|(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004779 {
John Bauman19bac1e2014-05-06 15:23:49 -04004780 if(CPUID::supportsMMX2())
4781 {
4782 return As<Int2>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
4783 }
4784 else
4785 {
4786 return RValue<Int2>(Nucleus::createOr(lhs.value, rhs.value));
4787 }
John Bauman89401822014-05-06 15:04:28 -04004788 }
4789
John Bauman19bac1e2014-05-06 15:23:49 -04004790 RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004791 {
John Bauman19bac1e2014-05-06 15:23:49 -04004792 if(CPUID::supportsMMX2())
4793 {
4794 return As<Int2>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
4795 }
4796 else
4797 {
4798 return RValue<Int2>(Nucleus::createXor(lhs.value, rhs.value));
4799 }
John Bauman89401822014-05-06 15:04:28 -04004800 }
4801
John Bauman19bac1e2014-05-06 15:23:49 -04004802 RValue<Int2> operator<<(RValue<Int2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004803 {
4804 // return RValue<Int2>(Nucleus::createShl(lhs.value, rhs.value));
4805
4806 return x86::pslld(lhs, rhs);
4807 }
4808
John Bauman19bac1e2014-05-06 15:23:49 -04004809 RValue<Int2> operator>>(RValue<Int2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04004810 {
4811 // return RValue<Int2>(Nucleus::createAShr(lhs.value, rhs.value));
4812
4813 return x86::psrad(lhs, rhs);
4814 }
4815
John Bauman19bac1e2014-05-06 15:23:49 -04004816 RValue<Int2> operator<<(RValue<Int2> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004817 {
4818 // return RValue<Int2>(Nucleus::createShl(lhs.value, rhs.value));
4819
4820 return x86::pslld(lhs, rhs);
4821 }
4822
John Bauman19bac1e2014-05-06 15:23:49 -04004823 RValue<Int2> operator>>(RValue<Int2> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004824 {
4825 // return RValue<Int2>(Nucleus::createAShr(lhs.value, rhs.value));
4826
4827 return x86::psrad(lhs, rhs);
4828 }
4829
John Bauman19bac1e2014-05-06 15:23:49 -04004830 RValue<Int2> operator+=(const Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004831 {
4832 return lhs = lhs + rhs;
4833 }
4834
John Bauman19bac1e2014-05-06 15:23:49 -04004835 RValue<Int2> operator-=(const Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004836 {
4837 return lhs = lhs - rhs;
4838 }
4839
John Bauman19bac1e2014-05-06 15:23:49 -04004840// RValue<Int2> operator*=(const Int2 &lhs, RValue<Int2> rhs)
4841// {
4842// return lhs = lhs * rhs;
4843// }
John Bauman89401822014-05-06 15:04:28 -04004844
John Bauman19bac1e2014-05-06 15:23:49 -04004845// RValue<Int2> operator/=(const Int2 &lhs, RValue<Int2> rhs)
4846// {
4847// return lhs = lhs / rhs;
4848// }
John Bauman89401822014-05-06 15:04:28 -04004849
John Bauman19bac1e2014-05-06 15:23:49 -04004850// RValue<Int2> operator%=(const Int2 &lhs, RValue<Int2> rhs)
4851// {
4852// return lhs = lhs % rhs;
4853// }
John Bauman89401822014-05-06 15:04:28 -04004854
John Bauman19bac1e2014-05-06 15:23:49 -04004855 RValue<Int2> operator&=(const Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004856 {
4857 return lhs = lhs & rhs;
4858 }
4859
John Bauman19bac1e2014-05-06 15:23:49 -04004860 RValue<Int2> operator|=(const Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004861 {
4862 return lhs = lhs | rhs;
4863 }
4864
John Bauman19bac1e2014-05-06 15:23:49 -04004865 RValue<Int2> operator^=(const Int2 &lhs, RValue<Int2> rhs)
John Bauman89401822014-05-06 15:04:28 -04004866 {
4867 return lhs = lhs ^ rhs;
4868 }
4869
4870 RValue<Int2> operator<<=(const Int2 &lhs, unsigned char rhs)
4871 {
4872 return lhs = lhs << rhs;
4873 }
4874
4875 RValue<Int2> operator>>=(const Int2 &lhs, unsigned char rhs)
4876 {
4877 return lhs = lhs >> rhs;
4878 }
4879
John Bauman19bac1e2014-05-06 15:23:49 -04004880 RValue<Int2> operator<<=(const Int2 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004881 {
4882 return lhs = lhs << rhs;
4883 }
4884
John Bauman19bac1e2014-05-06 15:23:49 -04004885 RValue<Int2> operator>>=(const Int2 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04004886 {
4887 return lhs = lhs >> rhs;
4888 }
4889
John Bauman19bac1e2014-05-06 15:23:49 -04004890// RValue<Int2> operator+(RValue<Int2> val)
4891// {
4892// return val;
4893// }
4894
4895// RValue<Int2> operator-(RValue<Int2> val)
4896// {
4897// return RValue<Int2>(Nucleus::createNeg(val.value));
4898// }
4899
4900 RValue<Int2> operator~(RValue<Int2> val)
John Bauman89401822014-05-06 15:04:28 -04004901 {
John Bauman19bac1e2014-05-06 15:23:49 -04004902 if(CPUID::supportsMMX2())
4903 {
4904 return val ^ Int2(0xFFFFFFFF, 0xFFFFFFFF);
4905 }
4906 else
4907 {
4908 return RValue<Int2>(Nucleus::createNot(val.value));
4909 }
John Bauman89401822014-05-06 15:04:28 -04004910 }
4911
John Bauman19bac1e2014-05-06 15:23:49 -04004912 RValue<Long1> UnpackLow(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04004913 {
John Bauman19bac1e2014-05-06 15:23:49 -04004914 if(CPUID::supportsMMX2())
4915 {
4916 return x86::punpckldq(x, y);
4917 }
4918 else
4919 {
4920 Constant *shuffle[2];
4921 shuffle[0] = Nucleus::createConstantInt(0);
4922 shuffle[1] = Nucleus::createConstantInt(2);
John Bauman89401822014-05-06 15:04:28 -04004923
John Bauman19bac1e2014-05-06 15:23:49 -04004924 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 2));
John Bauman89401822014-05-06 15:04:28 -04004925
John Bauman19bac1e2014-05-06 15:23:49 -04004926 return RValue<Long1>(Nucleus::createBitCast(packed, Long1::getType()));
4927 }
John Bauman89401822014-05-06 15:04:28 -04004928 }
John Bauman66b8ab22014-05-06 15:57:45 -04004929
John Bauman19bac1e2014-05-06 15:23:49 -04004930 RValue<Long1> UnpackHigh(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04004931 {
John Bauman19bac1e2014-05-06 15:23:49 -04004932 if(CPUID::supportsMMX2())
4933 {
4934 return x86::punpckhdq(x, y);
4935 }
4936 else
4937 {
4938 Constant *shuffle[2];
4939 shuffle[0] = Nucleus::createConstantInt(1);
4940 shuffle[1] = Nucleus::createConstantInt(3);
John Bauman89401822014-05-06 15:04:28 -04004941
John Bauman19bac1e2014-05-06 15:23:49 -04004942 Value *packed = Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 2));
John Bauman89401822014-05-06 15:04:28 -04004943
John Bauman19bac1e2014-05-06 15:23:49 -04004944 return RValue<Long1>(Nucleus::createBitCast(packed, Long1::getType()));
4945 }
John Bauman89401822014-05-06 15:04:28 -04004946 }
4947
John Bauman19bac1e2014-05-06 15:23:49 -04004948 RValue<Int> Extract(RValue<Int2> val, int i)
John Bauman89401822014-05-06 15:04:28 -04004949 {
4950 if(false) // FIXME: LLVM does not generate optimal code
4951 {
4952 return RValue<Int>(Nucleus::createExtractElement(val.value, i));
4953 }
4954 else
4955 {
4956 if(i == 0)
4957 {
John Bauman19bac1e2014-05-06 15:23:49 -04004958 return RValue<Int>(Nucleus::createExtractElement(Nucleus::createBitCast(val.value, VectorType::get(Int::getType(), 2)), 0));
John Bauman89401822014-05-06 15:04:28 -04004959 }
4960 else
4961 {
4962 Int2 val2 = As<Int2>(UnpackHigh(val, val));
4963
4964 return Extract(val2, 0);
4965 }
4966 }
4967 }
4968
Nicolas Capensfff3c9b2015-05-13 23:40:44 -04004969 RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i)
4970 {
4971 return RValue<Int2>(Nucleus::createBitCast(Nucleus::createInsertElement(Nucleus::createBitCast(val.value, VectorType::get(Int::getType(), 2)), element.value, i), Int2::getType()));
4972 }
John Bauman89401822014-05-06 15:04:28 -04004973
John Bauman19bac1e2014-05-06 15:23:49 -04004974 Type *Int2::getType()
John Bauman89401822014-05-06 15:04:28 -04004975 {
John Bauman19bac1e2014-05-06 15:23:49 -04004976 if(CPUID::supportsMMX2())
4977 {
4978 return MMX::getType();
4979 }
4980 else
4981 {
4982 return VectorType::get(Int::getType(), 2);
4983 }
John Bauman89401822014-05-06 15:04:28 -04004984 }
4985
4986 UInt2::UInt2()
4987 {
4988 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004989 }
4990
4991 UInt2::UInt2(unsigned int x, unsigned int y)
4992 {
4993 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04004994
4995 Constant *constantVector[2];
4996 constantVector[0] = Nucleus::createConstantInt(x);
4997 constantVector[1] = Nucleus::createConstantInt(y);
John Bauman19bac1e2014-05-06 15:23:49 -04004998 Value *vector = Nucleus::createConstantVector(constantVector, 2);
John Bauman89401822014-05-06 15:04:28 -04004999
John Bauman66b8ab22014-05-06 15:57:45 -04005000 storeValue(Nucleus::createBitCast(vector, getType()));
John Bauman89401822014-05-06 15:04:28 -04005001 }
5002
John Bauman19bac1e2014-05-06 15:23:49 -04005003 UInt2::UInt2(RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005004 {
5005 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005006
John Bauman66b8ab22014-05-06 15:57:45 -04005007 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005008 }
5009
5010 UInt2::UInt2(const UInt2 &rhs)
5011 {
5012 // xy.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005013
John Bauman66b8ab22014-05-06 15:57:45 -04005014 Value *value = rhs.loadValue();
5015 storeValue(value);
5016 }
5017
5018 UInt2::UInt2(const Reference<UInt2> &rhs)
5019 {
5020 // xy.parent = this;
5021
5022 Value *value = rhs.loadValue();
5023 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005024 }
5025
John Bauman19bac1e2014-05-06 15:23:49 -04005026 RValue<UInt2> UInt2::operator=(RValue<UInt2> rhs) const
John Bauman89401822014-05-06 15:04:28 -04005027 {
John Bauman66b8ab22014-05-06 15:57:45 -04005028 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005029
5030 return rhs;
5031 }
5032
5033 RValue<UInt2> UInt2::operator=(const UInt2 &rhs) const
5034 {
John Bauman66b8ab22014-05-06 15:57:45 -04005035 Value *value = rhs.loadValue();
5036 storeValue(value);
5037
5038 return RValue<UInt2>(value);
5039 }
5040
5041 RValue<UInt2> UInt2::operator=(const Reference<UInt2> &rhs) const
5042 {
5043 Value *value = rhs.loadValue();
5044 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005045
5046 return RValue<UInt2>(value);
5047 }
5048
John Bauman19bac1e2014-05-06 15:23:49 -04005049 RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005050 {
John Bauman19bac1e2014-05-06 15:23:49 -04005051 if(CPUID::supportsMMX2())
5052 {
5053 return As<UInt2>(x86::paddd(As<Int2>(lhs), As<Int2>(rhs)));
5054 }
5055 else
5056 {
5057 return RValue<UInt2>(Nucleus::createAdd(lhs.value, rhs.value));
5058 }
John Bauman89401822014-05-06 15:04:28 -04005059 }
5060
John Bauman19bac1e2014-05-06 15:23:49 -04005061 RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005062 {
John Bauman19bac1e2014-05-06 15:23:49 -04005063 if(CPUID::supportsMMX2())
5064 {
5065 return As<UInt2>(x86::psubd(As<Int2>(lhs), As<Int2>(rhs)));
5066 }
5067 else
5068 {
5069 return RValue<UInt2>(Nucleus::createSub(lhs.value, rhs.value));
5070 }
John Bauman89401822014-05-06 15:04:28 -04005071 }
5072
John Bauman19bac1e2014-05-06 15:23:49 -04005073// RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs)
5074// {
5075// return RValue<UInt2>(Nucleus::createMul(lhs.value, rhs.value));
5076// }
5077
5078// RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs)
5079// {
5080// return RValue<UInt2>(Nucleus::createUDiv(lhs.value, rhs.value));
5081// }
5082
5083// RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs)
5084// {
5085// return RValue<UInt2>(Nucleus::createURem(lhs.value, rhs.value));
5086// }
5087
5088 RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005089 {
John Bauman19bac1e2014-05-06 15:23:49 -04005090 if(CPUID::supportsMMX2())
5091 {
5092 return As<UInt2>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
5093 }
5094 else
5095 {
5096 return RValue<UInt2>(Nucleus::createAnd(lhs.value, rhs.value));
5097 }
John Bauman89401822014-05-06 15:04:28 -04005098 }
5099
John Bauman19bac1e2014-05-06 15:23:49 -04005100 RValue<UInt2> operator|(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005101 {
John Bauman19bac1e2014-05-06 15:23:49 -04005102 if(CPUID::supportsMMX2())
5103 {
5104 return As<UInt2>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
5105 }
5106 else
5107 {
5108 return RValue<UInt2>(Nucleus::createOr(lhs.value, rhs.value));
5109 }
John Bauman89401822014-05-06 15:04:28 -04005110 }
5111
John Bauman19bac1e2014-05-06 15:23:49 -04005112 RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005113 {
John Bauman19bac1e2014-05-06 15:23:49 -04005114 if(CPUID::supportsMMX2())
5115 {
5116 return As<UInt2>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
5117 }
5118 else
5119 {
5120 return RValue<UInt2>(Nucleus::createXor(lhs.value, rhs.value));
5121 }
John Bauman89401822014-05-06 15:04:28 -04005122 }
5123
John Bauman19bac1e2014-05-06 15:23:49 -04005124 RValue<UInt2> operator<<(RValue<UInt2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005125 {
5126 // return RValue<UInt2>(Nucleus::createShl(lhs.value, rhs.value));
5127
5128 return As<UInt2>(x86::pslld(As<Int2>(lhs), rhs));
5129 }
5130
John Bauman19bac1e2014-05-06 15:23:49 -04005131 RValue<UInt2> operator>>(RValue<UInt2> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005132 {
5133 // return RValue<UInt2>(Nucleus::createLShr(lhs.value, rhs.value));
5134
5135 return x86::psrld(lhs, rhs);
5136 }
5137
John Bauman19bac1e2014-05-06 15:23:49 -04005138 RValue<UInt2> operator<<(RValue<UInt2> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04005139 {
5140 // return RValue<UInt2>(Nucleus::createShl(lhs.value, rhs.value));
5141
5142 return As<UInt2>(x86::pslld(As<Int2>(lhs), rhs));
5143 }
5144
John Bauman19bac1e2014-05-06 15:23:49 -04005145 RValue<UInt2> operator>>(RValue<UInt2> lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04005146 {
5147 // return RValue<UInt2>(Nucleus::createLShr(lhs.value, rhs.value));
5148
5149 return x86::psrld(lhs, rhs);
5150 }
5151
John Bauman19bac1e2014-05-06 15:23:49 -04005152 RValue<UInt2> operator+=(const UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005153 {
5154 return lhs = lhs + rhs;
5155 }
5156
John Bauman19bac1e2014-05-06 15:23:49 -04005157 RValue<UInt2> operator-=(const UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005158 {
5159 return lhs = lhs - rhs;
5160 }
5161
John Bauman19bac1e2014-05-06 15:23:49 -04005162// RValue<UInt2> operator*=(const UInt2 &lhs, RValue<UInt2> rhs)
5163// {
5164// return lhs = lhs * rhs;
5165// }
John Bauman89401822014-05-06 15:04:28 -04005166
John Bauman19bac1e2014-05-06 15:23:49 -04005167// RValue<UInt2> operator/=(const UInt2 &lhs, RValue<UInt2> rhs)
5168// {
5169// return lhs = lhs / rhs;
5170// }
John Bauman89401822014-05-06 15:04:28 -04005171
John Bauman19bac1e2014-05-06 15:23:49 -04005172// RValue<UInt2> operator%=(const UInt2 &lhs, RValue<UInt2> rhs)
5173// {
5174// return lhs = lhs % rhs;
5175// }
John Bauman89401822014-05-06 15:04:28 -04005176
John Bauman19bac1e2014-05-06 15:23:49 -04005177 RValue<UInt2> operator&=(const UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005178 {
5179 return lhs = lhs & rhs;
5180 }
5181
John Bauman19bac1e2014-05-06 15:23:49 -04005182 RValue<UInt2> operator|=(const UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005183 {
5184 return lhs = lhs | rhs;
5185 }
5186
John Bauman19bac1e2014-05-06 15:23:49 -04005187 RValue<UInt2> operator^=(const UInt2 &lhs, RValue<UInt2> rhs)
John Bauman89401822014-05-06 15:04:28 -04005188 {
5189 return lhs = lhs ^ rhs;
5190 }
5191
5192 RValue<UInt2> operator<<=(const UInt2 &lhs, unsigned char rhs)
5193 {
5194 return lhs = lhs << rhs;
5195 }
5196
5197 RValue<UInt2> operator>>=(const UInt2 &lhs, unsigned char rhs)
5198 {
5199 return lhs = lhs >> rhs;
5200 }
5201
John Bauman19bac1e2014-05-06 15:23:49 -04005202 RValue<UInt2> operator<<=(const UInt2 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04005203 {
5204 return lhs = lhs << rhs;
5205 }
5206
John Bauman19bac1e2014-05-06 15:23:49 -04005207 RValue<UInt2> operator>>=(const UInt2 &lhs, RValue<Long1> rhs)
John Bauman89401822014-05-06 15:04:28 -04005208 {
5209 return lhs = lhs >> rhs;
5210 }
5211
John Bauman19bac1e2014-05-06 15:23:49 -04005212// RValue<UInt2> operator+(RValue<UInt2> val)
5213// {
5214// return val;
5215// }
5216
5217// RValue<UInt2> operator-(RValue<UInt2> val)
5218// {
5219// return RValue<UInt2>(Nucleus::createNeg(val.value));
5220// }
5221
5222 RValue<UInt2> operator~(RValue<UInt2> val)
John Bauman89401822014-05-06 15:04:28 -04005223 {
John Bauman19bac1e2014-05-06 15:23:49 -04005224 if(CPUID::supportsMMX2())
5225 {
5226 return val ^ UInt2(0xFFFFFFFF, 0xFFFFFFFF);
5227 }
5228 else
5229 {
5230 return RValue<UInt2>(Nucleus::createNot(val.value));
5231 }
John Bauman89401822014-05-06 15:04:28 -04005232 }
5233
John Bauman19bac1e2014-05-06 15:23:49 -04005234 Type *UInt2::getType()
John Bauman89401822014-05-06 15:04:28 -04005235 {
John Bauman19bac1e2014-05-06 15:23:49 -04005236 if(CPUID::supportsMMX2())
5237 {
5238 return MMX::getType();
5239 }
5240 else
5241 {
5242 return VectorType::get(UInt::getType(), 2);
5243 }
John Bauman89401822014-05-06 15:04:28 -04005244 }
5245
Meng-Lin Wu601d0052016-06-10 14:18:41 -04005246 Int4::Int4(RValue<Byte4> cast)
5247 {
5248 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
5249 Value *a = Nucleus::createInsertElement(UndefValue::get(Int4::getType()), x, 0);
5250
5251 Value *e;
5252
5253 if (CPUID::supportsSSE4_1())
5254 {
5255 e = x86::pmovzxbd(RValue<Int4>(a)).value;
5256 }
5257 else
5258 {
5259 Constant *swizzle[16];
5260 swizzle[0] = Nucleus::createConstantInt(0);
5261 swizzle[1] = Nucleus::createConstantInt(16);
5262 swizzle[2] = Nucleus::createConstantInt(1);
5263 swizzle[3] = Nucleus::createConstantInt(17);
5264 swizzle[4] = Nucleus::createConstantInt(2);
5265 swizzle[5] = Nucleus::createConstantInt(18);
5266 swizzle[6] = Nucleus::createConstantInt(3);
5267 swizzle[7] = Nucleus::createConstantInt(19);
5268 swizzle[8] = Nucleus::createConstantInt(4);
5269 swizzle[9] = Nucleus::createConstantInt(20);
5270 swizzle[10] = Nucleus::createConstantInt(5);
5271 swizzle[11] = Nucleus::createConstantInt(21);
5272 swizzle[12] = Nucleus::createConstantInt(6);
5273 swizzle[13] = Nucleus::createConstantInt(22);
5274 swizzle[14] = Nucleus::createConstantInt(7);
5275 swizzle[15] = Nucleus::createConstantInt(23);
5276
5277 Value *b = Nucleus::createBitCast(a, Byte16::getType());
5278 Value *c = Nucleus::createShuffleVector(b, Nucleus::createNullValue(Byte16::getType()), Nucleus::createConstantVector(swizzle, 16));
5279
5280 Constant *swizzle2[8];
5281 swizzle2[0] = Nucleus::createConstantInt(0);
5282 swizzle2[1] = Nucleus::createConstantInt(8);
5283 swizzle2[2] = Nucleus::createConstantInt(1);
5284 swizzle2[3] = Nucleus::createConstantInt(9);
5285 swizzle2[4] = Nucleus::createConstantInt(2);
5286 swizzle2[5] = Nucleus::createConstantInt(10);
5287 swizzle2[6] = Nucleus::createConstantInt(3);
5288 swizzle2[7] = Nucleus::createConstantInt(11);
5289
5290 Value *d = Nucleus::createBitCast(c, Short8::getType());
5291 e = Nucleus::createShuffleVector(d, Nucleus::createNullValue(Short8::getType()), Nucleus::createConstantVector(swizzle2, 8));
5292 }
5293
5294 Value *f = Nucleus::createBitCast(e, Int4::getType());
5295 storeValue(f);
5296 }
5297
5298 Int4::Int4(RValue<SByte4> cast)
5299 {
5300 Value *x = Nucleus::createBitCast(cast.value, Int::getType());
5301 Value *a = Nucleus::createInsertElement(UndefValue::get(Int4::getType()), x, 0);
5302
5303 Value *g;
5304
5305 if (CPUID::supportsSSE4_1())
5306 {
5307 g = x86::pmovsxbd(RValue<Int4>(a)).value;
5308 }
5309 else
5310 {
5311 Constant *swizzle[16];
5312 swizzle[0] = Nucleus::createConstantInt(0);
5313 swizzle[1] = Nucleus::createConstantInt(0);
5314 swizzle[2] = Nucleus::createConstantInt(1);
5315 swizzle[3] = Nucleus::createConstantInt(1);
5316 swizzle[4] = Nucleus::createConstantInt(2);
5317 swizzle[5] = Nucleus::createConstantInt(2);
5318 swizzle[6] = Nucleus::createConstantInt(3);
5319 swizzle[7] = Nucleus::createConstantInt(3);
5320 swizzle[8] = Nucleus::createConstantInt(4);
5321 swizzle[9] = Nucleus::createConstantInt(4);
5322 swizzle[10] = Nucleus::createConstantInt(5);
5323 swizzle[11] = Nucleus::createConstantInt(5);
5324 swizzle[12] = Nucleus::createConstantInt(6);
5325 swizzle[13] = Nucleus::createConstantInt(6);
5326 swizzle[14] = Nucleus::createConstantInt(7);
5327 swizzle[15] = Nucleus::createConstantInt(7);
5328
5329 Value *b = Nucleus::createBitCast(a, Byte16::getType());
5330 Value *c = Nucleus::createShuffleVector(b, b, Nucleus::createConstantVector(swizzle, 16));
5331
5332 Constant *swizzle2[8];
5333 swizzle2[0] = Nucleus::createConstantInt(0);
5334 swizzle2[1] = Nucleus::createConstantInt(0);
5335 swizzle2[2] = Nucleus::createConstantInt(1);
5336 swizzle2[3] = Nucleus::createConstantInt(1);
5337 swizzle2[4] = Nucleus::createConstantInt(2);
5338 swizzle2[5] = Nucleus::createConstantInt(2);
5339 swizzle2[6] = Nucleus::createConstantInt(3);
5340 swizzle2[7] = Nucleus::createConstantInt(3);
5341
5342 Value *d = Nucleus::createBitCast(c, Short8::getType());
5343 Value *e = Nucleus::createShuffleVector(d, d, Nucleus::createConstantVector(swizzle2, 8));
5344
5345 Value *f = Nucleus::createBitCast(e, Int4::getType());
5346 // g = Nucleus::createAShr(f, Nucleus::createConstantInt(24));
5347 g = x86::psrad(RValue<Int4>(f), 24).value;
5348 }
5349
5350 storeValue(g);
5351 }
5352
John Bauman19bac1e2014-05-06 15:23:49 -04005353 Int4::Int4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005354 {
5355 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005356
5357 Value *xyzw = Nucleus::createFPToSI(cast.value, Int4::getType());
John Bauman89401822014-05-06 15:04:28 -04005358
John Bauman66b8ab22014-05-06 15:57:45 -04005359 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04005360 }
5361
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005362 Int4::Int4(RValue<Short4> cast)
5363 {
5364 Value *long2 = UndefValue::get(Long2::getType());
5365 Value *element = Nucleus::createBitCast(cast.value, Long::getType());
5366 long2 = Nucleus::createInsertElement(long2, element, 0);
5367 RValue<Int4> vector = RValue<Int4>(Nucleus::createBitCast(long2, Int4::getType()));
Nicolas Capens05b3d662016-02-25 23:58:33 -05005368
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005369 if(CPUID::supportsSSE4_1())
5370 {
5371 storeValue(x86::pmovsxwd(vector).value);
5372 }
5373 else
5374 {
5375 Value *b = Nucleus::createBitCast(vector.value, Short8::getType());
5376
5377 Constant *swizzle[8];
5378 swizzle[0] = Nucleus::createConstantInt(0);
5379 swizzle[1] = Nucleus::createConstantInt(0);
5380 swizzle[2] = Nucleus::createConstantInt(1);
5381 swizzle[3] = Nucleus::createConstantInt(1);
5382 swizzle[4] = Nucleus::createConstantInt(2);
5383 swizzle[5] = Nucleus::createConstantInt(2);
5384 swizzle[6] = Nucleus::createConstantInt(3);
5385 swizzle[7] = Nucleus::createConstantInt(3);
5386
Nicolas Capens6ce5c332015-10-28 01:58:18 -04005387 Value *c = Nucleus::createShuffleVector(b, b, Nucleus::createConstantVector(swizzle, 8));
5388 Value *d = Nucleus::createBitCast(c, Int4::getType());
5389 storeValue(d);
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005390
5391 // Each Short is packed into each Int in the (Short | Short) format.
5392 // Shifting by 16 will retrieve the original Short value.
5393 // Shitfing an Int will propagate the sign bit, which will work
5394 // for both positive and negative values of a Short.
5395 *this >>= 16;
5396 }
5397 }
5398
5399 Int4::Int4(RValue<UShort4> cast)
5400 {
5401 Value *long2 = UndefValue::get(Long2::getType());
5402 Value *element = Nucleus::createBitCast(cast.value, Long::getType());
5403 long2 = Nucleus::createInsertElement(long2, element, 0);
5404 RValue<Int4> vector = RValue<Int4>(Nucleus::createBitCast(long2, Int4::getType()));
5405
5406 if(CPUID::supportsSSE4_1())
5407 {
5408 storeValue(x86::pmovzxwd(RValue<Int4>(vector)).value);
5409 }
5410 else
5411 {
5412 Value *b = Nucleus::createBitCast(vector.value, Short8::getType());
5413
5414 Constant *swizzle[8];
5415 swizzle[0] = Nucleus::createConstantInt(0);
5416 swizzle[1] = Nucleus::createConstantInt(8);
5417 swizzle[2] = Nucleus::createConstantInt(1);
5418 swizzle[3] = Nucleus::createConstantInt(9);
5419 swizzle[4] = Nucleus::createConstantInt(2);
5420 swizzle[5] = Nucleus::createConstantInt(10);
5421 swizzle[6] = Nucleus::createConstantInt(3);
5422 swizzle[7] = Nucleus::createConstantInt(11);
5423
Nicolas Capens6ce5c332015-10-28 01:58:18 -04005424 Value *c = Nucleus::createShuffleVector(b, Nucleus::createNullValue(Short8::getType()), Nucleus::createConstantVector(swizzle, 8));
5425 Value *d = Nucleus::createBitCast(c, Int4::getType());
5426 storeValue(d);
Alexis Hetu2aa852f2015-10-14 16:32:39 -04005427 }
5428 }
5429
John Bauman89401822014-05-06 15:04:28 -04005430 Int4::Int4()
5431 {
5432 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005433 }
5434
5435 Int4::Int4(int xyzw)
5436 {
5437 constant(xyzw, xyzw, xyzw, xyzw);
5438 }
5439
5440 Int4::Int4(int x, int yzw)
5441 {
5442 constant(x, yzw, yzw, yzw);
5443 }
5444
5445 Int4::Int4(int x, int y, int zw)
5446 {
5447 constant(x, y, zw, zw);
5448 }
5449
5450 Int4::Int4(int x, int y, int z, int w)
5451 {
5452 constant(x, y, z, w);
5453 }
5454
5455 void Int4::constant(int x, int y, int z, int w)
5456 {
5457 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005458
5459 Constant *constantVector[4];
5460 constantVector[0] = Nucleus::createConstantInt(x);
5461 constantVector[1] = Nucleus::createConstantInt(y);
5462 constantVector[2] = Nucleus::createConstantInt(z);
5463 constantVector[3] = Nucleus::createConstantInt(w);
5464
John Bauman66b8ab22014-05-06 15:57:45 -04005465 storeValue(Nucleus::createConstantVector(constantVector, 4));
John Bauman89401822014-05-06 15:04:28 -04005466 }
5467
John Bauman19bac1e2014-05-06 15:23:49 -04005468 Int4::Int4(RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005469 {
5470 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005471
John Bauman66b8ab22014-05-06 15:57:45 -04005472 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005473 }
5474
5475 Int4::Int4(const Int4 &rhs)
5476 {
5477 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005478
John Bauman66b8ab22014-05-06 15:57:45 -04005479 Value *value = rhs.loadValue();
5480 storeValue(value);
5481 }
5482
5483 Int4::Int4(const Reference<Int4> &rhs)
5484 {
5485 // xyzw.parent = this;
5486
5487 Value *value = rhs.loadValue();
5488 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005489 }
5490
John Bauman19bac1e2014-05-06 15:23:49 -04005491 Int4::Int4(RValue<UInt4> rhs)
5492 {
5493 // xyzw.parent = this;
John Bauman19bac1e2014-05-06 15:23:49 -04005494
John Bauman66b8ab22014-05-06 15:57:45 -04005495 storeValue(rhs.value);
John Bauman19bac1e2014-05-06 15:23:49 -04005496 }
5497
5498 Int4::Int4(const UInt4 &rhs)
5499 {
5500 // xyzw.parent = this;
John Bauman19bac1e2014-05-06 15:23:49 -04005501
John Bauman66b8ab22014-05-06 15:57:45 -04005502 Value *value = rhs.loadValue();
5503 storeValue(value);
5504 }
5505
5506 Int4::Int4(const Reference<UInt4> &rhs)
5507 {
5508 // xyzw.parent = this;
5509
5510 Value *value = rhs.loadValue();
5511 storeValue(value);
John Bauman19bac1e2014-05-06 15:23:49 -04005512 }
5513
Nicolas Capens62abb552016-01-05 12:03:47 -05005514 Int4::Int4(RValue<Int2> lo, RValue<Int2> hi)
5515 {
Nicolas Capens24c8cf02016-08-15 15:33:14 -04005516 // xyzw.parent = this;
5517
Nicolas Capens62abb552016-01-05 12:03:47 -05005518 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
5519 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
5520
5521 Value *long2 = UndefValue::get(Long2::getType());
5522 long2 = Nucleus::createInsertElement(long2, loLong, 0);
5523 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
5524 Value *int4 = Nucleus::createBitCast(long2, Int4::getType());
5525
5526 storeValue(int4);
5527 }
5528
Nicolas Capens24c8cf02016-08-15 15:33:14 -04005529 Int4::Int4(RValue<Int> rhs)
5530 {
5531 // xyzw.parent = this;
5532
5533 Value *vector = loadValue();
5534 Value *insert = Nucleus::createInsertElement(vector, rhs.value, 0);
5535
5536 Constant *swizzle[4];
5537 swizzle[0] = Nucleus::createConstantInt(0);
5538 swizzle[1] = Nucleus::createConstantInt(0);
5539 swizzle[2] = Nucleus::createConstantInt(0);
5540 swizzle[3] = Nucleus::createConstantInt(0);
5541
5542 Value *replicate = Nucleus::createShuffleVector(insert, UndefValue::get(Int4::getType()), Nucleus::createConstantVector(swizzle, 4));
5543
5544 storeValue(replicate);
5545 }
5546
5547 Int4::Int4(const Int &rhs)
5548 {
5549 // xyzw.parent = this;
5550
5551 *this = RValue<Int>(rhs.loadValue());
5552 }
5553
5554 Int4::Int4(const Reference<Int> &rhs)
5555 {
5556 // xyzw.parent = this;
5557
5558 *this = RValue<Int>(rhs.loadValue());
5559 }
5560
John Bauman19bac1e2014-05-06 15:23:49 -04005561 RValue<Int4> Int4::operator=(RValue<Int4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04005562 {
John Bauman66b8ab22014-05-06 15:57:45 -04005563 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005564
5565 return rhs;
5566 }
5567
5568 RValue<Int4> Int4::operator=(const Int4 &rhs) const
5569 {
John Bauman66b8ab22014-05-06 15:57:45 -04005570 Value *value = rhs.loadValue();
5571 storeValue(value);
5572
5573 return RValue<Int4>(value);
5574 }
5575
5576 RValue<Int4> Int4::operator=(const Reference<Int4> &rhs) const
5577 {
5578 Value *value = rhs.loadValue();
5579 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005580
5581 return RValue<Int4>(value);
5582 }
5583
John Bauman19bac1e2014-05-06 15:23:49 -04005584 RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005585 {
5586 return RValue<Int4>(Nucleus::createAdd(lhs.value, rhs.value));
5587 }
5588
John Bauman19bac1e2014-05-06 15:23:49 -04005589 RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005590 {
5591 return RValue<Int4>(Nucleus::createSub(lhs.value, rhs.value));
5592 }
5593
John Bauman19bac1e2014-05-06 15:23:49 -04005594 RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005595 {
5596 return RValue<Int4>(Nucleus::createMul(lhs.value, rhs.value));
5597 }
5598
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005599 RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs)
5600 {
5601 return RValue<Int4>(Nucleus::createSDiv(lhs.value, rhs.value));
5602 }
John Bauman89401822014-05-06 15:04:28 -04005603
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005604 RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs)
5605 {
5606 return RValue<Int4>(Nucleus::createSRem(lhs.value, rhs.value));
5607 }
John Bauman89401822014-05-06 15:04:28 -04005608
John Bauman19bac1e2014-05-06 15:23:49 -04005609 RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005610 {
5611 return RValue<Int4>(Nucleus::createAnd(lhs.value, rhs.value));
5612 }
5613
John Bauman19bac1e2014-05-06 15:23:49 -04005614 RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005615 {
5616 return RValue<Int4>(Nucleus::createOr(lhs.value, rhs.value));
5617 }
5618
John Bauman19bac1e2014-05-06 15:23:49 -04005619 RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005620 {
5621 return RValue<Int4>(Nucleus::createXor(lhs.value, rhs.value));
5622 }
5623
John Bauman19bac1e2014-05-06 15:23:49 -04005624 RValue<Int4> operator<<(RValue<Int4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005625 {
John Bauman89401822014-05-06 15:04:28 -04005626 return x86::pslld(lhs, rhs);
5627 }
5628
John Bauman19bac1e2014-05-06 15:23:49 -04005629 RValue<Int4> operator>>(RValue<Int4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005630 {
John Bauman89401822014-05-06 15:04:28 -04005631 return x86::psrad(lhs, rhs);
5632 }
5633
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005634 RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs)
5635 {
5636 return RValue<Int4>(Nucleus::createShl(lhs.value, rhs.value));
5637 }
5638
5639 RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs)
5640 {
5641 return RValue<Int4>(Nucleus::createAShr(lhs.value, rhs.value));
5642 }
5643
John Bauman19bac1e2014-05-06 15:23:49 -04005644 RValue<Int4> operator+=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005645 {
5646 return lhs = lhs + rhs;
5647 }
5648
John Bauman19bac1e2014-05-06 15:23:49 -04005649 RValue<Int4> operator-=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005650 {
5651 return lhs = lhs - rhs;
5652 }
5653
John Bauman19bac1e2014-05-06 15:23:49 -04005654 RValue<Int4> operator*=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005655 {
5656 return lhs = lhs * rhs;
5657 }
5658
John Bauman19bac1e2014-05-06 15:23:49 -04005659// RValue<Int4> operator/=(const Int4 &lhs, RValue<Int4> rhs)
5660// {
5661// return lhs = lhs / rhs;
5662// }
John Bauman89401822014-05-06 15:04:28 -04005663
John Bauman19bac1e2014-05-06 15:23:49 -04005664// RValue<Int4> operator%=(const Int4 &lhs, RValue<Int4> rhs)
5665// {
5666// return lhs = lhs % rhs;
5667// }
John Bauman89401822014-05-06 15:04:28 -04005668
John Bauman19bac1e2014-05-06 15:23:49 -04005669 RValue<Int4> operator&=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005670 {
5671 return lhs = lhs & rhs;
5672 }
5673
John Bauman19bac1e2014-05-06 15:23:49 -04005674 RValue<Int4> operator|=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005675 {
5676 return lhs = lhs | rhs;
5677 }
5678
John Bauman19bac1e2014-05-06 15:23:49 -04005679 RValue<Int4> operator^=(const Int4 &lhs, RValue<Int4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005680 {
5681 return lhs = lhs ^ rhs;
5682 }
5683
5684 RValue<Int4> operator<<=(const Int4 &lhs, unsigned char rhs)
5685 {
5686 return lhs = lhs << rhs;
5687 }
5688
5689 RValue<Int4> operator>>=(const Int4 &lhs, unsigned char rhs)
5690 {
5691 return lhs = lhs >> rhs;
5692 }
5693
John Bauman19bac1e2014-05-06 15:23:49 -04005694 RValue<Int4> operator+(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005695 {
5696 return val;
5697 }
5698
John Bauman19bac1e2014-05-06 15:23:49 -04005699 RValue<Int4> operator-(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005700 {
5701 return RValue<Int4>(Nucleus::createNeg(val.value));
5702 }
5703
John Bauman19bac1e2014-05-06 15:23:49 -04005704 RValue<Int4> operator~(RValue<Int4> val)
John Bauman89401822014-05-06 15:04:28 -04005705 {
5706 return RValue<Int4>(Nucleus::createNot(val.value));
5707 }
5708
John Bauman19bac1e2014-05-06 15:23:49 -04005709 RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y)
5710 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005711 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
Alexis Hetufb603992016-04-26 11:50:40 -04005712 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5713 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
5714 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005715 }
5716
5717 RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y)
5718 {
5719 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLT(x.value, y.value), Int4::getType()));
5720 }
5721
5722 RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y)
5723 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005724 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5725 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5726 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLE(x.value, y.value), Int4::getType()));
5727 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGT(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005728 }
5729
5730 RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y)
5731 {
5732 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
5733 }
5734
5735 RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y)
5736 {
Nicolas Capens197226a2016-04-27 23:08:50 -04005737 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
5738 // Restore the following line when LLVM is updated to a version where this issue is fixed.
5739 // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGE(x.value, y.value), Int4::getType()));
5740 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLT(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04005741 }
5742
5743 RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y)
5744 {
5745 return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGT(x.value, y.value), Int4::getType()));
5746 }
5747
5748 RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y)
5749 {
5750 if(CPUID::supportsSSE4_1())
5751 {
5752 return x86::pmaxsd(x, y);
5753 }
5754 else
5755 {
5756 RValue<Int4> greater = CmpNLE(x, y);
5757 return x & greater | y & ~greater;
5758 }
5759 }
5760
5761 RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y)
5762 {
5763 if(CPUID::supportsSSE4_1())
5764 {
5765 return x86::pminsd(x, y);
5766 }
5767 else
5768 {
5769 RValue<Int4> less = CmpLT(x, y);
5770 return x & less | y & ~less;
5771 }
5772 }
5773
5774 RValue<Int4> RoundInt(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005775 {
5776 return x86::cvtps2dq(cast);
5777 }
5778
John Bauman19bac1e2014-05-06 15:23:49 -04005779 RValue<Short8> Pack(RValue<Int4> x, RValue<Int4> y)
John Bauman89401822014-05-06 15:04:28 -04005780 {
5781 return x86::packssdw(x, y);
5782 }
5783
John Bauman19bac1e2014-05-06 15:23:49 -04005784 RValue<Int> Extract(RValue<Int4> x, int i)
John Bauman89401822014-05-06 15:04:28 -04005785 {
5786 return RValue<Int>(Nucleus::createExtractElement(x.value, i));
5787 }
5788
John Bauman19bac1e2014-05-06 15:23:49 -04005789 RValue<Int4> Insert(RValue<Int4> x, RValue<Int> element, int i)
John Bauman89401822014-05-06 15:04:28 -04005790 {
5791 return RValue<Int4>(Nucleus::createInsertElement(x.value, element.value, i));
5792 }
5793
John Bauman19bac1e2014-05-06 15:23:49 -04005794 RValue<Int> SignMask(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04005795 {
5796 return x86::movmskps(As<Float4>(x));
5797 }
5798
John Bauman19bac1e2014-05-06 15:23:49 -04005799 RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04005800 {
5801 return RValue<Int4>(Nucleus::createSwizzle(x.value, select));
5802 }
5803
John Bauman19bac1e2014-05-06 15:23:49 -04005804 Type *Int4::getType()
John Bauman89401822014-05-06 15:04:28 -04005805 {
5806 return VectorType::get(Int::getType(), 4);
5807 }
5808
John Bauman19bac1e2014-05-06 15:23:49 -04005809 UInt4::UInt4(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04005810 {
5811 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005812
Alexis Hetu764d1422016-09-28 08:44:22 -04005813 // Note: createFPToUI is broken, must perform conversion using createFPtoSI
5814 // Value *xyzw = Nucleus::createFPToUI(cast.value, UInt4::getType());
John Bauman89401822014-05-06 15:04:28 -04005815
Alexis Hetu764d1422016-09-28 08:44:22 -04005816 // Smallest positive value representable in UInt, but not in Int
5817 const unsigned int ustart = 0x80000000u;
5818 const float ustartf = float(ustart);
5819
5820 // Check if the value can be represented as an Int
5821 Int4 uiValue = CmpNLT(cast, Float4(ustartf));
5822 // If the value is too large, subtract ustart and re-add it after conversion.
5823 uiValue = (uiValue & As<Int4>(As<UInt4>(Int4(cast - Float4(ustartf))) + UInt4(ustart))) |
5824 // Otherwise, just convert normally
5825 (~uiValue & Int4(cast));
5826 // If the value is negative, store 0, otherwise store the result of the conversion
5827 storeValue((~(As<Int4>(cast) >> 31) & uiValue).value);
John Bauman89401822014-05-06 15:04:28 -04005828 }
5829
5830 UInt4::UInt4()
5831 {
5832 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005833 }
5834
John Bauman19bac1e2014-05-06 15:23:49 -04005835 UInt4::UInt4(int xyzw)
5836 {
5837 constant(xyzw, xyzw, xyzw, xyzw);
5838 }
5839
5840 UInt4::UInt4(int x, int yzw)
5841 {
5842 constant(x, yzw, yzw, yzw);
5843 }
5844
5845 UInt4::UInt4(int x, int y, int zw)
5846 {
5847 constant(x, y, zw, zw);
5848 }
5849
5850 UInt4::UInt4(int x, int y, int z, int w)
5851 {
5852 constant(x, y, z, w);
5853 }
5854
5855 void UInt4::constant(int x, int y, int z, int w)
John Bauman89401822014-05-06 15:04:28 -04005856 {
5857 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005858
5859 Constant *constantVector[4];
5860 constantVector[0] = Nucleus::createConstantInt(x);
5861 constantVector[1] = Nucleus::createConstantInt(y);
5862 constantVector[2] = Nucleus::createConstantInt(z);
5863 constantVector[3] = Nucleus::createConstantInt(w);
5864
John Bauman66b8ab22014-05-06 15:57:45 -04005865 storeValue(Nucleus::createConstantVector(constantVector, 4));
John Bauman89401822014-05-06 15:04:28 -04005866 }
5867
John Bauman19bac1e2014-05-06 15:23:49 -04005868 UInt4::UInt4(RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005869 {
5870 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005871
John Bauman66b8ab22014-05-06 15:57:45 -04005872 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005873 }
5874
5875 UInt4::UInt4(const UInt4 &rhs)
5876 {
5877 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04005878
John Bauman66b8ab22014-05-06 15:57:45 -04005879 Value *value = rhs.loadValue();
5880 storeValue(value);
5881 }
5882
5883 UInt4::UInt4(const Reference<UInt4> &rhs)
5884 {
5885 // xyzw.parent = this;
5886
5887 Value *value = rhs.loadValue();
5888 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005889 }
5890
John Bauman19bac1e2014-05-06 15:23:49 -04005891 UInt4::UInt4(RValue<Int4> rhs)
5892 {
5893 // xyzw.parent = this;
John Bauman19bac1e2014-05-06 15:23:49 -04005894
John Bauman66b8ab22014-05-06 15:57:45 -04005895 storeValue(rhs.value);
John Bauman19bac1e2014-05-06 15:23:49 -04005896 }
5897
5898 UInt4::UInt4(const Int4 &rhs)
5899 {
5900 // xyzw.parent = this;
John Bauman19bac1e2014-05-06 15:23:49 -04005901
John Bauman66b8ab22014-05-06 15:57:45 -04005902 Value *value = rhs.loadValue();
5903 storeValue(value);
5904 }
5905
5906 UInt4::UInt4(const Reference<Int4> &rhs)
5907 {
5908 // xyzw.parent = this;
5909
5910 Value *value = rhs.loadValue();
5911 storeValue(value);
John Bauman19bac1e2014-05-06 15:23:49 -04005912 }
5913
Nicolas Capens62abb552016-01-05 12:03:47 -05005914 UInt4::UInt4(RValue<UInt2> lo, RValue<UInt2> hi)
5915 {
5916 Value *loLong = Nucleus::createBitCast(lo.value, Long::getType());
5917 Value *hiLong = Nucleus::createBitCast(hi.value, Long::getType());
5918
5919 Value *long2 = UndefValue::get(Long2::getType());
5920 long2 = Nucleus::createInsertElement(long2, loLong, 0);
5921 long2 = Nucleus::createInsertElement(long2, hiLong, 1);
5922 Value *uint4 = Nucleus::createBitCast(long2, Int4::getType());
5923
5924 storeValue(uint4);
5925 }
5926
John Bauman19bac1e2014-05-06 15:23:49 -04005927 RValue<UInt4> UInt4::operator=(RValue<UInt4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04005928 {
John Bauman66b8ab22014-05-06 15:57:45 -04005929 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04005930
5931 return rhs;
5932 }
5933
5934 RValue<UInt4> UInt4::operator=(const UInt4 &rhs) const
5935 {
John Bauman66b8ab22014-05-06 15:57:45 -04005936 Value *value = rhs.loadValue();
5937 storeValue(value);
5938
5939 return RValue<UInt4>(value);
5940 }
5941
5942 RValue<UInt4> UInt4::operator=(const Reference<UInt4> &rhs) const
5943 {
5944 Value *value = rhs.loadValue();
5945 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04005946
5947 return RValue<UInt4>(value);
5948 }
5949
John Bauman19bac1e2014-05-06 15:23:49 -04005950 RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005951 {
5952 return RValue<UInt4>(Nucleus::createAdd(lhs.value, rhs.value));
5953 }
5954
John Bauman19bac1e2014-05-06 15:23:49 -04005955 RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005956 {
5957 return RValue<UInt4>(Nucleus::createSub(lhs.value, rhs.value));
5958 }
5959
John Bauman19bac1e2014-05-06 15:23:49 -04005960 RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005961 {
5962 return RValue<UInt4>(Nucleus::createMul(lhs.value, rhs.value));
5963 }
5964
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005965 RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs)
5966 {
5967 return RValue<UInt4>(Nucleus::createUDiv(lhs.value, rhs.value));
5968 }
John Bauman89401822014-05-06 15:04:28 -04005969
Alexis Hetud9d27bb2015-08-18 15:22:15 -04005970 RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs)
5971 {
5972 return RValue<UInt4>(Nucleus::createURem(lhs.value, rhs.value));
5973 }
John Bauman89401822014-05-06 15:04:28 -04005974
John Bauman19bac1e2014-05-06 15:23:49 -04005975 RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005976 {
5977 return RValue<UInt4>(Nucleus::createAnd(lhs.value, rhs.value));
5978 }
5979
John Bauman19bac1e2014-05-06 15:23:49 -04005980 RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005981 {
5982 return RValue<UInt4>(Nucleus::createOr(lhs.value, rhs.value));
5983 }
5984
John Bauman19bac1e2014-05-06 15:23:49 -04005985 RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04005986 {
5987 return RValue<UInt4>(Nucleus::createXor(lhs.value, rhs.value));
5988 }
5989
John Bauman19bac1e2014-05-06 15:23:49 -04005990 RValue<UInt4> operator<<(RValue<UInt4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005991 {
John Bauman89401822014-05-06 15:04:28 -04005992 return As<UInt4>(x86::pslld(As<Int4>(lhs), rhs));
5993 }
5994
John Bauman19bac1e2014-05-06 15:23:49 -04005995 RValue<UInt4> operator>>(RValue<UInt4> lhs, unsigned char rhs)
John Bauman89401822014-05-06 15:04:28 -04005996 {
John Bauman89401822014-05-06 15:04:28 -04005997 return x86::psrld(lhs, rhs);
5998 }
5999
Alexis Hetud9d27bb2015-08-18 15:22:15 -04006000 RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs)
6001 {
6002 return RValue<UInt4>(Nucleus::createShl(lhs.value, rhs.value));
6003 }
6004
6005 RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs)
6006 {
6007 return RValue<UInt4>(Nucleus::createLShr(lhs.value, rhs.value));
6008 }
6009
John Bauman19bac1e2014-05-06 15:23:49 -04006010 RValue<UInt4> operator+=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006011 {
6012 return lhs = lhs + rhs;
6013 }
6014
John Bauman19bac1e2014-05-06 15:23:49 -04006015 RValue<UInt4> operator-=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006016 {
6017 return lhs = lhs - rhs;
6018 }
6019
John Bauman19bac1e2014-05-06 15:23:49 -04006020 RValue<UInt4> operator*=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006021 {
6022 return lhs = lhs * rhs;
6023 }
6024
John Bauman19bac1e2014-05-06 15:23:49 -04006025// RValue<UInt4> operator/=(const UInt4 &lhs, RValue<UInt4> rhs)
6026// {
6027// return lhs = lhs / rhs;
6028// }
John Bauman89401822014-05-06 15:04:28 -04006029
John Bauman19bac1e2014-05-06 15:23:49 -04006030// RValue<UInt4> operator%=(const UInt4 &lhs, RValue<UInt4> rhs)
6031// {
6032// return lhs = lhs % rhs;
6033// }
John Bauman89401822014-05-06 15:04:28 -04006034
John Bauman19bac1e2014-05-06 15:23:49 -04006035 RValue<UInt4> operator&=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006036 {
6037 return lhs = lhs & rhs;
6038 }
6039
John Bauman19bac1e2014-05-06 15:23:49 -04006040 RValue<UInt4> operator|=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006041 {
6042 return lhs = lhs | rhs;
6043 }
6044
John Bauman19bac1e2014-05-06 15:23:49 -04006045 RValue<UInt4> operator^=(const UInt4 &lhs, RValue<UInt4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006046 {
6047 return lhs = lhs ^ rhs;
6048 }
6049
6050 RValue<UInt4> operator<<=(const UInt4 &lhs, unsigned char rhs)
6051 {
6052 return lhs = lhs << rhs;
6053 }
6054
6055 RValue<UInt4> operator>>=(const UInt4 &lhs, unsigned char rhs)
6056 {
6057 return lhs = lhs >> rhs;
6058 }
6059
John Bauman19bac1e2014-05-06 15:23:49 -04006060 RValue<UInt4> operator+(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04006061 {
6062 return val;
6063 }
6064
John Bauman19bac1e2014-05-06 15:23:49 -04006065 RValue<UInt4> operator-(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04006066 {
6067 return RValue<UInt4>(Nucleus::createNeg(val.value));
6068 }
6069
John Bauman19bac1e2014-05-06 15:23:49 -04006070 RValue<UInt4> operator~(RValue<UInt4> val)
John Bauman89401822014-05-06 15:04:28 -04006071 {
6072 return RValue<UInt4>(Nucleus::createNot(val.value));
6073 }
6074
John Bauman19bac1e2014-05-06 15:23:49 -04006075 RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y)
6076 {
Nicolas Capens197226a2016-04-27 23:08:50 -04006077 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
Alexis Hetufb603992016-04-26 11:50:40 -04006078 // Restore the following line when LLVM is updated to a version where this issue is fixed.
6079 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
6080 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04006081 }
6082
6083 RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y)
6084 {
6085 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULT(x.value, y.value), Int4::getType()));
6086 }
6087
6088 RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y)
6089 {
Nicolas Capens197226a2016-04-27 23:08:50 -04006090 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
6091 // Restore the following line when LLVM is updated to a version where this issue is fixed.
6092 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULE(x.value, y.value), Int4::getType()));
6093 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGT(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04006094 }
6095
6096 RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y)
6097 {
6098 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
6099 }
6100
6101 RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y)
6102 {
Nicolas Capens197226a2016-04-27 23:08:50 -04006103 // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
6104 // Restore the following line when LLVM is updated to a version where this issue is fixed.
6105 // return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGE(x.value, y.value), Int4::getType()));
6106 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULT(x.value, y.value), Int4::getType())) ^ UInt4(0xFFFFFFFF);
John Bauman19bac1e2014-05-06 15:23:49 -04006107 }
6108
6109 RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y)
6110 {
6111 return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGT(x.value, y.value), Int4::getType()));
6112 }
6113
6114 RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y)
6115 {
6116 if(CPUID::supportsSSE4_1())
6117 {
6118 return x86::pmaxud(x, y);
6119 }
6120 else
6121 {
6122 RValue<UInt4> greater = CmpNLE(x, y);
6123 return x & greater | y & ~greater;
6124 }
6125 }
6126
6127 RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y)
6128 {
6129 if(CPUID::supportsSSE4_1())
6130 {
6131 return x86::pminud(x, y);
6132 }
6133 else
6134 {
6135 RValue<UInt4> less = CmpLT(x, y);
6136 return x & less | y & ~less;
6137 }
6138 }
6139
6140 RValue<UShort8> Pack(RValue<UInt4> x, RValue<UInt4> y)
John Bauman89401822014-05-06 15:04:28 -04006141 {
6142 return x86::packusdw(x, y); // FIXME: Fallback required
6143 }
6144
John Bauman19bac1e2014-05-06 15:23:49 -04006145 Type *UInt4::getType()
John Bauman89401822014-05-06 15:04:28 -04006146 {
6147 return VectorType::get(UInt::getType(), 4);
6148 }
6149
John Bauman19bac1e2014-05-06 15:23:49 -04006150 Float::Float(RValue<Int> cast)
John Bauman89401822014-05-06 15:04:28 -04006151 {
John Bauman89401822014-05-06 15:04:28 -04006152 Value *integer = Nucleus::createSIToFP(cast.value, Float::getType());
6153
John Bauman66b8ab22014-05-06 15:57:45 -04006154 storeValue(integer);
John Bauman89401822014-05-06 15:04:28 -04006155 }
6156
6157 Float::Float()
6158 {
John Bauman66b8ab22014-05-06 15:57:45 -04006159
John Bauman89401822014-05-06 15:04:28 -04006160 }
6161
6162 Float::Float(float x)
6163 {
John Bauman66b8ab22014-05-06 15:57:45 -04006164 storeValue(Nucleus::createConstantFloat(x));
John Bauman89401822014-05-06 15:04:28 -04006165 }
6166
John Bauman19bac1e2014-05-06 15:23:49 -04006167 Float::Float(RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006168 {
John Bauman66b8ab22014-05-06 15:57:45 -04006169 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04006170 }
6171
6172 Float::Float(const Float &rhs)
6173 {
John Bauman66b8ab22014-05-06 15:57:45 -04006174 Value *value = rhs.loadValue();
6175 storeValue(value);
6176 }
John Bauman89401822014-05-06 15:04:28 -04006177
John Bauman66b8ab22014-05-06 15:57:45 -04006178 Float::Float(const Reference<Float> &rhs)
6179 {
6180 Value *value = rhs.loadValue();
6181 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04006182 }
6183
John Bauman19bac1e2014-05-06 15:23:49 -04006184 RValue<Float> Float::operator=(RValue<Float> rhs) const
John Bauman89401822014-05-06 15:04:28 -04006185 {
John Bauman66b8ab22014-05-06 15:57:45 -04006186 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04006187
6188 return rhs;
6189 }
6190
6191 RValue<Float> Float::operator=(const Float &rhs) const
6192 {
John Bauman66b8ab22014-05-06 15:57:45 -04006193 Value *value = rhs.loadValue();
6194 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04006195
6196 return RValue<Float>(value);
6197 }
6198
John Bauman66b8ab22014-05-06 15:57:45 -04006199 RValue<Float> Float::operator=(const Reference<Float> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04006200 {
John Bauman66b8ab22014-05-06 15:57:45 -04006201 Value *value = rhs.loadValue();
6202 storeValue(value);
6203
6204 return RValue<Float>(value);
John Bauman89401822014-05-06 15:04:28 -04006205 }
6206
John Bauman19bac1e2014-05-06 15:23:49 -04006207 RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006208 {
6209 return RValue<Float>(Nucleus::createFAdd(lhs.value, rhs.value));
6210 }
6211
John Bauman19bac1e2014-05-06 15:23:49 -04006212 RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006213 {
6214 return RValue<Float>(Nucleus::createFSub(lhs.value, rhs.value));
6215 }
6216
John Bauman19bac1e2014-05-06 15:23:49 -04006217 RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006218 {
6219 return RValue<Float>(Nucleus::createFMul(lhs.value, rhs.value));
6220 }
6221
John Bauman19bac1e2014-05-06 15:23:49 -04006222 RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006223 {
6224 return RValue<Float>(Nucleus::createFDiv(lhs.value, rhs.value));
6225 }
6226
John Bauman19bac1e2014-05-06 15:23:49 -04006227 RValue<Float> operator+=(const Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006228 {
6229 return lhs = lhs + rhs;
6230 }
6231
John Bauman19bac1e2014-05-06 15:23:49 -04006232 RValue<Float> operator-=(const Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006233 {
6234 return lhs = lhs - rhs;
6235 }
6236
John Bauman19bac1e2014-05-06 15:23:49 -04006237 RValue<Float> operator*=(const Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006238 {
6239 return lhs = lhs * rhs;
6240 }
6241
John Bauman19bac1e2014-05-06 15:23:49 -04006242 RValue<Float> operator/=(const Float &lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006243 {
6244 return lhs = lhs / rhs;
6245 }
6246
John Bauman19bac1e2014-05-06 15:23:49 -04006247 RValue<Float> operator+(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006248 {
6249 return val;
6250 }
6251
John Bauman19bac1e2014-05-06 15:23:49 -04006252 RValue<Float> operator-(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04006253 {
6254 return RValue<Float>(Nucleus::createFNeg(val.value));
6255 }
6256
John Bauman19bac1e2014-05-06 15:23:49 -04006257 RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006258 {
6259 return RValue<Bool>(Nucleus::createFCmpOLT(lhs.value, rhs.value));
6260 }
6261
John Bauman19bac1e2014-05-06 15:23:49 -04006262 RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006263 {
6264 return RValue<Bool>(Nucleus::createFCmpOLE(lhs.value, rhs.value));
6265 }
6266
John Bauman19bac1e2014-05-06 15:23:49 -04006267 RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006268 {
6269 return RValue<Bool>(Nucleus::createFCmpOGT(lhs.value, rhs.value));
6270 }
6271
John Bauman19bac1e2014-05-06 15:23:49 -04006272 RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006273 {
6274 return RValue<Bool>(Nucleus::createFCmpOGE(lhs.value, rhs.value));
6275 }
6276
John Bauman19bac1e2014-05-06 15:23:49 -04006277 RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006278 {
6279 return RValue<Bool>(Nucleus::createFCmpONE(lhs.value, rhs.value));
6280 }
6281
John Bauman19bac1e2014-05-06 15:23:49 -04006282 RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006283 {
6284 return RValue<Bool>(Nucleus::createFCmpOEQ(lhs.value, rhs.value));
6285 }
6286
John Bauman19bac1e2014-05-06 15:23:49 -04006287 RValue<Float> Abs(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006288 {
John Bauman66b8ab22014-05-06 15:57:45 -04006289 return IfThenElse(x > 0.0f, x, -x);
John Bauman89401822014-05-06 15:04:28 -04006290 }
6291
John Bauman19bac1e2014-05-06 15:23:49 -04006292 RValue<Float> Max(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006293 {
6294 return IfThenElse(x > y, x, y);
6295 }
6296
John Bauman19bac1e2014-05-06 15:23:49 -04006297 RValue<Float> Min(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04006298 {
6299 return IfThenElse(x < y, x, y);
6300 }
6301
Nicolas Capens05b3d662016-02-25 23:58:33 -05006302 RValue<Float> Rcp_pp(RValue<Float> x, bool exactAtPow2)
John Bauman89401822014-05-06 15:04:28 -04006303 {
Nicolas Capens05b3d662016-02-25 23:58:33 -05006304 if(exactAtPow2)
6305 {
6306 // rcpss uses a piecewise-linear approximation which minimizes the relative error
6307 // but is not exact at power-of-two values. Rectify by multiplying by the inverse.
6308 return x86::rcpss(x) * Float(1.0f / _mm_cvtss_f32(_mm_rcp_ss(_mm_set_ps1(1.0f))));
6309 }
6310 else
6311 {
6312 return x86::rcpss(x);
6313 }
John Bauman89401822014-05-06 15:04:28 -04006314 }
John Bauman66b8ab22014-05-06 15:57:45 -04006315
John Bauman19bac1e2014-05-06 15:23:49 -04006316 RValue<Float> RcpSqrt_pp(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006317 {
6318 return x86::rsqrtss(x);
6319 }
6320
John Bauman19bac1e2014-05-06 15:23:49 -04006321 RValue<Float> Sqrt(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006322 {
6323 return x86::sqrtss(x);
6324 }
6325
John Bauman19bac1e2014-05-06 15:23:49 -04006326 RValue<Float> Round(RValue<Float> x)
6327 {
6328 if(CPUID::supportsSSE4_1())
6329 {
6330 return x86::roundss(x, 0);
6331 }
6332 else
6333 {
6334 return Float4(Round(Float4(x))).x;
6335 }
6336 }
6337
6338 RValue<Float> Trunc(RValue<Float> x)
6339 {
6340 if(CPUID::supportsSSE4_1())
6341 {
6342 return x86::roundss(x, 3);
6343 }
6344 else
6345 {
6346 return Float(Int(x)); // Rounded toward zero
6347 }
6348 }
6349
6350 RValue<Float> Frac(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006351 {
6352 if(CPUID::supportsSSE4_1())
6353 {
6354 return x - x86::floorss(x);
6355 }
6356 else
6357 {
John Bauman19bac1e2014-05-06 15:23:49 -04006358 return Float4(Frac(Float4(x))).x;
John Bauman89401822014-05-06 15:04:28 -04006359 }
6360 }
6361
John Bauman19bac1e2014-05-06 15:23:49 -04006362 RValue<Float> Floor(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006363 {
6364 if(CPUID::supportsSSE4_1())
6365 {
6366 return x86::floorss(x);
6367 }
6368 else
6369 {
6370 return Float4(Floor(Float4(x))).x;
6371 }
6372 }
6373
John Bauman19bac1e2014-05-06 15:23:49 -04006374 RValue<Float> Ceil(RValue<Float> x)
John Bauman89401822014-05-06 15:04:28 -04006375 {
John Bauman19bac1e2014-05-06 15:23:49 -04006376 if(CPUID::supportsSSE4_1())
6377 {
6378 return x86::ceilss(x);
6379 }
6380 else
6381 {
6382 return Float4(Ceil(Float4(x))).x;
6383 }
John Bauman89401822014-05-06 15:04:28 -04006384 }
6385
John Bauman19bac1e2014-05-06 15:23:49 -04006386 Type *Float::getType()
John Bauman89401822014-05-06 15:04:28 -04006387 {
6388 return Type::getFloatTy(*Nucleus::getContext());
6389 }
6390
John Bauman19bac1e2014-05-06 15:23:49 -04006391 Float2::Float2(RValue<Float4> cast)
John Bauman89401822014-05-06 15:04:28 -04006392 {
6393 // xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006394
6395 Value *int64x2 = Nucleus::createBitCast(cast.value, Long2::getType());
6396 Value *int64 = Nucleus::createExtractElement(int64x2, 0);
6397 Value *float2 = Nucleus::createBitCast(int64, Float2::getType());
6398
John Bauman66b8ab22014-05-06 15:57:45 -04006399 storeValue(float2);
John Bauman89401822014-05-06 15:04:28 -04006400 }
6401
John Bauman19bac1e2014-05-06 15:23:49 -04006402 Type *Float2::getType()
John Bauman89401822014-05-06 15:04:28 -04006403 {
6404 return VectorType::get(Float::getType(), 2);
6405 }
6406
John Bauman19bac1e2014-05-06 15:23:49 -04006407 Float4::Float4(RValue<Byte4> cast)
John Bauman89401822014-05-06 15:04:28 -04006408 {
6409 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006410
6411 #if 0
6412 Value *xyzw = Nucleus::createUIToFP(cast.value, Float4::getType()); // FIXME: Crashes
6413 #elif 0
John Bauman66b8ab22014-05-06 15:57:45 -04006414 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04006415
6416 Value *i8x = Nucleus::createExtractElement(cast.value, 0);
6417 Value *f32x = Nucleus::createUIToFP(i8x, Float::getType());
6418 Value *x = Nucleus::createInsertElement(vector, f32x, 0);
6419
6420 Value *i8y = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(1));
6421 Value *f32y = Nucleus::createUIToFP(i8y, Float::getType());
6422 Value *xy = Nucleus::createInsertElement(x, f32y, Nucleus::createConstantInt(1));
6423
6424 Value *i8z = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(2));
6425 Value *f32z = Nucleus::createUIToFP(i8z, Float::getType());
6426 Value *xyz = Nucleus::createInsertElement(xy, f32z, Nucleus::createConstantInt(2));
6427
6428 Value *i8w = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(3));
6429 Value *f32w = Nucleus::createUIToFP(i8w, Float::getType());
6430 Value *xyzw = Nucleus::createInsertElement(xyz, f32w, Nucleus::createConstantInt(3));
6431 #else
Meng-Lin Wu601d0052016-06-10 14:18:41 -04006432 Value *a = Int4(cast).loadValue();
6433 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04006434 #endif
John Bauman66b8ab22014-05-06 15:57:45 -04006435
6436 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04006437 }
6438
John Bauman19bac1e2014-05-06 15:23:49 -04006439 Float4::Float4(RValue<SByte4> cast)
John Bauman89401822014-05-06 15:04:28 -04006440 {
6441 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006442
6443 #if 0
6444 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType()); // FIXME: Crashes
6445 #elif 0
John Bauman66b8ab22014-05-06 15:57:45 -04006446 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04006447
6448 Value *i8x = Nucleus::createExtractElement(cast.value, 0);
6449 Value *f32x = Nucleus::createSIToFP(i8x, Float::getType());
6450 Value *x = Nucleus::createInsertElement(vector, f32x, 0);
6451
6452 Value *i8y = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(1));
6453 Value *f32y = Nucleus::createSIToFP(i8y, Float::getType());
6454 Value *xy = Nucleus::createInsertElement(x, f32y, Nucleus::createConstantInt(1));
6455
6456 Value *i8z = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(2));
6457 Value *f32z = Nucleus::createSIToFP(i8z, Float::getType());
6458 Value *xyz = Nucleus::createInsertElement(xy, f32z, Nucleus::createConstantInt(2));
6459
6460 Value *i8w = Nucleus::createExtractElement(cast.value, Nucleus::createConstantInt(3));
6461 Value *f32w = Nucleus::createSIToFP(i8w, Float::getType());
6462 Value *xyzw = Nucleus::createInsertElement(xyz, f32w, Nucleus::createConstantInt(3));
6463 #else
Meng-Lin Wu601d0052016-06-10 14:18:41 -04006464 Value *a = Int4(cast).loadValue();
6465 Value *xyzw = Nucleus::createSIToFP(a, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04006466 #endif
John Bauman66b8ab22014-05-06 15:57:45 -04006467
6468 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04006469 }
6470
John Bauman19bac1e2014-05-06 15:23:49 -04006471 Float4::Float4(RValue<Short4> cast)
John Bauman89401822014-05-06 15:04:28 -04006472 {
6473 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006474
Alexis Hetu2aa852f2015-10-14 16:32:39 -04006475 Int4 c(cast);
6476 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
John Bauman89401822014-05-06 15:04:28 -04006477 }
6478
John Bauman19bac1e2014-05-06 15:23:49 -04006479 Float4::Float4(RValue<UShort4> cast)
John Bauman89401822014-05-06 15:04:28 -04006480 {
6481 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006482
Alexis Hetu2aa852f2015-10-14 16:32:39 -04006483 Int4 c(cast);
6484 storeValue(Nucleus::createSIToFP(RValue<Int4>(c).value, Float4::getType()));
John Bauman89401822014-05-06 15:04:28 -04006485 }
6486
John Bauman19bac1e2014-05-06 15:23:49 -04006487 Float4::Float4(RValue<Int4> cast)
John Bauman89401822014-05-06 15:04:28 -04006488 {
6489 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006490
6491 Value *xyzw = Nucleus::createSIToFP(cast.value, Float4::getType());
John Bauman89401822014-05-06 15:04:28 -04006492
John Bauman66b8ab22014-05-06 15:57:45 -04006493 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04006494 }
6495
John Bauman19bac1e2014-05-06 15:23:49 -04006496 Float4::Float4(RValue<UInt4> cast)
John Bauman89401822014-05-06 15:04:28 -04006497 {
6498 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006499
6500 Value *xyzw = Nucleus::createUIToFP(cast.value, Float4::getType());
6501
John Bauman66b8ab22014-05-06 15:57:45 -04006502 storeValue(xyzw);
John Bauman89401822014-05-06 15:04:28 -04006503 }
6504
6505 Float4::Float4()
6506 {
6507 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006508 }
John Bauman66b8ab22014-05-06 15:57:45 -04006509
John Bauman89401822014-05-06 15:04:28 -04006510 Float4::Float4(float xyzw)
6511 {
6512 constant(xyzw, xyzw, xyzw, xyzw);
6513 }
6514
6515 Float4::Float4(float x, float yzw)
6516 {
6517 constant(x, yzw, yzw, yzw);
6518 }
6519
6520 Float4::Float4(float x, float y, float zw)
6521 {
6522 constant(x, y, zw, zw);
6523 }
6524
6525 Float4::Float4(float x, float y, float z, float w)
6526 {
6527 constant(x, y, z, w);
6528 }
6529
6530 void Float4::constant(float x, float y, float z, float w)
6531 {
6532 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006533
6534 Constant *constantVector[4];
6535 constantVector[0] = Nucleus::createConstantFloat(x);
6536 constantVector[1] = Nucleus::createConstantFloat(y);
6537 constantVector[2] = Nucleus::createConstantFloat(z);
6538 constantVector[3] = Nucleus::createConstantFloat(w);
6539
John Bauman66b8ab22014-05-06 15:57:45 -04006540 storeValue(Nucleus::createConstantVector(constantVector, 4));
John Bauman89401822014-05-06 15:04:28 -04006541 }
6542
John Bauman19bac1e2014-05-06 15:23:49 -04006543 Float4::Float4(RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006544 {
6545 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006546
John Bauman66b8ab22014-05-06 15:57:45 -04006547 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04006548 }
6549
6550 Float4::Float4(const Float4 &rhs)
6551 {
6552 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006553
John Bauman66b8ab22014-05-06 15:57:45 -04006554 Value *value = rhs.loadValue();
6555 storeValue(value);
6556 }
6557
6558 Float4::Float4(const Reference<Float4> &rhs)
6559 {
6560 xyzw.parent = this;
6561
6562 Value *value = rhs.loadValue();
6563 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04006564 }
6565
John Bauman19bac1e2014-05-06 15:23:49 -04006566 Float4::Float4(RValue<Float> rhs)
John Bauman89401822014-05-06 15:04:28 -04006567 {
6568 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006569
John Bauman66b8ab22014-05-06 15:57:45 -04006570 Value *vector = loadValue();
John Bauman89401822014-05-06 15:04:28 -04006571 Value *insert = Nucleus::createInsertElement(vector, rhs.value, 0);
6572
6573 Constant *swizzle[4];
6574 swizzle[0] = Nucleus::createConstantInt(0);
6575 swizzle[1] = Nucleus::createConstantInt(0);
6576 swizzle[2] = Nucleus::createConstantInt(0);
6577 swizzle[3] = Nucleus::createConstantInt(0);
6578
6579 Value *replicate = Nucleus::createShuffleVector(insert, UndefValue::get(Float4::getType()), Nucleus::createConstantVector(swizzle, 4));
6580
John Bauman66b8ab22014-05-06 15:57:45 -04006581 storeValue(replicate);
John Bauman89401822014-05-06 15:04:28 -04006582 }
6583
6584 Float4::Float4(const Float &rhs)
6585 {
6586 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006587
John Bauman66b8ab22014-05-06 15:57:45 -04006588 *this = RValue<Float>(rhs.loadValue());
6589 }
John Bauman89401822014-05-06 15:04:28 -04006590
John Bauman66b8ab22014-05-06 15:57:45 -04006591 Float4::Float4(const Reference<Float> &rhs)
6592 {
6593 xyzw.parent = this;
John Bauman89401822014-05-06 15:04:28 -04006594
John Bauman66b8ab22014-05-06 15:57:45 -04006595 *this = RValue<Float>(rhs.loadValue());
John Bauman89401822014-05-06 15:04:28 -04006596 }
6597
6598 RValue<Float4> Float4::operator=(float x) const
6599 {
6600 return *this = Float4(x, x, x, x);
6601 }
6602
John Bauman19bac1e2014-05-06 15:23:49 -04006603 RValue<Float4> Float4::operator=(RValue<Float4> rhs) const
John Bauman89401822014-05-06 15:04:28 -04006604 {
John Bauman66b8ab22014-05-06 15:57:45 -04006605 storeValue(rhs.value);
John Bauman89401822014-05-06 15:04:28 -04006606
6607 return rhs;
6608 }
6609
6610 RValue<Float4> Float4::operator=(const Float4 &rhs) const
6611 {
John Bauman66b8ab22014-05-06 15:57:45 -04006612 Value *value = rhs.loadValue();
6613 storeValue(value);
6614
6615 return RValue<Float4>(value);
6616 }
6617
6618 RValue<Float4> Float4::operator=(const Reference<Float4> &rhs) const
6619 {
6620 Value *value = rhs.loadValue();
6621 storeValue(value);
John Bauman89401822014-05-06 15:04:28 -04006622
6623 return RValue<Float4>(value);
6624 }
6625
John Bauman19bac1e2014-05-06 15:23:49 -04006626 RValue<Float4> Float4::operator=(RValue<Float> rhs) const
John Bauman89401822014-05-06 15:04:28 -04006627 {
6628 return *this = Float4(rhs);
6629 }
6630
6631 RValue<Float4> Float4::operator=(const Float &rhs) const
6632 {
6633 return *this = Float4(rhs);
6634 }
6635
John Bauman66b8ab22014-05-06 15:57:45 -04006636 RValue<Float4> Float4::operator=(const Reference<Float> &rhs) const
John Bauman89401822014-05-06 15:04:28 -04006637 {
John Bauman66b8ab22014-05-06 15:57:45 -04006638 return *this = Float4(rhs);
John Bauman89401822014-05-06 15:04:28 -04006639 }
6640
John Bauman19bac1e2014-05-06 15:23:49 -04006641 RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006642 {
6643 return RValue<Float4>(Nucleus::createFAdd(lhs.value, rhs.value));
6644 }
6645
John Bauman19bac1e2014-05-06 15:23:49 -04006646 RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006647 {
6648 return RValue<Float4>(Nucleus::createFSub(lhs.value, rhs.value));
6649 }
6650
John Bauman19bac1e2014-05-06 15:23:49 -04006651 RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006652 {
6653 return RValue<Float4>(Nucleus::createFMul(lhs.value, rhs.value));
6654 }
6655
John Bauman19bac1e2014-05-06 15:23:49 -04006656 RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006657 {
6658 return RValue<Float4>(Nucleus::createFDiv(lhs.value, rhs.value));
6659 }
6660
John Bauman19bac1e2014-05-06 15:23:49 -04006661 RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006662 {
6663 return RValue<Float4>(Nucleus::createFRem(lhs.value, rhs.value));
6664 }
6665
John Bauman19bac1e2014-05-06 15:23:49 -04006666 RValue<Float4> operator+=(const Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006667 {
6668 return lhs = lhs + rhs;
6669 }
6670
John Bauman19bac1e2014-05-06 15:23:49 -04006671 RValue<Float4> operator-=(const Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006672 {
6673 return lhs = lhs - rhs;
6674 }
6675
John Bauman19bac1e2014-05-06 15:23:49 -04006676 RValue<Float4> operator*=(const Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006677 {
6678 return lhs = lhs * rhs;
6679 }
6680
John Bauman19bac1e2014-05-06 15:23:49 -04006681 RValue<Float4> operator/=(const Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006682 {
6683 return lhs = lhs / rhs;
6684 }
6685
John Bauman19bac1e2014-05-06 15:23:49 -04006686 RValue<Float4> operator%=(const Float4 &lhs, RValue<Float4> rhs)
John Bauman89401822014-05-06 15:04:28 -04006687 {
6688 return lhs = lhs % rhs;
6689 }
6690
John Bauman19bac1e2014-05-06 15:23:49 -04006691 RValue<Float4> operator+(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006692 {
6693 return val;
6694 }
6695
John Bauman19bac1e2014-05-06 15:23:49 -04006696 RValue<Float4> operator-(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04006697 {
6698 return RValue<Float4>(Nucleus::createFNeg(val.value));
6699 }
6700
John Bauman19bac1e2014-05-06 15:23:49 -04006701 RValue<Float4> Abs(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006702 {
6703 Value *vector = Nucleus::createBitCast(x.value, Int4::getType());
6704
6705 Constant *constantVector[4];
6706 constantVector[0] = Nucleus::createConstantInt(0x7FFFFFFF);
6707 constantVector[1] = Nucleus::createConstantInt(0x7FFFFFFF);
6708 constantVector[2] = Nucleus::createConstantInt(0x7FFFFFFF);
6709 constantVector[3] = Nucleus::createConstantInt(0x7FFFFFFF);
6710
6711 Value *result = Nucleus::createAnd(vector, Nucleus::createConstantVector(constantVector, 4));
6712
6713 return RValue<Float4>(Nucleus::createBitCast(result, Float4::getType()));
6714 }
6715
John Bauman19bac1e2014-05-06 15:23:49 -04006716 RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006717 {
6718 return x86::maxps(x, y);
6719 }
6720
John Bauman19bac1e2014-05-06 15:23:49 -04006721 RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006722 {
6723 return x86::minps(x, y);
6724 }
6725
Nicolas Capens05b3d662016-02-25 23:58:33 -05006726 RValue<Float4> Rcp_pp(RValue<Float4> x, bool exactAtPow2)
John Bauman89401822014-05-06 15:04:28 -04006727 {
Nicolas Capens05b3d662016-02-25 23:58:33 -05006728 if(exactAtPow2)
6729 {
6730 // rcpps uses a piecewise-linear approximation which minimizes the relative error
6731 // but is not exact at power-of-two values. Rectify by multiplying by the inverse.
6732 return x86::rcpps(x) * Float4(1.0f / _mm_cvtss_f32(_mm_rcp_ss(_mm_set_ps1(1.0f))));
6733 }
6734 else
6735 {
6736 return x86::rcpps(x);
6737 }
John Bauman89401822014-05-06 15:04:28 -04006738 }
John Bauman66b8ab22014-05-06 15:57:45 -04006739
John Bauman19bac1e2014-05-06 15:23:49 -04006740 RValue<Float4> RcpSqrt_pp(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006741 {
6742 return x86::rsqrtps(x);
6743 }
6744
John Bauman19bac1e2014-05-06 15:23:49 -04006745 RValue<Float4> Sqrt(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006746 {
6747 return x86::sqrtps(x);
6748 }
6749
John Bauman19bac1e2014-05-06 15:23:49 -04006750 RValue<Float4> Insert(const Float4 &val, RValue<Float> element, int i)
John Bauman89401822014-05-06 15:04:28 -04006751 {
John Bauman66b8ab22014-05-06 15:57:45 -04006752 llvm::Value *value = val.loadValue();
John Bauman89401822014-05-06 15:04:28 -04006753 llvm::Value *insert = Nucleus::createInsertElement(value, element.value, i);
6754
6755 val = RValue<Float4>(insert);
6756
6757 return val;
6758 }
6759
John Bauman19bac1e2014-05-06 15:23:49 -04006760 RValue<Float> Extract(RValue<Float4> x, int i)
John Bauman89401822014-05-06 15:04:28 -04006761 {
6762 return RValue<Float>(Nucleus::createExtractElement(x.value, i));
6763 }
6764
John Bauman19bac1e2014-05-06 15:23:49 -04006765 RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04006766 {
6767 return RValue<Float4>(Nucleus::createSwizzle(x.value, select));
6768 }
6769
John Bauman19bac1e2014-05-06 15:23:49 -04006770 RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04006771 {
6772 Constant *shuffle[4];
6773 shuffle[0] = Nucleus::createConstantInt(((imm >> 0) & 0x03) + 0);
6774 shuffle[1] = Nucleus::createConstantInt(((imm >> 2) & 0x03) + 0);
6775 shuffle[2] = Nucleus::createConstantInt(((imm >> 4) & 0x03) + 4);
6776 shuffle[3] = Nucleus::createConstantInt(((imm >> 6) & 0x03) + 4);
6777
6778 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 4)));
6779 }
6780
John Bauman19bac1e2014-05-06 15:23:49 -04006781 RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006782 {
6783 Constant *shuffle[4];
6784 shuffle[0] = Nucleus::createConstantInt(0);
6785 shuffle[1] = Nucleus::createConstantInt(4);
6786 shuffle[2] = Nucleus::createConstantInt(1);
6787 shuffle[3] = Nucleus::createConstantInt(5);
6788
6789 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 4)));
6790 }
6791
John Bauman19bac1e2014-05-06 15:23:49 -04006792 RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006793 {
6794 Constant *shuffle[4];
6795 shuffle[0] = Nucleus::createConstantInt(2);
6796 shuffle[1] = Nucleus::createConstantInt(6);
6797 shuffle[2] = Nucleus::createConstantInt(3);
6798 shuffle[3] = Nucleus::createConstantInt(7);
6799
6800 return RValue<Float4>(Nucleus::createShuffleVector(x.value, y.value, Nucleus::createConstantVector(shuffle, 4)));
6801 }
John Bauman66b8ab22014-05-06 15:57:45 -04006802
John Bauman19bac1e2014-05-06 15:23:49 -04006803 RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select)
John Bauman89401822014-05-06 15:04:28 -04006804 {
John Bauman66b8ab22014-05-06 15:57:45 -04006805 Value *vector = lhs.loadValue();
John Bauman89401822014-05-06 15:04:28 -04006806 Value *shuffle = Nucleus::createMask(vector, rhs.value, select);
John Bauman66b8ab22014-05-06 15:57:45 -04006807 lhs.storeValue(shuffle);
John Bauman89401822014-05-06 15:04:28 -04006808
6809 return RValue<Float4>(shuffle);
6810 }
6811
John Bauman19bac1e2014-05-06 15:23:49 -04006812 RValue<Int> SignMask(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006813 {
6814 return x86::movmskps(x);
6815 }
6816
John Bauman19bac1e2014-05-06 15:23:49 -04006817 RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006818 {
6819 // return As<Int4>(x86::cmpeqps(x, y));
6820 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOEQ(x.value, y.value), Int4::getType()));
6821 }
6822
John Bauman19bac1e2014-05-06 15:23:49 -04006823 RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006824 {
6825 // return As<Int4>(x86::cmpltps(x, y));
6826 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOLT(x.value, y.value), Int4::getType()));
6827 }
6828
John Bauman19bac1e2014-05-06 15:23:49 -04006829 RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006830 {
6831 // return As<Int4>(x86::cmpleps(x, y));
6832 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOLE(x.value, y.value), Int4::getType()));
6833 }
6834
John Bauman19bac1e2014-05-06 15:23:49 -04006835 RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006836 {
6837 // return As<Int4>(x86::cmpneqps(x, y));
6838 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpONE(x.value, y.value), Int4::getType()));
6839 }
6840
John Bauman19bac1e2014-05-06 15:23:49 -04006841 RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006842 {
6843 // return As<Int4>(x86::cmpnltps(x, y));
6844 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOGE(x.value, y.value), Int4::getType()));
6845 }
6846
John Bauman19bac1e2014-05-06 15:23:49 -04006847 RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04006848 {
6849 // return As<Int4>(x86::cmpnleps(x, y));
6850 return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOGT(x.value, y.value), Int4::getType()));
6851 }
6852
John Bauman19bac1e2014-05-06 15:23:49 -04006853 RValue<Float4> Round(RValue<Float4> x)
6854 {
6855 if(CPUID::supportsSSE4_1())
6856 {
6857 return x86::roundps(x, 0);
6858 }
6859 else
6860 {
6861 return Float4(RoundInt(x));
6862 }
6863 }
6864
6865 RValue<Float4> Trunc(RValue<Float4> x)
6866 {
6867 if(CPUID::supportsSSE4_1())
6868 {
6869 return x86::roundps(x, 3);
6870 }
6871 else
6872 {
6873 return Float4(Int4(x)); // Rounded toward zero
6874 }
6875 }
6876
6877 RValue<Float4> Frac(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006878 {
6879 if(CPUID::supportsSSE4_1())
6880 {
6881 return x - x86::floorps(x);
6882 }
6883 else
6884 {
John Bauman19bac1e2014-05-06 15:23:49 -04006885 Float4 frc = x - Float4(Int4(x)); // Signed fractional part
John Bauman89401822014-05-06 15:04:28 -04006886
John Bauman19bac1e2014-05-06 15:23:49 -04006887 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 -04006888 }
6889 }
6890
John Bauman19bac1e2014-05-06 15:23:49 -04006891 RValue<Float4> Floor(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006892 {
6893 if(CPUID::supportsSSE4_1())
6894 {
6895 return x86::floorps(x);
6896 }
6897 else
6898 {
John Bauman19bac1e2014-05-06 15:23:49 -04006899 return x - Frac(x);
John Bauman89401822014-05-06 15:04:28 -04006900 }
6901 }
6902
John Bauman19bac1e2014-05-06 15:23:49 -04006903 RValue<Float4> Ceil(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04006904 {
John Bauman19bac1e2014-05-06 15:23:49 -04006905 if(CPUID::supportsSSE4_1())
6906 {
6907 return x86::ceilps(x);
6908 }
6909 else
6910 {
6911 return -Floor(-x);
6912 }
John Bauman89401822014-05-06 15:04:28 -04006913 }
6914
John Bauman19bac1e2014-05-06 15:23:49 -04006915 Type *Float4::getType()
John Bauman89401822014-05-06 15:04:28 -04006916 {
6917 return VectorType::get(Float::getType(), 4);
6918 }
6919
Nicolas Capens81f18302016-01-14 09:32:35 -05006920 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006921 {
Nicolas Capens81f18302016-01-14 09:32:35 -05006922 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Nucleus::createConstantInt(offset)));
John Bauman89401822014-05-06 15:04:28 -04006923 }
6924
Nicolas Capens81f18302016-01-14 09:32:35 -05006925 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006926 {
Nicolas Capens81f18302016-01-14 09:32:35 -05006927 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, offset.value));
John Bauman89401822014-05-06 15:04:28 -04006928 }
6929
Nicolas Capens81f18302016-01-14 09:32:35 -05006930 RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006931 {
Nicolas Capens81f18302016-01-14 09:32:35 -05006932 return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, offset.value));
John Bauman89401822014-05-06 15:04:28 -04006933 }
6934
Nicolas Capens81f18302016-01-14 09:32:35 -05006935 RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006936 {
6937 return lhs = lhs + offset;
6938 }
6939
Nicolas Capens81f18302016-01-14 09:32:35 -05006940 RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006941 {
6942 return lhs = lhs + offset;
6943 }
6944
Nicolas Capens81f18302016-01-14 09:32:35 -05006945 RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006946 {
6947 return lhs = lhs + offset;
6948 }
6949
Nicolas Capens81f18302016-01-14 09:32:35 -05006950 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006951 {
6952 return lhs + -offset;
6953 }
6954
Nicolas Capens81f18302016-01-14 09:32:35 -05006955 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006956 {
6957 return lhs + -offset;
6958 }
6959
Nicolas Capens81f18302016-01-14 09:32:35 -05006960 RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006961 {
6962 return lhs + -offset;
6963 }
6964
Nicolas Capens81f18302016-01-14 09:32:35 -05006965 RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, int offset)
John Bauman89401822014-05-06 15:04:28 -04006966 {
6967 return lhs = lhs - offset;
6968 }
6969
Nicolas Capens81f18302016-01-14 09:32:35 -05006970 RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, RValue<Int> offset)
John Bauman89401822014-05-06 15:04:28 -04006971 {
6972 return lhs = lhs - offset;
6973 }
6974
Nicolas Capens81f18302016-01-14 09:32:35 -05006975 RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, RValue<UInt> offset)
John Bauman89401822014-05-06 15:04:28 -04006976 {
6977 return lhs = lhs - offset;
6978 }
6979
6980 void Return()
6981 {
John Bauman89401822014-05-06 15:04:28 -04006982 Nucleus::createRetVoid();
6983 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
John Bauman19bac1e2014-05-06 15:23:49 -04006984 Nucleus::createUnreachable();
6985 }
6986
6987 void Return(bool ret)
6988 {
John Bauman19bac1e2014-05-06 15:23:49 -04006989 Nucleus::createRet(Nucleus::createConstantBool(ret));
6990 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
6991 Nucleus::createUnreachable();
John Bauman89401822014-05-06 15:04:28 -04006992 }
6993
6994 void Return(const Int &ret)
6995 {
John Bauman66b8ab22014-05-06 15:57:45 -04006996 Nucleus::createRet(ret.loadValue());
John Bauman89401822014-05-06 15:04:28 -04006997 Nucleus::setInsertBlock(Nucleus::createBasicBlock());
John Bauman19bac1e2014-05-06 15:23:49 -04006998 Nucleus::createUnreachable();
John Bauman89401822014-05-06 15:04:28 -04006999 }
7000
7001 BasicBlock *beginLoop()
7002 {
7003 BasicBlock *loopBB = Nucleus::createBasicBlock();
7004
7005 Nucleus::createBr(loopBB);
John Bauman66b8ab22014-05-06 15:57:45 -04007006 Nucleus::setInsertBlock(loopBB);
John Bauman89401822014-05-06 15:04:28 -04007007
7008 return loopBB;
7009 }
7010
John Bauman19bac1e2014-05-06 15:23:49 -04007011 bool branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB)
John Bauman89401822014-05-06 15:04:28 -04007012 {
7013 Nucleus::createCondBr(cmp.value, bodyBB, endBB);
John Bauman66b8ab22014-05-06 15:57:45 -04007014 Nucleus::setInsertBlock(bodyBB);
7015
John Bauman89401822014-05-06 15:04:28 -04007016 return true;
7017 }
7018
7019 bool elseBlock(BasicBlock *falseBB)
7020 {
7021 falseBB->back().eraseFromParent();
John Bauman66b8ab22014-05-06 15:57:45 -04007022 Nucleus::setInsertBlock(falseBB);
John Bauman89401822014-05-06 15:04:28 -04007023
7024 return true;
7025 }
7026
7027 RValue<Long> Ticks()
7028 {
7029 Module *module = Nucleus::getModule();
7030 llvm::Function *rdtsc = Intrinsic::getDeclaration(module, Intrinsic::readcyclecounter);
7031
7032 return RValue<Long>(Nucleus::createCall(rdtsc));
7033 }
John Bauman89401822014-05-06 15:04:28 -04007034}
7035
7036namespace sw
7037{
7038 namespace x86
7039 {
John Bauman19bac1e2014-05-06 15:23:49 -04007040 RValue<Int> cvtss2si(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04007041 {
7042 Module *module = Nucleus::getModule();
7043 llvm::Function *cvtss2si = Intrinsic::getDeclaration(module, Intrinsic::x86_sse_cvtss2si);
John Bauman66b8ab22014-05-06 15:57:45 -04007044
John Bauman89401822014-05-06 15:04:28 -04007045 Float4 vector;
7046 vector.x = val;
7047
7048 return RValue<Int>(Nucleus::createCall(cvtss2si, RValue<Float4>(vector).value));
7049 }
7050
John Bauman19bac1e2014-05-06 15:23:49 -04007051 RValue<Int2> cvtps2pi(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04007052 {
7053 Module *module = Nucleus::getModule();
7054 llvm::Function *cvtps2pi = Intrinsic::getDeclaration(module, Intrinsic::x86_sse_cvtps2pi);
7055
7056 return RValue<Int2>(Nucleus::createCall(cvtps2pi, val.value));
7057 }
7058
John Bauman19bac1e2014-05-06 15:23:49 -04007059 RValue<Int2> cvttps2pi(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04007060 {
7061 Module *module = Nucleus::getModule();
7062 llvm::Function *cvttps2pi = Intrinsic::getDeclaration(module, Intrinsic::x86_sse_cvttps2pi);
7063
7064 return RValue<Int2>(Nucleus::createCall(cvttps2pi, val.value));
7065 }
7066
John Bauman19bac1e2014-05-06 15:23:49 -04007067 RValue<Int4> cvtps2dq(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04007068 {
7069 if(CPUID::supportsSSE2())
7070 {
7071 Module *module = Nucleus::getModule();
7072 llvm::Function *cvtps2dq = Intrinsic::getDeclaration(module, Intrinsic::x86_sse2_cvtps2dq);
7073
7074 return RValue<Int4>(Nucleus::createCall(cvtps2dq, val.value));
7075 }
7076 else
7077 {
7078 Int2 lo = x86::cvtps2pi(val);
7079 Int2 hi = x86::cvtps2pi(Swizzle(val, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04007080
Nicolas Capens62abb552016-01-05 12:03:47 -05007081 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007082 }
7083 }
7084
John Bauman19bac1e2014-05-06 15:23:49 -04007085 RValue<Float> rcpss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04007086 {
7087 Module *module = Nucleus::getModule();
7088 llvm::Function *rcpss = Intrinsic::getDeclaration(module, Intrinsic::x86_sse_rcp_ss);
7089
7090 Value *vector = Nucleus::createInsertElement(UndefValue::get(Float4::getType()), val.value, 0);
John Bauman66b8ab22014-05-06 15:57:45 -04007091
John Bauman89401822014-05-06 15:04:28 -04007092 return RValue<Float>(Nucleus::createExtractElement(Nucleus::createCall(rcpss, vector), 0));
7093 }
7094
John Bauman19bac1e2014-05-06 15:23:49 -04007095 RValue<Float> sqrtss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04007096 {
7097 Module *module = Nucleus::getModule();
7098 llvm::Function *sqrtss = Intrinsic::getDeclaration(module, Intrinsic::x86_sse_sqrt_ss);
7099
7100 Value *vector = Nucleus::createInsertElement(UndefValue::get(Float4::getType()), val.value, 0);
John Bauman66b8ab22014-05-06 15:57:45 -04007101
John Bauman89401822014-05-06 15:04:28 -04007102 return RValue<Float>(Nucleus::createExtractElement(Nucleus::createCall(sqrtss, vector), 0));
7103 }
7104
John Bauman19bac1e2014-05-06 15:23:49 -04007105 RValue<Float> rsqrtss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04007106 {
7107 Module *module = Nucleus::getModule();
7108 llvm::Function *rsqrtss = Intrinsic::getDeclaration(module, Intrinsic::x86_sse_rsqrt_ss);
John Bauman66b8ab22014-05-06 15:57:45 -04007109
John Bauman89401822014-05-06 15:04:28 -04007110 Value *vector = Nucleus::createInsertElement(UndefValue::get(Float4::getType()), val.value, 0);
7111
7112 return RValue<Float>(Nucleus::createExtractElement(Nucleus::createCall(rsqrtss, vector), 0));
7113 }
7114
John Bauman19bac1e2014-05-06 15:23:49 -04007115 RValue<Float4> rcpps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04007116 {
7117 Module *module = Nucleus::getModule();
7118 llvm::Function *rcpps = Intrinsic::getDeclaration(module, Intrinsic::x86_sse_rcp_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04007119
John Bauman89401822014-05-06 15:04:28 -04007120 return RValue<Float4>(Nucleus::createCall(rcpps, val.value));
7121 }
7122
John Bauman19bac1e2014-05-06 15:23:49 -04007123 RValue<Float4> sqrtps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04007124 {
7125 Module *module = Nucleus::getModule();
7126 llvm::Function *sqrtps = Intrinsic::getDeclaration(module, Intrinsic::x86_sse_sqrt_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04007127
John Bauman89401822014-05-06 15:04:28 -04007128 return RValue<Float4>(Nucleus::createCall(sqrtps, val.value));
7129 }
7130
John Bauman19bac1e2014-05-06 15:23:49 -04007131 RValue<Float4> rsqrtps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04007132 {
7133 Module *module = Nucleus::getModule();
7134 llvm::Function *rsqrtps = Intrinsic::getDeclaration(module, Intrinsic::x86_sse_rsqrt_ps);
John Bauman66b8ab22014-05-06 15:57:45 -04007135
John Bauman89401822014-05-06 15:04:28 -04007136 return RValue<Float4>(Nucleus::createCall(rsqrtps, val.value));
7137 }
7138
John Bauman19bac1e2014-05-06 15:23:49 -04007139 RValue<Float4> maxps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007140 {
7141 Module *module = Nucleus::getModule();
7142 llvm::Function *maxps = Intrinsic::getDeclaration(module, Intrinsic::x86_sse_max_ps);
7143
7144 return RValue<Float4>(Nucleus::createCall(maxps, x.value, y.value));
7145 }
7146
John Bauman19bac1e2014-05-06 15:23:49 -04007147 RValue<Float4> minps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007148 {
7149 Module *module = Nucleus::getModule();
7150 llvm::Function *minps = Intrinsic::getDeclaration(module, Intrinsic::x86_sse_min_ps);
7151
7152 return RValue<Float4>(Nucleus::createCall(minps, x.value, y.value));
7153 }
7154
John Bauman19bac1e2014-05-06 15:23:49 -04007155 RValue<Float> roundss(RValue<Float> val, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04007156 {
7157 Module *module = Nucleus::getModule();
7158 llvm::Function *roundss = Intrinsic::getDeclaration(module, Intrinsic::x86_sse41_round_ss);
7159
7160 Value *undef = UndefValue::get(Float4::getType());
7161 Value *vector = Nucleus::createInsertElement(undef, val.value, 0);
7162
7163 return RValue<Float>(Nucleus::createExtractElement(Nucleus::createCall(roundss, undef, vector, Nucleus::createConstantInt(imm)), 0));
7164 }
7165
John Bauman19bac1e2014-05-06 15:23:49 -04007166 RValue<Float> floorss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04007167 {
7168 return roundss(val, 1);
7169 }
7170
John Bauman19bac1e2014-05-06 15:23:49 -04007171 RValue<Float> ceilss(RValue<Float> val)
John Bauman89401822014-05-06 15:04:28 -04007172 {
7173 return roundss(val, 2);
7174 }
7175
John Bauman19bac1e2014-05-06 15:23:49 -04007176 RValue<Float4> roundps(RValue<Float4> val, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04007177 {
7178 Module *module = Nucleus::getModule();
7179 llvm::Function *roundps = Intrinsic::getDeclaration(module, Intrinsic::x86_sse41_round_ps);
7180
7181 return RValue<Float4>(Nucleus::createCall(roundps, val.value, Nucleus::createConstantInt(imm)));
7182 }
7183
John Bauman19bac1e2014-05-06 15:23:49 -04007184 RValue<Float4> floorps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04007185 {
7186 return roundps(val, 1);
7187 }
7188
John Bauman19bac1e2014-05-06 15:23:49 -04007189 RValue<Float4> ceilps(RValue<Float4> val)
John Bauman89401822014-05-06 15:04:28 -04007190 {
7191 return roundps(val, 2);
7192 }
7193
John Bauman19bac1e2014-05-06 15:23:49 -04007194 RValue<Float4> cmpps(RValue<Float4> x, RValue<Float4> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04007195 {
7196 Module *module = Nucleus::getModule();
7197 llvm::Function *cmpps = Intrinsic::getDeclaration(module, Intrinsic::x86_sse_cmp_ps);
7198
7199 return RValue<Float4>(Nucleus::createCall(cmpps, x.value, y.value, Nucleus::createConstantByte(imm)));
7200 }
7201
John Bauman19bac1e2014-05-06 15:23:49 -04007202 RValue<Float4> cmpeqps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007203 {
7204 return cmpps(x, y, 0);
7205 }
7206
John Bauman19bac1e2014-05-06 15:23:49 -04007207 RValue<Float4> cmpltps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007208 {
7209 return cmpps(x, y, 1);
7210 }
7211
John Bauman19bac1e2014-05-06 15:23:49 -04007212 RValue<Float4> cmpleps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007213 {
7214 return cmpps(x, y, 2);
7215 }
7216
John Bauman19bac1e2014-05-06 15:23:49 -04007217 RValue<Float4> cmpunordps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007218 {
7219 return cmpps(x, y, 3);
7220 }
7221
John Bauman19bac1e2014-05-06 15:23:49 -04007222 RValue<Float4> cmpneqps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007223 {
7224 return cmpps(x, y, 4);
7225 }
7226
John Bauman19bac1e2014-05-06 15:23:49 -04007227 RValue<Float4> cmpnltps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007228 {
7229 return cmpps(x, y, 5);
7230 }
7231
John Bauman19bac1e2014-05-06 15:23:49 -04007232 RValue<Float4> cmpnleps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007233 {
7234 return cmpps(x, y, 6);
7235 }
7236
John Bauman19bac1e2014-05-06 15:23:49 -04007237 RValue<Float4> cmpordps(RValue<Float4> x, RValue<Float4> y)
John Bauman89401822014-05-06 15:04:28 -04007238 {
7239 return cmpps(x, y, 7);
7240 }
7241
John Bauman19bac1e2014-05-06 15:23:49 -04007242 RValue<Float> cmpss(RValue<Float> x, RValue<Float> y, unsigned char imm)
John Bauman89401822014-05-06 15:04:28 -04007243 {
7244 Module *module = Nucleus::getModule();
7245 llvm::Function *cmpss = Intrinsic::getDeclaration(module, Intrinsic::x86_sse_cmp_ss);
7246
7247 Value *vector1 = Nucleus::createInsertElement(UndefValue::get(Float4::getType()), x.value, 0);
7248 Value *vector2 = Nucleus::createInsertElement(UndefValue::get(Float4::getType()), y.value, 0);
7249
7250 return RValue<Float>(Nucleus::createExtractElement(Nucleus::createCall(cmpss, vector1, vector2, Nucleus::createConstantByte(imm)), 0));
7251 }
7252
John Bauman19bac1e2014-05-06 15:23:49 -04007253 RValue<Float> cmpeqss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007254 {
7255 return cmpss(x, y, 0);
7256 }
7257
John Bauman19bac1e2014-05-06 15:23:49 -04007258 RValue<Float> cmpltss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007259 {
7260 return cmpss(x, y, 1);
7261 }
7262
John Bauman19bac1e2014-05-06 15:23:49 -04007263 RValue<Float> cmpless(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007264 {
7265 return cmpss(x, y, 2);
7266 }
7267
John Bauman19bac1e2014-05-06 15:23:49 -04007268 RValue<Float> cmpunordss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007269 {
7270 return cmpss(x, y, 3);
7271 }
7272
John Bauman19bac1e2014-05-06 15:23:49 -04007273 RValue<Float> cmpneqss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007274 {
7275 return cmpss(x, y, 4);
7276 }
7277
John Bauman19bac1e2014-05-06 15:23:49 -04007278 RValue<Float> cmpnltss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007279 {
7280 return cmpss(x, y, 5);
7281 }
7282
John Bauman19bac1e2014-05-06 15:23:49 -04007283 RValue<Float> cmpnless(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007284 {
7285 return cmpss(x, y, 6);
7286 }
7287
John Bauman19bac1e2014-05-06 15:23:49 -04007288 RValue<Float> cmpordss(RValue<Float> x, RValue<Float> y)
John Bauman89401822014-05-06 15:04:28 -04007289 {
7290 return cmpss(x, y, 7);
7291 }
7292
Alexis Hetu0f448072016-03-18 10:56:08 -04007293 RValue<Int4> pabsd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007294 {
7295 Module *module = Nucleus::getModule();
7296 llvm::Function *pabsd = Intrinsic::getDeclaration(module, Intrinsic::x86_ssse3_pabs_d_128);
7297
Alexis Hetu0f448072016-03-18 10:56:08 -04007298 return RValue<Int4>(Nucleus::createCall(pabsd, x.value));
John Bauman89401822014-05-06 15:04:28 -04007299 }
7300
John Bauman19bac1e2014-05-06 15:23:49 -04007301 RValue<Short4> paddsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007302 {
7303 Module *module = Nucleus::getModule();
7304 llvm::Function *paddsw = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_padds_w);
7305
John Bauman19bac1e2014-05-06 15:23:49 -04007306 return As<Short4>(RValue<MMX>(Nucleus::createCall(paddsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007307 }
John Bauman66b8ab22014-05-06 15:57:45 -04007308
John Bauman19bac1e2014-05-06 15:23:49 -04007309 RValue<Short4> psubsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007310 {
7311 Module *module = Nucleus::getModule();
7312 llvm::Function *psubsw = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_psubs_w);
7313
John Bauman19bac1e2014-05-06 15:23:49 -04007314 return As<Short4>(RValue<MMX>(Nucleus::createCall(psubsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007315 }
7316
John Bauman19bac1e2014-05-06 15:23:49 -04007317 RValue<UShort4> paddusw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007318 {
7319 Module *module = Nucleus::getModule();
7320 llvm::Function *paddusw = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_paddus_w);
7321
John Bauman19bac1e2014-05-06 15:23:49 -04007322 return As<UShort4>(RValue<MMX>(Nucleus::createCall(paddusw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007323 }
John Bauman66b8ab22014-05-06 15:57:45 -04007324
John Bauman19bac1e2014-05-06 15:23:49 -04007325 RValue<UShort4> psubusw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007326 {
7327 Module *module = Nucleus::getModule();
7328 llvm::Function *psubusw = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_psubus_w);
7329
John Bauman19bac1e2014-05-06 15:23:49 -04007330 return As<UShort4>(RValue<MMX>(Nucleus::createCall(psubusw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007331 }
7332
John Bauman19bac1e2014-05-06 15:23:49 -04007333 RValue<SByte8> paddsb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04007334 {
7335 Module *module = Nucleus::getModule();
7336 llvm::Function *paddsb = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_padds_b);
7337
John Bauman19bac1e2014-05-06 15:23:49 -04007338 return As<SByte8>(RValue<MMX>(Nucleus::createCall(paddsb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007339 }
John Bauman66b8ab22014-05-06 15:57:45 -04007340
John Bauman19bac1e2014-05-06 15:23:49 -04007341 RValue<SByte8> psubsb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04007342 {
7343 Module *module = Nucleus::getModule();
7344 llvm::Function *psubsb = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_psubs_b);
7345
John Bauman19bac1e2014-05-06 15:23:49 -04007346 return As<SByte8>(RValue<MMX>(Nucleus::createCall(psubsb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007347 }
John Bauman66b8ab22014-05-06 15:57:45 -04007348
John Bauman19bac1e2014-05-06 15:23:49 -04007349 RValue<Byte8> paddusb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04007350 {
7351 Module *module = Nucleus::getModule();
7352 llvm::Function *paddusb = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_paddus_b);
7353
John Bauman19bac1e2014-05-06 15:23:49 -04007354 return As<Byte8>(RValue<MMX>(Nucleus::createCall(paddusb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007355 }
John Bauman66b8ab22014-05-06 15:57:45 -04007356
John Bauman19bac1e2014-05-06 15:23:49 -04007357 RValue<Byte8> psubusb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04007358 {
7359 Module *module = Nucleus::getModule();
7360 llvm::Function *psubusb = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_psubus_b);
7361
John Bauman19bac1e2014-05-06 15:23:49 -04007362 return As<Byte8>(RValue<MMX>(Nucleus::createCall(psubusb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007363 }
7364
John Bauman19bac1e2014-05-06 15:23:49 -04007365 RValue<Short4> paddw(RValue<Short4> x, RValue<Short4> y)
7366 {
7367 Module *module = Nucleus::getModule();
7368 llvm::Function *paddw = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_padd_w);
7369
7370 return As<Short4>(RValue<MMX>(Nucleus::createCall(paddw, As<MMX>(x).value, As<MMX>(y).value)));
7371 }
7372
7373 RValue<Short4> psubw(RValue<Short4> x, RValue<Short4> y)
7374 {
7375 Module *module = Nucleus::getModule();
7376 llvm::Function *psubw = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_psub_w);
7377
7378 return As<Short4>(RValue<MMX>(Nucleus::createCall(psubw, As<MMX>(x).value, As<MMX>(y).value)));
7379 }
7380
7381 RValue<Short4> pmullw(RValue<Short4> x, RValue<Short4> y)
7382 {
7383 Module *module = Nucleus::getModule();
7384 llvm::Function *pmullw = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_pmull_w);
7385
7386 return As<Short4>(RValue<MMX>(Nucleus::createCall(pmullw, As<MMX>(x).value, As<MMX>(y).value)));
7387 }
7388
7389 RValue<Short4> pand(RValue<Short4> x, RValue<Short4> y)
7390 {
7391 Module *module = Nucleus::getModule();
7392 llvm::Function *pand = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_pand);
7393
7394 return As<Short4>(RValue<MMX>(Nucleus::createCall(pand, As<MMX>(x).value, As<MMX>(y).value)));
7395 }
7396
7397 RValue<Short4> por(RValue<Short4> x, RValue<Short4> y)
7398 {
7399 Module *module = Nucleus::getModule();
7400 llvm::Function *por = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_por);
7401
7402 return As<Short4>(RValue<MMX>(Nucleus::createCall(por, As<MMX>(x).value, As<MMX>(y).value)));
7403 }
7404
7405 RValue<Short4> pxor(RValue<Short4> x, RValue<Short4> y)
7406 {
7407 Module *module = Nucleus::getModule();
7408 llvm::Function *pxor = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_pxor);
7409
7410 return As<Short4>(RValue<MMX>(Nucleus::createCall(pxor, As<MMX>(x).value, As<MMX>(y).value)));
7411 }
7412
7413 RValue<Short4> pshufw(RValue<Short4> x, unsigned char y)
7414 {
7415 Module *module = Nucleus::getModule();
7416 llvm::Function *pshufw = Intrinsic::getDeclaration(module, Intrinsic::x86_sse_pshuf_w);
7417
7418 return As<Short4>(RValue<MMX>(Nucleus::createCall(pshufw, As<MMX>(x).value, Nucleus::createConstantByte(y))));
7419 }
7420
7421 RValue<Int2> punpcklwd(RValue<Short4> x, RValue<Short4> y)
7422 {
7423 Module *module = Nucleus::getModule();
7424 llvm::Function *punpcklwd = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_punpcklwd);
7425
7426 return As<Int2>(RValue<MMX>(Nucleus::createCall(punpcklwd, As<MMX>(x).value, As<MMX>(y).value)));
7427 }
7428
7429 RValue<Int2> punpckhwd(RValue<Short4> x, RValue<Short4> y)
7430 {
7431 Module *module = Nucleus::getModule();
7432 llvm::Function *punpckhwd = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_punpckhwd);
7433
7434 return As<Int2>(RValue<MMX>(Nucleus::createCall(punpckhwd, As<MMX>(x).value, As<MMX>(y).value)));
7435 }
7436
7437 RValue<Short4> pinsrw(RValue<Short4> x, RValue<Int> y, unsigned int i)
7438 {
7439 Module *module = Nucleus::getModule();
7440 llvm::Function *pinsrw = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_pinsr_w);
7441
7442 return As<Short4>(RValue<MMX>(Nucleus::createCall(pinsrw, As<MMX>(x).value, y.value, Nucleus::createConstantInt(i))));
7443 }
7444
7445 RValue<Int> pextrw(RValue<Short4> x, unsigned int i)
7446 {
7447 Module *module = Nucleus::getModule();
7448 llvm::Function *pextrw = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_pextr_w);
7449
7450 return RValue<Int>(Nucleus::createCall(pextrw, As<MMX>(x).value, Nucleus::createConstantInt(i)));
7451 }
7452
7453 RValue<Long1> punpckldq(RValue<Int2> x, RValue<Int2> y)
7454 {
7455 Module *module = Nucleus::getModule();
7456 llvm::Function *punpckldq = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_punpckldq);
7457
7458 return As<Long1>(RValue<MMX>(Nucleus::createCall(punpckldq, As<MMX>(x).value, As<MMX>(y).value)));
7459 }
7460
7461 RValue<Long1> punpckhdq(RValue<Int2> x, RValue<Int2> y)
7462 {
7463 Module *module = Nucleus::getModule();
7464 llvm::Function *punpckhdq = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_punpckhdq);
7465
7466 return As<Long1>(RValue<MMX>(Nucleus::createCall(punpckhdq, As<MMX>(x).value, As<MMX>(y).value)));
7467 }
7468
7469 RValue<Short4> punpcklbw(RValue<Byte8> x, RValue<Byte8> y)
7470 {
7471 Module *module = Nucleus::getModule();
7472 llvm::Function *punpcklbw = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_punpcklbw);
7473
7474 return As<Short4>(RValue<MMX>(Nucleus::createCall(punpcklbw, As<MMX>(x).value, As<MMX>(y).value)));
7475 }
7476
7477 RValue<Short4> punpckhbw(RValue<Byte8> x, RValue<Byte8> y)
7478 {
7479 Module *module = Nucleus::getModule();
7480 llvm::Function *punpckhbw = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_punpckhbw);
7481
7482 return As<Short4>(RValue<MMX>(Nucleus::createCall(punpckhbw, As<MMX>(x).value, As<MMX>(y).value)));
7483 }
7484
7485 RValue<Byte8> paddb(RValue<Byte8> x, RValue<Byte8> y)
7486 {
7487 Module *module = Nucleus::getModule();
7488 llvm::Function *paddb = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_padd_b);
7489
7490 return As<Byte8>(RValue<MMX>(Nucleus::createCall(paddb, As<MMX>(x).value, As<MMX>(y).value)));
7491 }
7492
7493 RValue<Byte8> psubb(RValue<Byte8> x, RValue<Byte8> y)
7494 {
7495 Module *module = Nucleus::getModule();
7496 llvm::Function *psubb = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_psub_b);
7497
7498 return As<Byte8>(RValue<MMX>(Nucleus::createCall(psubb, As<MMX>(x).value, As<MMX>(y).value)));
7499 }
7500
7501 RValue<Int2> paddd(RValue<Int2> x, RValue<Int2> y)
7502 {
7503 Module *module = Nucleus::getModule();
7504 llvm::Function *paddd = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_padd_d);
7505
7506 return As<Int2>(RValue<MMX>(Nucleus::createCall(paddd, As<MMX>(x).value, As<MMX>(y).value)));
7507 }
7508
7509 RValue<Int2> psubd(RValue<Int2> x, RValue<Int2> y)
7510 {
7511 Module *module = Nucleus::getModule();
7512 llvm::Function *psubd = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_psub_d);
7513
7514 return As<Int2>(RValue<MMX>(Nucleus::createCall(psubd, As<MMX>(x).value, As<MMX>(y).value)));
7515 }
7516
7517 RValue<UShort4> pavgw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007518 {
7519 Module *module = Nucleus::getModule();
7520 llvm::Function *pavgw = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_pavg_w);
7521
John Bauman19bac1e2014-05-06 15:23:49 -04007522 return As<UShort4>(RValue<MMX>(Nucleus::createCall(pavgw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007523 }
7524
John Bauman19bac1e2014-05-06 15:23:49 -04007525 RValue<Short4> pmaxsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007526 {
7527 Module *module = Nucleus::getModule();
7528 llvm::Function *pmaxsw = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_pmaxs_w);
7529
John Bauman19bac1e2014-05-06 15:23:49 -04007530 return As<Short4>(RValue<MMX>(Nucleus::createCall(pmaxsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007531 }
7532
John Bauman19bac1e2014-05-06 15:23:49 -04007533 RValue<Short4> pminsw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007534 {
7535 Module *module = Nucleus::getModule();
7536 llvm::Function *pminsw = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_pmins_w);
7537
John Bauman19bac1e2014-05-06 15:23:49 -04007538 return As<Short4>(RValue<MMX>(Nucleus::createCall(pminsw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007539 }
7540
John Bauman19bac1e2014-05-06 15:23:49 -04007541 RValue<Short4> pcmpgtw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007542 {
7543 Module *module = Nucleus::getModule();
7544 llvm::Function *pcmpgtw = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_pcmpgt_w);
7545
John Bauman19bac1e2014-05-06 15:23:49 -04007546 return As<Short4>(RValue<MMX>(Nucleus::createCall(pcmpgtw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007547 }
7548
John Bauman19bac1e2014-05-06 15:23:49 -04007549 RValue<Short4> pcmpeqw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007550 {
7551 Module *module = Nucleus::getModule();
7552 llvm::Function *pcmpeqw = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_pcmpeq_w);
7553
John Bauman19bac1e2014-05-06 15:23:49 -04007554 return As<Short4>(RValue<MMX>(Nucleus::createCall(pcmpeqw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007555 }
7556
John Bauman19bac1e2014-05-06 15:23:49 -04007557 RValue<Byte8> pcmpgtb(RValue<SByte8> x, RValue<SByte8> y)
John Bauman89401822014-05-06 15:04:28 -04007558 {
7559 Module *module = Nucleus::getModule();
7560 llvm::Function *pcmpgtb = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_pcmpgt_b);
7561
John Bauman19bac1e2014-05-06 15:23:49 -04007562 return As<Byte8>(RValue<MMX>(Nucleus::createCall(pcmpgtb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007563 }
7564
John Bauman19bac1e2014-05-06 15:23:49 -04007565 RValue<Byte8> pcmpeqb(RValue<Byte8> x, RValue<Byte8> y)
John Bauman89401822014-05-06 15:04:28 -04007566 {
7567 Module *module = Nucleus::getModule();
7568 llvm::Function *pcmpeqb = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_pcmpeq_b);
7569
John Bauman19bac1e2014-05-06 15:23:49 -04007570 return As<Byte8>(RValue<MMX>(Nucleus::createCall(pcmpeqb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007571 }
7572
John Bauman19bac1e2014-05-06 15:23:49 -04007573 RValue<Short4> packssdw(RValue<Int2> x, RValue<Int2> y)
John Bauman89401822014-05-06 15:04:28 -04007574 {
7575 Module *module = Nucleus::getModule();
7576 llvm::Function *packssdw = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_packssdw);
7577
John Bauman19bac1e2014-05-06 15:23:49 -04007578 return As<Short4>(RValue<MMX>(Nucleus::createCall(packssdw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007579 }
7580
John Bauman19bac1e2014-05-06 15:23:49 -04007581 RValue<Short8> packssdw(RValue<Int4> x, RValue<Int4> y)
John Bauman89401822014-05-06 15:04:28 -04007582 {
7583 if(CPUID::supportsSSE2())
7584 {
7585 Module *module = Nucleus::getModule();
7586 llvm::Function *packssdw = Intrinsic::getDeclaration(module, Intrinsic::x86_sse2_packssdw_128);
7587
7588 return RValue<Short8>(Nucleus::createCall(packssdw, x.value, y.value));
7589 }
7590 else
7591 {
7592 Int2 loX = Int2(x);
7593 Int2 hiX = Int2(Swizzle(x, 0xEE));
7594
7595 Int2 loY = Int2(y);
7596 Int2 hiY = Int2(Swizzle(y, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04007597
John Bauman89401822014-05-06 15:04:28 -04007598 Short4 lo = x86::packssdw(loX, hiX);
7599 Short4 hi = x86::packssdw(loY, hiY);
John Bauman66b8ab22014-05-06 15:57:45 -04007600
Nicolas Capens62abb552016-01-05 12:03:47 -05007601 return Short8(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007602 }
7603 }
7604
John Bauman19bac1e2014-05-06 15:23:49 -04007605 RValue<SByte8> packsswb(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007606 {
7607 Module *module = Nucleus::getModule();
7608 llvm::Function *packsswb = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_packsswb);
7609
John Bauman19bac1e2014-05-06 15:23:49 -04007610 return As<SByte8>(RValue<MMX>(Nucleus::createCall(packsswb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007611 }
7612
John Bauman19bac1e2014-05-06 15:23:49 -04007613 RValue<Byte8> packuswb(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007614 {
7615 Module *module = Nucleus::getModule();
7616 llvm::Function *packuswb = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_packuswb);
7617
John Bauman19bac1e2014-05-06 15:23:49 -04007618 return As<Byte8>(RValue<MMX>(Nucleus::createCall(packuswb, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007619 }
7620
John Bauman19bac1e2014-05-06 15:23:49 -04007621 RValue<UShort8> packusdw(RValue<UInt4> x, RValue<UInt4> y)
John Bauman89401822014-05-06 15:04:28 -04007622 {
7623 if(CPUID::supportsSSE4_1())
7624 {
7625 Module *module = Nucleus::getModule();
7626 llvm::Function *packusdw = Intrinsic::getDeclaration(module, Intrinsic::x86_sse41_packusdw);
John Bauman66b8ab22014-05-06 15:57:45 -04007627
John Bauman89401822014-05-06 15:04:28 -04007628 return RValue<UShort8>(Nucleus::createCall(packusdw, x.value, y.value));
7629 }
7630 else
7631 {
7632 // FIXME: Not an exact replacement!
John Bauman19bac1e2014-05-06 15:23:49 -04007633 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 -04007634 }
7635 }
7636
John Bauman19bac1e2014-05-06 15:23:49 -04007637 RValue<UShort4> psrlw(RValue<UShort4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007638 {
7639 Module *module = Nucleus::getModule();
7640 llvm::Function *psrlw = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_psrli_w);
7641
John Bauman19bac1e2014-05-06 15:23:49 -04007642 return As<UShort4>(RValue<MMX>(Nucleus::createCall(psrlw, As<MMX>(x).value, Nucleus::createConstantInt(y))));
John Bauman89401822014-05-06 15:04:28 -04007643 }
7644
John Bauman19bac1e2014-05-06 15:23:49 -04007645 RValue<UShort8> psrlw(RValue<UShort8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007646 {
7647 Module *module = Nucleus::getModule();
7648 llvm::Function *psrlw = Intrinsic::getDeclaration(module, Intrinsic::x86_sse2_psrli_w);
7649
7650 return RValue<UShort8>(Nucleus::createCall(psrlw, x.value, Nucleus::createConstantInt(y)));
7651 }
7652
John Bauman19bac1e2014-05-06 15:23:49 -04007653 RValue<Short4> psraw(RValue<Short4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007654 {
7655 Module *module = Nucleus::getModule();
7656 llvm::Function *psraw = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_psrai_w);
7657
John Bauman19bac1e2014-05-06 15:23:49 -04007658 return As<Short4>(RValue<MMX>(Nucleus::createCall(psraw, As<MMX>(x).value, Nucleus::createConstantInt(y))));
John Bauman89401822014-05-06 15:04:28 -04007659 }
7660
John Bauman19bac1e2014-05-06 15:23:49 -04007661 RValue<Short8> psraw(RValue<Short8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007662 {
7663 Module *module = Nucleus::getModule();
7664 llvm::Function *psraw = Intrinsic::getDeclaration(module, Intrinsic::x86_sse2_psrai_w);
7665
7666 return RValue<Short8>(Nucleus::createCall(psraw, x.value, Nucleus::createConstantInt(y)));
7667 }
7668
John Bauman19bac1e2014-05-06 15:23:49 -04007669 RValue<Short4> psllw(RValue<Short4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007670 {
7671 Module *module = Nucleus::getModule();
7672 llvm::Function *psllw = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_pslli_w);
7673
John Bauman19bac1e2014-05-06 15:23:49 -04007674 return As<Short4>(RValue<MMX>(Nucleus::createCall(psllw, As<MMX>(x).value, Nucleus::createConstantInt(y))));
John Bauman89401822014-05-06 15:04:28 -04007675 }
7676
John Bauman19bac1e2014-05-06 15:23:49 -04007677 RValue<Short8> psllw(RValue<Short8> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007678 {
7679 Module *module = Nucleus::getModule();
7680 llvm::Function *psllw = Intrinsic::getDeclaration(module, Intrinsic::x86_sse2_pslli_w);
7681
7682 return RValue<Short8>(Nucleus::createCall(psllw, x.value, Nucleus::createConstantInt(y)));
7683 }
7684
John Bauman19bac1e2014-05-06 15:23:49 -04007685 RValue<Int2> pslld(RValue<Int2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007686 {
7687 Module *module = Nucleus::getModule();
7688 llvm::Function *pslld = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_pslli_d);
7689
John Bauman19bac1e2014-05-06 15:23:49 -04007690 return As<Int2>(RValue<MMX>(Nucleus::createCall(pslld, As<MMX>(x).value, Nucleus::createConstantInt(y))));
John Bauman89401822014-05-06 15:04:28 -04007691 }
7692
John Bauman19bac1e2014-05-06 15:23:49 -04007693 RValue<Int4> pslld(RValue<Int4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007694 {
7695 if(CPUID::supportsSSE2())
7696 {
7697 Module *module = Nucleus::getModule();
7698 llvm::Function *pslld = Intrinsic::getDeclaration(module, Intrinsic::x86_sse2_pslli_d);
7699
7700 return RValue<Int4>(Nucleus::createCall(pslld, x.value, Nucleus::createConstantInt(y)));
7701 }
7702 else
7703 {
7704 Int2 lo = Int2(x);
7705 Int2 hi = Int2(Swizzle(x, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04007706
John Bauman89401822014-05-06 15:04:28 -04007707 lo = x86::pslld(lo, y);
7708 hi = x86::pslld(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04007709
Nicolas Capens62abb552016-01-05 12:03:47 -05007710 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007711 }
7712 }
7713
John Bauman19bac1e2014-05-06 15:23:49 -04007714 RValue<Int2> psrad(RValue<Int2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007715 {
7716 Module *module = Nucleus::getModule();
7717 llvm::Function *psrad = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_psrai_d);
7718
John Bauman19bac1e2014-05-06 15:23:49 -04007719 return As<Int2>(RValue<MMX>(Nucleus::createCall(psrad, As<MMX>(x).value, Nucleus::createConstantInt(y))));
John Bauman89401822014-05-06 15:04:28 -04007720 }
7721
John Bauman19bac1e2014-05-06 15:23:49 -04007722 RValue<Int4> psrad(RValue<Int4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007723 {
7724 if(CPUID::supportsSSE2())
7725 {
7726 Module *module = Nucleus::getModule();
7727 llvm::Function *psrad = Intrinsic::getDeclaration(module, Intrinsic::x86_sse2_psrai_d);
7728
7729 return RValue<Int4>(Nucleus::createCall(psrad, x.value, Nucleus::createConstantInt(y)));
7730 }
7731 else
7732 {
7733 Int2 lo = Int2(x);
7734 Int2 hi = Int2(Swizzle(x, 0xEE));
John Bauman66b8ab22014-05-06 15:57:45 -04007735
John Bauman89401822014-05-06 15:04:28 -04007736 lo = x86::psrad(lo, y);
7737 hi = x86::psrad(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04007738
Nicolas Capens62abb552016-01-05 12:03:47 -05007739 return Int4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007740 }
7741 }
7742
John Bauman19bac1e2014-05-06 15:23:49 -04007743 RValue<UInt2> psrld(RValue<UInt2> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007744 {
7745 Module *module = Nucleus::getModule();
7746 llvm::Function *psrld = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_psrli_d);
7747
John Bauman19bac1e2014-05-06 15:23:49 -04007748 return As<UInt2>(RValue<MMX>(Nucleus::createCall(psrld, As<MMX>(x).value, Nucleus::createConstantInt(y))));
John Bauman89401822014-05-06 15:04:28 -04007749 }
7750
John Bauman19bac1e2014-05-06 15:23:49 -04007751 RValue<UInt4> psrld(RValue<UInt4> x, unsigned char y)
John Bauman89401822014-05-06 15:04:28 -04007752 {
7753 if(CPUID::supportsSSE2())
7754 {
7755 Module *module = Nucleus::getModule();
7756 llvm::Function *psrld = Intrinsic::getDeclaration(module, Intrinsic::x86_sse2_psrli_d);
7757
7758 return RValue<UInt4>(Nucleus::createCall(psrld, x.value, Nucleus::createConstantInt(y)));
7759 }
7760 else
7761 {
7762 UInt2 lo = As<UInt2>(Int2(As<Int4>(x)));
7763 UInt2 hi = As<UInt2>(Int2(Swizzle(As<Int4>(x), 0xEE)));
John Bauman66b8ab22014-05-06 15:57:45 -04007764
John Bauman89401822014-05-06 15:04:28 -04007765 lo = x86::psrld(lo, y);
7766 hi = x86::psrld(hi, y);
John Bauman66b8ab22014-05-06 15:57:45 -04007767
Nicolas Capens62abb552016-01-05 12:03:47 -05007768 return UInt4(lo, hi);
John Bauman89401822014-05-06 15:04:28 -04007769 }
7770 }
7771
John Bauman19bac1e2014-05-06 15:23:49 -04007772 RValue<UShort4> psrlw(RValue<UShort4> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007773 {
7774 Module *module = Nucleus::getModule();
7775 llvm::Function *psrlw = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_psrl_w);
7776
John Bauman19bac1e2014-05-06 15:23:49 -04007777 return As<UShort4>(RValue<MMX>(Nucleus::createCall(psrlw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007778 }
7779
John Bauman19bac1e2014-05-06 15:23:49 -04007780 RValue<Short4> psraw(RValue<Short4> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007781 {
7782 Module *module = Nucleus::getModule();
7783 llvm::Function *psraw = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_psra_w);
7784
John Bauman19bac1e2014-05-06 15:23:49 -04007785 return As<Short4>(RValue<MMX>(Nucleus::createCall(psraw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007786 }
7787
John Bauman19bac1e2014-05-06 15:23:49 -04007788 RValue<Short4> psllw(RValue<Short4> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007789 {
7790 Module *module = Nucleus::getModule();
7791 llvm::Function *psllw = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_psll_w);
7792
John Bauman19bac1e2014-05-06 15:23:49 -04007793 return As<Short4>(RValue<MMX>(Nucleus::createCall(psllw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007794 }
7795
John Bauman19bac1e2014-05-06 15:23:49 -04007796 RValue<Int2> pslld(RValue<Int2> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007797 {
7798 Module *module = Nucleus::getModule();
7799 llvm::Function *pslld = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_psll_d);
7800
John Bauman19bac1e2014-05-06 15:23:49 -04007801 return As<Int2>(RValue<MMX>(Nucleus::createCall(pslld, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007802 }
7803
John Bauman19bac1e2014-05-06 15:23:49 -04007804 RValue<UInt2> psrld(RValue<UInt2> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007805 {
7806 Module *module = Nucleus::getModule();
7807 llvm::Function *psrld = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_psrl_d);
7808
John Bauman19bac1e2014-05-06 15:23:49 -04007809 return As<UInt2>(RValue<MMX>(Nucleus::createCall(psrld, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007810 }
7811
John Bauman19bac1e2014-05-06 15:23:49 -04007812 RValue<Int2> psrad(RValue<Int2> x, RValue<Long1> y)
John Bauman89401822014-05-06 15:04:28 -04007813 {
7814 Module *module = Nucleus::getModule();
7815 llvm::Function *psrld = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_psra_d);
7816
John Bauman19bac1e2014-05-06 15:23:49 -04007817 return As<Int2>(RValue<MMX>(Nucleus::createCall(psrld, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007818 }
7819
John Bauman19bac1e2014-05-06 15:23:49 -04007820 RValue<Int4> pmaxsd(RValue<Int4> x, RValue<Int4> y)
7821 {
7822 Module *module = Nucleus::getModule();
7823 llvm::Function *pmaxsd = Intrinsic::getDeclaration(module, Intrinsic::x86_sse41_pmaxsd);
7824
7825 return RValue<Int4>(Nucleus::createCall(pmaxsd, x.value, y.value));
7826 }
7827
7828 RValue<Int4> pminsd(RValue<Int4> x, RValue<Int4> y)
7829 {
7830 Module *module = Nucleus::getModule();
7831 llvm::Function *pminsd = Intrinsic::getDeclaration(module, Intrinsic::x86_sse41_pminsd);
7832
7833 return RValue<Int4>(Nucleus::createCall(pminsd, x.value, y.value));
7834 }
7835
7836 RValue<UInt4> pmaxud(RValue<UInt4> x, RValue<UInt4> y)
7837 {
7838 Module *module = Nucleus::getModule();
7839 llvm::Function *pmaxud = Intrinsic::getDeclaration(module, Intrinsic::x86_sse41_pmaxud);
7840
John Bauman66b8ab22014-05-06 15:57:45 -04007841 return RValue<UInt4>(Nucleus::createCall(pmaxud, x.value, y.value));
John Bauman19bac1e2014-05-06 15:23:49 -04007842 }
7843
7844 RValue<UInt4> pminud(RValue<UInt4> x, RValue<UInt4> y)
7845 {
7846 Module *module = Nucleus::getModule();
7847 llvm::Function *pminud = Intrinsic::getDeclaration(module, Intrinsic::x86_sse41_pminud);
7848
John Bauman66b8ab22014-05-06 15:57:45 -04007849 return RValue<UInt4>(Nucleus::createCall(pminud, x.value, y.value));
John Bauman19bac1e2014-05-06 15:23:49 -04007850 }
7851
7852 RValue<Short4> pmulhw(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007853 {
7854 Module *module = Nucleus::getModule();
7855 llvm::Function *pmulhw = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_pmulh_w);
7856
John Bauman19bac1e2014-05-06 15:23:49 -04007857 return As<Short4>(RValue<MMX>(Nucleus::createCall(pmulhw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007858 }
7859
John Bauman19bac1e2014-05-06 15:23:49 -04007860 RValue<UShort4> pmulhuw(RValue<UShort4> x, RValue<UShort4> y)
John Bauman89401822014-05-06 15:04:28 -04007861 {
7862 Module *module = Nucleus::getModule();
7863 llvm::Function *pmulhuw = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_pmulhu_w);
7864
John Bauman19bac1e2014-05-06 15:23:49 -04007865 return As<UShort4>(RValue<MMX>(Nucleus::createCall(pmulhuw, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007866 }
7867
John Bauman19bac1e2014-05-06 15:23:49 -04007868 RValue<Int2> pmaddwd(RValue<Short4> x, RValue<Short4> y)
John Bauman89401822014-05-06 15:04:28 -04007869 {
7870 Module *module = Nucleus::getModule();
7871 llvm::Function *pmaddwd = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_pmadd_wd);
7872
John Bauman19bac1e2014-05-06 15:23:49 -04007873 return As<Int2>(RValue<MMX>(Nucleus::createCall(pmaddwd, As<MMX>(x).value, As<MMX>(y).value)));
John Bauman89401822014-05-06 15:04:28 -04007874 }
7875
John Bauman19bac1e2014-05-06 15:23:49 -04007876 RValue<Short8> pmulhw(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04007877 {
7878 Module *module = Nucleus::getModule();
7879 llvm::Function *pmulhw = Intrinsic::getDeclaration(module, Intrinsic::x86_sse2_pmulh_w);
7880
7881 return RValue<Short8>(Nucleus::createCall(pmulhw, x.value, y.value));
7882 }
7883
John Bauman19bac1e2014-05-06 15:23:49 -04007884 RValue<UShort8> pmulhuw(RValue<UShort8> x, RValue<UShort8> y)
John Bauman89401822014-05-06 15:04:28 -04007885 {
7886 Module *module = Nucleus::getModule();
7887 llvm::Function *pmulhuw = Intrinsic::getDeclaration(module, Intrinsic::x86_sse2_pmulhu_w);
7888
7889 return RValue<UShort8>(Nucleus::createCall(pmulhuw, x.value, y.value));
7890 }
7891
John Bauman19bac1e2014-05-06 15:23:49 -04007892 RValue<Int4> pmaddwd(RValue<Short8> x, RValue<Short8> y)
John Bauman89401822014-05-06 15:04:28 -04007893 {
7894 Module *module = Nucleus::getModule();
7895 llvm::Function *pmaddwd = Intrinsic::getDeclaration(module, Intrinsic::x86_sse2_pmadd_wd);
7896
7897 return RValue<Int4>(Nucleus::createCall(pmaddwd, x.value, y.value));
7898 }
7899
John Bauman19bac1e2014-05-06 15:23:49 -04007900 RValue<Int> movmskps(RValue<Float4> x)
John Bauman89401822014-05-06 15:04:28 -04007901 {
7902 Module *module = Nucleus::getModule();
7903 llvm::Function *movmskps = Intrinsic::getDeclaration(module, Intrinsic::x86_sse_movmsk_ps);
7904
7905 return RValue<Int>(Nucleus::createCall(movmskps, x.value));
7906 }
7907
John Bauman19bac1e2014-05-06 15:23:49 -04007908 RValue<Int> pmovmskb(RValue<Byte8> x)
John Bauman89401822014-05-06 15:04:28 -04007909 {
7910 Module *module = Nucleus::getModule();
7911 llvm::Function *pmovmskb = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_pmovmskb);
7912
John Bauman19bac1e2014-05-06 15:23:49 -04007913 return RValue<Int>(Nucleus::createCall(pmovmskb, As<MMX>(x).value));
John Bauman89401822014-05-06 15:04:28 -04007914 }
7915
Nicolas Capens81f18302016-01-14 09:32:35 -05007916 //RValue<Int2> movd(RValue<Pointer<Int>> x)
John Bauman89401822014-05-06 15:04:28 -04007917 //{
7918 // Value *element = Nucleus::createLoad(x.value);
7919
7920 //// Value *int2 = UndefValue::get(Int2::getType());
7921 //// int2 = Nucleus::createInsertElement(int2, element, ConstantInt::get(Int::getType(), 0));
7922
7923 // Value *int2 = Nucleus::createBitCast(Nucleus::createZExt(element, Long::getType()), Int2::getType());
7924
7925 // return RValue<Int2>(int2);
7926 //}
7927
John Bauman19bac1e2014-05-06 15:23:49 -04007928 //RValue<Int2> movdq2q(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007929 //{
7930 // Value *long2 = Nucleus::createBitCast(x.value, Long2::getType());
7931 // Value *element = Nucleus::createExtractElement(long2, ConstantInt::get(Int::getType(), 0));
7932
7933 // return RValue<Int2>(Nucleus::createBitCast(element, Int2::getType()));
7934 //}
7935
John Bauman19bac1e2014-05-06 15:23:49 -04007936 RValue<Int4> pmovzxbd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007937 {
7938 Module *module = Nucleus::getModule();
7939 llvm::Function *pmovzxbd = Intrinsic::getDeclaration(module, Intrinsic::x86_sse41_pmovzxbd);
John Bauman66b8ab22014-05-06 15:57:45 -04007940
John Bauman89401822014-05-06 15:04:28 -04007941 return RValue<Int4>(Nucleus::createCall(pmovzxbd, Nucleus::createBitCast(x.value, Byte16::getType())));
7942 }
7943
John Bauman19bac1e2014-05-06 15:23:49 -04007944 RValue<Int4> pmovsxbd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007945 {
7946 Module *module = Nucleus::getModule();
7947 llvm::Function *pmovsxbd = Intrinsic::getDeclaration(module, Intrinsic::x86_sse41_pmovsxbd);
John Bauman66b8ab22014-05-06 15:57:45 -04007948
John Bauman89401822014-05-06 15:04:28 -04007949 return RValue<Int4>(Nucleus::createCall(pmovsxbd, Nucleus::createBitCast(x.value, SByte16::getType())));
7950 }
7951
John Bauman19bac1e2014-05-06 15:23:49 -04007952 RValue<Int4> pmovzxwd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007953 {
7954 Module *module = Nucleus::getModule();
7955 llvm::Function *pmovzxwd = Intrinsic::getDeclaration(module, Intrinsic::x86_sse41_pmovzxwd);
John Bauman66b8ab22014-05-06 15:57:45 -04007956
John Bauman89401822014-05-06 15:04:28 -04007957 return RValue<Int4>(Nucleus::createCall(pmovzxwd, Nucleus::createBitCast(x.value, UShort8::getType())));
7958 }
7959
John Bauman19bac1e2014-05-06 15:23:49 -04007960 RValue<Int4> pmovsxwd(RValue<Int4> x)
John Bauman89401822014-05-06 15:04:28 -04007961 {
7962 Module *module = Nucleus::getModule();
7963 llvm::Function *pmovsxwd = Intrinsic::getDeclaration(module, Intrinsic::x86_sse41_pmovsxwd);
John Bauman66b8ab22014-05-06 15:57:45 -04007964
John Bauman89401822014-05-06 15:04:28 -04007965 return RValue<Int4>(Nucleus::createCall(pmovsxwd, Nucleus::createBitCast(x.value, Short8::getType())));
7966 }
7967
7968 void emms()
7969 {
7970 Module *module = Nucleus::getModule();
7971 llvm::Function *emms = Intrinsic::getDeclaration(module, Intrinsic::x86_mmx_emms);
7972
7973 Nucleus::createCall(emms);
7974 }
7975 }
7976}