New IR_COND node for evaluating conditional expressions (for if/while/for).

This commit is contained in:
Brian 2006-12-20 12:41:59 -07:00
parent 79a340bc15
commit 2cc7dba718
3 changed files with 64 additions and 26 deletions

View file

@ -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);

View file

@ -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:

View file

@ -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