summaryrefslogtreecommitdiffstats
path: root/src/mesa/pipe/llvm/instructions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/pipe/llvm/instructions.cpp')
-rw-r--r--src/mesa/pipe/llvm/instructions.cpp51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/mesa/pipe/llvm/instructions.cpp b/src/mesa/pipe/llvm/instructions.cpp
index 1e6b74eac62..ee9104434ff 100644
--- a/src/mesa/pipe/llvm/instructions.cpp
+++ b/src/mesa/pipe/llvm/instructions.cpp
@@ -16,6 +16,7 @@ Instructions::Instructions(llvm::Module *mod, llvm::BasicBlock *block)
m_llvmFSqrt = 0;
m_llvmFAbs = 0;
m_llvmPow = 0;
+ m_llvmFloor = 0;
}
llvm::Value * Instructions::add(llvm::Value *in1, llvm::Value *in2)
@@ -311,3 +312,53 @@ llvm::Value * Instructions::ex2(llvm::Value *in)
return vectorFromVals(val, val, val, val);
}
+llvm::Value * Instructions::callFloor(llvm::Value *val)
+{
+ if (!m_llvmFloor) {
+ // predeclare the intrinsic
+ std::vector<const Type*> floorArgs;
+ floorArgs.push_back(Type::FloatTy);
+ ParamAttrsList *floorPal = 0;
+ FunctionType* floorType = FunctionType::get(
+ /*Result=*/Type::FloatTy,
+ /*Params=*/floorArgs,
+ /*isVarArg=*/false,
+ /*ParamAttrs=*/floorPal);
+ m_llvmFloor = new Function(
+ /*Type=*/floorType,
+ /*Linkage=*/GlobalValue::ExternalLinkage,
+ /*Name=*/"floorf", m_mod);
+ m_llvmFloor->setCallingConv(CallingConv::C);
+ }
+ CallInst *call = new CallInst(m_llvmFloor, val,
+ name("floorf"),
+ m_block);
+ call->setCallingConv(CallingConv::C);
+ call->setTailCall(false);
+ return call;
+}
+
+llvm::Value * Instructions::floor(llvm::Value *in)
+{
+ ExtractElementInst *x = new ExtractElementInst(in, unsigned(0),
+ name("extractx"),
+ m_block);
+ ExtractElementInst *y = new ExtractElementInst(in, unsigned(1),
+ name("extracty"),
+ m_block);
+ ExtractElementInst *z = new ExtractElementInst(in, unsigned(2),
+ name("extractz"),
+ m_block);
+ ExtractElementInst *w = new ExtractElementInst(in, unsigned(3),
+ name("extractw"),
+ m_block);
+ return vectorFromVals(callFloor(x), callFloor(y),
+ callFloor(z), callFloor(w));
+}
+
+llvm::Value * Instructions::frc(llvm::Value *in)
+{
+ llvm::Value *flr = floor(in);
+ return sub(in, flr);
+}
+