summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/pipe/llvm/instructions.cpp51
-rw-r--r--src/mesa/pipe/llvm/instructions.h6
-rw-r--r--src/mesa/pipe/llvm/llvmtgsi.cpp8
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;