summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian <brian@yutani.localnet.net>2006-12-16 12:52:19 -0700
committerBrian <brian@yutani.localnet.net>2006-12-16 12:52:19 -0700
commitf7159552ae12f6a47641f3325c9ece6f1c052feb (patch)
tree497d7b80ddba8fcbbfed0965c1f8345b15999cc1
parent3a2815370d26012b41d742540237985a333b6ae4 (diff)
Initial code for conditional constructs.
-rw-r--r--src/mesa/shader/slang/slang_codegen.c67
-rw-r--r--src/mesa/shader/slang/slang_emit.c28
2 files changed, 79 insertions, 16 deletions
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index f62ff01f2d..2f2b2b2a4e 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -931,13 +931,13 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper)
/* list of operations */
assert(oper->num_children > 0);
{
- slang_ir_node *n, *first = NULL;
+ slang_ir_node *n, *tree = NULL;
GLuint i;
for (i = 0; i < oper->num_children; i++) {
n = slang_assemble_operation(A, &oper->children[i]);
- first = first ? new_seq(first, n) : n;
+ tree = tree ? new_seq(tree, n) : n;
}
- return first;
+ return tree;
}
break;
case slang_oper_expression:
@@ -945,6 +945,7 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper)
break;
case slang_oper_while:
{
+ slang_ir_node *tree;
slang_ir_node *nStartLabel = new_label("while-start");
slang_ir_node *nCond = slang_assemble_operation(A, &oper->children[0]);
slang_ir_node *nNotCond = new_node(IR_NOT, nCond, NULL);
@@ -953,14 +954,13 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper)
slang_ir_node *nCJump = new_cjump(nNotCond, "while-end");
slang_ir_node *nJump = new_jump("while-start");
- return new_seq(nStartLabel,
- new_seq(nCJump,
- new_seq(nBody,
- new_seq(nJump,
- nEndLabel)
- )
- )
- );
+ tree = new_seq(nStartLabel, nCond);
+ tree = new_seq(tree, nNotCond);
+ tree = new_seq(tree, nBody);
+ tree = new_seq(tree, nEndLabel);
+ tree = new_seq(tree, nCJump);
+ tree = new_seq(tree, nJump);
+ return tree;
}
break;
case slang_oper_equal:
@@ -977,9 +977,20 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper)
slang_assemble_operation(A, &oper->children[1]));
case slang_oper_less:
/* child[0] < child[1] ----> child[1] > child[0] */
+#if 0
+ {
+ slang_ir_node *n;
+ assert(oper->num_children == 2);
+ /* XXX tranpose children */
+ n = slang_assemble_function_call_name(A, "<", oper, NULL);
+ return n;
+ }
+#else
+ /** the operands must be ints or floats, not vectors */
return new_node(IR_SGT,
slang_assemble_operation(A, &oper->children[1]),
slang_assemble_operation(A, &oper->children[0]));
+#endif
case slang_oper_greaterequal:
return new_node(IR_SGE,
slang_assemble_operation(A, &oper->children[0]),
@@ -1101,6 +1112,15 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper)
return n;
}
break;
+ case slang_oper_mulassign:
+ {
+ slang_ir_node *n;
+ assert(oper->num_children == 2);
+ /* XXX tranpose children */
+ n = slang_assemble_function_call_name(A, "*=", oper, NULL);
+ return n;
+ }
+ break;
case slang_oper_asm:
return slang_assemble_asm(A, oper, NULL);
case slang_oper_call:
@@ -1124,6 +1144,25 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper)
return n;
}
break;
+ case slang_oper_if:
+ {
+ slang_ir_node *cond, *bra, *body, *endif, *tree;
+
+ cond = slang_assemble_operation(A, &oper->children[0]);
+ /*assert(cond->Store);*/
+ bra = new_node(IR_CJUMP, NULL, NULL);
+ bra->Target = _mesa_strdup("__endif");
+
+ body = slang_assemble_operation(A, &oper->children[1]);
+
+ endif = new_label("__endif");
+
+ tree = new_seq(cond, bra);
+ tree = new_seq(tree, body);
+ tree = new_seq(tree, endif);
+ return tree;
+ }
+ break;
case slang_oper_field:
{
slang_assembly_typeinfo ti;
@@ -1214,13 +1253,13 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper)
break;
case slang_oper_sequence:
{
- slang_ir_node *top = NULL;
+ slang_ir_node *tree = NULL;
GLuint i;
for (i = 0; i < oper->num_children; i++) {
slang_ir_node *n = slang_assemble_operation(A, &oper->children[i]);
- top = top ? new_seq(top, n) : n;
+ tree = tree ? new_seq(tree, n) : n;
}
- return top;
+ return tree;
}
break;
case slang_oper_none:
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 3d9d525e18..fbee314d24 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -930,6 +930,29 @@ emit_unop(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
static struct prog_instruction *
+emit_label(const char *target, struct gl_program *prog)
+{
+ struct prog_instruction *inst;
+ inst = new_instruction(prog, OPCODE_NOP);
+ inst->Comment = _mesa_strdup(target);
+ return inst;
+}
+
+
+static struct prog_instruction *
+emit_cjump(const char *target, struct gl_program *prog)
+{
+ struct prog_instruction *inst;
+ inst = new_instruction(prog, OPCODE_BRA);
+ inst->DstReg.CondMask = COND_EQ; /* branch if equal to zero */
+ inst->DstReg.CondSwizzle = SWIZZLE_X;
+ inst->Comment = _mesa_strdup(target);
+ return inst;
+}
+
+
+
+static struct prog_instruction *
emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
{
struct prog_instruction *inst;
@@ -1045,8 +1068,7 @@ emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
return emit_unop(gc, n, prog);
break;
case IR_LABEL:
- /*printf("LAB: %s\n", n->Target);*/
- break;
+ return emit_label(n->Target, prog);
case IR_JUMP:
#if 0
inst = new_instruction(prog, OPCODE_BRA);
@@ -1056,6 +1078,8 @@ emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
case IR_FLOAT:
n->Store = alloc_constant(n->Value, 4, prog); /*XXX fix size */
break;
+ case IR_CJUMP:
+ return emit_cjump(n->Target, prog);
default:
printf("emit: ?\n");
abort();