summaryrefslogtreecommitdiff
path: root/src/mesa/shader/slang/slang_codegen.c
diff options
context:
space:
mode:
authorBrian <brian@yutani.localnet.net>2007-01-20 09:22:13 -0700
committerBrian <brian@yutani.localnet.net>2007-01-20 09:22:13 -0700
commita3e938b8da07e656775e88bb4b078429723689a2 (patch)
tree8b27fbcf45e6a9580bb8f428ffdad229385d3e1d /src/mesa/shader/slang/slang_codegen.c
parent9f07ed00e4d4bca95189720dd44bf57a228baf02 (diff)
Reimplement && and || to do short-circuit evaluation.
Improved shader error handling.
Diffstat (limited to 'src/mesa/shader/slang/slang_codegen.c')
-rw-r--r--src/mesa/shader/slang/slang_codegen.c158
1 files changed, 107 insertions, 51 deletions
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 60bf57035f..6923c00562 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -544,18 +544,11 @@ new_label(slang_atom labName)
}
static slang_ir_node *
-new_float_literal(float x, float y, float z, float w)
+new_float_literal(const float v[4])
{
- GLuint size;
+ const GLuint size = (v[0] == v[1] && v[0] == v[2] && v[0] == v[3]) ? 1 : 4;
slang_ir_node *n = new_node(IR_FLOAT, NULL, NULL);
- if (x == y && x == z && x == w)
- size = 1;
- else
- size = 4;
- n->Value[0] = x;
- n->Value[1] = y;
- n->Value[2] = z;
- n->Value[3] = w;
+ COPY_4V(n->Value, v);
/* allocate a storage object, but compute actual location (Index) later */
n->Store = _slang_new_ir_storage(PROGRAM_CONSTANT, -1, size);
return n;
@@ -598,10 +591,8 @@ new_var(slang_assemble_ctx *A, slang_operation *oper, slang_atom name)
{
slang_variable *v = _slang_locate_variable(oper->locals, name, GL_TRUE);
slang_ir_node *n = new_node(IR_VAR, NULL, NULL);
- if (!v) {
- printf("VAR NOT FOUND %s\n", (char *) name);
- assert(v);
- }
+ if (!v)
+ return NULL;
assert(!oper->var || oper->var == v);
v->used = GL_TRUE;
n->Var = v;
@@ -1626,9 +1617,12 @@ _slang_gen_select(slang_assemble_ctx *A, slang_operation *oper)
slang_ir_node *altLab, *endLab;
slang_ir_node *tree, *tmpDecl, *tmpVar, *cond, *cjump, *jump;
slang_ir_node *bodx, *body, *assignx, *assigny;
- slang_assembly_typeinfo type;
+ slang_assembly_typeinfo type;
int size;
+ assert(oper->type == slang_oper_select);
+ assert(oper->num_children == 3);
+
/* size of x or y's type */
slang_assembly_typeinfo_construct(&type);
_slang_typeof_operation(A, &oper->children[1], &type);
@@ -1647,10 +1641,10 @@ _slang_gen_select(slang_assemble_ctx *A, slang_operation *oper)
cjump = new_cjump(altAtom, 0);
tree = new_seq(tree, cjump);
- /* evaluate child 2 (y) and assign to tmp */
+ /* evaluate child 1 (x) and assign to tmp */
tmpVar = new_node(IR_VAR, NULL, NULL);
tmpVar->Store = tmpDecl->Store;
- body = _slang_gen_operation(A, &oper->children[2]);
+ body = _slang_gen_operation(A, &oper->children[1]);
assigny = new_node(IR_MOVE, tmpVar, body);
tree = new_seq(tree, assigny);
@@ -1662,10 +1656,10 @@ _slang_gen_select(slang_assemble_ctx *A, slang_operation *oper)
altLab = new_label(altAtom);
tree = new_seq(tree, altLab);
- /* evaluate child 1 (x) and assign to tmp */
+ /* evaluate child 2 (y) and assign to tmp */
tmpVar = new_node(IR_VAR, NULL, NULL);
tmpVar->Store = tmpDecl->Store;
- bodx = _slang_gen_operation(A, &oper->children[1]);
+ bodx = _slang_gen_operation(A, &oper->children[2]);
assignx = new_node(IR_MOVE, tmpVar, bodx);
tree = new_seq(tree, assignx);
@@ -1683,6 +1677,67 @@ _slang_gen_select(slang_assemble_ctx *A, slang_operation *oper)
/**
+ * Generate code for &&.
+ */
+static slang_ir_node *
+_slang_gen_logical_and(slang_assemble_ctx *A, slang_operation *oper)
+{
+ /* rewrite "a && b" as "a ? b : false" */
+ slang_operation *select;
+ slang_ir_node *n;
+
+ select = slang_operation_new(1);
+ select->type = slang_oper_select;
+ select->num_children = 3;
+ select->children = slang_operation_new(3);
+
+ slang_operation_copy(&select->children[0], &oper->children[0]);
+ slang_operation_copy(&select->children[1], &oper->children[1]);
+ select->children[2].type = slang_oper_literal_bool;
+ ASSIGN_4V(select->children[2].literal, 0, 0, 0, 0);
+
+ n = _slang_gen_select(A, select);
+
+ /* xxx wrong */
+ free(select->children);
+ free(select);
+
+ return n;
+}
+
+
+/**
+ * Generate code for ||.
+ */
+static slang_ir_node *
+_slang_gen_logical_or(slang_assemble_ctx *A, slang_operation *oper)
+{
+ /* rewrite "a || b" as "a ? true : b" */
+ slang_operation *select;
+ slang_ir_node *n;
+
+ select = slang_operation_new(1);
+ select->type = slang_oper_select;
+ select->num_children = 3;
+ select->children = slang_operation_new(3);
+
+ slang_operation_copy(&select->children[0], &oper->children[0]);
+ select->children[1].type = slang_oper_literal_bool;
+ ASSIGN_4V(select->children[2].literal, 1, 1, 1, 1);
+ slang_operation_copy(&select->children[2], &oper->children[1]);
+
+ n = _slang_gen_select(A, select);
+
+ /* xxx wrong */
+ free(select->children);
+ free(select);
+
+ return n;
+}
+
+
+
+/**
* Generate IR tree for a return statement.
*/
static slang_ir_node *
@@ -1779,6 +1834,7 @@ _slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper)
slang_ir_node *n;
slang_ir_node *varDecl;
slang_variable *v;
+ const char *varName = (char *) oper->a_id;
assert(oper->num_children == 0 || oper->num_children == 1);
@@ -1792,10 +1848,10 @@ _slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper)
slang_ir_node *var, *init, *rhs;
assert(oper->num_children == 1);
var = new_var(A, oper, oper->a_id);
+ if (!var) {
+ RETURN_ERROR2("Undefined variable:", varName, 0);
+ }
/* XXX make copy of this initializer? */
- /*
- printf("\n*** ASSEMBLE INITIALIZER %p\n", (void*) v->initializer);
- */
rhs = _slang_gen_operation(A, &oper->children[0]);
assert(rhs);
init = new_node(IR_MOVE, var, rhs);
@@ -1805,10 +1861,10 @@ _slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper)
else if (v->initializer) {
slang_ir_node *var, *init, *rhs;
var = new_var(A, oper, oper->a_id);
+ if (!var) {
+ RETURN_ERROR2("Undefined variable:", varName, 0);
+ }
/* XXX make copy of this initializer? */
- /*
- printf("\n*** ASSEMBLE INITIALIZER %p\n", (void*) v->initializer);
- */
rhs = _slang_gen_operation(A, v->initializer);
assert(rhs);
init = new_node(IR_MOVE, var, rhs);
@@ -1835,9 +1891,9 @@ _slang_gen_variable(slang_assemble_ctx * A, slang_operation *oper)
*/
slang_atom aVar = oper->var ? oper->var->a_name : oper->a_id;
slang_ir_node *n = new_var(A, oper, aVar);
- /*
- assert(oper->var);
- */
+ if (!n) {
+ RETURN_ERROR2("Undefined variable:", (char *) aVar, 0);
+ }
return n;
}
@@ -1876,18 +1932,19 @@ _slang_gen_assignment(slang_assemble_ctx * A, slang_operation *oper)
}
c0 = _slang_gen_operation(A, lhs);
c1 = _slang_gen_operation(A, &oper->children[1]);
-
- assert(c1);
- n = new_node(IR_MOVE, c0, c1);
- /*
- assert(c1->Opcode != IR_SEQ);
- */
- if (c0->Writemask != WRITEMASK_XYZW)
- /* XXX this is a hack! */
- n->Writemask = c0->Writemask;
- else
- n->Writemask = mask;
- return n;
+ if (c0 && c1) {
+ n = new_node(IR_MOVE, c0, c1);
+ /*assert(c1->Opcode != IR_SEQ);*/
+ if (c0->Writemask != WRITEMASK_XYZW)
+ /* XXX this is a hack! */
+ n->Writemask = c0->Writemask;
+ else
+ n->Writemask = mask;
+ return n;
+ }
+ else {
+ return NULL;
+ }
}
}
@@ -2206,25 +2263,25 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper)
n = _slang_gen_function_call_name(A, "/=", oper, &oper->children[0]);
return n;
}
- case slang_oper_logicalor:
+ case slang_oper_logicaland:
{
slang_ir_node *n;
assert(oper->num_children == 2);
- n = _slang_gen_function_call_name(A, "__logicalOr", oper, NULL);
+ n = _slang_gen_logical_and(A, oper);
return n;
}
- case slang_oper_logicalxor:
+ case slang_oper_logicalor:
{
slang_ir_node *n;
assert(oper->num_children == 2);
- n = _slang_gen_function_call_name(A, "__logicalXor", oper, NULL);
+ n = _slang_gen_logical_or(A, oper);
return n;
}
- case slang_oper_logicaland:
+ case slang_oper_logicalxor:
{
slang_ir_node *n;
assert(oper->num_children == 2);
- n = _slang_gen_function_call_name(A, "__logicalAnd", oper, NULL);
+ n = _slang_gen_function_call_name(A, "__logicalXor", oper, NULL);
return n;
}
case slang_oper_not:
@@ -2239,7 +2296,7 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper)
{
slang_ir_node *n;
assert(oper->num_children == 3);
- n = _slang_gen_select(A, oper );
+ n = _slang_gen_select(A, oper);
return n;
}
@@ -2263,12 +2320,11 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper)
case slang_oper_subscript:
return _slang_gen_subscript(A, oper);
case slang_oper_literal_float:
- return new_float_literal(oper->literal[0], oper->literal[1],
- oper->literal[2], oper->literal[3]);
+ /* fall-through */
case slang_oper_literal_int:
- return new_float_literal(oper->literal[0], 0, 0, 0);
+ /* fall-through */
case slang_oper_literal_bool:
- return new_float_literal(oper->literal[0], 0, 0, 0);
+ return new_float_literal(oper->literal);
case slang_oper_postincrement: /* var++ */
{