summaryrefslogtreecommitdiffstats
path: root/src/mesa/pipe/llvm/storage.cpp
diff options
context:
space:
mode:
authorZack Rusin <[email protected]>2007-10-24 07:49:24 -0400
committerZack Rusin <[email protected]>2007-10-24 11:21:05 -0400
commit5040eefbb758fb0e02125ad3a6bfb3dba13cb7fa (patch)
treec41eadb25f4ac6cd5ac0edd3f7abdd3ac1239ba0 /src/mesa/pipe/llvm/storage.cpp
parentba823b3ded1b6ec47b8a0e26ed08a229fe1a9140 (diff)
Implement arl, lerp opcodes and do a first stab at if/endif
handling and branching support.
Diffstat (limited to 'src/mesa/pipe/llvm/storage.cpp')
-rw-r--r--src/mesa/pipe/llvm/storage.cpp130
1 files changed, 117 insertions, 13 deletions
diff --git a/src/mesa/pipe/llvm/storage.cpp b/src/mesa/pipe/llvm/storage.cpp
index 3bf37c75673..5b1f05190e2 100644
--- a/src/mesa/pipe/llvm/storage.cpp
+++ b/src/mesa/pipe/llvm/storage.cpp
@@ -17,7 +17,8 @@ Storage::Storage(llvm::BasicBlock *block, llvm::Value *out,
llvm::Value *in, llvm::Value *consts)
: m_block(block), m_OUT(out),
m_IN(in), m_CONST(consts),
- m_temps(32), m_dstCache(32),
+ m_temps(32), m_addrs(32),
+ m_dstCache(32),
m_idx(0)
{
m_floatVecType = VectorType::get(Type::FloatTy, 4);
@@ -88,15 +89,29 @@ llvm::ConstantInt *Storage::constantInt(int idx)
return const_int;
}
-llvm::Value *Storage::inputElement(int idx)
+llvm::Value *Storage::inputElement(int idx, llvm::Value *indIdx)
{
- if (m_inputs.find(idx) != m_inputs.end()) {
+ if (!indIdx && m_inputs.find(idx) != m_inputs.end()) {
return m_inputs[idx];
}
- GetElementPtrInst *getElem = new GetElementPtrInst(m_IN,
- constantInt(idx),
- name("input_ptr"),
- m_block);
+ GetElementPtrInst *getElem = 0;
+
+ if (indIdx) {
+ getElem = new GetElementPtrInst(m_IN,
+ BinaryOperator::create(Instruction::Add,
+ indIdx,
+ constantInt(idx),
+ name("add"),
+ m_block),
+ name("input_ptr"),
+ m_block);
+ } else {
+ getElem = new GetElementPtrInst(m_IN,
+ constantInt(idx),
+ name("input_ptr"),
+ m_block);
+ }
+
LoadInst *load = new LoadInst(getElem, name("input"),
false, m_block);
load->setAlignment(8);
@@ -105,16 +120,29 @@ llvm::Value *Storage::inputElement(int idx)
return load;
}
-llvm::Value *Storage::constElement(int idx)
+llvm::Value *Storage::constElement(int idx, llvm::Value *indIdx)
{
m_numConsts = ((idx + 1) > m_numConsts) ? (idx + 1) : m_numConsts;
- if (m_consts.find(idx) != m_consts.end()) {
+ if (!indIdx && m_consts.find(idx) != m_consts.end()) {
return m_consts[idx];
}
- GetElementPtrInst *getElem = new GetElementPtrInst(m_CONST,
- constantInt(idx),
- name("const_ptr"),
- m_block);
+
+ GetElementPtrInst *getElem = 0;
+
+ if (indIdx)
+ getElem = new GetElementPtrInst(m_CONST,
+ BinaryOperator::create(Instruction::Add,
+ indIdx,
+ constantInt(idx),
+ name("add"),
+ m_block),
+ name("const_ptr"),
+ m_block);
+ else
+ getElem = new GetElementPtrInst(m_CONST,
+ constantInt(idx),
+ name("const_ptr"),
+ m_block);
LoadInst *load = new LoadInst(getElem, name("const"),
false, m_block);
load->setAlignment(8);
@@ -146,7 +174,17 @@ void Storage::setTempElement(int idx, llvm::Value *val, int mask)
llvm::Value *templ = m_temps[idx];
val = maskWrite(val, mask, templ);
}
+ llvm::Value *templ = m_temps[idx];
+ if (templ) {
+ BasicBlock *block = m_varBlocks[templ];
+ if (block != m_block) {
+ addPhiNode(idx, val, m_block, templ, block);
+ } else
+ updatePhiNode(idx, val);
+ }
+
m_temps[idx] = val;
+ m_varBlocks[val] = m_block;
}
void Storage::store(int dstIdx, llvm::Value *val, int mask)
@@ -208,3 +246,69 @@ int Storage::numConsts() const
{
return m_numConsts;
}
+
+llvm::Value * Storage::addrElement(int idx) const
+{
+ Value *ret = m_addrs[idx];
+ if (!ret)
+ return m_undefFloatVec;
+ return ret;
+}
+
+void Storage::setAddrElement(int idx, llvm::Value *val, int mask)
+{
+ if (mask != TGSI_WRITEMASK_XYZW) {
+ llvm::Value *templ = m_addrs[idx];
+ val = maskWrite(val, mask, templ);
+ }
+ m_addrs[idx] = val;
+}
+
+llvm::Value * Storage::extractIndex(llvm::Value *vec)
+{
+ llvm::Value *x = new ExtractElementInst(vec, unsigned(0),
+ name("x"), m_block);
+ return new FPToSIInst(x, IntegerType::get(32), name("intidx"), m_block);
+}
+
+void Storage::setCurrentBlock(llvm::BasicBlock *block)
+{
+ m_block = block;
+}
+
+void Storage::addPhiNode(int idx, llvm::Value *val1, llvm::BasicBlock *blk1,
+ llvm::Value *val2, llvm::BasicBlock *blk2)
+{
+ PhiNode node;
+ node.val1 = val1;
+ node.block1 = blk1;
+ node.val2 = val2;
+ node.block2 = blk2;
+ m_phiNodes[idx] = node;
+}
+
+void Storage::updatePhiNode(int idx, llvm::Value *val1)
+{
+ if (m_phiNodes.find(idx) == m_phiNodes.end())
+ return;
+ PhiNode node = m_phiNodes[idx];
+ node.val1 = val1;
+ m_phiNodes[idx] = node;
+}
+
+void Storage::popPhiNode()
+{
+ if (!m_phiNodes.empty()) {
+ std::map<int, PhiNode>::const_iterator itr;
+ for (itr = m_phiNodes.begin(); itr != m_phiNodes.end(); ++itr) {
+ PhiNode node = (*itr).second;
+ PHINode *dest = new PHINode(m_floatVecType,
+ name("phiDest"), m_block);
+ dest->reserveOperandSpace(2);
+ dest->addIncoming(node.val1, node.block1);
+ dest->addIncoming(node.val2, node.block2);
+ m_temps[(*itr).first] = dest;
+ }
+ }
+ m_phiNodes.clear();
+}