summaryrefslogtreecommitdiff
path: root/src/mesa/pipe/llvm/instructions.cpp
diff options
context:
space:
mode:
authorZack Rusin <zack@tungstengraphics.com>2007-10-17 13:27:25 -0400
committerZack Rusin <zack@tungstengraphics.com>2007-10-24 11:21:04 -0400
commite20294be114c2593035afaf6fe0726e0ce628ed0 (patch)
treea5d1fff22f0d220d446cd878f09e23e9af82f8a3 /src/mesa/pipe/llvm/instructions.cpp
parentfcbde5e9f44ee7254b6618b6fe2be98a1c803ed2 (diff)
Implement pow/rcp and sub opcodes
Diffstat (limited to 'src/mesa/pipe/llvm/instructions.cpp')
-rw-r--r--src/mesa/pipe/llvm/instructions.cpp66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/mesa/pipe/llvm/instructions.cpp b/src/mesa/pipe/llvm/instructions.cpp
index 147a1b64f2..31729d0f58 100644
--- a/src/mesa/pipe/llvm/instructions.cpp
+++ b/src/mesa/pipe/llvm/instructions.cpp
@@ -12,8 +12,10 @@ Instructions::Instructions(llvm::Module *mod, llvm::BasicBlock *block)
: m_mod(mod), m_block(block), m_idx(0)
{
m_floatVecType = VectorType::get(Type::FloatTy, 4);
+
m_llvmFSqrt = 0;
m_llvmFAbs = 0;
+ m_llvmPow = 0;
}
llvm::Value * Instructions::add(llvm::Value *in1, llvm::Value *in2)
@@ -160,3 +162,67 @@ llvm::Value * Instructions::lit(llvm::Value *in1)
return in1;
}
+llvm::Value * Instructions::sub(llvm::Value *in1, llvm::Value *in2)
+{
+ BinaryOperator *res = BinaryOperator::create(Instruction::Sub, in1, in2,
+ name("sub"),
+ m_block);
+ return res;
+}
+
+llvm::Value * Instructions::callPow(llvm::Value *val1, llvm::Value *val2)
+{
+ if (!m_llvmPow) {
+ // predeclare the intrinsic
+ std::vector<const Type*> powArgs;
+ powArgs.push_back(Type::FloatTy);
+ powArgs.push_back(Type::FloatTy);
+ ParamAttrsList *powPal = 0;
+ FunctionType* powType = FunctionType::get(
+ /*Result=*/Type::FloatTy,
+ /*Params=*/powArgs,
+ /*isVarArg=*/false,
+ /*ParamAttrs=*/powPal);
+ m_llvmPow = new Function(
+ /*Type=*/powType,
+ /*Linkage=*/GlobalValue::ExternalLinkage,
+ /*Name=*/"llvm.pow.f32", m_mod);
+ m_llvmPow->setCallingConv(CallingConv::C);
+ }
+ std::vector<Value*> params;
+ params.push_back(val1);
+ params.push_back(val2);
+ CallInst *call = new CallInst(m_llvmPow, params.begin(), params.end(),
+ name("pow"),
+ m_block);
+ call->setCallingConv(CallingConv::C);
+ call->setTailCall(false);
+ return call;
+}
+
+llvm::Value * Instructions::pow(llvm::Value *in1, llvm::Value *in2)
+{
+ ExtractElementInst *x1 = new ExtractElementInst(in1, unsigned(0),
+ name("x1"),
+ m_block);
+ ExtractElementInst *x2 = new ExtractElementInst(in2, unsigned(0),
+ name("x2"),
+ m_block);
+ llvm::Value *val = callPow(x1, x2);
+ return vectorFromVals(val, val, val, val);
+}
+
+llvm::Value * Instructions::rcp(llvm::Value *in1)
+{
+ ExtractElementInst *x1 = new ExtractElementInst(in1, unsigned(0),
+ name("x1"),
+ m_block);
+ BinaryOperator *res = BinaryOperator::create(Instruction::FDiv,
+ ConstantFP::get(Type::FloatTy,
+ APFloat(1.f)),
+ x1,
+ name("rcp"),
+ m_block);
+ return vectorFromVals(res, res, res, res);
+}
+