From 059e9014462fe5361055e529a344338dcbc43c5d Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 20 Jan 2007 10:47:10 -0700 Subject: Add a simple mechanism for annotating instructions for easier debugging. --- src/mesa/shader/slang/slang_emit.c | 152 ++++++++++++++++++++++++++++++++++++- 1 file changed, 148 insertions(+), 4 deletions(-) diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 0f6d6cb554..036509c51c 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -40,6 +40,8 @@ #define PEEPHOLE_OPTIMIZATIONS 1 +#define ANNOTATE 0 + /** * Assembly and IR info @@ -436,6 +438,131 @@ static struct prog_instruction * emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog); +/** + * Return an annotation string for given node's storage. + */ +static char * +storage_annotation(const slang_ir_node *n, const struct gl_program *prog) +{ +#if ANNOTATE + const slang_ir_storage *st = n->Store; + static char s[100] = ""; + + if (!st) + return _mesa_strdup(""); + + switch (st->File) { + case PROGRAM_CONSTANT: + if (st->Index >= 0) { + const GLfloat *val = prog->Parameters->ParameterValues[st->Index]; + if (st->Swizzle == SWIZZLE_NOOP) + sprintf(s, "{%f, %f, %f, %f}", val[0], val[1], val[2], val[3]); + else { + sprintf(s, "%f", val[GET_SWZ(st->Swizzle, 0)]); + } + } + break; + case PROGRAM_TEMPORARY: + if (n->Var) + sprintf(s, "%s", (char *) n->Var->a_name); + else + sprintf(s, "t[%d]", st->Index); + break; + case PROGRAM_STATE_VAR: + case PROGRAM_UNIFORM: + sprintf(s, "%s", prog->Parameters->Parameters[st->Index].Name); + break; + case PROGRAM_VARYING: + sprintf(s, "%s", prog->Varying->Parameters[st->Index].Name); + break; + case PROGRAM_INPUT: + sprintf(s, "input[%d]", st->Index); + break; + case PROGRAM_OUTPUT: + sprintf(s, "output[%d]", st->Index); + break; + default: + s[0] = 0; + } + return _mesa_strdup(s); +#else + return NULL; +#endif +} + + +/** + * Return an annotation string for an instruction. + */ +static char * +instruction_annotation(gl_inst_opcode opcode, + char *dstAnnot, char *srcAnnot0, char *srcAnnot1) +{ +#if ANNOTATE + const char *operator; + char *s; + int len = 50; + + if (dstAnnot) + len += strlen(dstAnnot); + else + dstAnnot = _mesa_strdup(""); + + if (srcAnnot0) + len += strlen(srcAnnot0); + else + srcAnnot0 = _mesa_strdup(""); + + if (srcAnnot1) + len += strlen(srcAnnot1); + else + srcAnnot1 = _mesa_strdup(""); + + switch (opcode) { + case OPCODE_ADD: + operator = "+"; + break; + case OPCODE_SUB: + operator = "-"; + break; + case OPCODE_MUL: + operator = "*"; + break; + case OPCODE_DP3: + operator = "DP3"; + break; + case OPCODE_DP4: + operator = "DP4"; + break; + case OPCODE_XPD: + operator = "XPD"; + break; + case OPCODE_RSQ: + operator = "RSQ"; + break; + case OPCODE_SGT: + operator = ">"; + break; + default: + operator = ","; + } + + s = (char *) malloc(len); + sprintf(s, "%s = %s %s %s", dstAnnot, srcAnnot0, operator, srcAnnot1); + assert(_mesa_strlen(s) < len); + + free(dstAnnot); + free(srcAnnot0); + free(srcAnnot1); + + return s; +#else + return NULL; +#endif +} + + + /** * Generate code for a simple binary-op instruction. */ @@ -444,6 +571,7 @@ emit_binop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) { struct prog_instruction *inst; const slang_ir_info *info = slang_find_ir_info(n->Opcode); + char *srcAnnot0 = NULL, *srcAnnot1 = NULL, *dstAnnot = NULL; assert(info); assert(info->InstOpcode != OPCODE_NOP); @@ -497,6 +625,10 @@ emit_binop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) inst = new_instruction(prog, info->InstOpcode); storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); storage_to_src_reg(&inst->SrcReg[1], n->Children[1]->Store); + + srcAnnot0 = storage_annotation(n->Children[0], prog); + srcAnnot1 = storage_annotation(n->Children[1], prog); + free_temp_storage(vt, n->Children[0]); free_temp_storage(vt, n->Children[1]); } @@ -506,7 +638,10 @@ emit_binop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) } storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); - inst->Comment = n->Comment; + dstAnnot = storage_annotation(n, prog); + inst->Comment = instruction_annotation(inst->Opcode, dstAnnot, + srcAnnot0, srcAnnot1); + /*_mesa_print_instruction(inst);*/ return inst; } @@ -517,8 +652,9 @@ emit_unop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) { struct prog_instruction *inst; const slang_ir_info *info = slang_find_ir_info(n->Opcode); - assert(info); + char *srcAnnot, *dstAnnot; + assert(info); assert(info->NumParams == 1); /* gen code for child */ @@ -527,6 +663,7 @@ emit_unop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) /* gen this instruction */ inst = new_instruction(prog, info->InstOpcode); storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); + srcAnnot = storage_annotation(n->Children[0], prog); free_temp_storage(vt, n->Children[0]); if (!n->Store) { @@ -534,8 +671,10 @@ emit_unop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) } storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); - inst->Comment = n->Comment; - /*_mesa_print_instruction(inst);*/ + dstAnnot = storage_annotation(n, prog); + inst->Comment = instruction_annotation(inst->Opcode, dstAnnot, + NULL, srcAnnot); + return inst; } @@ -702,11 +841,16 @@ emit_move(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) } else { /* single register move */ + char *srcAnnot, *dstAnnot; inst = new_instruction(prog, OPCODE_MOV); assert(n->Children[0]->Store->Index >= 0); assert(n->Children[0]->Store->Index < 16); storage_to_dst_reg(&inst->DstReg, n->Children[0]->Store, n->Writemask); storage_to_src_reg(&inst->SrcReg[0], n->Children[1]->Store); + dstAnnot = storage_annotation(n->Children[0], prog); + srcAnnot = storage_annotation(n->Children[1], prog); + inst->Comment = instruction_annotation(inst->Opcode, dstAnnot, + srcAnnot, NULL); } /* XXX is this test correct? */ if (_slang_is_temp(vt, n->Children[1]->Store->Index)) { -- cgit v1.2.3