combine emit_unop(), emit_binop(), emit_triop() into emit_arith()

This commit is contained in:
Brian 2007-01-28 16:26:09 -07:00
parent 62e7c033c0
commit a06f929362

View file

@ -503,8 +503,8 @@ storage_annotation(const slang_ir_node *n, const struct gl_program *prog)
* Return an annotation string for an instruction.
*/
static char *
instruction_annotation(gl_inst_opcode opcode,
char *dstAnnot, char *srcAnnot0, char *srcAnnot1)
instruction_annotation(gl_inst_opcode opcode, char *dstAnnot,
char *srcAnnot0, char *srcAnnot1, char *srcAnnot2)
{
#if ANNOTATE
const char *operator;
@ -526,6 +526,11 @@ instruction_annotation(gl_inst_opcode opcode,
else
srcAnnot1 = _mesa_strdup("");
if (srcAnnot2)
len += strlen(srcAnnot2);
else
srcAnnot2 = _mesa_strdup("");
switch (opcode) {
case OPCODE_ADD:
operator = "+";
@ -556,12 +561,14 @@ instruction_annotation(gl_inst_opcode opcode,
}
s = (char *) malloc(len);
sprintf(s, "%s = %s %s %s", dstAnnot, srcAnnot0, operator, srcAnnot1);
sprintf(s, "%s = %s %s %s %s", dstAnnot,
srcAnnot0, operator, srcAnnot1, srcAnnot2);
assert(_mesa_strlen(s) < len);
free(dstAnnot);
free(srcAnnot0);
free(srcAnnot1);
free(srcAnnot2);
return s;
#else
@ -572,21 +579,26 @@ instruction_annotation(gl_inst_opcode opcode,
/**
* Generate code for a simple binary-op instruction.
* Generate code for a simple arithmetic instruction.
* Either 1, 2 or 3 operands.
*/
static struct prog_instruction *
emit_binop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
emit_arith(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;
char *srcAnnot[3], *dstAnnot;
GLuint i;
assert(info);
assert(info->InstOpcode != OPCODE_NOP);
srcAnnot[0] = srcAnnot[1] = srcAnnot[2] = dstAnnot = NULL;
#if PEEPHOLE_OPTIMIZATIONS
/* Look for MAD opportunity */
if (n->Opcode == IR_ADD && n->Children[0]->Opcode == IR_MUL) {
if (info->NumParams == 2 &&
n->Opcode == IR_ADD && n->Children[0]->Opcode == IR_MUL) {
/* found pattern IR_ADD(IR_MUL(A, B), C) */
emit(vt, n->Children[0]->Children[0], prog); /* A */
emit(vt, n->Children[0]->Children[1], prog); /* B */
@ -601,7 +613,8 @@ emit_binop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
free_temp_storage(vt, n->Children[0]->Children[1]);
free_temp_storage(vt, n->Children[1]);
}
else if (n->Opcode == IR_ADD && n->Children[1]->Opcode == IR_MUL) {
else if (info->NumParams == 2 &&
n->Opcode == IR_ADD && n->Children[1]->Opcode == IR_MUL) {
/* found pattern IR_ADD(A, IR_MUL(B, C)) */
emit(vt, n->Children[0], prog); /* A */
emit(vt, n->Children[1]->Children[0], prog); /* B */
@ -622,21 +635,24 @@ emit_binop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
/* normal case */
/* gen code for children */
emit(vt, n->Children[0], prog);
emit(vt, n->Children[1], prog);
for (i = 0; i < info->NumParams; i++)
emit(vt, n->Children[i], prog);
/* gen this instruction */
/* gen this instruction and src registers */
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);
for (i = 0; i < info->NumParams; i++)
storage_to_src_reg(&inst->SrcReg[i], n->Children[i]->Store);
srcAnnot0 = storage_annotation(n->Children[0], prog);
srcAnnot1 = storage_annotation(n->Children[1], prog);
/* annotation */
for (i = 0; i < info->NumParams; i++)
srcAnnot[i] = storage_annotation(n->Children[i], prog);
free_temp_storage(vt, n->Children[0]);
free_temp_storage(vt, n->Children[1]);
/* free temps */
for (i = 0; i < info->NumParams; i++)
free_temp_storage(vt, n->Children[i]);
}
/* result storage */
if (!n->Store) {
if (!alloc_temp_storage(vt, n, info->ResultSize))
return NULL;
@ -644,87 +660,15 @@ emit_binop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
dstAnnot = storage_annotation(n, prog);
inst->Comment = instruction_annotation(inst->Opcode, dstAnnot,
srcAnnot0, srcAnnot1);
inst->Comment = instruction_annotation(inst->Opcode, dstAnnot, srcAnnot[0],
srcAnnot[1], srcAnnot[2]);
/*_mesa_print_instruction(inst);*/
return inst;
}
static struct prog_instruction *
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);
char *srcAnnot, *dstAnnot;
assert(info);
assert(info->NumParams == 1);
/* gen code for child */
emit(vt, n->Children[0], 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) {
if (!alloc_temp_storage(vt, n, info->ResultSize))
return NULL;
}
storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
dstAnnot = storage_annotation(n, prog);
inst->Comment = instruction_annotation(inst->Opcode, dstAnnot,
NULL, srcAnnot);
return inst;
}
/**
* Generate code for a simple tri-op instruction.
*/
static struct prog_instruction *
emit_triop(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);
assert(info->InstOpcode != OPCODE_NOP);
/* only one tri-op IR node (for now): */
assert(info->InstOpcode == OPCODE_LRP);
/* gen code for children */
emit(vt, n->Children[0], prog);
emit(vt, n->Children[1], prog);
emit(vt, n->Children[2], prog);
/* gen this instruction */
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);
storage_to_src_reg(&inst->SrcReg[2], n->Children[2]->Store);
free_temp_storage(vt, n->Children[0]);
free_temp_storage(vt, n->Children[1]);
free_temp_storage(vt, n->Children[2]);
if (!n->Store) {
if (!alloc_temp_storage(vt, n, info->ResultSize))
return NULL;
}
storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
return inst;
}
static struct prog_instruction *
emit_negation(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
@ -898,7 +842,7 @@ emit_move(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
dstAnnot = storage_annotation(n->Children[0], prog);
srcAnnot = storage_annotation(n->Children[1], prog);
inst->Comment = instruction_annotation(inst->Opcode, dstAnnot,
srcAnnot, NULL);
srcAnnot, NULL, NULL);
}
free_temp_storage(vt, n->Children[1]);
assert(!n->Store);
@ -1038,7 +982,19 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
n->Store->Swizzle);
return NULL;
/* Simple binary operators */
/* Simple arithmetic */
/* unary */
case IR_RSQ:
case IR_RCP:
case IR_FLOOR:
case IR_FRAC:
case IR_F_TO_I:
case IR_ABS:
case IR_SIN:
case IR_COS:
case IR_DDX:
case IR_DDY:
/* binary */
case IR_ADD:
case IR_SUB:
case IR_MUL:
@ -1054,22 +1010,9 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
case IR_POW:
case IR_EXP:
case IR_EXP2:
return emit_binop(vt, n, prog);
/* Simple unary operators */
case IR_RSQ:
case IR_RCP:
case IR_FLOOR:
case IR_FRAC:
case IR_F_TO_I:
case IR_ABS:
case IR_SIN:
case IR_COS:
case IR_DDX:
case IR_DDY:
return emit_unop(vt, n, prog);
/* trianary operators */
/* trinary operators */
case IR_LRP:
return emit_triop(vt, n, prog);
return emit_arith(vt, n, prog);
case IR_TEX:
case IR_TEXB:
case IR_TEXP: