From 3975f34fd36f8b04d499bb6b3d48eaeef5cab24e Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Wed, 17 Oct 2007 11:27:46 -0400 Subject: Implement basic opcode translation and storage translation. --- src/mesa/pipe/llvm/instructions.cpp | 162 ++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 src/mesa/pipe/llvm/instructions.cpp (limited to 'src/mesa/pipe/llvm/instructions.cpp') diff --git a/src/mesa/pipe/llvm/instructions.cpp b/src/mesa/pipe/llvm/instructions.cpp new file mode 100644 index 0000000000..147a1b64f2 --- /dev/null +++ b/src/mesa/pipe/llvm/instructions.cpp @@ -0,0 +1,162 @@ +#include "instructions.h" + +#include +#include +#include +#include +#include + +using namespace llvm; + +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; +} + +llvm::Value * Instructions::add(llvm::Value *in1, llvm::Value *in2) +{ + BinaryOperator *res = BinaryOperator::create(Instruction::Add, in1, in2, + name("add"), + m_block); + return res; +} + +llvm::Value * Instructions::madd(llvm::Value *in1, llvm::Value *in2, + llvm::Value *in3) +{ + Value *mulRes = mul(in1, in2); + return add(mulRes, in3); +} + +llvm::Value * Instructions::mul(llvm::Value *in1, llvm::Value *in2) +{ + BinaryOperator *res = BinaryOperator::create(Instruction::Mul, in1, in2, + name("mul"), + m_block); + return res; +} + +const char * Instructions::name(const char *prefix) +{ + ++m_idx; + snprintf(m_name, 32, "%s%d", prefix, m_idx); + return m_name; +} + +llvm::Value * Instructions::dp3(llvm::Value *in1, llvm::Value *in2) +{ + Value *mulRes = mul(in1, in2); + ExtractElementInst *x = new ExtractElementInst(mulRes, unsigned(0), + name("extractx"), + m_block); + ExtractElementInst *y = new ExtractElementInst(mulRes, unsigned(1), + name("extracty"), + m_block); + ExtractElementInst *z = new ExtractElementInst(mulRes, unsigned(2), + name("extractz"), + m_block); + BinaryOperator *xy = BinaryOperator::create(Instruction::Add, x, y, + name("xy"), + m_block); + BinaryOperator *dot3 = BinaryOperator::create(Instruction::Add, xy, z, + name("dot3"), + m_block); + return vectorFromVals(dot3, dot3, dot3, dot3); +} + +llvm::Value *Instructions::callFSqrt(llvm::Value *val) +{ + if (!m_llvmFSqrt) { + // predeclare the intrinsic + std::vector fsqrtArgs; + fsqrtArgs.push_back(Type::FloatTy); + ParamAttrsList *fsqrtPal = 0; + FunctionType* fsqrtType = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/fsqrtArgs, + /*isVarArg=*/false, + /*ParamAttrs=*/fsqrtPal); + m_llvmFSqrt = new Function( + /*Type=*/fsqrtType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"llvm.sqrt.f32", m_mod); + m_llvmFSqrt->setCallingConv(CallingConv::C); + } + CallInst *call = new CallInst(m_llvmFSqrt, val, + name("sqrt"), + m_block); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::rsq(llvm::Value *in1) +{ + ExtractElementInst *x = new ExtractElementInst(in1, unsigned(0), + name("extractx"), + m_block); + Value *abs = callFAbs(x); + Value *sqrt = callFSqrt(abs); + + BinaryOperator *rsqrt = BinaryOperator::create(Instruction::FDiv, + ConstantFP::get(Type::FloatTy, + APFloat(1.f)), + sqrt, + name("rsqrt"), + m_block); + return vectorFromVals(rsqrt, rsqrt, rsqrt, rsqrt); +} + +llvm::Value * Instructions::vectorFromVals(llvm::Value *x, llvm::Value *y, + llvm::Value *z, llvm::Value *w) +{ + Constant *const_vec = Constant::getNullValue(m_floatVecType); + InsertElementInst *res = new InsertElementInst(const_vec, x, unsigned(0), + name("vecx"), m_block); + res = new InsertElementInst(res, y, unsigned(1), + name("vecxy"), + m_block); + res = new InsertElementInst(res, z, unsigned(2), + name("vecxyz"), + m_block); + if (w) + res = new InsertElementInst(res, w, unsigned(3), + name("vecxyw"), + m_block); + return res; +} + +llvm::Value *Instructions::callFAbs(llvm::Value *val) +{ + if (!m_llvmFAbs) { + // predeclare the intrinsic + std::vector fabsArgs; + fabsArgs.push_back(Type::FloatTy); + ParamAttrsList *fabsPal = 0; + FunctionType* fabsType = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/fabsArgs, + /*isVarArg=*/false, + /*ParamAttrs=*/fabsPal); + m_llvmFAbs = new Function( + /*Type=*/fabsType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"fabs", m_mod); + m_llvmFAbs->setCallingConv(CallingConv::C); + } + CallInst *call = new CallInst(m_llvmFAbs, val, + name("fabs"), + m_block); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::lit(llvm::Value *in1) +{ + return in1; +} + -- cgit v1.2.3