From: Keith Whitwell Date: Thu, 12 Jun 2008 22:01:05 +0000 (-0600) Subject: gallium: fix SSE codegen for instructions that use both a CONSTANT and IMMEDIATE X-Git-Tag: 062012170305~17580^2~390^2~1235 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=08f1b8ac709105d42ec34f8b8a81421e3b0fbc81;p=profile%2Fivi%2Fmesa.git gallium: fix SSE codegen for instructions that use both a CONSTANT and IMMEDIATE Fixes codegen for instructions like MUL dst, CONST[0], IMM[0]; the two operands would up getting aliased in the x86/sse code. Fixes glean/vertProg1/fogparams test. --- diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 5d4a8b3..388dd3f 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -67,19 +67,30 @@ static INLINE boolean eq( struct x86_reg a, } struct x86_reg aos_get_x86( struct aos_compilation *cp, + unsigned which_reg, /* quick hack */ unsigned value ) { - if (cp->ebp != value) { + struct x86_reg reg; + + if (which_reg == 0) + reg = cp->temp_EBP; + else + reg = cp->tmp_EAX; + + if (cp->x86_reg[which_reg] != value) { unsigned offset; switch (value) { case X86_IMMEDIATES: + assert(which_reg == 0); offset = Offset(struct aos_machine, immediates); break; case X86_CONSTANTS: + assert(which_reg == 1); offset = Offset(struct aos_machine, constants); break; case X86_ATTRIBS: + assert(which_reg == 0); offset = Offset(struct aos_machine, attrib); break; default: @@ -87,14 +98,14 @@ struct x86_reg aos_get_x86( struct aos_compilation *cp, offset = 0; } - x86_mov(cp->func, cp->temp_EBP, + + x86_mov(cp->func, reg, x86_make_disp(cp->machine_EDX, offset)); - /* x86_deref(x86_make_disp(cp->machine_EDX, offset))); */ - cp->ebp = value; + cp->x86_reg[which_reg] = value; } - return cp->temp_EBP; + return reg; } @@ -118,10 +129,10 @@ static struct x86_reg get_reg_ptr(struct aos_compilation *cp, return x86_make_disp(ptr, Offset(struct aos_machine, internal[idx])); case TGSI_FILE_IMMEDIATE: - return x86_make_disp(aos_get_x86(cp, X86_IMMEDIATES), idx * 4 * sizeof(float)); + return x86_make_disp(aos_get_x86(cp, 0, X86_IMMEDIATES), idx * 4 * sizeof(float)); case TGSI_FILE_CONSTANT: - return x86_make_disp(aos_get_x86(cp, X86_CONSTANTS), idx * 4 * sizeof(float)); + return x86_make_disp(aos_get_x86(cp, 1, X86_CONSTANTS), idx * 4 * sizeof(float)); default: ERROR(cp, "unknown reg file"); @@ -1413,6 +1424,7 @@ static boolean emit_POW( struct aos_compilation *cp, const struct tgsi_full_inst x87_fld_src( cp, &op->FullSrcRegisters[0], 0 ); x87_fstp( cp->func, x86_make_disp( cp->stack_ESP, 0 ) ); + /* tmp_EAX has been pushed & will be restored below */ x86_mov_reg_imm( cp->func, cp->tmp_EAX, (unsigned long) _powerf ); x86_call( cp->func, cp->tmp_EAX ); diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.h b/src/gallium/auxiliary/draw/draw_vs_aos.h index 66944a4..64e021f 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.h +++ b/src/gallium/auxiliary/draw/draw_vs_aos.h @@ -145,7 +145,7 @@ struct aos_compilation { unsigned last_used; } xmm[8]; - unsigned ebp; /* one of X86_* */ + unsigned x86_reg[2]; /* one of X86_* */ boolean input_fetched[PIPE_MAX_ATTRIBS]; unsigned output_last_write[PIPE_MAX_ATTRIBS]; @@ -213,6 +213,7 @@ do { \ #define X86_ATTRIBS 3 struct x86_reg aos_get_x86( struct aos_compilation *cp, + unsigned which_reg, unsigned value ); diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c index b720185..6b92811 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c @@ -96,7 +96,7 @@ static void get_src_ptr( struct aos_compilation *cp, struct x86_reg elt, unsigned a ) { - struct x86_reg attrib = x86_make_disp(aos_get_x86( cp, X86_ATTRIBS ), + struct x86_reg attrib = x86_make_disp(aos_get_x86( cp, 0, X86_ATTRIBS ), a * sizeof(struct aos_attrib)); struct x86_reg input_ptr = x86_make_disp(attrib,