summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZack Rusin <zack@tungstengraphics.com>2007-10-25 11:47:25 -0400
committerZack Rusin <zack@tungstengraphics.com>2007-10-25 11:47:25 -0400
commit4a4e6f2cabdf39e9032e3e513f9966f471454077 (patch)
treebe8abacf1a2b5e71c51217fbfcca17e244c8ad24
parent1d17cb721afaa53317614af90488a45c26e083e3 (diff)
Implement loops
-rw-r--r--progs/vpglsl/for.glsl7
-rw-r--r--src/mesa/pipe/llvm/instructions.cpp64
-rw-r--r--src/mesa/pipe/llvm/instructions.h11
-rw-r--r--src/mesa/pipe/llvm/llvmtgsi.cpp21
4 files changed, 98 insertions, 5 deletions
diff --git a/progs/vpglsl/for.glsl b/progs/vpglsl/for.glsl
new file mode 100644
index 00000000000..45d6845dacc
--- /dev/null
+++ b/progs/vpglsl/for.glsl
@@ -0,0 +1,7 @@
+
+void main() {
+ gl_Position = gl_Vertex;
+ gl_FrontColor = vec4(0);
+ for (int i = 0; i < 4; ++i)
+ gl_FrontColor += gl_Color;
+}
diff --git a/src/mesa/pipe/llvm/instructions.cpp b/src/mesa/pipe/llvm/instructions.cpp
index a0645c58045..5b54af87178 100644
--- a/src/mesa/pipe/llvm/instructions.cpp
+++ b/src/mesa/pipe/llvm/instructions.cpp
@@ -1016,3 +1016,67 @@ llvm::Value * Instructions::lerp(llvm::Value *in1, llvm::Value *in2,
return add(m, mul(s, in3));
}
+void Instructions::beginLoop()
+{
+ BasicBlock *begin = new BasicBlock(name("loop"), m_func,0);
+ BasicBlock *end = new BasicBlock(name("endloop"), m_func,0);
+
+ new BranchInst(begin, m_block);
+ Loop loop;
+ loop.begin = begin;
+ loop.end = end;
+ m_block = begin;
+ m_loopStack.push(loop);
+}
+
+void Instructions::endLoop()
+{
+ assert(!m_loopStack.empty());
+ Loop loop = m_loopStack.top();
+ new BranchInst(loop.begin, m_block);
+ loop.end->moveAfter(m_block);
+ m_block = loop.end;
+ m_loopStack.pop();
+}
+
+void Instructions::brk()
+{
+ assert(!m_loopStack.empty());
+ BasicBlock *unr = new BasicBlock(name("unreachable"), m_func,0);
+ new BranchInst(m_loopStack.top().end, m_block);
+ m_block = unr;
+}
+
+llvm::Value * Instructions::trunc(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);
+ CastInst *icastx = new FPToSIInst(x, IntegerType::get(32),
+ name("ftoix"), m_block);
+ CastInst *icasty = new FPToSIInst(y, IntegerType::get(32),
+ name("ftoiy"), m_block);
+ CastInst *icastz = new FPToSIInst(z, IntegerType::get(32),
+ name("ftoiz"), m_block);
+ CastInst *icastw = new FPToSIInst(w, IntegerType::get(32),
+ name("ftoiw"), m_block);
+ CastInst *fx = new SIToFPInst(icastx, Type::FloatTy,
+ name("fx"), m_block);
+ CastInst *fy = new SIToFPInst(icasty, Type::FloatTy,
+ name("fy"), m_block);
+ CastInst *fz = new SIToFPInst(icastz, Type::FloatTy,
+ name("fz"), m_block);
+ CastInst *fw = new SIToFPInst(icastw, Type::FloatTy,
+ name("fw"), m_block);
+ return vectorFromVals(fx, fy, fz, fw);
+}
+
diff --git a/src/mesa/pipe/llvm/instructions.h b/src/mesa/pipe/llvm/instructions.h
index b0608e1da6b..29ae168e760 100644
--- a/src/mesa/pipe/llvm/instructions.h
+++ b/src/mesa/pipe/llvm/instructions.h
@@ -54,13 +54,16 @@ public:
llvm::Value *abs(llvm::Value *in1);
llvm::Value *arl(llvm::Value *in1);
llvm::Value *add(llvm::Value *in1, llvm::Value *in2);
+ void beginLoop();
+ void brk();
llvm::Value *cross(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);
llvm::Value *dst(llvm::Value *in1, llvm::Value *in2);
- void endif();
void elseop();
+ void endif();
+ void endLoop();
llvm::Value *ex2(llvm::Value *in);
llvm::Value *floor(llvm::Value *in);
llvm::Value *frc(llvm::Value *in);
@@ -81,6 +84,7 @@ public:
llvm::Value *sgt(llvm::Value *in1, llvm::Value *in2);
llvm::Value *slt(llvm::Value *in1, llvm::Value *in2);
llvm::Value *sub(llvm::Value *in1, llvm::Value *in2);
+ llvm::Value *trunc(llvm::Value *in);
void printVector(llvm::Value *val);
private:
@@ -115,6 +119,11 @@ private:
llvm::Constant *m_fmtPtr;
std::stack<llvm::BasicBlock*> m_ifStack;
+ struct Loop {
+ llvm::BasicBlock *begin;
+ llvm::BasicBlock *end;
+ };
+ std::stack<Loop> m_loopStack;
};
#endif
diff --git a/src/mesa/pipe/llvm/llvmtgsi.cpp b/src/mesa/pipe/llvm/llvmtgsi.cpp
index 6ff4bc22708..6eae46d3ae0 100644
--- a/src/mesa/pipe/llvm/llvmtgsi.cpp
+++ b/src/mesa/pipe/llvm/llvmtgsi.cpp
@@ -447,7 +447,10 @@ translate_instruction(llvm::Module *module,
break;
case TGSI_OPCODE_TXL:
break;
- case TGSI_OPCODE_BRK:
+ case TGSI_OPCODE_BRK: {
+ instr->brk();
+ return;
+ }
break;
case TGSI_OPCODE_IF: {
instr->ifop(inputs[0]);
@@ -485,7 +488,9 @@ translate_instruction(llvm::Module *module,
break;
case TGSI_OPCODE_NOT:
break;
- case TGSI_OPCODE_TRUNC:
+ case TGSI_OPCODE_TRUNC: {
+ out = instr->trunc(inputs[0]);
+ }
break;
case TGSI_OPCODE_SHL:
break;
@@ -511,11 +516,19 @@ translate_instruction(llvm::Module *module,
break;
case TGSI_OPCODE_ENDPRIM:
break;
- case TGSI_OPCODE_BGNLOOP2:
+ case TGSI_OPCODE_BGNLOOP2: {
+ instr->beginLoop();
+ storage->setCurrentBlock(instr->currentBlock());
+ return;
+ }
break;
case TGSI_OPCODE_BGNSUB:
break;
- case TGSI_OPCODE_ENDLOOP2:
+ case TGSI_OPCODE_ENDLOOP2: {
+ instr->endLoop();
+ storage->setCurrentBlock(instr->currentBlock());
+ return;
+ }
break;
case TGSI_OPCODE_ENDSUB:
break;