gallium: fix SSE codegen for instructions that use both a CONSTANT and IMMEDIATE
authorKeith Whitwell <keith@tungstengraphics.com>
Thu, 12 Jun 2008 22:01:05 +0000 (16:01 -0600)
committerBrian Paul <brian.paul@tungstengraphics.com>
Thu, 12 Jun 2008 22:01:05 +0000 (16:01 -0600)
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.

src/gallium/auxiliary/draw/draw_vs_aos.c
src/gallium/auxiliary/draw/draw_vs_aos.h
src/gallium/auxiliary/draw/draw_vs_aos_io.c

index 5d4a8b38c876f133b37a75dab77683291b188f46..388dd3fbee07b6c11d9bca4a9e075f903c3a11b3 100644 (file)
@@ -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 );
 
index 66944a4e33f5a72733ac6a9f511a14fad39a6e19..64e021ff6b7c9ab7d257707ab6bd55187f3960f0 100644 (file)
@@ -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 );
 
 
index b720185709c08e7e8b3311b1b725fb44646f0e9d..6b9281187072c11128cc6bb5410f1d1a5e2bb1a8 100644 (file)
@@ -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,