summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrian <brian@yutani.localnet.net>2006-12-20 12:41:59 -0700
committerBrian <brian@yutani.localnet.net>2006-12-20 12:41:59 -0700
commit2cc7dba718aa45ce446c63cf9a64cb88b1a3c39f (patch)
tree7dbfe1e6c5feb5aa3546705755a95a6dce595594 /src
parent79a340bc15e13643b1016d011556ba622dd18a5f (diff)
New IR_COND node for evaluating conditional expressions (for if/while/for).
Diffstat (limited to 'src')
-rw-r--r--src/mesa/shader/slang/slang_codegen.c11
-rw-r--r--src/mesa/shader/slang/slang_emit.c42
-rw-r--r--src/mesa/shader/slang/slang_ir.h37
3 files changed, 64 insertions, 26 deletions
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 51bf26ada8..a2be043542 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -813,6 +813,14 @@ _slang_is_noop(const slang_operation *oper)
}
+static slang_ir_node *
+_slang_gen_cond(slang_ir_node *n)
+{
+ slang_ir_node *c = new_node(IR_COND, n, NULL);
+ return c;
+}
+
+
/**
* Assemble a function call, given a particular function name.
* \param name the function's name (operators like '*' are possible).
@@ -866,6 +874,7 @@ _slang_gen_while(slang_assemble_ctx * A, const slang_operation *oper)
startLab = new_label(startAtom);
cond = _slang_gen_operation(A, &oper->children[0]);
+ cond = _slang_gen_cond(cond);
tree = new_seq(startLab, cond);
bra = new_cjump(endAtom);
@@ -922,6 +931,7 @@ _slang_gen_for(slang_assemble_ctx * A, const slang_operation *oper)
tree = new_seq(init, startLab);
cond = _slang_gen_operation(A, &oper->children[1]);
+ cond = _slang_gen_cond(cond);
tree = new_seq(tree, cond);
bra = new_cjump(endAtom);
@@ -972,6 +982,7 @@ _slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper)
slang_atom endifAtom = slang_atom_pool_gen(A->atoms, "__endif");
cond = _slang_gen_operation(A, &oper->children[0]);
+ cond = _slang_gen_cond(cond);
/*assert(cond->Store);*/
bra = new_cjump(haveElseClause ? elseAtom : endifAtom);
tree = new_seq(cond, bra);
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index ba1290b45e..d7c224541a 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -85,6 +85,7 @@ static slang_ir_info IrInfo[] = {
{ IR_LABEL, "IR_LABEL", 0, 0, 0 },
{ IR_JUMP, "IR_JUMP", 0, 0, 0 },
{ IR_CJUMP, "IR_CJUMP", 0, 0, 0 },
+ { IR_COND, "IR_COND", 0, 0, 0 },
{ IR_CALL, "IR_CALL", 0, 0, 0 },
{ IR_MOVE, "IR_MOVE", 0, 0, 1 },
{ IR_NOT, "IR_NOT", 0, 1, 1 },
@@ -300,6 +301,10 @@ slang_print_ir(const slang_ir_node *n, int indent)
case IR_LABEL:
printf("LABEL: %s\n", n->Target);
break;
+ case IR_COND:
+ printf("COND\n");
+ slang_print_ir(n->Children[0], indent + 3);
+ break;
case IR_JUMP:
printf("JUMP %s\n", n->Target);
break;
@@ -897,12 +902,6 @@ emit_binop(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
storage_to_src_reg(&inst->SrcReg[1], n->Children[1]->Store,
n->Children[1]->Swizzle);
inst->Comment = n->Comment;
-
- if (inst->Opcode == OPCODE_SGT) {
- /* update cond codes */
- inst->CondUpdate = GL_TRUE;
- }
-
return inst;
}
@@ -1075,7 +1074,6 @@ emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
case IR_EXP:
case IR_EXP2:
return emit_binop(gc, n, prog);
- break;
case IR_RSQ:
case IR_RCP:
case IR_FLOOR:
@@ -1084,12 +1082,40 @@ emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
case IR_SIN:
case IR_COS:
return emit_unop(gc, n, prog);
- break;
case IR_LABEL:
return emit_label(n->Target, prog);
case IR_FLOAT:
n->Store = alloc_constant(n->Value, 4, prog); /*XXX fix size */
break;
+ case IR_COND:
+ {
+ /* Conditional expression (in if/while/for stmts).
+ * Need to update condition code register.
+ * Next instruction is typically an IR_CJUMP.
+ */
+ /* last child expr instruction: */
+ struct prog_instruction *inst = emit(gc, n->Children[0], prog);
+ if (inst) {
+ /* set inst's CondUpdate flag */
+ inst->CondUpdate = GL_TRUE;
+ return inst; /* XXX or null? */
+ }
+ else {
+ /* This'll happen for things like "if (i) ..." where no code
+ * is normally generated for the expression "i".
+ * Generate a move instruction just to set condition codes.
+ */
+ slang_alloc_temp_storage(gc, n, 1);
+ inst = new_instruction(prog, OPCODE_MOV);
+ inst->CondUpdate = GL_TRUE;
+ storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
+ storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store,
+ n->Children[0]->Swizzle);
+ free_temporary(gc, n->Store->Index, n->Store->Size);
+ return inst; /* XXX or null? */
+ }
+ }
+ return NULL;
case IR_JUMP:
return emit_jump(n->Target, prog);
case IR_CJUMP:
diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h
index 5c054a5636..188d7d96d3 100644
--- a/src/mesa/shader/slang/slang_ir.h
+++ b/src/mesa/shader/slang/slang_ir.h
@@ -44,11 +44,12 @@
typedef enum
{
IR_NOP = 0,
- IR_SEQ,
+ IR_SEQ, /* sequence (eval left, then right) */
IR_LABEL, /* target of a jump or cjump */
IR_JUMP, /* unconditional jump */
IR_CJUMP, /* conditional jump */
- IR_CALL,
+ IR_COND, /* conditional expression */
+ IR_CALL, /* call subroutine */
IR_MOVE,
IR_ADD,
IR_SUB,
@@ -56,27 +57,27 @@ typedef enum
IR_DIV,
IR_DOT4,
IR_DOT3,
- IR_CROSS,
+ IR_CROSS, /* vec3 cross product */
IR_MIN,
IR_MAX,
- IR_SEQUAL,
- IR_SNEQUAL,
- IR_SGE,
- IR_SGT,
- IR_POW,
- IR_EXP,
- IR_EXP2,
- IR_LOG2,
- IR_RSQ,
- IR_RCP,
+ IR_SEQUAL, /* Set if not equal */
+ IR_SNEQUAL, /* Set if equal */
+ IR_SGE, /* Set if greater or equal */
+ IR_SGT, /* Set if greater than */
+ IR_POW, /* x^y */
+ IR_EXP, /* e^x */
+ IR_EXP2, /* 2^x */
+ IR_LOG2, /* log base 2 */
+ IR_RSQ, /* 1/sqrt() */
+ IR_RCP, /* recipricol */
IR_FLOOR,
IR_FRAC,
IR_ABS,
- IR_SIN,
- IR_COS,
- IR_NOT,
- IR_VAR,
- IR_VAR_DECL,
+ IR_SIN, /* sine */
+ IR_COS, /* cosine */
+ IR_NOT, /* logical not */
+ IR_VAR, /* variable reference */
+ IR_VAR_DECL,/* var declaration */
IR_FLOAT,
IR_FIELD,
IR_I_TO_F