m_block);
FCmpInst *xcmp = new FCmpInst(FCmpInst::FCMP_UNE, x, float0,
name("xcmp"), m_block);
- new BranchInst(ifend, ifthen, xcmp, m_block);
+ new BranchInst(ifthen, ifend, xcmp, m_block);
//m_block = yblock;
static void
translate_declaration(llvm::Module *module,
+ Storage *storage,
struct tgsi_full_declaration *decl,
struct tgsi_full_declaration *fd)
{
+ if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
+ switch( decl->Declaration.Declare ) {
+ case TGSI_DECLARE_RANGE: {
+ int start = decl->u.DeclarationRange.First;
+ int end = decl->u.DeclarationRange.Last;
+ for (int i = start; i <= end; ++i) {
+ storage->declareTemp(i);
+ }
+ }
+ break;
+ default:
+ assert( 0 );
+ }
+ }
}
val = storage->inputElement(src->SrcRegister.Index, indIdx);
} else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) {
val = storage->tempElement(src->SrcRegister.Index);
+ } else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) {
+ fprintf(stderr, "FIXME: do somethign with immediates?\n");
} else {
- fprintf(stderr, "ERROR: not supported llvm source\n");
+ fprintf(stderr, "ERROR: not supported llvm source %d\n", src->SrcRegister.File);
return;
}
case TGSI_OPCODE_ENDIF: {
instr->endif();
storage->setCurrentBlock(instr->currentBlock());
- storage->popPhiNode();
return; //just update the state
}
break;
switch (parse.FullToken.Token.Type) {
case TGSI_TOKEN_TYPE_DECLARATION:
- translate_declaration(mod,
+ translate_declaration(mod, &storage,
&parse.FullToken.FullDeclaration,
&fd);
break;
}
-llvm::Value *Storage::tempElement(int idx) const
+llvm::Value *Storage::tempElement(int idx)
{
- Value *ret = m_temps[idx];
- if (!ret)
+ Value *ptr = m_temps[idx];
+ if (!ptr)
return m_undefFloatVec;
- return ret;
+ llvm::LoadInst *li = new LoadInst(ptr, name("temp"),
+ false, m_block);
+ li->setAlignment(8);
+ return li;
}
void Storage::setTempElement(int idx, llvm::Value *val, int mask)
{
if (mask != TGSI_WRITEMASK_XYZW) {
- llvm::Value *templ = m_temps[idx];
+ llvm::Value *templ = 0;
+ if (m_temps[idx])
+ templ = tempElement(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;
+ llvm::Value *ptr = m_temps[idx];
+ assert(ptr);
+ StoreInst *st = new StoreInst(val, ptr, false, m_block);
+ st->setAlignment(8);
}
void Storage::store(int dstIdx, llvm::Value *val, int mask)
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()
+void Storage::declareTemp(int idx)
{
- 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();
+ m_temps[idx] = new AllocaInst(m_floatVecType, name("temp"), m_block);
}
llvm::Value *inputElement(int idx, llvm::Value *indIdx =0);
llvm::Value *constElement(int idx, llvm::Value *indIdx =0);
- llvm::Value *tempElement(int idx) const;
+ llvm::Value *tempElement(int idx);
void setTempElement(int idx, llvm::Value *val, int mask);
+ void declareTemp(int idx);
llvm::Value *addrElement(int idx) const;
void setAddrElement(int idx, llvm::Value *val, int mask);
void store(int dstIdx, llvm::Value *val, int mask);
- void popPhiNode();
-
int numConsts() const;
private:
llvm::Value *maskWrite(llvm::Value *src, int mask, llvm::Value *templ);
int m_idx;
int m_numConsts;
-
- void addPhiNode(int, llvm::Value*, llvm::BasicBlock*,
- llvm::Value*, llvm::BasicBlock*);
- void updatePhiNode(int, llvm::Value*);
- struct PhiNode {
- llvm::Value *val1;
- llvm::BasicBlock *block1;
- llvm::Value *val2;
- llvm::BasicBlock *block2;
- };
-
- std::map<llvm::Value*, llvm::BasicBlock*> m_varBlocks;
- std::map<int, PhiNode> m_phiNodes;
};
#endif