summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary
diff options
context:
space:
mode:
authorKeith Whitwell <[email protected]>2008-06-12 16:01:05 -0600
committerBrian Paul <[email protected]>2008-06-12 16:01:05 -0600
commit08f1b8ac709105d42ec34f8b8a81421e3b0fbc81 (patch)
tree56273a585cb4cbc7f9a4cd1b87c6c61607dce997 /src/gallium/auxiliary
parentb19e8f720bb2f4d360f5497b64901fc48321f172 (diff)
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.
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_aos.c26
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_aos.h3
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_aos_io.c2
3 files changed, 22 insertions, 9 deletions
diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c
index 5d4a8b38c87..388dd3fbee0 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 66944a4e33f..64e021ff6b7 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 b720185709c..6b928118707 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,