diff options
-rw-r--r-- | src/mesa/pipe/llvm/instructions.cpp | 51 | ||||
-rw-r--r-- | src/mesa/pipe/llvm/instructions.h | 6 | ||||
-rw-r--r-- | src/mesa/pipe/llvm/llvmtgsi.cpp | 8 |
3 files changed, 62 insertions, 3 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); +} + diff --git a/src/mesa/pipe/llvm/instructions.h b/src/mesa/pipe/llvm/instructions.h index de33b79e378..17165ac9e70 100644 --- a/src/mesa/pipe/llvm/instructions.h +++ b/src/mesa/pipe/llvm/instructions.h @@ -20,6 +20,8 @@ public: llvm::Value *dph(llvm::Value *in1, llvm::Value *in2); llvm::Value *dst(llvm::Value *in1, llvm::Value *in2); llvm::Value *ex2(llvm::Value *in1); + llvm::Value *floor(llvm::Value *in1); + llvm::Value *frc(llvm::Value *in1); llvm::Value *lit(llvm::Value *in1); llvm::Value *madd(llvm::Value *in1, llvm::Value *in2, llvm::Value *in2); @@ -31,8 +33,9 @@ public: private: const char *name(const char *prefix); - llvm::Value *callFSqrt(llvm::Value *val); llvm::Value *callFAbs(llvm::Value *val); + llvm::Value *callFloor(llvm::Value *val); + llvm::Value *callFSqrt(llvm::Value *val); llvm::Value *callPow(llvm::Value *val1, llvm::Value *val2); llvm::Value *vectorFromVals(llvm::Value *x, llvm::Value *y, @@ -48,6 +51,7 @@ private: llvm::Function *m_llvmFSqrt; llvm::Function *m_llvmFAbs; llvm::Function *m_llvmPow; + llvm::Function *m_llvmFloor; }; #endif diff --git a/src/mesa/pipe/llvm/llvmtgsi.cpp b/src/mesa/pipe/llvm/llvmtgsi.cpp index 5ad45ff6ccf..44caa59d52f 100644 --- a/src/mesa/pipe/llvm/llvmtgsi.cpp +++ b/src/mesa/pipe/llvm/llvmtgsi.cpp @@ -241,11 +241,15 @@ translate_instruction(llvm::Module *module, break; case TGSI_OPCODE_NEGATE: break; - case TGSI_OPCODE_FRAC: + case TGSI_OPCODE_FRAC: { + out = instr->frc(inputs[0]); + } break; case TGSI_OPCODE_CLAMP: break; - case TGSI_OPCODE_FLOOR: + case TGSI_OPCODE_FLOOR: { + out = instr->floor(inputs[0]); + } break; case TGSI_OPCODE_ROUND: break; |