mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-17 23:40:29 +01:00
New IR_COND node for evaluating conditional expressions (for if/while/for).
This commit is contained in:
parent
79a340bc15
commit
2cc7dba718
3 changed files with 64 additions and 26 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue