summaryrefslogtreecommitdiffstats
path: root/src/mesa/shader/slang/slang_emit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/shader/slang/slang_emit.c')
-rw-r--r--src/mesa/shader/slang/slang_emit.c44
1 files changed, 42 insertions, 2 deletions
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 6e2394f2656..d83880a26f2 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -332,6 +332,9 @@ slang_print_ir(const slang_ir_node *n, int indent)
case IR_BREAK:
printf("BREAK\n");
break;
+ case IR_BREAK_IF_FALSE:
+ printf("BREAK_IF_FALSE\n");
+ break;
case IR_VAR:
printf("VAR %s%s at %s store %p\n",
@@ -1153,13 +1156,17 @@ emit_loop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
*/
for (ir = n->BranchNode; ir; ir = ir->BranchNode) {
struct prog_instruction *inst = prog->Instructions + ir->InstLocation;
- if (ir->Opcode == IR_BREAK) {
+ if (ir->Opcode == IR_BREAK ||
+ ir->Opcode == IR_BREAK_IF_FALSE ||
+ ir->Opcode == IR_BREAK_IF_TRUE) {
assert(inst->Opcode == OPCODE_BRK ||
inst->Opcode == OPCODE_BRA);
inst->BranchTarget = endInstLoc + 1;
}
else {
- assert(ir->Opcode == IR_CONT);
+ assert(ir->Opcode == IR_CONT ||
+ ir->Opcode == IR_CONT_IF_FALSE ||
+ ir->Opcode == IR_CONT_IF_TRUE);
assert(inst->Opcode == OPCODE_CONT ||
inst->Opcode == OPCODE_BRA);
/* XXX goto top of loop instead! */
@@ -1192,6 +1199,35 @@ emit_cont_break(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
/**
+ * Conditional loop continue/break.
+ */
+static struct prog_instruction *
+emit_cont_break_if(slang_var_table *vt, slang_ir_node *n,
+ struct gl_program *prog, GLboolean breakTrue)
+{
+ gl_inst_opcode opcode;
+ struct prog_instruction *inst;
+
+ /* evaluate condition expr, setting cond codes */
+ inst = emit(vt, n->Children[0], prog);
+ assert(inst);
+ inst->CondUpdate = GL_TRUE;
+
+ n->InstLocation = prog->NumInstructions;
+ if (EmitHighLevelInstructions) {
+ opcode = (n->Opcode == IR_CONT) ? OPCODE_CONT : OPCODE_BRK;
+ }
+ else {
+ opcode = OPCODE_BRA;
+ }
+ inst = new_instruction(prog, opcode);
+ inst->DstReg.CondMask = breakTrue ? COND_NE : COND_EQ;
+ return inst;
+}
+
+
+
+/**
* Remove any SWIZZLE_NIL terms from given swizzle mask (smear prev term).
* Ex: fix_swizzle("zyNN") -> "zyyy"
*/
@@ -1407,6 +1443,10 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
case IR_LOOP:
return emit_loop(vt, n, prog);
+ case IR_BREAK_IF_FALSE:
+ return emit_cont_break_if(vt, n, prog, GL_FALSE);
+ case IR_BREAK_IF_TRUE:
+ return emit_cont_break_if(vt, n, prog, GL_TRUE);
case IR_BREAK:
/* fall-through */
case IR_CONT: