From: Stephane Marchesin Date: Sun, 28 Sep 2008 17:48:26 +0000 (+0200) Subject: Gallivm: more instructions. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a0a06cbc5b26d7530bd5066f09efe3c1f980d35d;p=mesa.git Gallivm: more instructions. --- diff --git a/src/gallium/auxiliary/gallivm/instructions.cpp b/src/gallium/auxiliary/gallivm/instructions.cpp index 5fdfe09d182..3eaf9aacf60 100644 --- a/src/gallium/auxiliary/gallivm/instructions.cpp +++ b/src/gallium/auxiliary/gallivm/instructions.cpp @@ -163,9 +163,18 @@ void Instructions::cal(int label, llvm::Value *input) m_builder.CreateCall(func, params.begin(), params.end()); } +llvm::Value * Instructions::ceil(llvm::Value *in) +{ + std::vector vec = extractVector(in); + return vectorFromVals(callCeil(vec[0]), callCeil(vec[1]), + callCeil(vec[2]), callCeil(vec[3])); +} + llvm::Value * Instructions::clamp(llvm::Value *in1) { - // FIXME + llvm::Value *zero = constVector(0.0f, 0.0f, 0.0f, 0.0f); + llvm::Value *one = constVector(1.0f, 1.0f, 1.0f, 1.0f); + return min( max(zero, in1), one); } llvm::Value * Instructions::cmp(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3) @@ -289,12 +298,14 @@ llvm::Value * Instructions::cross(llvm::Value *in1, llvm::Value *in2) llvm::Value * Instructions::ddx(llvm::Value *in) { - // FIXME + // FIXME + assert(0); } llvm::Value * Instructions::ddy(llvm::Value *in) { - // FIXME + // FIXME + assert(0); } llvm::Value * Instructions::div(llvm::Value *in1, llvm::Value *in2) @@ -319,6 +330,19 @@ llvm::Value * Instructions::dot2add(llvm::Value *in1, llvm::Value *in2, llvm::Va return vectorFromVals(dot2add, dot2add, dot2add, dot2add); } +llvm::Value * Instructions::dp2(llvm::Value *in1, llvm::Value *in2) +{ + Value *mulRes = mul(in1, in2); + Value *x = m_builder.CreateExtractElement(mulRes, + m_storage->constantInt(0), + name("extractx")); + Value *y = m_builder.CreateExtractElement(mulRes, + m_storage->constantInt(1), + name("extracty")); + Value *xy = m_builder.CreateAdd(x, y,name("xy")); + return vectorFromVals(xy, xy, xy, xy); +} + llvm::Value * Instructions::dp3(llvm::Value *in1, llvm::Value *in2) { Value *mulRes = mul(in1, in2); @@ -581,6 +605,12 @@ llvm::Value * Instructions::neg(llvm::Value *in) return neg; } +llvm::Value * Instructions::nrm(llvm::Value *in) +{ + llvm::Value *v = rsq(in); + return mul(v, in); +} + llvm::Value * Instructions::pow(llvm::Value *in1, llvm::Value *in2) { Value *x1 = m_builder.CreateExtractElement(in1, @@ -887,6 +917,31 @@ const char * Instructions::name(const char *prefix) return m_name; } +llvm::Value * Instructions::callCeil(llvm::Value *val) +{ + if (!m_llvmCeil) { + // predeclare the intrinsic + std::vector ceilArgs; + ceilArgs.push_back(Type::FloatTy); + PAListPtr ceilPal; + FunctionType* ceilType = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/ceilArgs, + /*isVarArg=*/false); + m_llvmCeil = Function::Create( + /*Type=*/ceilType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"ceilf", m_mod); + m_llvmCeil->setCallingConv(CallingConv::C); + m_llvmCeil->setParamAttrs(ceilPal); + } + CallInst *call = m_builder.CreateCall(m_llvmCeil, val, + name("ceilf")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + llvm::Value *Instructions::callFAbs(llvm::Value *val) { if (!m_llvmFAbs) { diff --git a/src/gallium/auxiliary/gallivm/instructions.h b/src/gallium/auxiliary/gallivm/instructions.h index 8df30f62c8a..c3b28e97469 100644 --- a/src/gallium/auxiliary/gallivm/instructions.h +++ b/src/gallium/auxiliary/gallivm/instructions.h @@ -63,6 +63,7 @@ public: void bgnSub(unsigned); void brk(); void cal(int label, llvm::Value *input); + llvm::Value *ceil(llvm::Value *in); llvm::Value *clamp(llvm::Value *in); llvm::Value *cmp(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3); llvm::Value *cnd(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3); @@ -73,6 +74,7 @@ public: llvm::Value *ddy(llvm::Value *in); llvm::Value *div(llvm::Value *in1, llvm::Value *in2); llvm::Value *dot2add(llvm::Value *in, llvm::Value *in2, llvm::Value *in3); + llvm::Value *dp2(llvm::Value *in1, llvm::Value *in2); llvm::Value *dp3(llvm::Value *in1, llvm::Value *in2); llvm::Value *dp4(llvm::Value *in1, llvm::Value *in2); llvm::Value *dph(llvm::Value *in1, llvm::Value *in2); @@ -99,6 +101,7 @@ public: llvm::Value *min(llvm::Value *in1, llvm::Value *in2); llvm::Value *mul(llvm::Value *in1, llvm::Value *in2); llvm::Value *neg(llvm::Value *in); + llvm::Value *nrm(llvm::Value *in); llvm::Value *pow(llvm::Value *in1, llvm::Value *in2); llvm::Value *rcp(llvm::Value *in); llvm::Value *rsq(llvm::Value *in); @@ -120,6 +123,7 @@ public: private: const char *name(const char *prefix); + llvm::Value *callCeil(llvm::Value *val); llvm::Value *callFAbs(llvm::Value *val); llvm::Value *callFExp(llvm::Value *val); llvm::Value *callFLog(llvm::Value *val); @@ -147,6 +151,7 @@ private: llvm::VectorType *m_floatVecType; + llvm::Function *m_llvmCeil; llvm::Function *m_llvmFSqrt; llvm::Function *m_llvmFAbs; llvm::Function *m_llvmPow; diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp index 398fbd67bd1..fdfbb76c16a 100644 --- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp +++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp @@ -498,11 +498,18 @@ translate_instruction(llvm::Module *module, break; case TGSI_OPCODE_TXB: break; - case TGSI_OPCODE_NRM: + case TGSI_OPCODE_NRM4: + case TGSI_OPCODE_NRM: { + out = instr->nrm(inputs[0]); + } break; - case TGSI_OPCODE_DIV: + case TGSI_OPCODE_DIV: { + out = instr->div(inputs[0], inputs[1]); + } break; - case TGSI_OPCODE_DP2: + case TGSI_OPCODE_DP2: { + out = instr->dp2(inputs[0], inputs[1]); + } break; case TGSI_OPCODE_TXL: break; @@ -620,8 +627,6 @@ translate_instruction(llvm::Module *module, break; case TGSI_OPCODE_M3X2: break; - case TGSI_OPCODE_NRM4: - break; case TGSI_OPCODE_CALLNZ: break; case TGSI_OPCODE_IFC: