mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-04 11:20:20 +01:00
Merge branch 'master' of git+ssh://znh@git.freedesktop.org/git/mesa/mesa
This commit is contained in:
commit
da82d86ea0
9 changed files with 220 additions and 103 deletions
|
|
@ -571,6 +571,13 @@ _mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent,
|
|||
_mesa_printf("CAL %u", inst->BranchTarget);
|
||||
print_comment(inst);
|
||||
break;
|
||||
case OPCODE_RET:
|
||||
_mesa_printf("RET (%s%s); # (goto %d)",
|
||||
condcode_string(inst->DstReg.CondMask),
|
||||
_mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE),
|
||||
inst->BranchTarget);
|
||||
print_comment(inst);
|
||||
break;
|
||||
case OPCODE_IF:
|
||||
if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
|
||||
/* Use ordinary register */
|
||||
|
|
@ -622,7 +629,7 @@ _mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent,
|
|||
break;
|
||||
|
||||
case OPCODE_BGNSUB:
|
||||
_mesa_printf("SUB");
|
||||
_mesa_printf("BGNSUB");
|
||||
print_comment(inst);
|
||||
return indent + 3;
|
||||
case OPCODE_ENDSUB:
|
||||
|
|
|
|||
|
|
@ -468,13 +468,28 @@ new_float_literal(const float v[4], GLuint size)
|
|||
return n;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inlined subroutine.
|
||||
*/
|
||||
static slang_ir_node *
|
||||
new_inlined_function_call(slang_ir_node *code, slang_label *name)
|
||||
{
|
||||
slang_ir_node *n = new_node1(IR_FUNC, code);
|
||||
assert(name);
|
||||
if (n)
|
||||
n->Label = name;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unconditional jump.
|
||||
*/
|
||||
static slang_ir_node *
|
||||
new_jump(slang_label *dest)
|
||||
new_return(slang_label *dest)
|
||||
{
|
||||
slang_ir_node *n = new_node0(IR_JUMP);
|
||||
slang_ir_node *n = new_node0(IR_RETURN);
|
||||
assert(dest);
|
||||
if (n)
|
||||
n->Label = dest;
|
||||
|
|
@ -606,6 +621,24 @@ _slang_is_noop(const slang_operation *oper)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Recursively search tree for a node of the given type.
|
||||
*/
|
||||
static slang_operation *
|
||||
_slang_find_node_type(slang_operation *oper, slang_operation_type type)
|
||||
{
|
||||
GLuint i;
|
||||
if (oper->type == type)
|
||||
return oper;
|
||||
for (i = 0; i < oper->num_children; i++) {
|
||||
slang_operation *p = _slang_find_node_type(&oper->children[i], type);
|
||||
if (p)
|
||||
return p;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Produce inline code for a call to an assembly instruction.
|
||||
* XXX Note: children are passed as asm args in-order, not by name!
|
||||
|
|
@ -681,11 +714,8 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper,
|
|||
GLuint i;
|
||||
v = _slang_locate_variable(oper->locals, id, GL_TRUE);
|
||||
if (!v) {
|
||||
printf("var %s not found!\n", (char *) oper->a_id);
|
||||
_slang_print_var_scope(oper->locals, 6);
|
||||
|
||||
abort();
|
||||
break;
|
||||
_mesa_problem(NULL, "var %s not found!\n", (char *) oper->a_id);
|
||||
return;
|
||||
}
|
||||
|
||||
/* look for a substitution */
|
||||
|
|
@ -716,7 +746,7 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper,
|
|||
case SLANG_OPER_RETURN:
|
||||
/* do return replacement here too */
|
||||
assert(oper->num_children == 0 || oper->num_children == 1);
|
||||
if (!_slang_is_noop(oper)) {
|
||||
if (oper->num_children == 1 && !_slang_is_noop(&oper->children[0])) {
|
||||
/* replace:
|
||||
* return expr;
|
||||
* with:
|
||||
|
|
@ -725,6 +755,14 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper,
|
|||
* then do substitutions on the assignment.
|
||||
*/
|
||||
slang_operation *blockOper, *assignOper, *returnOper;
|
||||
|
||||
/* check if function actually has a return type */
|
||||
assert(A->CurFunction);
|
||||
if (A->CurFunction->header.type.specifier.type == SLANG_SPEC_VOID) {
|
||||
slang_info_log_error(A->log, "illegal return expression");
|
||||
return;
|
||||
}
|
||||
|
||||
blockOper = slang_operation_new(1);
|
||||
blockOper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE;
|
||||
blockOper->num_children = 2;
|
||||
|
|
@ -744,7 +782,7 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper,
|
|||
slang_operation_copy(&assignOper->children[1],
|
||||
&oper->children[0]);
|
||||
|
||||
returnOper->type = SLANG_OPER_RETURN;
|
||||
returnOper->type = SLANG_OPER_RETURN; /* return w/ no value */
|
||||
assert(returnOper->num_children == 0);
|
||||
|
||||
/* do substitutions on the "__retVal = expr" sub-tree */
|
||||
|
|
@ -755,6 +793,14 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper,
|
|||
slang_operation_copy(oper, blockOper);
|
||||
slang_operation_destruct(blockOper);
|
||||
}
|
||||
else {
|
||||
/* check if return value was expected */
|
||||
assert(A->CurFunction);
|
||||
if (A->CurFunction->header.type.specifier.type != SLANG_SPEC_VOID) {
|
||||
slang_info_log_error(A->log, "return statement requires an expression");
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SLANG_OPER_ASSIGN:
|
||||
|
|
@ -806,6 +852,11 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
|
|||
slang_variable **substOld;
|
||||
slang_operation **substNew;
|
||||
GLuint substCount, numCopyIn, i;
|
||||
slang_function *prevFunction;
|
||||
|
||||
/* save / push */
|
||||
prevFunction = A->CurFunction;
|
||||
A->CurFunction = fun;
|
||||
|
||||
/*assert(oper->type == SLANG_OPER_CALL); (or (matrix) multiply, etc) */
|
||||
assert(fun->param_count == totalArgs);
|
||||
|
|
@ -1027,6 +1078,10 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
|
|||
fun->parameters->num_variables, numArgs);
|
||||
slang_print_tree(top, 0);
|
||||
#endif
|
||||
|
||||
/* pop */
|
||||
A->CurFunction = prevFunction;
|
||||
|
||||
return top;
|
||||
}
|
||||
|
||||
|
|
@ -1052,8 +1107,18 @@ _slang_gen_function_call(slang_assemble_ctx *A, slang_function *fun,
|
|||
else {
|
||||
/* non-assembly function */
|
||||
inlined = slang_inline_function_call(A, fun, oper, dest);
|
||||
if (inlined) {
|
||||
assert(inlined->type == SLANG_OPER_BLOCK_NEW_SCOPE ||
|
||||
inlined->type == SLANG_OPER_SEQUENCE);
|
||||
inlined->type = SLANG_OPER_INLINED_CALL;
|
||||
inlined->fun = fun;
|
||||
inlined->label = _slang_label_new((char*) fun->header.a_name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!inlined)
|
||||
return NULL;
|
||||
|
||||
/* Replace the function call with the inlined block */
|
||||
slang_operation_destruct(oper);
|
||||
*oper = *inlined;
|
||||
|
|
@ -1109,7 +1174,8 @@ make_writemask(const char *field)
|
|||
mask |= WRITEMASK_W;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
_mesa_problem(NULL, "invalid writemask in make_writemask()");
|
||||
return 0;
|
||||
}
|
||||
field++;
|
||||
}
|
||||
|
|
@ -1703,26 +1769,25 @@ _slang_gen_logical_or(slang_assemble_ctx *A, slang_operation *oper)
|
|||
static slang_ir_node *
|
||||
_slang_gen_return(slang_assemble_ctx * A, slang_operation *oper)
|
||||
{
|
||||
if (oper->num_children == 0 ||
|
||||
(oper->num_children == 1 &&
|
||||
oper->children[0].type == SLANG_OPER_VOID)) {
|
||||
/* Convert from:
|
||||
* return;
|
||||
* To:
|
||||
* goto __endOfFunction;
|
||||
*/
|
||||
slang_ir_node *n;
|
||||
slang_operation gotoOp;
|
||||
slang_operation_construct(&gotoOp);
|
||||
gotoOp.type = SLANG_OPER_GOTO;
|
||||
gotoOp.label = A->curFuncEndLabel;
|
||||
assert(gotoOp.label);
|
||||
const GLboolean haveReturnValue
|
||||
= (oper->num_children == 1 &&
|
||||
oper->children[0].type != SLANG_OPER_VOID);
|
||||
|
||||
/* assemble the new code */
|
||||
n = _slang_gen_operation(A, &gotoOp);
|
||||
/* destroy temp code */
|
||||
slang_operation_destruct(&gotoOp);
|
||||
return n;
|
||||
/* error checking */
|
||||
assert(A->CurFunction);
|
||||
if (haveReturnValue &&
|
||||
A->CurFunction->header.type.specifier.type == SLANG_SPEC_VOID) {
|
||||
slang_info_log_error(A->log, "illegal return expression");
|
||||
return NULL;
|
||||
}
|
||||
else if (!haveReturnValue &&
|
||||
A->CurFunction->header.type.specifier.type != SLANG_SPEC_VOID) {
|
||||
slang_info_log_error(A->log, "return statement requires an expression");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!haveReturnValue) {
|
||||
return new_return(A->curFuncEndLabel);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
|
|
@ -1730,9 +1795,9 @@ _slang_gen_return(slang_assemble_ctx * A, slang_operation *oper)
|
|||
* return expr;
|
||||
* To:
|
||||
* __retVal = expr;
|
||||
* goto __endOfFunction;
|
||||
* return; // goto __endOfFunction
|
||||
*/
|
||||
slang_operation *block, *assign, *jump;
|
||||
slang_operation *assign;
|
||||
slang_atom a_retVal;
|
||||
slang_ir_node *n;
|
||||
|
||||
|
|
@ -1743,21 +1808,15 @@ _slang_gen_return(slang_assemble_ctx * A, slang_operation *oper)
|
|||
{
|
||||
slang_variable *v
|
||||
= _slang_locate_variable(oper->locals, a_retVal, GL_TRUE);
|
||||
assert(v);
|
||||
if (!v) {
|
||||
/* trying to return a value in a void-valued function */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
block = slang_operation_new(1);
|
||||
block->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE;
|
||||
assert(block->locals);
|
||||
block->locals->outer_scope = oper->locals->outer_scope;
|
||||
block->num_children = 2;
|
||||
block->children = slang_operation_new(2);
|
||||
|
||||
/* child[0]: __retVal = expr; */
|
||||
assign = &block->children[0];
|
||||
assign = slang_operation_new(1);
|
||||
assign->type = SLANG_OPER_ASSIGN;
|
||||
assign->locals->outer_scope = block->locals;
|
||||
assign->num_children = 2;
|
||||
assign->children = slang_operation_new(2);
|
||||
/* lhs (__retVal) */
|
||||
|
|
@ -1768,22 +1827,11 @@ _slang_gen_return(slang_assemble_ctx * A, slang_operation *oper)
|
|||
/* XXX we might be able to avoid this copy someday */
|
||||
slang_operation_copy(&assign->children[1], &oper->children[0]);
|
||||
|
||||
/* child[1]: goto __endOfFunction */
|
||||
jump = &block->children[1];
|
||||
jump->type = SLANG_OPER_GOTO;
|
||||
assert(A->curFuncEndLabel);
|
||||
/* XXX don't call function? */
|
||||
jump->label = A->curFuncEndLabel;
|
||||
assert(jump->label);
|
||||
|
||||
#if 0 /* debug */
|
||||
printf("NEW RETURN:\n");
|
||||
slang_print_tree(block, 0);
|
||||
#endif
|
||||
|
||||
/* assemble the new code */
|
||||
n = _slang_gen_operation(A, block);
|
||||
slang_operation_delete(block);
|
||||
n = new_seq(_slang_gen_operation(A, assign),
|
||||
new_return(A->curFuncEndLabel));
|
||||
|
||||
slang_operation_delete(assign);
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
|
@ -1843,6 +1891,9 @@ _slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper)
|
|||
_slang_simplify(v->initializer, &A->space, A->atoms);
|
||||
rhs = _slang_gen_operation(A, v->initializer);
|
||||
#endif
|
||||
if (!rhs)
|
||||
return NULL;
|
||||
|
||||
assert(rhs);
|
||||
init = new_node2(IR_MOVE, var, rhs);
|
||||
/*
|
||||
|
|
@ -2509,8 +2560,6 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper)
|
|||
oper, NULL);
|
||||
case SLANG_OPER_RETURN:
|
||||
return _slang_gen_return(A, oper);
|
||||
case SLANG_OPER_GOTO:
|
||||
return new_jump(oper->label);
|
||||
case SLANG_OPER_LABEL:
|
||||
return new_label(oper->label);
|
||||
case SLANG_OPER_IDENTIFIER:
|
||||
|
|
@ -2557,6 +2606,7 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper)
|
|||
return n;
|
||||
}
|
||||
|
||||
case SLANG_OPER_INLINED_CALL:
|
||||
case SLANG_OPER_SEQUENCE:
|
||||
{
|
||||
slang_ir_node *tree = NULL;
|
||||
|
|
@ -2565,6 +2615,9 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper)
|
|||
slang_ir_node *n = _slang_gen_operation(A, &oper->children[i]);
|
||||
tree = tree ? new_seq(tree, n) : n;
|
||||
}
|
||||
if (oper->type == SLANG_OPER_INLINED_CALL) {
|
||||
tree = new_inlined_function_call(tree, oper->label);
|
||||
}
|
||||
return tree;
|
||||
}
|
||||
|
||||
|
|
@ -2574,8 +2627,8 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper)
|
|||
return new_node0(IR_NOP);
|
||||
|
||||
default:
|
||||
printf("Unhandled node type %d\n", oper->type);
|
||||
abort();
|
||||
_mesa_problem(NULL, "bad node type %d in _slang_gen_operation",
|
||||
oper->type);
|
||||
return new_node0(IR_NOP);
|
||||
}
|
||||
|
||||
|
|
@ -2774,6 +2827,23 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
|
|||
/* we only really generate code for main, all other functions get
|
||||
* inlined.
|
||||
*/
|
||||
#if 0
|
||||
/* do some basic error checking though */
|
||||
if (fun->header.type.specifier.type != SLANG_SPEC_VOID) {
|
||||
/* check that non-void functions actually return something */
|
||||
slang_operation *op
|
||||
= _slang_find_node_type(fun->body, SLANG_OPER_RETURN);
|
||||
if (!op) {
|
||||
slang_info_log_error(A->log,
|
||||
"function \"%s\" has no return statement",
|
||||
(char *) fun->header.a_name);
|
||||
printf(
|
||||
"function \"%s\" has no return statement\n",
|
||||
(char *) fun->header.a_name);
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return GL_TRUE; /* not an error */
|
||||
}
|
||||
|
||||
|
|
@ -2786,6 +2856,8 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
|
|||
assert(A->program->Parameters );
|
||||
assert(A->program->Varying);
|
||||
assert(A->vartable);
|
||||
A->CurLoop = NULL;
|
||||
A->CurFunction = fun;
|
||||
|
||||
/* fold constant expressions, etc. */
|
||||
_slang_simplify(fun->body, &A->space, A->atoms);
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ typedef enum slang_operation_type_
|
|||
SLANG_OPER_CONTINUE, /* "continue" statement */
|
||||
SLANG_OPER_DISCARD, /* "discard" (kill fragment) statement */
|
||||
SLANG_OPER_RETURN, /* "return" [expr] */
|
||||
SLANG_OPER_GOTO, /* jump to label */
|
||||
SLANG_OPER_LABEL, /* a jump target */
|
||||
SLANG_OPER_EXPRESSION, /* [expr] */
|
||||
SLANG_OPER_IF, /* "if" [0] then [1] else [2] */
|
||||
|
|
@ -94,6 +93,7 @@ typedef enum slang_operation_type_
|
|||
SLANG_OPER_NOT, /* "!" [expr] */
|
||||
SLANG_OPER_SUBSCRIPT, /* [expr] "[" [expr] "]" */
|
||||
SLANG_OPER_CALL, /* [func name] [param] [param] [...] */
|
||||
SLANG_OPER_INLINED_CALL, /* inlined function call */
|
||||
SLANG_OPER_FIELD, /* i.e.: ".next" or ".xzy" or ".xxx" etc */
|
||||
SLANG_OPER_POSTINCREMENT, /* [var] "++" */
|
||||
SLANG_OPER_POSTDECREMENT /* [var] "--" */
|
||||
|
|
@ -118,7 +118,7 @@ typedef struct slang_operation_
|
|||
slang_variable_scope *locals; /**< local vars for scope */
|
||||
struct slang_function_ *fun; /**< If type == SLANG_OPER_CALL */
|
||||
struct slang_variable_ *var; /**< If type == slang_oper_identier */
|
||||
struct slang_label_ *label; /**< If type == SLANG_OPER_LABEL or GOTO */
|
||||
struct slang_label_ *label; /**< If type == SLANG_OPER_LABEL */
|
||||
} slang_operation;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ typedef struct
|
|||
/* code-gen options */
|
||||
GLboolean EmitHighLevelInstructions;
|
||||
GLboolean EmitCondCodes;
|
||||
GLboolean EmitBeginEndSub;
|
||||
GLboolean EmitComments;
|
||||
} slang_emit_info;
|
||||
|
||||
|
|
@ -203,6 +204,13 @@ new_instruction(slang_emit_info *emitInfo, gl_inst_opcode opcode)
|
|||
{
|
||||
struct gl_program *prog = emitInfo->prog;
|
||||
struct prog_instruction *inst;
|
||||
|
||||
#if 0
|
||||
/* print prev inst */
|
||||
if (prog->NumInstructions > 0) {
|
||||
_mesa_print_instruction(prog->Instructions + prog->NumInstructions - 1);
|
||||
}
|
||||
#endif
|
||||
prog->Instructions = _mesa_realloc_instructions(prog->Instructions,
|
||||
prog->NumInstructions,
|
||||
prog->NumInstructions + 1);
|
||||
|
|
@ -710,13 +718,36 @@ emit_label(slang_emit_info *emitInfo, const slang_ir_node *n)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Emit code for an inlined function call.
|
||||
*/
|
||||
static struct prog_instruction *
|
||||
emit_jump(slang_emit_info *emitInfo, slang_ir_node *n)
|
||||
emit_func(slang_emit_info *emitInfo, slang_ir_node *n)
|
||||
{
|
||||
struct prog_instruction *inst;
|
||||
assert(n->Label);
|
||||
if (emitInfo->EmitBeginEndSub) {
|
||||
inst = new_instruction(emitInfo, OPCODE_BGNSUB);
|
||||
inst->Comment = _mesa_strdup(n->Label->Name);
|
||||
}
|
||||
inst = emit(emitInfo, n->Children[0]);
|
||||
if (emitInfo->EmitBeginEndSub) {
|
||||
inst = new_instruction(emitInfo, OPCODE_ENDSUB);
|
||||
inst->Comment = _mesa_strdup(n->Label->Name);
|
||||
}
|
||||
n->Store = n->Children[0]->Store;
|
||||
return inst;
|
||||
}
|
||||
|
||||
|
||||
static struct prog_instruction *
|
||||
emit_return(slang_emit_info *emitInfo, slang_ir_node *n)
|
||||
{
|
||||
struct prog_instruction *inst;
|
||||
assert(n);
|
||||
assert(n->Opcode == IR_RETURN);
|
||||
assert(n->Label);
|
||||
inst = new_instruction(emitInfo, OPCODE_BRA);
|
||||
inst = new_instruction(emitInfo, OPCODE_BRA /*RET*/); /*XXX TEMPORARY*/
|
||||
inst->DstReg.CondMask = COND_TR; /* always branch */
|
||||
inst->BranchTarget = _slang_label_get_location(n->Label);
|
||||
if (inst->BranchTarget < 0) {
|
||||
|
|
@ -793,22 +824,29 @@ emit_move(slang_emit_info *emitInfo, slang_ir_node *n)
|
|||
assert(n->Children[1]);
|
||||
inst = emit(emitInfo, n->Children[1]);
|
||||
|
||||
if (!n->Children[1]->Store) {
|
||||
slang_info_log_error(emitInfo->log, "invalid assignment");
|
||||
return NULL;
|
||||
}
|
||||
assert(n->Children[1]->Store->Index >= 0);
|
||||
|
||||
#if 0
|
||||
assert(!n->Store);
|
||||
#endif
|
||||
n->Store = n->Children[0]->Store;
|
||||
|
||||
#if PEEPHOLE_OPTIMIZATIONS
|
||||
if (inst && _slang_is_temp(emitInfo->vt, n->Children[1]->Store)) {
|
||||
if (inst &&
|
||||
_slang_is_temp(emitInfo->vt, n->Children[1]->Store) &&
|
||||
(inst->DstReg.File == n->Children[1]->Store->File) &&
|
||||
(inst->DstReg.Index == n->Children[1]->Store->Index)) {
|
||||
/* Peephole optimization:
|
||||
* Just modify the RHS to put its result into the dest of this
|
||||
* MOVE operation. Then, this MOVE is a no-op.
|
||||
* The Right-Hand-Side has its results in a temporary place.
|
||||
* Modify the RHS (and the prev instruction) to store its results
|
||||
* in the destination specified by n->Children[0].
|
||||
* Then, this MOVE is a no-op.
|
||||
*/
|
||||
_slang_free_temp(emitInfo->vt, n->Children[1]->Store);
|
||||
if (n->Children[1]->Opcode != IR_SWIZZLE)
|
||||
_slang_free_temp(emitInfo->vt, n->Children[1]->Store);
|
||||
*n->Children[1]->Store = *n->Children[0]->Store;
|
||||
/* fixup the prev (RHS) instruction */
|
||||
/* fixup the previous instruction (which stored the RHS result) */
|
||||
assert(n->Children[0]->Store->Index >= 0);
|
||||
storage_to_dst_reg(&inst->DstReg, n->Children[0]->Store, n->Writemask);
|
||||
return inst;
|
||||
|
|
@ -868,11 +906,17 @@ emit_cond(slang_emit_info *emitInfo, slang_ir_node *n)
|
|||
* Need to update condition code register.
|
||||
* Next instruction is typically an IR_IF.
|
||||
*/
|
||||
if (inst) {
|
||||
/* set inst's CondUpdate flag */
|
||||
if (inst &&
|
||||
n->Children[0]->Store &&
|
||||
inst->DstReg.File == n->Children[0]->Store->File &&
|
||||
inst->DstReg.Index == n->Children[0]->Store->Index) {
|
||||
/* The previous instruction wrote to the register who's value
|
||||
* we're testing. Just update that instruction so that the
|
||||
* condition codes are updated.
|
||||
*/
|
||||
inst->CondUpdate = GL_TRUE;
|
||||
n->Store = n->Children[0]->Store;
|
||||
return inst; /* XXX or null? */
|
||||
return inst;
|
||||
}
|
||||
else {
|
||||
/* This'll happen for things like "if (i) ..." where no code
|
||||
|
|
@ -1225,8 +1269,9 @@ static struct prog_instruction *
|
|||
emit_swizzle(slang_emit_info *emitInfo, slang_ir_node *n)
|
||||
{
|
||||
GLuint swizzle;
|
||||
struct prog_instruction *inst;
|
||||
|
||||
(void) emit(emitInfo, n->Children[0]);
|
||||
inst = emit(emitInfo, n->Children[0]);
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
|
|
@ -1244,10 +1289,10 @@ emit_swizzle(slang_emit_info *emitInfo, slang_ir_node *n)
|
|||
n->Store->Index = n->Children[0]->Store->Index;
|
||||
n->Store->Size = swizzle_size(n->Store->Swizzle);
|
||||
#if 0
|
||||
printf("Emit Swizzle reg %d chSize %d size %d swz %s\n",
|
||||
printf("Emit Swizzle %s reg %d chSize %d mySize %d\n",
|
||||
_mesa_swizzle_string(n->Store->Swizzle, 0, 0),
|
||||
n->Store->Index, n->Children[0]->Store->Size,
|
||||
n->Store->Size,
|
||||
_mesa_swizzle_string(n->Store->Swizzle, 0, 0));
|
||||
n->Store->Size);
|
||||
#endif
|
||||
|
||||
/* apply this swizzle to child's swizzle to get composed swizzle */
|
||||
|
|
@ -1255,7 +1300,7 @@ emit_swizzle(slang_emit_info *emitInfo, slang_ir_node *n)
|
|||
n->Store->Swizzle = swizzle_swizzle(n->Children[0]->Store->Swizzle,
|
||||
swizzle);
|
||||
|
||||
return NULL;
|
||||
return inst;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1499,13 +1544,13 @@ emit(slang_emit_info *emitInfo, slang_ir_node *n)
|
|||
|
||||
case IR_LABEL:
|
||||
return emit_label(emitInfo, n);
|
||||
case IR_JUMP:
|
||||
assert(n);
|
||||
assert(n->Label);
|
||||
return emit_jump(emitInfo, n);
|
||||
|
||||
case IR_KILL:
|
||||
return emit_kill(emitInfo);
|
||||
|
||||
case IR_FUNC:
|
||||
return emit_func(emitInfo, n);
|
||||
|
||||
case IR_IF:
|
||||
return emit_if(emitInfo, n);
|
||||
|
||||
|
|
@ -1527,14 +1572,13 @@ emit(slang_emit_info *emitInfo, slang_ir_node *n)
|
|||
case IR_END_SUB:
|
||||
return new_instruction(emitInfo, OPCODE_ENDSUB);
|
||||
case IR_RETURN:
|
||||
return new_instruction(emitInfo, OPCODE_RET);
|
||||
return emit_return(emitInfo, n);
|
||||
|
||||
case IR_NOP:
|
||||
return NULL;
|
||||
|
||||
default:
|
||||
_mesa_problem(NULL, "Unexpected IR opcode in emit()\n");
|
||||
abort();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1555,6 +1599,7 @@ _slang_emit_code(slang_ir_node *n, slang_var_table *vt,
|
|||
|
||||
emitInfo.EmitHighLevelInstructions = ctx->Shader.EmitHighLevelInstructions;
|
||||
emitInfo.EmitCondCodes = ctx->Shader.EmitCondCodes;
|
||||
emitInfo.EmitBeginEndSub = 0; /* XXX temporary */
|
||||
emitInfo.EmitComments = ctx->Shader.EmitComments;
|
||||
|
||||
(void) emit(&emitInfo, n);
|
||||
|
|
|
|||
|
|
@ -74,7 +74,6 @@ static const slang_ir_info IrInfo[] = {
|
|||
{ IR_SEQ, "IR_SEQ", OPCODE_NOP, 0, 0 },
|
||||
{ IR_SCOPE, "IR_SCOPE", OPCODE_NOP, 0, 0 },
|
||||
{ IR_LABEL, "IR_LABEL", OPCODE_NOP, 0, 0 },
|
||||
{ IR_JUMP, "IR_JUMP", OPCODE_NOP, 0, 0 },
|
||||
{ IR_IF, "IR_IF", OPCODE_NOP, 0, 0 },
|
||||
{ IR_KILL, "IR_KILL", OPCODE_NOP, 0, 0 },
|
||||
{ IR_COND, "IR_COND", OPCODE_NOP, 0, 0 },
|
||||
|
|
@ -281,9 +280,6 @@ _slang_print_ir_tree(const slang_ir_node *n, int indent)
|
|||
printf("COND\n");
|
||||
_slang_print_ir_tree(n->Children[0], indent + 3);
|
||||
break;
|
||||
case IR_JUMP:
|
||||
printf("JUMP %s\n", n->Label->Name);
|
||||
break;
|
||||
|
||||
case IR_IF:
|
||||
printf("IF \n");
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ typedef enum
|
|||
IR_SCOPE, /* new variable scope (one child) */
|
||||
|
||||
IR_LABEL, /* target of a jump or cjump */
|
||||
IR_JUMP, /* unconditional jump */
|
||||
|
||||
IR_COND, /* conditional expression/predicate */
|
||||
|
||||
IR_IF, /* high-level IF/then/else */
|
||||
|
|
@ -62,6 +62,8 @@ typedef enum
|
|||
IR_RETURN, /* return from subroutine */
|
||||
IR_CALL, /* call subroutine */
|
||||
|
||||
IR_FUNC, /* inlined function code */
|
||||
|
||||
IR_LOOP, /* high-level loop-begin / loop-end */
|
||||
/* Children[0] = loop body */
|
||||
/* Children[1] = loop tail code, or NULL */
|
||||
|
|
|
|||
|
|
@ -208,10 +208,11 @@ link_uniform_vars(struct gl_shader_program *shProg, struct gl_program *prog)
|
|||
j = _mesa_add_sampler(shProg->Uniforms, p->Name);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
_mesa_problem(NULL, "bad parameter type in link_uniform_vars()");
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ASSERT(j >= 0);
|
||||
|
||||
size = p->Size;
|
||||
|
|
@ -544,7 +545,7 @@ _slang_link(GLcontext *ctx,
|
|||
if (!_slang_resolve_attributes(shProg, &shProg->VertexProgram->Base)) {
|
||||
/*goto cleanup;*/
|
||||
_mesa_problem(ctx, "_slang_resolve_attributes() failed");
|
||||
abort(); /* XXX fix */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -274,10 +274,8 @@ slang_print_tree(const slang_operation *op, int indent)
|
|||
*/
|
||||
}
|
||||
else {
|
||||
abort();
|
||||
spaces(indent);
|
||||
printf("DECL %s (anonymous variable!!!!)\n", (char *) op->a_id);
|
||||
/*abort();*/
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -310,11 +308,6 @@ slang_print_tree(const slang_operation *op, int indent)
|
|||
slang_print_tree(&op->children[0], indent + 3);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_GOTO:
|
||||
spaces(indent);
|
||||
printf("GOTO %s\n", (char *) op->a_id);
|
||||
break;
|
||||
|
||||
case SLANG_OPER_LABEL:
|
||||
spaces(indent);
|
||||
printf("LABEL %s\n", (char *) op->a_id);
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ typedef struct slang_assemble_ctx_
|
|||
slang_info_log *log;
|
||||
struct slang_label_ *curFuncEndLabel;
|
||||
struct slang_ir_node_ *CurLoop;
|
||||
struct slang_function_ *CurFunction;
|
||||
} slang_assemble_ctx;
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue