Remove tgsi_sse2.
authorJosé Fonseca <jose.r.fonseca@gmail.com>
Tue, 8 Nov 2011 00:10:47 +0000 (00:10 +0000)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Tue, 8 Nov 2011 22:57:34 +0000 (22:57 +0000)
tgsi_exec is simple. llvm is fast. tgsi_sse2 ends up being neither.

20 files changed:
src/gallium/auxiliary/Makefile.sources
src/gallium/auxiliary/draw/draw_private.h
src/gallium/auxiliary/draw/draw_vs.c
src/gallium/auxiliary/draw/draw_vs.h
src/gallium/auxiliary/draw/draw_vs_aos.c [deleted file]
src/gallium/auxiliary/draw/draw_vs_aos.h [deleted file]
src/gallium/auxiliary/draw/draw_vs_aos_io.c [deleted file]
src/gallium/auxiliary/draw/draw_vs_aos_machine.c [deleted file]
src/gallium/auxiliary/draw/draw_vs_ppc.c
src/gallium/auxiliary/draw/draw_vs_sse.c [deleted file]
src/gallium/auxiliary/tgsi/tgsi_sse2.c [deleted file]
src/gallium/auxiliary/tgsi/tgsi_sse2.h [deleted file]
src/gallium/drivers/softpipe/Android.mk
src/gallium/drivers/softpipe/Makefile
src/gallium/drivers/softpipe/SConscript
src/gallium/drivers/softpipe/sp_context.c
src/gallium/drivers/softpipe/sp_context.h
src/gallium/drivers/softpipe/sp_fs.h
src/gallium/drivers/softpipe/sp_fs_sse.c [deleted file]
src/gallium/drivers/softpipe/sp_state_shader.c

index 766beb0fafc238e73c5b6b2f8c6cc18a775121d6..baded909cec985ff8f4dba6ff9c81e7625fbb11f 100644 (file)
@@ -33,12 +33,8 @@ C_SOURCES := \
        draw/draw_pt_vsplit.c \
        draw/draw_vertex.c \
        draw/draw_vs.c \
-       draw/draw_vs_aos.c \
-       draw/draw_vs_aos_io.c \
-       draw/draw_vs_aos_machine.c \
        draw/draw_vs_exec.c \
        draw/draw_vs_ppc.c \
-       draw/draw_vs_sse.c \
        draw/draw_vs_variant.c \
        os/os_misc.c \
        os/os_stream.c \
@@ -83,7 +79,6 @@ C_SOURCES := \
        tgsi/tgsi_ppc.c \
        tgsi/tgsi_sanity.c \
        tgsi/tgsi_scan.c \
-       tgsi/tgsi_sse2.c \
        tgsi/tgsi_text.c \
        tgsi/tgsi_transform.c \
        tgsi/tgsi_ureg.c \
index b84d2b77179bc0e8b83ab47831b2f1bfbf4148e5..3521a035e2f5560073bf3d5f3d96eb8aee3a436f 100644 (file)
@@ -237,10 +237,6 @@ struct draw_context
       uint num_samplers;
       struct tgsi_sampler **samplers;
 
-      /* Here's another one:
-       */
-      struct aos_machine *aos_machine; 
-
 
       const void *aligned_constants[PIPE_MAX_CONSTANT_BUFFERS];
 
index 1763dbc199f4c8a41a6ab75d706e289e95e0bc65..957bbe57a82ee00b0a696d1a21eac825ffdaff09 100644 (file)
@@ -81,14 +81,12 @@ draw_vs_set_constants(struct draw_context *draw,
    }
 
    draw->vs.aligned_constants[slot] = constants;
-   draw_vs_aos_machine_constants(draw->vs.aos_machine, slot, constants);
 }
 
 
 void draw_vs_set_viewport( struct draw_context *draw,
                            const struct pipe_viewport_state *viewport )
 {
-   draw_vs_aos_machine_viewport( draw->vs.aos_machine, viewport );
 }
 
 
@@ -103,22 +101,8 @@ draw_create_vertex_shader(struct draw_context *draw,
       tgsi_dump(shader->tokens, 0);
    }
 
-   if (!draw->pt.middle.llvm) {
-#if 0
-/* these paths don't support vertex clamping
- * TODO: either add it, or remove them completely
- * use LLVM instead if you want performance
- * use exec instead if you want debugging/more correctness
- */
-#if defined(PIPE_ARCH_X86)
-      vs = draw_create_vs_sse( draw, shader );
-#elif defined(PIPE_ARCH_PPC)
-      vs = draw_create_vs_ppc( draw, shader );
-#endif
-#endif
-   }
 #if HAVE_LLVM
-   else {
+   if (draw->pt.middle.llvm) {
       vs = draw_create_vs_llvm(draw, shader);
    }
 #endif
@@ -199,12 +183,6 @@ draw_vs_init( struct draw_context *draw )
    if (!draw->vs.fetch_cache) 
       return FALSE;
 
-   draw->vs.aos_machine = draw_vs_aos_machine();
-#ifdef PIPE_ARCH_X86
-   if (!draw->vs.aos_machine)
-      return FALSE;
-#endif
-      
    return TRUE;
 }
 
@@ -219,9 +197,6 @@ draw_vs_destroy( struct draw_context *draw )
    if (draw->vs.emit_cache)
       translate_cache_destroy(draw->vs.emit_cache);
 
-   if (draw->vs.aos_machine)
-      draw_vs_aos_machine_destroy(draw->vs.aos_machine);
-
    for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
       if (draw->vs.aligned_constant_storage[i]) {
          align_free((void *)draw->vs.aligned_constant_storage[i]);
index e6d187e97742bfe0ee8d18f6c3bd58b98e3cbb33..49229f8164b675d78eea29072dad7d3c08503994 100644 (file)
@@ -158,10 +158,6 @@ struct draw_vertex_shader *
 draw_create_vs_exec(struct draw_context *draw,
                    const struct pipe_shader_state *templ);
 
-struct draw_vertex_shader *
-draw_create_vs_sse(struct draw_context *draw,
-                  const struct pipe_shader_state *templ);
-
 struct draw_vertex_shader *
 draw_create_vs_ppc(struct draw_context *draw,
                   const struct pipe_shader_state *templ);
@@ -170,10 +166,6 @@ draw_create_vs_ppc(struct draw_context *draw,
 struct draw_vs_variant_key;
 struct draw_vertex_shader;
 
-struct draw_vs_variant *
-draw_vs_create_variant_aos_sse( struct draw_vertex_shader *vs,
-                                const struct draw_vs_variant_key *key );
-
 #if HAVE_LLVM
 struct draw_vertex_shader *
 draw_create_vs_llvm(struct draw_context *draw,
@@ -214,18 +206,6 @@ static INLINE int draw_vs_variant_key_compare( const struct draw_vs_variant_key
 }
 
 
-struct aos_machine *draw_vs_aos_machine( void );
-void draw_vs_aos_machine_destroy( struct aos_machine *machine );
-
-void
-draw_vs_aos_machine_constants(struct aos_machine *machine,
-                              unsigned slot,
-                              const void *constants);
-
-void draw_vs_aos_machine_viewport( struct aos_machine *machine,
-                                   const struct pipe_viewport_state *viewport );
-
-
 #define MAX_TGSI_VERTICES 4
    
 
diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c
deleted file mode 100644 (file)
index 7b90dba..0000000
+++ /dev/null
@@ -1,2267 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.3
- *
- * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * Translate tgsi vertex programs to x86/x87/SSE/SSE2 machine code
- * using the rtasm runtime assembler.  Based on the old
- * t_vb_arb_program_sse.c
- */
-
-
-#include "util/u_memory.h"
-#include "util/u_math.h"
-#include "pipe/p_shader_tokens.h"
-#include "util/u_debug.h"
-#include "tgsi/tgsi_parse.h"
-#include "tgsi/tgsi_util.h"
-#include "tgsi/tgsi_exec.h"
-#include "tgsi/tgsi_dump.h"
-
-#include "draw_vs.h"
-#include "draw_vs_aos.h"
-
-#include "rtasm/rtasm_x86sse.h"
-
-#ifdef PIPE_ARCH_X86
-#define DISASSEM 0
-#define FAST_MATH 1
-
-static const char *files[] =
-{
-   "NULL",
-   "CONST",
-   "IN",
-   "OUT",
-   "TEMP",
-   "SAMP",
-   "ADDR",
-   "IMM",
-   "INTERNAL",
-};
-
-static INLINE boolean eq( struct x86_reg a,
-                           struct x86_reg b )
-{
-   return (a.file == b.file &&
-          a.idx == b.idx &&
-          a.mod == b.mod &&
-          a.disp == b.disp);
-}
-      
-struct x86_reg aos_get_x86( struct aos_compilation *cp,
-                            unsigned which_reg, /* quick hack */
-                            unsigned 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_BUFFERS:
-         assert(which_reg == 0);
-         offset = Offset(struct aos_machine, buffer);
-         break;
-      default:
-         assert(0);
-         offset = 0;
-      }
-
-
-      x86_mov(cp->func, reg, 
-              x86_make_disp(cp->machine_EDX, offset));
-
-      cp->x86_reg[which_reg] = value;
-   }
-
-   return reg;
-}
-
-
-static struct x86_reg get_reg_ptr(struct aos_compilation *cp,
-                                  unsigned file,
-                                 unsigned idx )
-{
-   struct x86_reg ptr = cp->machine_EDX;
-
-   switch (file) {
-   case TGSI_FILE_INPUT:
-      assert(idx < MAX_INPUTS);
-      return x86_make_disp(ptr, Offset(struct aos_machine, input[idx]));
-
-   case TGSI_FILE_OUTPUT:
-      return x86_make_disp(ptr, Offset(struct aos_machine, output[idx]));
-
-   case TGSI_FILE_TEMPORARY:
-      assert(idx < MAX_TEMPS);
-      return x86_make_disp(ptr, Offset(struct aos_machine, temp[idx]));
-
-   case AOS_FILE_INTERNAL:
-      assert(idx < MAX_INTERNALS);
-      return x86_make_disp(ptr, Offset(struct aos_machine, internal[idx]));
-
-   case TGSI_FILE_IMMEDIATE: 
-      assert(idx < MAX_IMMEDIATES);  /* just a sanity check */
-      return x86_make_disp(aos_get_x86(cp, 0, X86_IMMEDIATES), idx * 4 * sizeof(float));
-
-   case TGSI_FILE_CONSTANT: 
-      assert(idx < MAX_CONSTANTS);  /* just a sanity check */
-      return x86_make_disp(aos_get_x86(cp, 1, X86_CONSTANTS), idx * 4 * sizeof(float));
-
-   default:
-      AOS_ERROR(cp, "unknown reg file");
-      return x86_make_reg(0,0);
-   }
-}
-               
-
-
-#define X87_CW_EXCEPTION_INV_OP       (1<<0)
-#define X87_CW_EXCEPTION_DENORM_OP    (1<<1)
-#define X87_CW_EXCEPTION_ZERO_DIVIDE  (1<<2)
-#define X87_CW_EXCEPTION_OVERFLOW     (1<<3)
-#define X87_CW_EXCEPTION_UNDERFLOW    (1<<4)
-#define X87_CW_EXCEPTION_PRECISION    (1<<5)
-#define X87_CW_PRECISION_SINGLE       (0<<8)
-#define X87_CW_PRECISION_RESERVED     (1<<8)
-#define X87_CW_PRECISION_DOUBLE       (2<<8)
-#define X87_CW_PRECISION_DOUBLE_EXT   (3<<8)
-#define X87_CW_PRECISION_MASK         (3<<8)
-#define X87_CW_ROUND_NEAREST          (0<<10)
-#define X87_CW_ROUND_DOWN             (1<<10)
-#define X87_CW_ROUND_UP               (2<<10)
-#define X87_CW_ROUND_ZERO             (3<<10)
-#define X87_CW_ROUND_MASK             (3<<10)
-#define X87_CW_INFINITY               (1<<12)
-
-
-
-
-static void spill( struct aos_compilation *cp, unsigned idx )
-{
-   if (!cp->xmm[idx].dirty ||
-       (cp->xmm[idx].file != TGSI_FILE_INPUT && /* inputs are fetched into xmm & set dirty */
-        cp->xmm[idx].file != TGSI_FILE_OUTPUT &&
-        cp->xmm[idx].file != TGSI_FILE_TEMPORARY)) {
-      AOS_ERROR(cp, "invalid spill");
-      return;
-   }
-   else {
-      struct x86_reg oldval = get_reg_ptr(cp,
-                                          cp->xmm[idx].file,
-                                          cp->xmm[idx].idx);
-     
-      if (0) debug_printf("\nspill %s[%d]", 
-                          files[cp->xmm[idx].file],
-                          cp->xmm[idx].idx);
-      assert(cp->xmm[idx].dirty);
-      sse_movaps(cp->func, oldval, x86_make_reg(file_XMM, idx));
-      cp->xmm[idx].dirty = 0;
-   }
-}
-
-
-void aos_spill_all( struct aos_compilation *cp )
-{
-   unsigned i;
-
-   for (i = 0; i < 8; i++) {
-      if (cp->xmm[i].dirty) 
-         spill(cp, i);
-      aos_release_xmm_reg(cp, i);
-   }
-}
-
-
-static struct x86_reg get_xmm_writable( struct aos_compilation *cp,
-                                        struct x86_reg reg )
-{
-   if (reg.file != file_XMM ||
-       cp->xmm[reg.idx].file != TGSI_FILE_NULL)
-   {
-      struct x86_reg tmp = aos_get_xmm_reg(cp);
-      sse_movaps(cp->func, tmp, reg);
-      reg = tmp;
-   }
-
-   cp->xmm[reg.idx].last_used = cp->insn_counter;
-   return reg;
-}
-
-static struct x86_reg get_xmm( struct aos_compilation *cp,
-                               struct x86_reg reg )
-{
-   if (reg.file != file_XMM) 
-   {
-      struct x86_reg tmp = aos_get_xmm_reg(cp);
-      sse_movaps(cp->func, tmp, reg);
-      reg = tmp;
-   }
-
-   cp->xmm[reg.idx].last_used = cp->insn_counter;
-   return reg;
-}
-
-
-/* Allocate an empty xmm register, either as a temporary or later to
- * "adopt" as a shader reg.
- */
-struct x86_reg aos_get_xmm_reg( struct aos_compilation *cp )
-{
-   unsigned i;
-   unsigned oldest = 0;
-   boolean found = FALSE;
-
-   for (i = 0; i < 8; i++) 
-      if (cp->xmm[i].last_used != cp->insn_counter &&
-          cp->xmm[i].file == TGSI_FILE_NULL) {
-        oldest = i;
-         found = TRUE;
-      }
-
-   if (!found) {
-      for (i = 0; i < 8; i++) 
-         if (cp->xmm[i].last_used < cp->xmm[oldest].last_used)
-            oldest = i;
-   }
-
-   /* Need to write out the old value?
-    */
-   if (cp->xmm[oldest].dirty) 
-      spill(cp, oldest);
-
-   assert(cp->xmm[oldest].last_used != cp->insn_counter);
-
-   cp->xmm[oldest].file = TGSI_FILE_NULL;
-   cp->xmm[oldest].idx = 0;
-   cp->xmm[oldest].dirty = 0;
-   cp->xmm[oldest].last_used = cp->insn_counter;
-   return x86_make_reg(file_XMM, oldest);
-}
-
-void aos_release_xmm_reg( struct aos_compilation *cp,
-                          unsigned idx )
-{
-   cp->xmm[idx].file = TGSI_FILE_NULL;
-   cp->xmm[idx].idx = 0;
-   cp->xmm[idx].dirty = 0;
-   cp->xmm[idx].last_used = 0;
-}
-
-
-static void aos_soft_release_xmm( struct aos_compilation *cp,
-                                  struct x86_reg reg )
-{
-   if (reg.file == file_XMM) {
-      assert(cp->xmm[reg.idx].last_used == cp->insn_counter);
-      cp->xmm[reg.idx].last_used = cp->insn_counter - 1;
-   }
-}
-
-
-     
-/* Mark an xmm reg as holding the current copy of a shader reg.
- */
-void aos_adopt_xmm_reg( struct aos_compilation *cp,
-                        struct x86_reg reg,
-                        unsigned file,
-                        unsigned idx,
-                        unsigned dirty )
-{
-   unsigned i;
-
-   if (reg.file != file_XMM) {
-      assert(0);
-      return;
-   }
-
-
-   /* If any xmm reg thinks it holds this shader reg, break the
-    * illusion.
-    */
-   for (i = 0; i < 8; i++) {
-      if (cp->xmm[i].file == file && 
-          cp->xmm[i].idx == idx) 
-      {
-         /* If an xmm reg is already holding this shader reg, take into account its
-          * dirty flag...
-          */
-         dirty |= cp->xmm[i].dirty;
-         aos_release_xmm_reg(cp, i);
-      }
-   }
-
-   cp->xmm[reg.idx].file = file;
-   cp->xmm[reg.idx].idx = idx;
-   cp->xmm[reg.idx].dirty = dirty;
-   cp->xmm[reg.idx].last_used = cp->insn_counter;
-}
-
-
-/* Return a pointer to the in-memory copy of the reg, making sure it is uptodate.
- */
-static struct x86_reg aos_get_shader_reg_ptr( struct aos_compilation *cp, 
-                                              unsigned file,
-                                              unsigned idx )
-{
-   unsigned i;
-
-   /* Ensure the in-memory copy of this reg is up-to-date
-    */
-   for (i = 0; i < 8; i++) {
-      if (cp->xmm[i].file == file && 
-          cp->xmm[i].idx == idx &&
-          cp->xmm[i].dirty) {
-         spill(cp, i);
-      }
-   }
-
-   return get_reg_ptr( cp, file, idx );
-}
-
-
-/* As above, but return a pointer.  Note - this pointer may alias
- * those returned by get_arg_ptr().
- */
-static struct x86_reg get_dst_ptr( struct aos_compilation *cp, 
-                                   const struct tgsi_full_dst_register *dst )
-{
-   unsigned file = dst->Register.File;
-   unsigned idx = dst->Register.Index;
-   unsigned i;
-   
-
-   /* Ensure in-memory copy of this reg is up-to-date and invalidate
-    * any xmm copies.
-    */
-   for (i = 0; i < 8; i++) {
-      if (cp->xmm[i].file == file &&
-          cp->xmm[i].idx == idx)
-      {
-         if (cp->xmm[i].dirty) 
-            spill(cp, i);
-         
-         aos_release_xmm_reg(cp, i);
-      }
-   }
-
-   return get_reg_ptr( cp, file, idx );
-}
-
-
-
-
-
-/* Return an XMM reg if the argument is resident, otherwise return a
- * base+offset pointer to the saved value.
- */
-struct x86_reg aos_get_shader_reg( struct aos_compilation *cp, 
-                                   unsigned file,
-                                   unsigned idx )
-{
-   unsigned i;
-
-   for (i = 0; i < 8; i++) {
-      if (cp->xmm[i].file == file &&
-         cp->xmm[i].idx  == idx) 
-      {
-        cp->xmm[i].last_used = cp->insn_counter;
-        return x86_make_reg(file_XMM, i);
-      }
-   }
-
-   /* If not found in the XMM register file, return an indirect
-    * reference to the in-memory copy:
-    */
-   return get_reg_ptr( cp, file, idx );
-}
-
-
-
-static struct x86_reg aos_get_shader_reg_xmm( struct aos_compilation *cp, 
-                                              unsigned file,
-                                              unsigned idx )
-{
-   struct x86_reg reg = get_xmm( cp,
-                                 aos_get_shader_reg( cp, file, idx ) );
-
-   aos_adopt_xmm_reg( cp,
-                      reg,
-                      file,
-                      idx,
-                      FALSE );
-   
-   return reg;
-}
-
-
-
-struct x86_reg aos_get_internal_xmm( struct aos_compilation *cp,
-                                     unsigned imm )
-{
-   return aos_get_shader_reg_xmm( cp, AOS_FILE_INTERNAL, imm );
-}
-
-
-struct x86_reg aos_get_internal( struct aos_compilation *cp,
-                                 unsigned imm )
-{
-   return aos_get_shader_reg( cp, AOS_FILE_INTERNAL, imm );
-}
-
-
-
-
-
-/* Emulate pshufd insn in regular SSE, if necessary:
- */
-static void emit_pshufd( struct aos_compilation *cp,
-                        struct x86_reg dst,
-                        struct x86_reg arg0,
-                        ubyte shuf )
-{
-   if (cp->have_sse2) {
-      sse2_pshufd(cp->func, dst, arg0, shuf);
-   }
-   else {
-      if (!eq(dst, arg0)) 
-        sse_movaps(cp->func, dst, arg0);
-
-      sse_shufps(cp->func, dst, dst, shuf);
-   }
-}
-
-/* load masks (pack into negs??)
- * pshufd - shuffle according to writemask
- * and - result, mask
- * nand - dest, mask
- * or - dest, result
- */
-static boolean mask_write( struct aos_compilation *cp,
-                           struct x86_reg dst,
-                           struct x86_reg result,
-                           unsigned mask )
-{
-   struct x86_reg imm_swz = aos_get_internal_xmm(cp, IMM_SWZ);
-   struct x86_reg tmp = aos_get_xmm_reg(cp);
-   
-   emit_pshufd(cp, tmp, imm_swz, 
-               SHUF((mask & 1) ? 2 : 3,
-                    (mask & 2) ? 2 : 3,
-                    (mask & 4) ? 2 : 3,
-                    (mask & 8) ? 2 : 3));
-
-   sse_andps(cp->func, dst, tmp);
-   sse_andnps(cp->func, tmp, result);
-   sse_orps(cp->func, dst, tmp);
-
-   aos_release_xmm_reg(cp, tmp.idx);
-   return TRUE;
-}
-
-
-
-
-/* Helper for writemask:
- */
-static boolean emit_shuf_copy2( struct aos_compilation *cp,
-                                 struct x86_reg dst,
-                                 struct x86_reg arg0,
-                                 struct x86_reg arg1,
-                                 ubyte shuf )
-{
-   struct x86_reg tmp = aos_get_xmm_reg(cp);
-
-   emit_pshufd(cp, dst, arg1, shuf);
-   emit_pshufd(cp, tmp, arg0, shuf);
-   sse_shufps(cp->func, dst, tmp, SHUF(X, Y, Z, W));
-   emit_pshufd(cp, dst, dst, shuf);
-
-   aos_release_xmm_reg(cp, tmp.idx);
-   return TRUE;
-}
-
-
-
-#define SSE_SWIZZLE_NOOP ((0<<0) | (1<<2) | (2<<4) | (3<<6))
-
-
-/* Locate a source register and perform any required (simple) swizzle.  
- * 
- * Just fail on complex swizzles at this point.
- */
-static struct x86_reg fetch_src( struct aos_compilation *cp, 
-                                 const struct tgsi_full_src_register *src ) 
-{
-   struct x86_reg arg0 = aos_get_shader_reg(cp, 
-                                            src->Register.File, 
-                                            src->Register.Index);
-   unsigned i;
-   ubyte swz = 0;
-   unsigned negs = 0;
-   unsigned abs = 0;
-
-   for (i = 0; i < 4; i++) {
-      unsigned swizzle = tgsi_util_get_full_src_register_swizzle( src, i );
-      unsigned neg = tgsi_util_get_full_src_register_sign_mode( src, i );
-
-      swz |= (swizzle & 0x3) << (i * 2);
-
-      switch (neg) {
-      case TGSI_UTIL_SIGN_TOGGLE:
-         negs |= (1<<i);
-         break;
-         
-      case TGSI_UTIL_SIGN_KEEP:
-         break;
-
-      case TGSI_UTIL_SIGN_CLEAR:
-         abs |= (1<<i);
-         break;
-
-      default:
-         AOS_ERROR(cp, "unsupported sign-mode");
-         break;
-      }
-   }
-
-   if (swz != SSE_SWIZZLE_NOOP || negs != 0 || abs != 0) {
-      struct x86_reg dst = aos_get_xmm_reg(cp);
-
-      if (swz != SSE_SWIZZLE_NOOP)
-         emit_pshufd(cp, dst, arg0, swz);
-      else
-         sse_movaps(cp->func, dst, arg0);
-
-      if (negs && negs != 0xf) {
-         struct x86_reg imm_swz = aos_get_internal_xmm(cp, IMM_SWZ);
-         struct x86_reg tmp = aos_get_xmm_reg(cp);
-
-         /* Load 1,-1,0,0
-          * Use neg as arg to pshufd
-          * Multiply
-          */
-         emit_pshufd(cp, tmp, imm_swz, 
-                     SHUF((negs & 1) ? 1 : 0,
-                          (negs & 2) ? 1 : 0,
-                          (negs & 4) ? 1 : 0,
-                          (negs & 8) ? 1 : 0));
-         sse_mulps(cp->func, dst, tmp);
-
-         aos_release_xmm_reg(cp, tmp.idx);
-         aos_soft_release_xmm(cp, imm_swz);
-      }
-      else if (negs) {
-         struct x86_reg imm_negs = aos_get_internal_xmm(cp, IMM_NEGS);
-         sse_mulps(cp->func, dst, imm_negs);
-         aos_soft_release_xmm(cp, imm_negs);
-      }
-
-
-      if (abs && abs != 0xf) {
-         AOS_ERROR(cp, "unsupported partial abs");
-      }
-      else if (abs) {
-         struct x86_reg neg = aos_get_internal(cp, IMM_NEGS);
-         struct x86_reg tmp = aos_get_xmm_reg(cp);
-
-         sse_movaps(cp->func, tmp, dst);
-         sse_mulps(cp->func, tmp, neg);
-         sse_maxps(cp->func, dst, tmp);
-
-         aos_release_xmm_reg(cp, tmp.idx);
-         aos_soft_release_xmm(cp, neg);
-      }
-
-      aos_soft_release_xmm(cp, arg0);
-      return dst;
-   }
-      
-   return arg0;
-}
-
-static void x87_fld_src( struct aos_compilation *cp, 
-                         const struct tgsi_full_src_register *src,
-                         unsigned channel ) 
-{
-   struct x86_reg arg0 = aos_get_shader_reg_ptr(cp, 
-                                                src->Register.File, 
-                                                src->Register.Index);
-
-   unsigned swizzle = tgsi_util_get_full_src_register_swizzle( src, channel );
-   unsigned neg = tgsi_util_get_full_src_register_sign_mode( src, channel );
-
-   x87_fld( cp->func, x86_make_disp(arg0, (swizzle & 3) * sizeof(float)) );
-
-   switch (neg) {
-   case TGSI_UTIL_SIGN_TOGGLE:
-      /* Flip the sign:
-       */
-      x87_fchs( cp->func );
-      break;
-         
-   case TGSI_UTIL_SIGN_KEEP:
-      break;
-
-   case TGSI_UTIL_SIGN_CLEAR:
-      x87_fabs( cp->func );
-      break;
-
-   case TGSI_UTIL_SIGN_SET:
-      x87_fabs( cp->func );
-      x87_fchs( cp->func );
-      break;
-
-   default:
-      AOS_ERROR(cp, "unsupported sign-mode");
-      break;
-   }
-}
-
-
-
-
-
-
-/* Used to implement write masking.  This and most of the other instructions
- * here would be easier to implement if there had been a translation
- * to a 2 argument format (dst/arg0, arg1) at the shader level before
- * attempting to translate to x86/sse code.
- */
-static void store_dest( struct aos_compilation *cp, 
-                        const struct tgsi_full_dst_register *reg,
-                        struct x86_reg result )
-{
-   struct x86_reg dst;
-
-   switch (reg->Register.WriteMask) {
-   case 0:
-      return;
-   
-   case TGSI_WRITEMASK_XYZW:
-      aos_adopt_xmm_reg(cp, 
-                        get_xmm_writable(cp, result), 
-                        reg->Register.File,
-                        reg->Register.Index,
-                        TRUE);
-      return;
-   default: 
-      break;
-   }
-
-   dst = aos_get_shader_reg_xmm(cp, 
-                                reg->Register.File,
-                                reg->Register.Index);
-
-   switch (reg->Register.WriteMask) {
-   case TGSI_WRITEMASK_X:
-      sse_movss(cp->func, dst, get_xmm(cp, result));
-      break;
-      
-   case TGSI_WRITEMASK_ZW:
-      sse_shufps(cp->func, dst, get_xmm(cp, result), SHUF(X, Y, Z, W));
-      break;
-
-   case TGSI_WRITEMASK_XY: 
-      result = get_xmm_writable(cp, result);
-      sse_shufps(cp->func, result, dst, SHUF(X, Y, Z, W));
-      dst = result;
-      break;
-
-   case TGSI_WRITEMASK_YZW: 
-      result = get_xmm_writable(cp, result);
-      sse_movss(cp->func, result, dst);
-      dst = result;
-      break;
-
-   default:
-      mask_write(cp, dst, result, reg->Register.WriteMask);
-      break;
-   }
-
-   aos_adopt_xmm_reg(cp, 
-                     dst, 
-                     reg->Register.File,
-                     reg->Register.Index,
-                     TRUE);
-
-}
-
-static void inject_scalar( struct aos_compilation *cp,
-                           struct x86_reg dst,
-                           struct x86_reg result,
-                           ubyte swizzle )
-{
-   sse_shufps(cp->func, dst, dst, swizzle);
-   sse_movss(cp->func, dst, result);
-   sse_shufps(cp->func, dst, dst, swizzle);
-}
-
-
-static void store_scalar_dest( struct aos_compilation *cp, 
-                               const struct tgsi_full_dst_register *reg,
-                               struct x86_reg result )
-{
-   unsigned writemask = reg->Register.WriteMask;
-   struct x86_reg dst;
-
-   if (writemask != TGSI_WRITEMASK_X &&
-       writemask != TGSI_WRITEMASK_Y &&
-       writemask != TGSI_WRITEMASK_Z &&
-       writemask != TGSI_WRITEMASK_W &&
-       writemask != 0) 
-   {
-      result = get_xmm_writable(cp, result); /* already true, right? */
-      sse_shufps(cp->func, result, result, SHUF(X,X,X,X));
-      store_dest(cp, reg, result);
-      return;
-   }
-
-   result = get_xmm(cp, result);
-   dst = aos_get_shader_reg_xmm(cp, 
-                                reg->Register.File,
-                                reg->Register.Index);
-
-
-
-   switch (reg->Register.WriteMask) {
-   case TGSI_WRITEMASK_X:
-      sse_movss(cp->func, dst, result);
-      break;
-
-   case TGSI_WRITEMASK_Y:
-      inject_scalar(cp, dst, result, SHUF(Y, X, Z, W));
-      break;
-
-   case TGSI_WRITEMASK_Z:
-      inject_scalar(cp, dst, result, SHUF(Z, Y, X, W));
-      break;
-
-   case TGSI_WRITEMASK_W:
-      inject_scalar(cp, dst, result, SHUF(W, Y, Z, X));
-      break;
-
-   default:
-      break;
-   }
-
-   aos_adopt_xmm_reg(cp, 
-                     dst, 
-                     reg->Register.File,
-                     reg->Register.Index,
-                     TRUE);
-}
-   
-
-
-static void x87_fst_or_nop( struct x86_function *func,
-                            unsigned writemask,
-                            unsigned channel,
-                            struct x86_reg ptr )
-{
-   assert(ptr.file == file_REG32);
-   if (writemask & (1<<channel)) 
-      x87_fst( func, x86_make_disp(ptr, channel * sizeof(float)) );
-}
-
-static void x87_fstp_or_pop( struct x86_function *func,
-                             unsigned writemask,
-                             unsigned channel,
-                             struct x86_reg ptr )
-{
-   assert(ptr.file == file_REG32);
-   if (writemask & (1<<channel)) 
-      x87_fstp( func, x86_make_disp(ptr, channel * sizeof(float)) );
-   else
-      x87_fstp( func, x86_make_reg( file_x87, 0 ));
-}
-
-
-
-/* 
- */
-static void x87_fstp_dest4( struct aos_compilation *cp,
-                            const struct tgsi_full_dst_register *dst )
-{
-   struct x86_reg ptr = get_dst_ptr(cp, dst); 
-   unsigned writemask = dst->Register.WriteMask;
-
-   x87_fst_or_nop(cp->func, writemask, 0, ptr);
-   x87_fst_or_nop(cp->func, writemask, 1, ptr);
-   x87_fst_or_nop(cp->func, writemask, 2, ptr);
-   x87_fstp_or_pop(cp->func, writemask, 3, ptr);
-}
-
-/* Save current x87 state and put it into single precision mode.
- */
-static void save_fpu_state( struct aos_compilation *cp )
-{
-   x87_fnstcw( cp->func, x86_make_disp(cp->machine_EDX, 
-                                       Offset(struct aos_machine, fpu_restore)));
-}
-
-static void restore_fpu_state( struct aos_compilation *cp )
-{
-   x87_fnclex(cp->func);
-   x87_fldcw( cp->func, x86_make_disp(cp->machine_EDX, 
-                                      Offset(struct aos_machine, fpu_restore)));
-}
-
-static void set_fpu_round_neg_inf( struct aos_compilation *cp )
-{
-   if (cp->fpucntl != FPU_RND_NEG) {
-      cp->fpucntl = FPU_RND_NEG;
-      x87_fnclex(cp->func);
-      x87_fldcw( cp->func, x86_make_disp(cp->machine_EDX, 
-                                         Offset(struct aos_machine, fpu_rnd_neg_inf)));
-   }
-}
-
-static void set_fpu_round_nearest( struct aos_compilation *cp )
-{
-   if (cp->fpucntl != FPU_RND_NEAREST) {
-      cp->fpucntl = FPU_RND_NEAREST;
-      x87_fnclex(cp->func);
-      x87_fldcw( cp->func, x86_make_disp(cp->machine_EDX, 
-                                         Offset(struct aos_machine, fpu_rnd_nearest)));
-   }
-}
-
-#if 0
-static void x87_emit_ex2( struct aos_compilation *cp )
-{
-   struct x86_reg st0 = x86_make_reg(file_x87, 0);
-   struct x86_reg st1 = x86_make_reg(file_x87, 1);
-   int stack = cp->func->x87_stack;
-
-   /* set_fpu_round_neg_inf( cp ); */
-
-   x87_fld(cp->func, st0);      /* a a */
-   x87_fprndint( cp->func );   /* int(a) a*/
-   x87_fsubr(cp->func, st1, st0);    /* int(a) frc(a) */
-   x87_fxch(cp->func, st1);     /* frc(a) int(a) */
-   x87_f2xm1(cp->func);         /* (2^frc(a))-1 int(a) */
-   x87_fld1(cp->func);          /* 1 (2^frc(a))-1 int(a) */
-   x87_faddp(cp->func, st1);   /* 2^frac(a) int(a)  */
-   x87_fscale(cp->func);       /* (2^frac(a)*2^int(int(a))) int(a) */
-                                /* 2^a int(a) */
-   x87_fstp(cp->func, st1);     /* 2^a */
-
-   assert( stack == cp->func->x87_stack);
-      
-}
-#endif
-
-#if 0
-static void PIPE_CDECL print_reg( const char *msg,
-                                  const float *reg )
-{
-   debug_printf("%s: %f %f %f %f\n", msg, reg[0], reg[1], reg[2], reg[3]);
-}
-#endif
-
-#if 0
-static void emit_print( struct aos_compilation *cp,
-                        const char *message, /* must point to a static string! */
-                        unsigned file,
-                        unsigned idx )
-{
-   struct x86_reg ecx = x86_make_reg( file_REG32, reg_CX );
-   struct x86_reg arg = aos_get_shader_reg_ptr( cp, file, idx );
-   unsigned i;
-
-   /* There shouldn't be anything on the x87 stack.  Can add this
-    * capacity later if need be.
-    */
-   assert(cp->func->x87_stack == 0);
-
-   /* For absolute correctness, need to spill/invalidate all XMM regs
-    * too.  We're obviously not concerned about performance on this
-    * debug path, so here goes:
-    */
-   for (i = 0; i < 8; i++) {
-      if (cp->xmm[i].dirty) 
-         spill(cp, i);
-
-      aos_release_xmm_reg(cp, i);
-   }
-
-   /* Push caller-save (ie scratch) regs.  
-    */
-   x86_cdecl_caller_push_regs( cp->func );
-
-
-   /* Push the arguments:
-    */
-   x86_lea( cp->func, ecx, arg );
-   x86_push( cp->func, ecx );
-   x86_push_imm32( cp->func, (int)message );
-
-   /* Call the helper.  Could call debug_printf directly, but
-    * print_reg is a nice place to put a breakpoint if need be.
-    */
-   x86_mov_reg_imm( cp->func, ecx, (int)print_reg );
-   x86_call( cp->func, ecx );
-   x86_pop( cp->func, ecx );
-   x86_pop( cp->func, ecx );
-
-   /* Pop caller-save regs 
-    */
-   x86_cdecl_caller_pop_regs( cp->func );
-
-   /* Done... 
-    */
-}
-#endif
-
-/**
- * The traditional instructions.  All operate on internal registers
- * and ignore write masks and swizzling issues.
- */
-
-static boolean emit_ABS( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) 
-{
-   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
-   struct x86_reg neg = aos_get_internal(cp, IMM_NEGS);
-   struct x86_reg tmp = aos_get_xmm_reg(cp);
-
-   sse_movaps(cp->func, tmp, arg0);
-   sse_mulps(cp->func, tmp, neg);
-   sse_maxps(cp->func, tmp, arg0);
-   
-   store_dest(cp, &op->Dst[0], tmp);
-   return TRUE;
-}
-
-static boolean emit_ADD( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
-{
-   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
-   struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
-   struct x86_reg dst = get_xmm_writable(cp, arg0);
-
-   sse_addps(cp->func, dst, arg1);
-
-   store_dest(cp, &op->Dst[0], dst);
-   return TRUE;
-}
-
-static boolean emit_COS( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) 
-{
-   x87_fld_src(cp, &op->Src[0], 0);
-   x87_fcos(cp->func);
-   x87_fstp_dest4(cp, &op->Dst[0]);
-   return TRUE;
-}
-
-/* The dotproduct instructions don't really do that well in sse:
- * XXX: produces wrong results -- disabled.
- */
-static boolean emit_DP3( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
-{
-   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
-   struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
-   struct x86_reg tmp = aos_get_xmm_reg(cp); 
-   struct x86_reg dst = get_xmm_writable(cp, arg0);
-
-   sse_mulps(cp->func, dst, arg1);
-   /* Now the hard bit: sum the first 3 values:
-    */ 
-   sse_movhlps(cp->func, tmp, dst);
-   sse_addss(cp->func, dst, tmp); /* a*x+c*z, b*y, ?, ? */
-   emit_pshufd(cp, tmp, dst, SHUF(Y,X,W,Z));
-   sse_addss(cp->func, dst, tmp);
-   
-   aos_release_xmm_reg(cp, tmp.idx);
-   store_scalar_dest(cp, &op->Dst[0], dst);
-   return TRUE;
-}
-
-static boolean emit_DP4( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
-{
-   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
-   struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
-   struct x86_reg tmp = aos_get_xmm_reg(cp);      
-   struct x86_reg dst = get_xmm_writable(cp, arg0);
-
-   sse_mulps(cp->func, dst, arg1);
-   
-   /* Now the hard bit: sum the values:
-    */ 
-   sse_movhlps(cp->func, tmp, dst);
-   sse_addps(cp->func, dst, tmp); /* a*x+c*z, b*y+d*w, a*x+c*z, b*y+d*w */
-   emit_pshufd(cp, tmp, dst, SHUF(Y,X,W,Z));
-   sse_addss(cp->func, dst, tmp);
-
-   aos_release_xmm_reg(cp, tmp.idx);
-   store_scalar_dest(cp, &op->Dst[0], dst);
-   return TRUE;
-}
-
-static boolean emit_DPH( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
-{
-   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
-   struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
-   struct x86_reg tmp = aos_get_xmm_reg(cp);
-   struct x86_reg dst = get_xmm_writable(cp, arg0);
-
-   sse_mulps(cp->func, dst, arg1);
-
-   /* Now the hard bit: sum the values (from DP3):
-    */ 
-   sse_movhlps(cp->func, tmp, dst);
-   sse_addss(cp->func, dst, tmp); /* a*x+c*z, b*y, ?, ? */
-   emit_pshufd(cp, tmp, dst, SHUF(Y,X,W,Z));
-   sse_addss(cp->func, dst, tmp);
-   emit_pshufd(cp, tmp, arg1, SHUF(W,W,W,W));
-   sse_addss(cp->func, dst, tmp);
-
-   aos_release_xmm_reg(cp, tmp.idx);
-   store_scalar_dest(cp, &op->Dst[0], dst);
-   return TRUE;
-}
-
-static boolean emit_DST( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
-{
-    struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
-    struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
-    struct x86_reg dst = aos_get_xmm_reg(cp);
-    struct x86_reg tmp = aos_get_xmm_reg(cp);
-    struct x86_reg ones = aos_get_internal(cp, IMM_ONES);
-
-/*    dst[0] = 1.0     * 1.0F; */
-/*    dst[1] = arg0[1] * arg1[1]; */
-/*    dst[2] = arg0[2] * 1.0; */
-/*    dst[3] = 1.0     * arg1[3]; */
-
-    emit_shuf_copy2(cp, dst, arg0, ones, SHUF(X,W,Z,Y));
-    emit_shuf_copy2(cp, tmp, arg1, ones, SHUF(X,Z,Y,W));
-    sse_mulps(cp->func, dst, tmp);
-
-    aos_release_xmm_reg(cp, tmp.idx);
-    store_dest(cp, &op->Dst[0], dst);
-    return TRUE;
-}
-
-static boolean emit_LG2( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) 
-{
-   x87_fld1(cp->func);         /* 1 */
-   x87_fld_src(cp, &op->Src[0], 0);    /* a0 1 */
-   x87_fyl2x(cp->func);        /* log2(a0) */
-   x87_fstp_dest4(cp, &op->Dst[0]);
-   return TRUE;
-}
-
-#if 0
-static boolean emit_EX2( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) 
-{
-   x87_fld_src(cp, &op->Src[0], 0);
-   x87_emit_ex2(cp);
-   x87_fstp_dest4(cp, &op->Dst[0]);
-   return TRUE;
-}
-#endif
-
-
-static boolean emit_FLR( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) 
-{
-   struct x86_reg dst = get_dst_ptr(cp, &op->Dst[0]); 
-   unsigned writemask = op->Dst[0].Register.WriteMask;
-   int i;
-
-   set_fpu_round_neg_inf( cp );
-
-   /* Load all sources first to avoid aliasing
-    */
-   for (i = 3; i >= 0; i--) {
-      if (writemask & (1<<i)) {
-         x87_fld_src(cp, &op->Src[0], i);   
-      }
-   }
-
-   for (i = 0; i < 4; i++) {
-      if (writemask & (1<<i)) {
-         x87_fprndint( cp->func );   
-         x87_fstp(cp->func, x86_make_disp(dst, i*4));
-      }
-   }
-
-   return TRUE;
-}
-
-
-static boolean emit_RND( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) 
-{
-   struct x86_reg dst = get_dst_ptr(cp, &op->Dst[0]); 
-   unsigned writemask = op->Dst[0].Register.WriteMask;
-   int i;
-
-   set_fpu_round_nearest( cp );
-
-   /* Load all sources first to avoid aliasing
-    */
-   for (i = 3; i >= 0; i--) {
-      if (writemask & (1<<i)) {
-         x87_fld_src(cp, &op->Src[0], i);   
-      }
-   }
-
-   for (i = 0; i < 4; i++) {
-      if (writemask & (1<<i)) {
-         x87_fprndint( cp->func );   
-         x87_fstp(cp->func, x86_make_disp(dst, i*4));
-      }
-   }
-
-   return TRUE;
-}
-
-
-static boolean emit_FRC( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) 
-{
-   struct x86_reg dst = get_dst_ptr(cp, &op->Dst[0]); 
-   struct x86_reg st0 = x86_make_reg(file_x87, 0);
-   struct x86_reg st1 = x86_make_reg(file_x87, 1);
-   unsigned writemask = op->Dst[0].Register.WriteMask;
-   int i;
-
-   set_fpu_round_neg_inf( cp );
-
-   /* suck all the source values onto the stack before writing out any
-    * dst, which may alias...
-    */
-   for (i = 3; i >= 0; i--) {
-      if (writemask & (1<<i)) {
-         x87_fld_src(cp, &op->Src[0], i);   
-      }
-   }
-
-   for (i = 0; i < 4; i++) {
-      if (writemask & (1<<i)) {
-         x87_fld(cp->func, st0);     /* a a */
-         x87_fprndint( cp->func );   /* flr(a) a */
-         x87_fsubp(cp->func, st1);  /* frc(a) */
-         x87_fstp(cp->func, x86_make_disp(dst, i*4));
-      }
-   }
-
-   return TRUE;
-}
-
-
-
-
-
-
-static boolean emit_LIT( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
-{
-   struct x86_reg ecx = x86_make_reg( file_REG32, reg_CX );
-   unsigned writemask = op->Dst[0].Register.WriteMask;
-   unsigned lit_count = cp->lit_count++;
-   struct x86_reg result, arg0;
-   unsigned i;
-
-#if 1
-   /* For absolute correctness, need to spill/invalidate all XMM regs
-    * too.  
-    */
-   for (i = 0; i < 8; i++) {
-      if (cp->xmm[i].dirty) 
-         spill(cp, i);
-      aos_release_xmm_reg(cp, i);
-   }
-#endif
-
-   if (writemask != TGSI_WRITEMASK_XYZW) 
-      result = x86_make_disp(cp->machine_EDX, Offset(struct aos_machine, tmp[0]));
-   else 
-      result = get_dst_ptr(cp, &op->Dst[0]);    
-
-   
-   arg0 = fetch_src( cp, &op->Src[0] );
-   if (arg0.file == file_XMM) {
-      struct x86_reg tmp = x86_make_disp(cp->machine_EDX, 
-                                         Offset(struct aos_machine, tmp[1]));
-      sse_movaps( cp->func, tmp, arg0 );
-      arg0 = tmp;
-   }
-                  
-      
-
-   /* Push caller-save (ie scratch) regs.  
-    */
-   x86_cdecl_caller_push_regs( cp->func );
-
-   /* Push the arguments:
-    */
-   x86_push_imm32( cp->func, lit_count );
-
-   x86_lea( cp->func, ecx, arg0 );
-   x86_push( cp->func, ecx );
-
-   x86_lea( cp->func, ecx, result );
-   x86_push( cp->func, ecx );
-
-   x86_push( cp->func, cp->machine_EDX );
-
-   if (lit_count < MAX_LIT_INFO) {
-      x86_mov( cp->func, ecx, x86_make_disp( cp->machine_EDX, 
-                                             Offset(struct aos_machine, lit_info) + 
-                                             lit_count * sizeof(struct lit_info) + 
-                                             Offset(struct lit_info, func)));
-   }
-   else {
-      x86_mov_reg_imm( cp->func, ecx, (int)aos_do_lit );
-   }
-
-   x86_call( cp->func, ecx );
-            
-   x86_pop( cp->func, ecx );    /* fixme... */
-   x86_pop( cp->func, ecx );
-   x86_pop( cp->func, ecx );
-   x86_pop( cp->func, ecx );
-
-   x86_cdecl_caller_pop_regs( cp->func );
-
-   if (writemask != TGSI_WRITEMASK_XYZW) {
-      store_dest( cp, 
-                  &op->Dst[0],
-                  get_xmm_writable( cp, result ) );
-   }
-
-   return TRUE;
-}
-
-#if 0   
-static boolean emit_inline_LIT( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
-{
-   struct x86_reg dst = get_dst_ptr(cp, &op->Dst[0]); 
-   unsigned writemask = op->Dst[0].Register.WriteMask;
-
-   if (writemask & TGSI_WRITEMASK_YZ) {
-      struct x86_reg st1 = x86_make_reg(file_x87, 1);
-      struct x86_reg st2 = x86_make_reg(file_x87, 2);
-
-      /* a1' = a1 <= 0 ? 1 : a1;  
-       */
-      x87_fldz(cp->func);                           /* 1 0  */
-#if 1
-      x87_fld1(cp->func);                           /* 1 0  */
-#else
-      /* Correct but slow due to fp exceptions generated in fyl2x - fix me.
-       */
-      x87_fldz(cp->func);                           /* 1 0  */
-#endif
-      x87_fld_src(cp, &op->Src[0], 1); /* a1 1 0  */
-      x87_fcomi(cp->func, st2);                            /* a1 1 0  */
-      x87_fcmovb(cp->func, st1);                    /* a1' 1 0  */
-      x87_fstp(cp->func, st1);                      /* a1' 0  */
-      x87_fstp(cp->func, st1);                      /* a1'  */
-
-      x87_fld_src(cp, &op->Src[0], 3); /* a3 a1'  */
-      x87_fxch(cp->func, st1);                      /* a1' a3  */
-      
-
-      /* Compute pow(a1, a3)
-       */
-      x87_fyl2x(cp->func);     /* a3*log2(a1)      */
-      x87_emit_ex2( cp );       /* 2^(a3*log2(a1))   */
-
-
-      /* a0' = max2(a0, 0):
-       */
-      x87_fldz(cp->func);                           /* 0 r2 */
-      x87_fld_src(cp, &op->Src[0], 0); /* a0 0 r2 */
-      x87_fcomi(cp->func, st1);        
-      x87_fcmovb(cp->func, st1);                    /* a0' 0 r2 */
-
-      x87_fst_or_nop(cp->func, writemask, 1, dst); /* result[1] = a0' */
-
-      x87_fcomi(cp->func, st1);  /* a0' 0 r2 */
-      x87_fcmovnbe(cp->func, st2); /* r2' 0' r2 */
-
-      x87_fstp_or_pop(cp->func, writemask, 2, dst); /* 0 r2 */
-      x87_fpop(cp->func);       /* r2 */
-      x87_fpop(cp->func);
-   }
-
-   if (writemask & TGSI_WRITEMASK_XW) {
-      x87_fld1(cp->func);
-      x87_fst_or_nop(cp->func, writemask, 0, dst);
-      x87_fstp_or_pop(cp->func, writemask, 3, dst);
-   }
-
-   return TRUE;
-}
-#endif
-
-
-
-static boolean emit_MAX( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
-{
-   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
-   struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
-   struct x86_reg dst = get_xmm_writable(cp, arg0);
-
-   sse_maxps(cp->func, dst, arg1);
-
-   store_dest(cp, &op->Dst[0], dst);
-   return TRUE;
-}
-
-
-static boolean emit_MIN( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
-{
-   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
-   struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
-   struct x86_reg dst = get_xmm_writable(cp, arg0);
-
-   sse_minps(cp->func, dst, arg1);
-
-   store_dest(cp, &op->Dst[0], dst);
-   return TRUE;
-}
-
-static boolean emit_MOV( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
-{
-   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
-   struct x86_reg dst = get_xmm_writable(cp, arg0);
-
-   /* potentially nothing to do */
-
-   store_dest(cp, &op->Dst[0], dst);
-   return TRUE;
-}
-
-static boolean emit_MUL( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
-{
-   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
-   struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
-   struct x86_reg dst = get_xmm_writable(cp, arg0);
-
-   sse_mulps(cp->func, dst, arg1);
-
-   store_dest(cp, &op->Dst[0], dst);
-   return TRUE;
-}
-
-
-static boolean emit_MAD( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
-{
-   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
-   struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
-   struct x86_reg arg2 = fetch_src(cp, &op->Src[2]);
-
-   /* If we can't clobber old contents of arg0, get a temporary & copy
-    * it there, then clobber it...
-    */
-   arg0 = get_xmm_writable(cp, arg0);
-
-   sse_mulps(cp->func, arg0, arg1);
-   sse_addps(cp->func, arg0, arg2);
-   store_dest(cp, &op->Dst[0], arg0);
-   return TRUE;
-}
-
-
-
-/* A wrapper for powf().
- * Makes sure it is cdecl and operates on floats.
- */
-static float PIPE_CDECL _powerf( float x, float y )
-{
-#if FAST_MATH
-   return util_fast_pow(x, y);
-#else
-   return powf( x, y );
-#endif
-}
-
-#if FAST_MATH
-static float PIPE_CDECL _exp2(float x)
-{
-   return util_fast_exp2(x);
-}
-#endif
-
-
-/* Really not sufficient -- need to check for conditions that could
- * generate inf/nan values, which will slow things down hugely.
- */
-static boolean emit_POW( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) 
-{
-#if 0
-   x87_fld_src(cp, &op->Src[1], 0);  /* a1.x */
-   x87_fld_src(cp, &op->Src[0], 0);    /* a0.x a1.x */
-   x87_fyl2x(cp->func);                                        /* a1*log2(a0) */
-
-   x87_emit_ex2( cp );         /* 2^(a1*log2(a0)) */
-
-   x87_fstp_dest4(cp, &op->Dst[0]);
-#else
-   uint i;
-
-   /* For absolute correctness, need to spill/invalidate all XMM regs
-    * too.  
-    */
-   for (i = 0; i < 8; i++) {
-      if (cp->xmm[i].dirty) 
-         spill(cp, i);
-      aos_release_xmm_reg(cp, i);
-   }
-
-   /* Push caller-save (ie scratch) regs.  
-    */
-   x86_cdecl_caller_push_regs( cp->func );
-
-   x86_lea( cp->func, cp->stack_ESP, x86_make_disp(cp->stack_ESP, -8) );
-
-   x87_fld_src( cp, &op->Src[1], 0 );
-   x87_fstp( cp->func, x86_make_disp( cp->stack_ESP, 4 ) );
-   x87_fld_src( cp, &op->Src[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 );
-
-   x86_lea( cp->func, cp->stack_ESP, x86_make_disp(cp->stack_ESP, 8) );
-
-   x86_cdecl_caller_pop_regs( cp->func );
-
-   /* Note retval on x87 stack:
-    */
-   cp->func->x87_stack++;
-
-   x87_fstp_dest4( cp, &op->Dst[0] );
-#endif
-   return TRUE;
-}
-
-
-#if FAST_MATH
-static boolean emit_EXPBASE2( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) 
-{
-   uint i;
-
-   /* For absolute correctness, need to spill/invalidate all XMM regs
-    * too.  
-    */
-   for (i = 0; i < 8; i++) {
-      if (cp->xmm[i].dirty) 
-         spill(cp, i);
-      aos_release_xmm_reg(cp, i);
-   }
-
-   /* Push caller-save (ie scratch) regs.  
-    */
-   x86_cdecl_caller_push_regs( cp->func );
-
-   x86_lea( cp->func, cp->stack_ESP, x86_make_disp(cp->stack_ESP, -4) );
-
-   x87_fld_src( cp, &op->Src[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) _exp2 );
-   x86_call( cp->func, cp->tmp_EAX );
-
-   x86_lea( cp->func, cp->stack_ESP, x86_make_disp(cp->stack_ESP, 4) );
-
-   x86_cdecl_caller_pop_regs( cp->func );
-
-   /* Note retval on x87 stack:
-    */
-   cp->func->x87_stack++;
-
-   x87_fstp_dest4( cp, &op->Dst[0] );
-
-   return TRUE;
-}
-#endif
-
-
-static boolean emit_RCP( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
-{
-   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
-   struct x86_reg dst = aos_get_xmm_reg(cp);
-
-   if (cp->have_sse2) {
-      sse2_rcpss(cp->func, dst, arg0);
-      /* extend precision here...
-       */
-   }
-   else {
-      struct x86_reg ones = aos_get_internal(cp, IMM_ONES);
-      sse_movss(cp->func, dst, ones);
-      sse_divss(cp->func, dst, arg0);
-   }
-
-   store_scalar_dest(cp, &op->Dst[0], dst);
-   return TRUE;
-}
-
-
-/* Although rsqrtps() and rcpps() are low precision on some/all SSE
- * implementations, it is possible to improve its precision at
- * fairly low cost, using a newton/raphson step, as below:
- * 
- * x1 = 2 * rcpps(a) - a * rcpps(a) * rcpps(a)
- * x1 = 0.5 * rsqrtps(a) * [3.0 - (a * rsqrtps(a))* rsqrtps(a)]
- * or:
- *   x1 = rsqrtps(a) * [1.5 - .5 * a * rsqrtps(a) * rsqrtps(a)]
- * 
- *
- * See: http://softwarecommunity.intel.com/articles/eng/1818.htm
- */
-static boolean emit_RSQ( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
-{
-   if (0) {
-      struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
-      struct x86_reg r = aos_get_xmm_reg(cp);
-      sse_rsqrtss(cp->func, r, arg0);
-      store_scalar_dest(cp, &op->Dst[0], r);
-      return TRUE;
-   }
-   else {
-      struct x86_reg arg0           = fetch_src(cp, &op->Src[0]);
-      struct x86_reg r              = aos_get_xmm_reg(cp);
-
-      struct x86_reg neg_half       = get_reg_ptr( cp, AOS_FILE_INTERNAL, IMM_RSQ );
-      struct x86_reg one_point_five = x86_make_disp( neg_half, 4 );
-      struct x86_reg src            = get_xmm_writable( cp, arg0 );
-      struct x86_reg neg            = aos_get_internal(cp, IMM_NEGS);
-      struct x86_reg tmp            = aos_get_xmm_reg(cp);
-
-      sse_movaps(cp->func, tmp, src);
-      sse_mulps(cp->func, tmp, neg);
-      sse_maxps(cp->func, tmp, src);
-   
-      sse_rsqrtss( cp->func, r, tmp  );             /* rsqrtss(a) */
-      sse_mulss(   cp->func, tmp, neg_half  );      /* -.5 * a */
-      sse_mulss(   cp->func, tmp,  r );             /* -.5 * a * r */
-      sse_mulss(   cp->func, tmp,  r );             /* -.5 * a * r * r */
-      sse_addss(   cp->func, tmp, one_point_five ); /* 1.5 - .5 * a * r * r */
-      sse_mulss(   cp->func, r,  tmp );             /* r * (1.5 - .5 * a * r * r) */
-
-      store_scalar_dest(cp, &op->Dst[0], r);
-
-      aos_release_xmm_reg(cp, tmp.idx);
-
-      return TRUE;
-   }
-}
-
-
-static boolean emit_SGE( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
-{
-   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
-   struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
-   struct x86_reg ones = aos_get_internal(cp, IMM_ONES);
-   struct x86_reg dst = get_xmm_writable(cp, arg0);
-
-   sse_cmpps(cp->func, dst, arg1, cc_NotLessThan);
-   sse_andps(cp->func, dst, ones);
-
-   store_dest(cp, &op->Dst[0], dst);
-   return TRUE;
-}
-
-static boolean emit_SIN( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) 
-{
-   x87_fld_src(cp, &op->Src[0], 0);
-   x87_fsin(cp->func);
-   x87_fstp_dest4(cp, &op->Dst[0]);
-   return TRUE;
-}
-
-
-
-static boolean emit_SLT( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
-{
-   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
-   struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
-   struct x86_reg ones = aos_get_internal(cp, IMM_ONES);
-   struct x86_reg dst = get_xmm_writable(cp, arg0);
-   
-   sse_cmpps(cp->func, dst, arg1, cc_LessThan);
-   sse_andps(cp->func, dst, ones);
-
-   store_dest(cp, &op->Dst[0], dst);
-   return TRUE;
-}
-
-static boolean emit_SUB( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) 
-{
-   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
-   struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
-   struct x86_reg dst = get_xmm_writable(cp, arg0);
-
-   sse_subps(cp->func, dst, arg1);
-
-   store_dest(cp, &op->Dst[0], dst);
-   return TRUE;
-}
-
-static boolean emit_TRUNC( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
-{
-   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
-   struct x86_reg tmp0 = aos_get_xmm_reg(cp);
-
-   sse2_cvttps2dq(cp->func, tmp0, arg0);
-   sse2_cvtdq2ps(cp->func, tmp0, tmp0);
-
-   store_dest(cp, &op->Dst[0], tmp0);
-   return TRUE;
-}
-
-static boolean emit_XPD( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) 
-{
-   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
-   struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
-   struct x86_reg tmp0 = aos_get_xmm_reg(cp);
-   struct x86_reg tmp1 = aos_get_xmm_reg(cp);
-
-   emit_pshufd(cp, tmp1, arg1, SHUF(Y, Z, X, W));
-   sse_mulps(cp->func, tmp1, arg0);
-   emit_pshufd(cp, tmp0, arg0, SHUF(Y, Z, X, W));
-   sse_mulps(cp->func, tmp0, arg1);
-   sse_subps(cp->func, tmp1, tmp0);
-   sse_shufps(cp->func, tmp1, tmp1, SHUF(Y, Z, X, W));
-
-/*    dst[2] = arg0[0] * arg1[1] - arg0[1] * arg1[0]; */
-/*    dst[0] = arg0[1] * arg1[2] - arg0[2] * arg1[1]; */
-/*    dst[1] = arg0[2] * arg1[0] - arg0[0] * arg1[2]; */
-/*    dst[3] is undef */
-
-
-   aos_release_xmm_reg(cp, tmp0.idx);
-   store_dest(cp, &op->Dst[0], tmp1);
-   return TRUE;
-}
-
-
-
-static boolean
-emit_instruction( struct aos_compilation *cp,
-                  struct tgsi_full_instruction *inst )
-{
-   x87_assert_stack_empty(cp->func);
-
-   switch( inst->Instruction.Opcode ) {
-   case TGSI_OPCODE_MOV:
-      return emit_MOV( cp, inst );
-
-   case TGSI_OPCODE_LIT:
-      return emit_LIT(cp, inst);
-
-   case TGSI_OPCODE_RCP:
-      return emit_RCP(cp, inst);
-
-   case TGSI_OPCODE_RSQ:
-      return emit_RSQ(cp, inst);
-
-   case TGSI_OPCODE_EXP:
-      /*return emit_EXP(cp, inst);*/
-      return FALSE;
-
-   case TGSI_OPCODE_LOG:
-      /*return emit_LOG(cp, inst);*/
-      return FALSE;
-
-   case TGSI_OPCODE_MUL:
-      return emit_MUL(cp, inst);
-
-   case TGSI_OPCODE_ADD:
-      return emit_ADD(cp, inst);
-
-   case TGSI_OPCODE_DP3:
-      return emit_DP3(cp, inst);
-
-   case TGSI_OPCODE_DP4:
-      return emit_DP4(cp, inst);
-
-   case TGSI_OPCODE_DST:
-      return emit_DST(cp, inst);
-
-   case TGSI_OPCODE_MIN:
-      return emit_MIN(cp, inst);
-
-   case TGSI_OPCODE_MAX:
-      return emit_MAX(cp, inst);
-
-   case TGSI_OPCODE_SLT:
-      return emit_SLT(cp, inst);
-
-   case TGSI_OPCODE_SGE:
-      return emit_SGE(cp, inst);
-
-   case TGSI_OPCODE_MAD:
-      return emit_MAD(cp, inst);
-
-   case TGSI_OPCODE_SUB:
-      return emit_SUB(cp, inst);
-   case TGSI_OPCODE_LRP:
-      /*return emit_LERP(cp, inst);*/
-      return FALSE;
-
-   case TGSI_OPCODE_FRC:
-      return emit_FRC(cp, inst);
-
-   case TGSI_OPCODE_CLAMP:
-      /*return emit_CLAMP(cp, inst);*/
-      return FALSE;
-
-   case TGSI_OPCODE_FLR:
-      return emit_FLR(cp, inst);
-
-   case TGSI_OPCODE_ROUND:
-      return emit_RND(cp, inst);
-
-   case TGSI_OPCODE_EX2:
-#if FAST_MATH
-      return emit_EXPBASE2(cp, inst);
-#elif 0
-      /* this seems to fail for "larger" exponents.
-       * See glean tvertProg1's EX2 test.
-       */
-      return emit_EX2(cp, inst);
-#else
-      return FALSE;
-#endif
-
-   case TGSI_OPCODE_LG2:
-      return emit_LG2(cp, inst);
-
-   case TGSI_OPCODE_POW:
-      return emit_POW(cp, inst);
-
-   case TGSI_OPCODE_XPD:
-      return emit_XPD(cp, inst);
-
-   case TGSI_OPCODE_ABS:
-      return emit_ABS(cp, inst);
-
-   case TGSI_OPCODE_DPH:
-      return emit_DPH(cp, inst);
-
-   case TGSI_OPCODE_COS:
-      return emit_COS(cp, inst);
-
-   case TGSI_OPCODE_SIN:
-      return emit_SIN(cp, inst);
-
-   case TGSI_OPCODE_TRUNC:
-      return emit_TRUNC(cp, inst);
-
-   case TGSI_OPCODE_END:
-      return TRUE;
-
-   default:
-      return FALSE;
-   }
-}
-
-
-static boolean emit_viewport( struct aos_compilation *cp )
-{
-   struct x86_reg pos = aos_get_shader_reg_xmm(cp, 
-                                               TGSI_FILE_OUTPUT, 
-                                               cp->vaos->draw->vs.position_output );
-
-   struct x86_reg scale = x86_make_disp(cp->machine_EDX, 
-                                        Offset(struct aos_machine, scale));
-
-   struct x86_reg translate = x86_make_disp(cp->machine_EDX, 
-                                        Offset(struct aos_machine, translate));
-
-   sse_mulps(cp->func, pos, scale);
-   sse_addps(cp->func, pos, translate);
-
-   aos_adopt_xmm_reg( cp,
-                      pos,
-                      TGSI_FILE_OUTPUT,
-                      cp->vaos->draw->vs.position_output,
-                      TRUE );
-   return TRUE;
-}
-
-
-/* This is useful to be able to see the results on softpipe.  Doesn't
- * do proper clipping, just assumes the backend can do it during
- * rasterization -- for debug only...
- */
-static boolean emit_rhw_viewport( struct aos_compilation *cp )
-{
-   struct x86_reg tmp = aos_get_xmm_reg(cp);
-   struct x86_reg pos = aos_get_shader_reg_xmm(cp, 
-                                               TGSI_FILE_OUTPUT, 
-                                               cp->vaos->draw->vs.position_output);
-
-   struct x86_reg scale = x86_make_disp(cp->machine_EDX, 
-                                        Offset(struct aos_machine, scale));
-
-   struct x86_reg translate = x86_make_disp(cp->machine_EDX, 
-                                        Offset(struct aos_machine, translate));
-
-
-
-   emit_pshufd(cp, tmp, pos, SHUF(W, W, W, W));
-   sse2_rcpss(cp->func, tmp, tmp);
-   sse_shufps(cp->func, tmp, tmp, SHUF(X, X, X, X));
-   
-   sse_mulps(cp->func, pos, scale);
-   sse_mulps(cp->func, pos, tmp);
-   sse_addps(cp->func, pos, translate);
-
-   /* Set pos[3] = w 
-    */
-   mask_write(cp, pos, tmp, TGSI_WRITEMASK_W);
-
-   aos_adopt_xmm_reg( cp,
-                      pos,
-                      TGSI_FILE_OUTPUT,
-                      cp->vaos->draw->vs.position_output,
-                      TRUE );
-   return TRUE;
-}
-
-
-#if 0
-static boolean note_immediate( struct aos_compilation *cp,
-                               struct tgsi_full_immediate *imm )
-{
-   unsigned pos = cp->num_immediates++;
-   unsigned j;
-
-   assert( imm->Immediate.NrTokens <= 4 + 1 );
-   for (j = 0; j < imm->Immediate.NrTokens - 1; j++) {
-      cp->vaos->machine->immediate[pos][j] = imm->u[j].Float;
-   }
-
-   return TRUE;
-}
-#endif
-
-
-
-
-static void find_last_write_outputs( struct aos_compilation *cp )
-{
-   struct tgsi_parse_context parse;
-   unsigned this_instruction = 0;
-   unsigned i;
-
-   tgsi_parse_init( &parse, cp->vaos->base.vs->state.tokens );
-
-   while (!tgsi_parse_end_of_tokens( &parse )) {
-      
-      tgsi_parse_token( &parse );
-
-      if (parse.FullToken.Token.Type != TGSI_TOKEN_TYPE_INSTRUCTION) 
-         continue;
-
-      for (i = 0; i < TGSI_FULL_MAX_DST_REGISTERS; i++) {
-         if (parse.FullToken.FullInstruction.Dst[i].Register.File ==
-             TGSI_FILE_OUTPUT) 
-         {
-            unsigned idx = parse.FullToken.FullInstruction.Dst[i].Register.Index;
-            cp->output_last_write[idx] = this_instruction;
-         }
-      }
-
-      this_instruction++;
-   }
-
-   tgsi_parse_free( &parse );
-}
-
-
-#define ARG_MACHINE    1
-#define ARG_START_ELTS 2
-#define ARG_COUNT      3
-#define ARG_OUTBUF     4
-
-
-static boolean build_vertex_program( struct draw_vs_variant_aos_sse *variant,
-                                     boolean linear )
-{ 
-   struct tgsi_parse_context parse;
-   struct aos_compilation cp;
-   unsigned fixup, label;
-
-   util_init_math();
-
-   tgsi_parse_init( &parse, variant->base.vs->state.tokens );
-
-   memset(&cp, 0, sizeof(cp));
-
-   cp.insn_counter = 1;
-   cp.vaos = variant;
-   cp.have_sse2 = 1;
-   cp.func = &variant->func[ linear ? 0 : 1 ];
-
-   cp.tmp_EAX       = x86_make_reg(file_REG32, reg_AX);
-   cp.idx_EBX      = x86_make_reg(file_REG32, reg_BX);
-   cp.outbuf_ECX    = x86_make_reg(file_REG32, reg_CX);
-   cp.machine_EDX   = x86_make_reg(file_REG32, reg_DX);
-   cp.count_ESI     = x86_make_reg(file_REG32, reg_SI);
-   cp.temp_EBP     = x86_make_reg(file_REG32, reg_BP);
-   cp.stack_ESP = x86_make_reg( file_REG32, reg_SP );
-
-   x86_init_func(cp.func);
-
-   find_last_write_outputs(&cp);
-
-   x86_push(cp.func, cp.idx_EBX);
-   x86_push(cp.func, cp.count_ESI);
-   x86_push(cp.func, cp.temp_EBP);
-
-
-   /* Load arguments into regs:
-    */
-   x86_mov(cp.func, cp.machine_EDX, x86_fn_arg(cp.func, ARG_MACHINE));
-   x86_mov(cp.func, cp.idx_EBX, x86_fn_arg(cp.func, ARG_START_ELTS));
-   x86_mov(cp.func, cp.count_ESI, x86_fn_arg(cp.func, ARG_COUNT));
-   x86_mov(cp.func, cp.outbuf_ECX, x86_fn_arg(cp.func, ARG_OUTBUF));
-
-
-   /* Compare count to zero and possibly bail.
-    */
-   x86_xor(cp.func, cp.tmp_EAX, cp.tmp_EAX);
-   x86_cmp(cp.func, cp.count_ESI, cp.tmp_EAX);
-   fixup = x86_jcc_forward(cp.func, cc_E);
-
-
-   save_fpu_state( &cp );
-   set_fpu_round_nearest( &cp );
-
-   aos_init_inputs( &cp, linear );
-
-   cp.x86_reg[0] = 0;
-   cp.x86_reg[1] = 0;
-   
-   /* Note address for loop jump 
-    */
-   label = x86_get_label(cp.func);
-   {
-      /* Fetch inputs...  TODO:  fetch lazily...
-       */
-      if (!aos_fetch_inputs( &cp, linear ))
-         goto fail;
-
-      /* Emit the shader:
-       */
-      while( !tgsi_parse_end_of_tokens( &parse ) && !cp.error ) 
-      {
-         tgsi_parse_token( &parse );
-
-         switch (parse.FullToken.Token.Type) {
-         case TGSI_TOKEN_TYPE_IMMEDIATE:
-#if 0
-            if (!note_immediate( &cp, &parse.FullToken.FullImmediate ))
-               goto fail;
-#endif
-            break;
-
-         case TGSI_TOKEN_TYPE_INSTRUCTION:
-            if (DISASSEM)
-               tgsi_dump_instruction( &parse.FullToken.FullInstruction, cp.insn_counter );
-
-            if (!emit_instruction( &cp, &parse.FullToken.FullInstruction ))
-               goto fail;
-            break;
-         }
-
-         x87_assert_stack_empty(cp.func);
-         cp.insn_counter++;
-
-         if (DISASSEM)
-            debug_printf("\n");
-      }
-
-   
-      {
-         unsigned i;
-         for (i = 0; i < 8; i++) {
-            if (cp.xmm[i].file != TGSI_FILE_OUTPUT) {
-               cp.xmm[i].file = TGSI_FILE_NULL;
-               cp.xmm[i].dirty = 0;
-            }
-         }
-      }
-
-      if (cp.error)
-         goto fail;
-
-      if (cp.vaos->base.key.clip) {
-         /* not really handling clipping, just do the rhw so we can
-          * see the results...
-          */
-         emit_rhw_viewport(&cp); 
-      }
-      else if (cp.vaos->base.key.viewport) {
-         emit_viewport(&cp);
-      }
-
-      /* Emit output...  TODO: do this eagerly after the last write to a
-       * given output.
-       */
-      if (!aos_emit_outputs( &cp ))
-         goto fail;
-
-
-      /* Next vertex:
-       */
-      x86_lea(cp.func, 
-              cp.outbuf_ECX, 
-              x86_make_disp(cp.outbuf_ECX, 
-                            cp.vaos->base.key.output_stride));
-
-      /* Incr index
-       */   
-      aos_incr_inputs( &cp, linear );
-   }
-   /* decr count, loop if not zero
-    */
-   x86_dec(cp.func, cp.count_ESI);
-   x86_jcc(cp.func, cc_NZ, label);
-
-   restore_fpu_state(&cp);
-
-   /* Land forward jump here:
-    */
-   x86_fixup_fwd_jump(cp.func, fixup);
-
-   /* Exit mmx state?
-    */
-   if (cp.func->need_emms)
-      mmx_emms(cp.func);
-
-   x86_pop(cp.func, cp.temp_EBP);
-   x86_pop(cp.func, cp.count_ESI);
-   x86_pop(cp.func, cp.idx_EBX);
-
-   x87_assert_stack_empty(cp.func);
-   x86_ret(cp.func);
-
-   tgsi_parse_free( &parse );
-   return !cp.error;
-
- fail:
-   tgsi_parse_free( &parse );
-   return FALSE;
-}
-
-
-/** cast wrapper */
-static INLINE struct draw_vs_variant_aos_sse *
-draw_vs_variant_aos_sse(struct draw_vs_variant *variant)
-{
-   return (struct draw_vs_variant_aos_sse *) variant;
-}
-
-
-static void vaos_set_buffer( struct draw_vs_variant *variant,
-                             unsigned buf,
-                             const void *ptr,
-                             unsigned stride,
-                             unsigned max_stride)
-{
-   struct draw_vs_variant_aos_sse *vaos = draw_vs_variant_aos_sse(variant);
-
-   if (buf < vaos->nr_vb) {
-      vaos->buffer[buf].base_ptr = (char *)ptr;
-      vaos->buffer[buf].stride = stride;
-   }
-
-   if (0) debug_printf("%s %d/%d: %p %d\n", __FUNCTION__, buf, vaos->nr_vb, ptr, stride);
-}
-
-
-
-static void PIPE_CDECL vaos_run_elts( struct draw_vs_variant *variant,
-                                      const unsigned *elts,
-                                      unsigned count,
-                                      void *output_buffer )
-{
-   struct draw_vs_variant_aos_sse *vaos = draw_vs_variant_aos_sse(variant);
-   struct aos_machine *machine = vaos->draw->vs.aos_machine;
-   unsigned i;
-
-   if (0) debug_printf("%s %d\n", __FUNCTION__, count);
-
-   machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size;
-   for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
-      machine->constants[i] = vaos->draw->vs.aligned_constants[i];
-   }
-   machine->immediates = vaos->base.vs->immediates;
-   machine->buffer = vaos->buffer;
-
-   vaos->gen_run_elts( machine,
-                       elts,
-                       count,
-                       output_buffer );
-}
-
-static void PIPE_CDECL vaos_run_linear( struct draw_vs_variant *variant,
-                                        unsigned start,
-                                        unsigned count,
-                                        void *output_buffer )
-{
-   struct draw_vs_variant_aos_sse *vaos = draw_vs_variant_aos_sse(variant);
-   struct aos_machine *machine = vaos->draw->vs.aos_machine;
-   unsigned i;
-
-   if (0) debug_printf("%s %d %d const: %x\n", __FUNCTION__, start, count, 
-                       vaos->base.key.const_vbuffers);
-
-   machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size;
-   for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
-      machine->constants[i] = vaos->draw->vs.aligned_constants[i];
-   }
-   machine->immediates = vaos->base.vs->immediates;
-   machine->buffer = vaos->buffer;
-
-   vaos->gen_run_linear( machine,
-                         start,
-                         count,
-                         output_buffer );
-
-   /* Sanity spot checks to make sure we didn't trash our constants */
-   assert(machine->internal[IMM_ONES][0] == 1.0f);
-   assert(machine->internal[IMM_IDENTITY][0] == 0.0f);
-   assert(machine->internal[IMM_NEGS][0] == -1.0f);
-}
-
-
-
-static void vaos_destroy( struct draw_vs_variant *variant )
-{
-   struct draw_vs_variant_aos_sse *vaos = draw_vs_variant_aos_sse(variant);
-
-   FREE( vaos->buffer );
-
-   x86_release_func( &vaos->func[0] );
-   x86_release_func( &vaos->func[1] );
-
-   FREE(vaos);
-}
-
-
-
-static struct draw_vs_variant *variant_aos_sse( struct draw_vertex_shader *vs,
-                                                 const struct draw_vs_variant_key *key )
-{
-   unsigned i;
-   struct draw_vs_variant_aos_sse *vaos = CALLOC_STRUCT(draw_vs_variant_aos_sse);
-
-   if (!vaos)
-      goto fail;
-   
-   vaos->base.key = *key;
-   vaos->base.vs = vs;
-   vaos->base.set_buffer = vaos_set_buffer;
-   vaos->base.destroy = vaos_destroy;
-   vaos->base.run_linear = vaos_run_linear;
-   vaos->base.run_elts = vaos_run_elts;
-
-   vaos->draw = vs->draw;
-
-   for (i = 0; i < key->nr_inputs; i++) 
-      vaos->nr_vb = MAX2( vaos->nr_vb, key->element[i].in.buffer + 1 );
-
-   vaos->buffer = MALLOC( vaos->nr_vb * sizeof(vaos->buffer[0]) );
-   if (!vaos->buffer)
-      goto fail;
-
-   if (0)
-      debug_printf("nr_vb: %d const: %x\n", vaos->nr_vb, vaos->base.key.const_vbuffers);
-
-#if 0
-   tgsi_dump(vs->state.tokens, 0);
-#endif
-
-   if (!build_vertex_program( vaos, TRUE ))
-      goto fail;
-
-   if (!build_vertex_program( vaos, FALSE ))
-      goto fail;
-
-   vaos->gen_run_linear = (vaos_run_linear_func)x86_get_func(&vaos->func[0]);
-   if (!vaos->gen_run_linear)
-      goto fail;
-
-   vaos->gen_run_elts = (vaos_run_elts_func)x86_get_func(&vaos->func[1]);
-   if (!vaos->gen_run_elts)
-      goto fail;
-
-   return &vaos->base;
-
- fail:
-   if (vaos && vaos->buffer)
-      FREE(vaos->buffer);
-
-   if (vaos)
-      x86_release_func( &vaos->func[0] );
-
-   if (vaos)
-      x86_release_func( &vaos->func[1] );
-
-   FREE(vaos);
-   
-   return NULL;
-}
-
-
-struct draw_vs_variant *
-draw_vs_create_variant_aos_sse( struct draw_vertex_shader *vs,
-                                const struct draw_vs_variant_key *key )
-{
-   struct draw_vs_variant *variant = variant_aos_sse( vs, key );
-
-   if (variant == NULL) {
-      variant = draw_vs_create_variant_generic( vs, key );
-   }
-
-   return variant;
-}
-
-
-
-#endif /* PIPE_ARCH_X86 */
diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.h b/src/gallium/auxiliary/draw/draw_vs_aos.h
deleted file mode 100644 (file)
index 55e63d8..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
- */
-
-#ifndef DRAW_VS_AOS_H
-#define DRAW_VS_AOS_H
-
-#include "pipe/p_config.h"
-#include "tgsi/tgsi_exec.h"
-#include "draw_vs.h"
-
-#ifdef PIPE_ARCH_X86
-
-struct tgsi_token;
-struct x86_function;
-
-#include "pipe/p_state.h"
-#include "rtasm/rtasm_x86sse.h"
-
-
-
-
-
-#define X    0
-#define Y    1
-#define Z    2
-#define W    3
-
-#define MAX_INPUTS     PIPE_MAX_ATTRIBS
-#define MAX_OUTPUTS    PIPE_MAX_SHADER_OUTPUTS
-#define MAX_TEMPS      TGSI_EXEC_NUM_TEMPS
-#define MAX_CONSTANTS  1024  /** only used for sanity checking */
-#define MAX_IMMEDIATES 1024  /** only used for sanity checking */
-#define MAX_INTERNALS  8     /** see IMM_x values below */
-
-#define AOS_FILE_INTERNAL TGSI_FILE_COUNT
-
-#define FPU_RND_NEG    1
-#define FPU_RND_NEAREST 2
-
-struct aos_machine;
-typedef void (PIPE_CDECL *lit_func)( struct aos_machine *,
-                                    float *result,
-                                    const float *in,
-                                    unsigned count );
-
-void PIPE_CDECL aos_do_lit( struct aos_machine *machine,
-                            float *result,
-                            const float *in,
-                            unsigned count );
-
-struct shine_tab {
-   float exponent;
-   float values[258];
-   unsigned last_used;
-};
-
-struct lit_info {
-   lit_func func;
-   struct shine_tab *shine_tab;
-};
-
-#define MAX_SHINE_TAB    4
-#define MAX_LIT_INFO     16
-
-struct aos_buffer {
-   const void *base_ptr;
-   unsigned stride;
-   void *ptr;                   /* updated per vertex */
-};
-
-
-
-
-/* This is the temporary storage used by all the aos_sse vs variants.
- * Create one per context and reuse by passing a pointer in at
- * vs_variant creation??
- */
-struct aos_machine {
-   float input    [MAX_INPUTS    ][4];
-   float output   [MAX_OUTPUTS   ][4];
-   float temp     [MAX_TEMPS     ][4];
-   float internal [MAX_INTERNALS ][4];
-
-   float scale[4];              /* viewport */
-   float translate[4];          /* viewport */
-
-   float tmp[2][4];             /* scratch space for LIT */
-
-   struct shine_tab shine_tab[MAX_SHINE_TAB];
-   struct lit_info  lit_info[MAX_LIT_INFO];
-   unsigned now;
-   
-
-   ushort fpu_rnd_nearest;
-   ushort fpu_rnd_neg_inf;
-   ushort fpu_restore;
-   ushort fpucntl;              /* one of FPU_* above */
-
-   const float (*immediates)[4];     /* points to shader data */
-   const void *constants[PIPE_MAX_CONSTANT_BUFFERS]; /* points to draw data */
-
-   const struct aos_buffer *buffer; /* points to ? */
-};
-
-
-
-
-struct aos_compilation {
-   struct x86_function *func;
-   struct draw_vs_variant_aos_sse *vaos;
-
-   unsigned insn_counter;
-   unsigned num_immediates;
-   unsigned count;
-   unsigned lit_count;
-
-   struct {
-      unsigned idx:16;
-      unsigned file:8;
-      unsigned dirty:8;
-      unsigned last_used;
-   } xmm[8];
-
-   unsigned x86_reg[2];                /* one of X86_* */
-
-   boolean input_fetched[PIPE_MAX_ATTRIBS];
-   unsigned output_last_write[PIPE_MAX_ATTRIBS];
-
-   boolean have_sse2;
-   boolean error;
-   short fpucntl;
-
-   /* these are actually known values, but putting them in a struct
-    * like this is helpful to keep them in sync across the file.
-    */
-   struct x86_reg tmp_EAX;
-   struct x86_reg idx_EBX;     /* either start+i or &elt[i] */
-   struct x86_reg outbuf_ECX;
-   struct x86_reg machine_EDX;
-   struct x86_reg count_ESI;    /* decrements to zero */
-   struct x86_reg temp_EBP;
-   struct x86_reg stack_ESP;
-};
-
-struct x86_reg aos_get_xmm_reg( struct aos_compilation *cp );
-void aos_release_xmm_reg( struct aos_compilation *cp, unsigned idx );
-
-void aos_adopt_xmm_reg( struct aos_compilation *cp,
-                        struct x86_reg reg,
-                        unsigned file,
-                        unsigned idx,
-                        unsigned dirty );
-
-void aos_spill_all( struct aos_compilation *cp );
-
-struct x86_reg aos_get_shader_reg( struct aos_compilation *cp, 
-                                   unsigned file,
-                                   unsigned idx );
-
-boolean aos_init_inputs( struct aos_compilation *cp, boolean linear );
-boolean aos_fetch_inputs( struct aos_compilation *cp, boolean linear );
-boolean aos_incr_inputs( struct aos_compilation *cp, boolean linear );
-
-boolean aos_emit_outputs( struct aos_compilation *cp );
-
-
-#define IMM_ONES     0              /* 1, 1,1,1 */
-#define IMM_SWZ      1              /* 1,-1,0, 0xffffffff */
-#define IMM_IDENTITY 2              /* 0, 0,0,1 */
-#define IMM_INV_255  3              /* 1/255, 1/255, 1/255, 1/255 */
-#define IMM_255      4              /* 255, 255, 255, 255 */
-#define IMM_NEGS     5              /* -1,-1,-1,-1 */
-#define IMM_RSQ      6              /* -.5,1.5,_,_ */
-#define IMM_PSIZE    7              /* not really an immediate - updated each run */
-
-struct x86_reg aos_get_internal( struct aos_compilation *cp,
-                                 unsigned imm );
-struct x86_reg aos_get_internal_xmm( struct aos_compilation *cp,
-                                     unsigned imm );
-
-
-#define AOS_ERROR(cp, msg)                                                  \
-do {                                                                    \
-   if (0) debug_printf("%s: x86 translation failed: %s\n", __FUNCTION__, msg); \
-   cp->error = 1;                                                       \
-} while (0)
-
-
-#define X86_NULL       0
-#define X86_IMMEDIATES 1
-#define X86_CONSTANTS  2
-#define X86_BUFFERS    3
-
-struct x86_reg aos_get_x86( struct aos_compilation *cp,
-                            unsigned which_reg,
-                            unsigned value );
-
-
-typedef void (PIPE_CDECL *vaos_run_elts_func)( struct aos_machine *,
-                                               const unsigned *elts,
-                                               unsigned count,
-                                               void *output_buffer);
-
-typedef void (PIPE_CDECL *vaos_run_linear_func)( struct aos_machine *,
-                                                unsigned start,
-                                                unsigned count,
-                                                void *output_buffer);
-
-
-struct draw_vs_variant_aos_sse {
-   struct draw_vs_variant base;
-   struct draw_context *draw;
-
-   struct aos_buffer *buffer;
-   unsigned nr_vb;
-
-   vaos_run_linear_func gen_run_linear;
-   vaos_run_elts_func gen_run_elts;
-
-
-   struct x86_function func[2];
-};
-
-
-#endif
-
-#endif 
-
diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c
deleted file mode 100644 (file)
index f1dd448..0000000
+++ /dev/null
@@ -1,460 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-
-#include "util/u_memory.h"
-#include "pipe/p_shader_tokens.h"
-#include "tgsi/tgsi_parse.h"
-#include "tgsi/tgsi_util.h"
-#include "tgsi/tgsi_exec.h"
-#include "draw_vs.h"
-#include "draw_vs_aos.h"
-#include "draw_vertex.h"
-
-#include "rtasm/rtasm_x86sse.h"
-
-#ifdef PIPE_ARCH_X86
-
-/* Note - don't yet have to worry about interacting with the code in
- * draw_vs_aos.c as there is no intermingling of generated code...
- * That may have to change, we'll see.
- */
-static void emit_load_R32G32B32A32( struct aos_compilation *cp,                           
-                                   struct x86_reg data,
-                                   struct x86_reg src_ptr )
-{
-   sse_movups(cp->func, data, src_ptr);
-}
-
-static void emit_load_R32G32B32( struct aos_compilation *cp,                      
-                                struct x86_reg data,
-                                struct x86_reg src_ptr )
-{
-#if 1
-   sse_movss(cp->func, data, x86_make_disp(src_ptr, 8));
-   /* data = z ? ? ? */
-   sse_shufps(cp->func, data, aos_get_internal_xmm( cp, IMM_IDENTITY ), SHUF(X,Y,Z,W) );
-   /* data = z ? 0 1 */
-   sse_shufps(cp->func, data, data, SHUF(Y,Z,X,W) );
-   /* data = ? 0 z 1 */
-   sse_movlps(cp->func, data, src_ptr);
-   /* data = x y z 1 */
-#else
-   sse_movups(cp->func, data, src_ptr);
-   /* data = x y z ? */
-   sse2_pshufd(cp->func, data, data, SHUF(W,X,Y,Z) );
-   /* data = ? x y z */
-   sse_movss(cp->func, data, aos_get_internal_xmm( cp, IMM_ONES ) );
-   /* data = 1 x y z */
-   sse2_pshufd(cp->func, data, data, SHUF(Y,Z,W,X) );
-   /* data = x y z 1 */
-#endif
-}
-
-static void emit_load_R32G32( struct aos_compilation *cp, 
-                          struct x86_reg data,
-                          struct x86_reg src_ptr )
-{
-   sse_movups(cp->func, data, aos_get_internal_xmm( cp, IMM_IDENTITY ) );
-   sse_movlps(cp->func, data, src_ptr);
-}
-
-
-static void emit_load_R32( struct aos_compilation *cp, 
-                          struct x86_reg data,
-                          struct x86_reg src_ptr )
-{
-   sse_movss(cp->func, data, src_ptr);
-   sse_orps(cp->func, data, aos_get_internal_xmm( cp, IMM_IDENTITY ) );
-}
-
-
-static void emit_load_R8G8B8A8_UNORM( struct aos_compilation *cp,
-                                      struct x86_reg data,
-                                      struct x86_reg src_ptr )
-{
-   sse_movss(cp->func, data, src_ptr);
-   sse2_punpcklbw(cp->func, data, aos_get_internal_xmm( cp, IMM_IDENTITY ));
-   sse2_punpcklbw(cp->func, data, aos_get_internal_xmm( cp, IMM_IDENTITY ));
-   sse2_cvtdq2ps(cp->func, data, data);
-   sse_mulps(cp->func, data, aos_get_internal(cp, IMM_INV_255));
-}
-
-
-
-/* Extended swizzles?  Maybe later.
- */  
-static void emit_swizzle( struct aos_compilation *cp,
-                         struct x86_reg dest,
-                         struct x86_reg src,
-                         ubyte shuffle )
-{
-   sse_shufps(cp->func, dest, src, shuffle);
-}
-
-
-
-static boolean get_buffer_ptr( struct aos_compilation *cp,
-                               boolean linear,
-                               unsigned buf_idx,
-                               struct x86_reg elt,
-                               struct x86_reg ptr)
-{
-   struct x86_reg buf = x86_make_disp(aos_get_x86( cp, 0, X86_BUFFERS ), 
-                                      buf_idx * sizeof(struct aos_buffer));
-
-   struct x86_reg buf_stride = x86_make_disp(buf, 
-                                             Offset(struct aos_buffer, stride));
-   if (linear) {
-      struct x86_reg buf_ptr = x86_make_disp(buf, 
-                                             Offset(struct aos_buffer, ptr));
-
-
-      /* Calculate pointer to current attrib:
-       */
-      x86_mov(cp->func, ptr, buf_ptr);
-      x86_mov(cp->func, elt, buf_stride);
-      x86_add(cp->func, elt, ptr);
-      if (buf_idx == 0) sse_prefetchnta(cp->func, x86_make_disp(elt, 192));
-      x86_mov(cp->func, buf_ptr, elt);
-   }
-   else {
-      struct x86_reg buf_base_ptr = x86_make_disp(buf, 
-                                                  Offset(struct aos_buffer, base_ptr));
-
-
-      /* Calculate pointer to current attrib:
-       */
-      x86_mov(cp->func, ptr, buf_stride);
-      x86_imul(cp->func, ptr, elt);
-      x86_add(cp->func, ptr, buf_base_ptr);
-   }
-
-   cp->insn_counter++;
-
-   return TRUE;
-}
-
-
-static boolean load_input( struct aos_compilation *cp,
-                           unsigned idx,
-                           struct x86_reg bufptr )
-{
-   unsigned format = cp->vaos->base.key.element[idx].in.format;
-   unsigned offset = cp->vaos->base.key.element[idx].in.offset;
-   struct x86_reg dataXMM = aos_get_xmm_reg(cp);
-
-   /* Figure out source pointer address:
-    */
-   struct x86_reg src = x86_make_disp(bufptr, offset);
-
-   aos_adopt_xmm_reg( cp,
-                      dataXMM,
-                      TGSI_FILE_INPUT,
-                      idx,
-                      TRUE );
-
-   switch (format) {
-   case PIPE_FORMAT_R32_FLOAT:
-      emit_load_R32(cp, dataXMM, src);
-      break;
-   case PIPE_FORMAT_R32G32_FLOAT:
-      emit_load_R32G32(cp, dataXMM, src);
-      break;
-   case PIPE_FORMAT_R32G32B32_FLOAT:
-      emit_load_R32G32B32(cp, dataXMM, src);
-      break;
-   case PIPE_FORMAT_R32G32B32A32_FLOAT:
-      emit_load_R32G32B32A32(cp, dataXMM, src);
-      break;
-   case PIPE_FORMAT_A8R8G8B8_UNORM:
-      emit_load_R8G8B8A8_UNORM(cp, dataXMM, src);
-      emit_swizzle(cp, dataXMM, dataXMM, SHUF(Z,Y,X,W));
-      break;
-   case PIPE_FORMAT_R8G8B8A8_UNORM:
-      emit_load_R8G8B8A8_UNORM(cp, dataXMM, src);
-      break;
-   default:
-      AOS_ERROR(cp, "unhandled input format");
-      return FALSE;
-   }
-
-   return TRUE;
-}
-
-static boolean load_inputs( struct aos_compilation *cp,
-                            unsigned buffer,
-                            struct x86_reg ptr )
-{
-   unsigned i;
-
-   for (i = 0; i < cp->vaos->base.key.nr_inputs; i++) {
-      if (cp->vaos->base.key.element[i].in.buffer == buffer) {
-
-         if (!load_input( cp, i, ptr ))
-            return FALSE;
-
-         cp->insn_counter++;
-      }
-   }
-   
-   return TRUE;
-}
-
-boolean aos_init_inputs( struct aos_compilation *cp, boolean linear )
-{
-   unsigned i;
-   for (i = 0; i < cp->vaos->nr_vb; i++) {
-      struct x86_reg buf = x86_make_disp(aos_get_x86( cp, 0, X86_BUFFERS ), 
-                                         i * sizeof(struct aos_buffer));
-
-      struct x86_reg buf_base_ptr = x86_make_disp(buf, 
-                                                  Offset(struct aos_buffer, base_ptr));
-
-      if (cp->vaos->base.key.const_vbuffers & (1<<i)) {
-         struct x86_reg ptr = cp->tmp_EAX;
-
-         x86_mov(cp->func, ptr, buf_base_ptr);
-
-         /* Load all inputs for this constant vertex buffer
-          */
-         load_inputs( cp, i, x86_deref(ptr) );
-         
-         /* Then just force them out to aos_machine.input[]
-          */
-         aos_spill_all( cp );
-
-      }
-      else if (linear) {
-
-         struct x86_reg elt = cp->idx_EBX;
-         struct x86_reg ptr = cp->tmp_EAX;
-
-         struct x86_reg buf_stride = x86_make_disp(buf, 
-                                                   Offset(struct aos_buffer, stride));
-
-         struct x86_reg buf_ptr = x86_make_disp(buf, 
-                                                Offset(struct aos_buffer, ptr));
-
-
-         /* Calculate pointer to current attrib:
-          */
-         x86_mov(cp->func, ptr, buf_stride);
-         x86_imul(cp->func, ptr, elt);
-         x86_add(cp->func, ptr, buf_base_ptr);
-
-
-         /* In the linear case, keep the buffer pointer instead of the
-          * index number.
-          */
-         if (cp->vaos->nr_vb == 1) 
-            x86_mov( cp->func, elt, ptr );
-         else
-            x86_mov( cp->func, buf_ptr, ptr );
-
-         cp->insn_counter++;
-      }
-   }
-
-   return TRUE;
-}
-
-boolean aos_fetch_inputs( struct aos_compilation *cp, boolean linear )
-{
-   unsigned j;
-
-   for (j = 0; j < cp->vaos->nr_vb; j++) {
-      if (cp->vaos->base.key.const_vbuffers & (1<<j)) {
-         /* just retreive pre-transformed input */
-      }
-      else if (linear && cp->vaos->nr_vb == 1) {
-         load_inputs( cp, 0, cp->idx_EBX );
-      }
-      else {
-         struct x86_reg elt = linear ? cp->idx_EBX : x86_deref(cp->idx_EBX);
-         struct x86_reg ptr = cp->tmp_EAX;
-
-         if (!get_buffer_ptr( cp, linear, j, elt, ptr ))
-            return FALSE;
-
-         if (!load_inputs( cp, j, ptr ))
-            return FALSE;
-      }
-   }
-
-   return TRUE;
-}
-
-boolean aos_incr_inputs( struct aos_compilation *cp, boolean linear )
-{
-   if (linear && cp->vaos->nr_vb == 1) {
-      struct x86_reg stride = x86_make_disp(aos_get_x86( cp, 0, X86_BUFFERS ), 
-                                            (0 * sizeof(struct aos_buffer) + 
-                                             Offset(struct aos_buffer, stride)));
-
-      x86_add(cp->func, cp->idx_EBX, stride);
-      sse_prefetchnta(cp->func, x86_make_disp(cp->idx_EBX, 192));
-   }
-   else if (linear) {
-      /* Nothing to do */
-   } 
-   else {
-      x86_lea(cp->func, cp->idx_EBX, x86_make_disp(cp->idx_EBX, 4));
-   }
-
-   return TRUE;
-}
-
-
-
-
-
-
-static void emit_store_R32G32B32A32( struct aos_compilation *cp,                          
-                                    struct x86_reg dst_ptr,
-                                    struct x86_reg dataXMM )
-{
-   sse_movups(cp->func, dst_ptr, dataXMM);
-}
-
-static void emit_store_R32G32B32( struct aos_compilation *cp, 
-                                 struct x86_reg dst_ptr,
-                                 struct x86_reg dataXMM )
-{
-   sse_movlps(cp->func, dst_ptr, dataXMM);
-   sse_shufps(cp->func, dataXMM, dataXMM, SHUF(Z,Z,Z,Z) ); /* NOTE! destructive */
-   sse_movss(cp->func, x86_make_disp(dst_ptr,8), dataXMM);
-}
-
-static void emit_store_R32G32( struct aos_compilation *cp, 
-                              struct x86_reg dst_ptr,
-                              struct x86_reg dataXMM )
-{
-   sse_movlps(cp->func, dst_ptr, dataXMM);
-}
-
-static void emit_store_R32( struct aos_compilation *cp, 
-                           struct x86_reg dst_ptr,
-                           struct x86_reg dataXMM )
-{
-   sse_movss(cp->func, dst_ptr, dataXMM);
-}
-
-
-
-static void emit_store_R8G8B8A8_UNORM( struct aos_compilation *cp,
-                                      struct x86_reg dst_ptr,
-                                      struct x86_reg dataXMM )
-{
-   sse_mulps(cp->func, dataXMM, aos_get_internal(cp, IMM_255));
-   sse2_cvtps2dq(cp->func, dataXMM, dataXMM);
-   sse2_packssdw(cp->func, dataXMM, dataXMM);
-   sse2_packuswb(cp->func, dataXMM, dataXMM);
-   sse_movss(cp->func, dst_ptr, dataXMM);
-}
-
-
-
-
-
-static boolean emit_output( struct aos_compilation *cp,
-                            struct x86_reg ptr,
-                            struct x86_reg dataXMM, 
-                            enum attrib_emit format )
-{
-   switch (format) {
-   case EMIT_1F:
-   case EMIT_1F_PSIZE:
-      emit_store_R32(cp, ptr, dataXMM);
-      break;
-   case EMIT_2F:
-      emit_store_R32G32(cp, ptr, dataXMM);
-      break;
-   case EMIT_3F:
-      emit_store_R32G32B32(cp, ptr, dataXMM);
-      break;
-   case EMIT_4F:
-      emit_store_R32G32B32A32(cp, ptr, dataXMM);
-      break;
-   case EMIT_4UB:
-      emit_store_R8G8B8A8_UNORM(cp, ptr, dataXMM);
-      break;
-   case EMIT_4UB_BGRA:
-      emit_swizzle(cp, dataXMM, dataXMM, SHUF(Z,Y,X,W));
-      emit_store_R8G8B8A8_UNORM(cp, ptr, dataXMM);
-      break;
-   default:
-      AOS_ERROR(cp, "unhandled output format");
-      return FALSE;
-   }
-
-   return TRUE;
-}
-
-
-
-boolean aos_emit_outputs( struct aos_compilation *cp )
-{
-   unsigned i;
-   
-   for (i = 0; i < cp->vaos->base.key.nr_outputs; i++) {
-      enum attrib_emit format = cp->vaos->base.key.element[i].out.format;
-      unsigned offset = cp->vaos->base.key.element[i].out.offset;
-      unsigned vs_output = cp->vaos->base.key.element[i].out.vs_output;
-
-      struct x86_reg data;
-
-      if (format == EMIT_1F_PSIZE) {
-         data = aos_get_internal_xmm( cp, IMM_PSIZE );
-      }
-      else {
-         data = aos_get_shader_reg( cp, 
-                                    TGSI_FILE_OUTPUT,
-                                    vs_output );
-      }
-
-      if (data.file != file_XMM) {
-         struct x86_reg tmp = aos_get_xmm_reg( cp );
-         sse_movaps(cp->func, tmp, data);
-         data = tmp;
-      }
-      
-      if (!emit_output( cp, 
-                        x86_make_disp( cp->outbuf_ECX, offset ),
-                        data, 
-                        format ))
-         return FALSE;
-
-      aos_release_xmm_reg( cp, data.idx );
-
-      cp->insn_counter++;
-   }
-
-   return TRUE;
-}
-
-#endif
diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_machine.c b/src/gallium/auxiliary/draw/draw_vs_aos_machine.c
deleted file mode 100644 (file)
index 0eda414..0000000
+++ /dev/null
@@ -1,328 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-
-#include "pipe/p_config.h"
-
-
-#include "pipe/p_shader_tokens.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#include "tgsi/tgsi_parse.h"
-#include "tgsi/tgsi_util.h"
-#include "tgsi/tgsi_exec.h"
-#include "draw_vs.h"
-#include "draw_vs_aos.h"
-#include "draw_vertex.h"
-
-#ifdef PIPE_ARCH_X86
-
-#include "rtasm/rtasm_x86sse.h"
-
-
-#define X87_CW_EXCEPTION_INV_OP       (1<<0)
-#define X87_CW_EXCEPTION_DENORM_OP    (1<<1)
-#define X87_CW_EXCEPTION_ZERO_DIVIDE  (1<<2)
-#define X87_CW_EXCEPTION_OVERFLOW     (1<<3)
-#define X87_CW_EXCEPTION_UNDERFLOW    (1<<4)
-#define X87_CW_EXCEPTION_PRECISION    (1<<5)
-#define X87_CW_PRECISION_SINGLE       (0<<8)
-#define X87_CW_PRECISION_RESERVED     (1<<8)
-#define X87_CW_PRECISION_DOUBLE       (2<<8)
-#define X87_CW_PRECISION_DOUBLE_EXT   (3<<8)
-#define X87_CW_PRECISION_MASK         (3<<8)
-#define X87_CW_ROUND_NEAREST          (0<<10)
-#define X87_CW_ROUND_DOWN             (1<<10)
-#define X87_CW_ROUND_UP               (2<<10)
-#define X87_CW_ROUND_ZERO             (3<<10)
-#define X87_CW_ROUND_MASK             (3<<10)
-#define X87_CW_INFINITY               (1<<12)
-
-
-void PIPE_CDECL aos_do_lit( struct aos_machine *machine,
-                            float *result,
-                            const float *in,
-                            unsigned count )
-{
-   if (in[0] > 0) 
-   {
-      if (in[1] <= 0.0) 
-      {
-         result[0] = 1.0F;
-         result[1] = in[0];
-         result[2] = 0.0F;
-         result[3] = 1.0F;
-      }
-      else
-      {
-         const float epsilon = 1.0F / 256.0F;    
-         float exponent = CLAMP(in[3], -(128.0F - epsilon), (128.0F - epsilon));
-         result[0] = 1.0F;
-         result[1] = in[0];
-         result[2] = powf(in[1], exponent);
-         result[3] = 1.0;
-      }
-   }
-   else 
-   {
-      result[0] = 1.0F;
-      result[1] = 0.0;
-      result[2] = 0.0;
-      result[3] = 1.0F;
-   }
-}
-
-
-static void PIPE_CDECL do_lit_lut( struct aos_machine *machine,
-                                   float *result,
-                                   const float *in,
-                                   unsigned count )
-{
-   if (in[0] > 0) 
-   {
-      if (in[1] <= 0.0) 
-      {
-         result[0] = 1.0F;
-         result[1] = in[0];
-         result[2] = 0.0F;
-         result[3] = 1.0F;
-         return;
-      }
-      
-      if (machine->lit_info[count].shine_tab->exponent != in[3]) {
-         machine->lit_info[count].func = aos_do_lit;
-         goto no_luck;
-      }
-
-      if (in[1] <= 1.0)
-      {
-         const float *tab = machine->lit_info[count].shine_tab->values;
-         float f = in[1] * 256;
-         int k = (int)f;
-         float frac = f - (float)k;
-         
-         result[0] = 1.0F;
-         result[1] = in[0];
-         result[2] = tab[k] + frac*(tab[k+1]-tab[k]);
-         result[3] = 1.0;
-         return;
-      }
-      
-   no_luck:
-      {
-         const float epsilon = 1.0F / 256.0F;    
-         float exponent = CLAMP(in[3], -(128.0F - epsilon), (128.0F - epsilon));
-         result[0] = 1.0F;
-         result[1] = in[0];
-         result[2] = powf(in[1], exponent);
-         result[3] = 1.0;
-      }
-   }
-   else 
-   {
-      result[0] = 1.0F;
-      result[1] = 0.0;
-      result[2] = 0.0;
-      result[3] = 1.0F;
-   }
-}
-
-
-static void do_populate_lut( struct shine_tab *tab,
-                             float unclamped_exponent )
-{
-   const float epsilon = 1.0F / 256.0F;    
-   float exponent = CLAMP(unclamped_exponent, -(128.0F - epsilon), (128.0F - epsilon));
-   unsigned i;
-
-   tab->exponent = unclamped_exponent; /* for later comparison */
-   
-   tab->values[0] = 0;
-   if (exponent == 0) {
-      for (i = 1; i < 258; i++) {
-         tab->values[i] = 1.0;
-      }      
-   }
-   else {
-      for (i = 1; i < 258; i++) {
-         tab->values[i] = powf((float)i * epsilon, exponent);
-      }
-   }
-}
-
-
-
-
-static void PIPE_CDECL populate_lut( struct aos_machine *machine,
-                                     float *result,
-                                     const float *in,
-                                     unsigned count )
-{
-   unsigned i, tab;
-
-   /* Search for an existing table for this value.  Note that without
-    * static analysis we don't really know if in[3] will be constant,
-    * but it usually is...
-    */
-   for (tab = 0; tab < 4; tab++) {
-      if (machine->shine_tab[tab].exponent == in[3]) {
-         goto found;
-      }
-   }
-
-   for (tab = 0, i = 1; i < 4; i++) {
-      if (machine->shine_tab[i].last_used < machine->shine_tab[tab].last_used)
-         tab = i;
-   }
-
-   if (machine->shine_tab[tab].last_used == machine->now) {
-      /* No unused tables (this is not a ffvertex program...).  Just
-       * call pow each time:
-       */
-      machine->lit_info[count].func = aos_do_lit;
-      machine->lit_info[count].func( machine, result, in, count );
-      return;
-   }
-   else {
-      do_populate_lut( &machine->shine_tab[tab], in[3] );
-   }
-
- found:
-   machine->shine_tab[tab].last_used = machine->now;
-   machine->lit_info[count].shine_tab = &machine->shine_tab[tab];
-   machine->lit_info[count].func = do_lit_lut;
-   machine->lit_info[count].func( machine, result, in, count );
-}
-
-
-void
-draw_vs_aos_machine_constants(struct aos_machine *machine,
-                              unsigned slot,
-                              const void *constants)
-{
-   machine->constants[slot] = constants;
-
-   {
-      unsigned i;
-      for (i = 0; i < MAX_LIT_INFO; i++) {
-         machine->lit_info[i].func = populate_lut;
-         machine->now++;
-      }
-   }
-}
-
-
-void draw_vs_aos_machine_viewport( struct aos_machine *machine,
-                                   const struct pipe_viewport_state *viewport )
-{
-   memcpy(machine->scale, viewport->scale, 4 * sizeof(float));
-   memcpy(machine->translate, viewport->translate, 4 * sizeof(float));
-}
-
-
-
-void draw_vs_aos_machine_destroy( struct aos_machine *machine )
-{
-   align_free(machine);
-}
-
-struct aos_machine *draw_vs_aos_machine( void )
-{
-   struct aos_machine *machine;
-   unsigned i;
-   float inv = 1.0f/255.0f;
-   float f255 = 255.0f;
-
-   machine = align_malloc(sizeof(struct aos_machine), 16);
-   if (!machine)
-      return NULL;
-
-   memset(machine, 0, sizeof(*machine));
-
-   ASSIGN_4V(machine->internal[IMM_SWZ],       1.0f,  -1.0f,  0.0f, 1.0f);
-   *(unsigned *)&machine->internal[IMM_SWZ][3] = 0xffffffff;
-
-   ASSIGN_4V(machine->internal[IMM_ONES],      1.0f,  1.0f,  1.0f,  1.0f);
-   ASSIGN_4V(machine->internal[IMM_NEGS],     -1.0f, -1.0f, -1.0f, -1.0f);
-   ASSIGN_4V(machine->internal[IMM_IDENTITY],  0.0f,  0.0f,  0.0f,  1.0f);
-   ASSIGN_4V(machine->internal[IMM_INV_255],   inv,   inv,   inv,   inv);
-   ASSIGN_4V(machine->internal[IMM_255],       f255,  f255,  f255,  f255);
-   ASSIGN_4V(machine->internal[IMM_RSQ],       -.5f,  1.5f,  0.0f,  0.0f);
-
-
-   machine->fpu_rnd_nearest = (X87_CW_EXCEPTION_INV_OP |
-                               X87_CW_EXCEPTION_DENORM_OP |
-                               X87_CW_EXCEPTION_ZERO_DIVIDE |
-                               X87_CW_EXCEPTION_OVERFLOW |
-                               X87_CW_EXCEPTION_UNDERFLOW |
-                               X87_CW_EXCEPTION_PRECISION |
-                               (1<<6) |
-                               X87_CW_ROUND_NEAREST |
-                               X87_CW_PRECISION_DOUBLE_EXT);
-
-   assert(machine->fpu_rnd_nearest == 0x37f);
-                               
-   machine->fpu_rnd_neg_inf = (X87_CW_EXCEPTION_INV_OP |
-                               X87_CW_EXCEPTION_DENORM_OP |
-                               X87_CW_EXCEPTION_ZERO_DIVIDE |
-                               X87_CW_EXCEPTION_OVERFLOW |
-                               X87_CW_EXCEPTION_UNDERFLOW |
-                               X87_CW_EXCEPTION_PRECISION |
-                               (1<<6) |
-                               X87_CW_ROUND_DOWN |
-                               X87_CW_PRECISION_DOUBLE_EXT);
-
-   for (i = 0; i < MAX_SHINE_TAB; i++)
-      do_populate_lut( &machine->shine_tab[i], 1.0f );
-
-   return machine;
-}
-
-#else
-
-void draw_vs_aos_machine_viewport( struct aos_machine *machine,
-                                   const struct pipe_viewport_state *viewport )
-{
-}
-
-void
-draw_vs_aos_machine_constants(struct aos_machine *machine,
-                              unsigned slot,
-                              const void *constants)
-{
-}
-
-void draw_vs_aos_machine_destroy( struct aos_machine *machine )
-{
-}
-
-struct aos_machine *draw_vs_aos_machine( void )
-{
-   return NULL;
-}
-#endif
-
index cf894bbe8af8f58f6d58019ed297da7368ede233..7fb0e0953e29c8ca985b002afd2c07c41a3c6285 100644 (file)
@@ -185,12 +185,7 @@ draw_create_vs_ppc(struct draw_context *draw,
    tgsi_scan_shader(templ->tokens, &vs->base.info);
 
    vs->base.draw = draw;
-#if 0
-   if (1)
-      vs->base.create_variant = draw_vs_variant_aos_ppc;
-   else
-#endif
-      vs->base.create_variant = draw_vs_create_variant_generic;
+   vs->base.create_variant = draw_vs_create_variant_generic;
    vs->base.prepare = vs_ppc_prepare;
    vs->base.run_linear = vs_ppc_run_linear;
    vs->base.delete = vs_ppc_delete;
diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c
deleted file mode 100644 (file)
index d918579..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
- /*
-  * Authors:
-  *   Keith Whitwell <keith@tungstengraphics.com>
-  *   Brian Paul
-  */
-
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#include "pipe/p_config.h"
-
-#include "draw_vs.h"
-
-#if defined(PIPE_ARCH_X86)
-
-#include "pipe/p_shader_tokens.h"
-
-#include "draw_private.h"
-#include "draw_context.h"
-
-#include "rtasm/rtasm_cpu.h"
-#include "rtasm/rtasm_x86sse.h"
-#include "tgsi/tgsi_sse2.h"
-#include "tgsi/tgsi_parse.h"
-#include "tgsi/tgsi_exec.h"
-
-#define SSE_MAX_VERTICES 4
-
-
-struct draw_sse_vertex_shader {
-   struct draw_vertex_shader base;
-   struct x86_function sse2_program;
-
-   tgsi_sse2_vs_func func;
-   
-   struct tgsi_exec_machine *machine;
-};
-
-
-static void
-vs_sse_prepare( struct draw_vertex_shader *base,
-               struct draw_context *draw )
-{
-   struct draw_sse_vertex_shader *shader = (struct draw_sse_vertex_shader *)base;
-   struct tgsi_exec_machine *machine = shader->machine;
-
-   machine->Samplers = draw->vs.samplers;
-
-   if (base->info.uses_instanceid) {
-      unsigned i = machine->SysSemanticToIndex[TGSI_SEMANTIC_INSTANCEID];
-      assert(i < Elements(machine->SystemValue));
-      machine->SystemValue[i][0] = base->draw->instance_id;
-   }
-}
-
-
-
-/* Simplified vertex shader interface for the pt paths.  Given the
- * complexity of code-generating all the above operations together,
- * it's time to try doing all the other stuff separately.
- */
-static void
-vs_sse_run_linear( struct draw_vertex_shader *base,
-                  const float (*input)[4],
-                  float (*output)[4],
-                  const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
-                 const unsigned const_size[PIPE_MAX_CONSTANT_BUFFERS],
-                  unsigned count,
-                  unsigned input_stride,
-                  unsigned output_stride )
-{
-   struct draw_sse_vertex_shader *shader = (struct draw_sse_vertex_shader *)base;
-   struct tgsi_exec_machine *machine = shader->machine;
-   unsigned int i;
-
-   /* By default, execute all channels.  XXX move this inside the loop
-    * below when we support shader conditionals/loops.
-    */
-   tgsi_set_exec_mask(machine, 1, 1, 1, 1);
-
-   for (i = 0; i < count; i += MAX_TGSI_VERTICES) {
-      unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i);
-
-      if (max_vertices < 4) {
-         /* disable the unused execution channels */
-         tgsi_set_exec_mask(machine,
-                            1,
-                            max_vertices > 1,
-                            max_vertices > 2,
-                            0);
-      }
-
-      /* run compiled shader
-       */
-      shader->func(machine,
-                   (const float (*)[4])constants[0],
-                  shader->base.immediates,
-                   input,
-                   base->info.num_inputs,
-                   input_stride,
-                   output,
-                   base->info.num_outputs,
-                   output_stride );
-
-      input = (const float (*)[4])((const char *)input + input_stride * max_vertices);
-      output = (float (*)[4])((char *)output + output_stride * max_vertices);
-   }
-}
-
-
-
-
-static void
-vs_sse_delete( struct draw_vertex_shader *base )
-{
-   struct draw_sse_vertex_shader *shader = (struct draw_sse_vertex_shader *)base;
-   
-   x86_release_func( &shader->sse2_program );
-
-   align_free( (void *) shader->base.immediates );
-
-   FREE( (void*) shader->base.state.tokens );
-   FREE( shader );
-}
-
-
-struct draw_vertex_shader *
-draw_create_vs_sse(struct draw_context *draw,
-                          const struct pipe_shader_state *templ)
-{
-   struct draw_sse_vertex_shader *vs;
-
-   if (!rtasm_cpu_has_sse2())
-      return NULL;
-
-   vs = CALLOC_STRUCT( draw_sse_vertex_shader );
-   if (vs == NULL) 
-      return NULL;
-
-   /* we make a private copy of the tokens */
-   vs->base.state.tokens = tgsi_dup_tokens(templ->tokens);
-   if (!vs->base.state.tokens)
-      goto fail;
-
-   tgsi_scan_shader(templ->tokens, &vs->base.info);
-
-   vs->base.draw = draw;
-   if (1)
-      vs->base.create_variant = draw_vs_create_variant_aos_sse;
-   else
-      vs->base.create_variant = draw_vs_create_variant_generic;
-   vs->base.prepare = vs_sse_prepare;
-   vs->base.run_linear = vs_sse_run_linear;
-   vs->base.delete = vs_sse_delete;
-   
-   vs->base.immediates = align_malloc(TGSI_EXEC_NUM_IMMEDIATES * 4 *
-                                      sizeof(float), 16);
-
-   vs->machine = draw->vs.machine;
-   
-   x86_init_func( &vs->sse2_program );
-
-   if (!tgsi_emit_sse2( (struct tgsi_token *) vs->base.state.tokens,
-                       &vs->sse2_program, 
-                        (float (*)[4])vs->base.immediates, 
-                        TRUE )) 
-      goto fail;
-      
-   vs->func = (tgsi_sse2_vs_func) x86_get_func( &vs->sse2_program );
-   if (!vs->func) {
-      goto fail;
-   }
-   
-   return &vs->base;
-
-fail:
-   if (0)
-      debug_warning("tgsi_emit_sse2() failed, falling back to interpreter\n");
-
-   x86_release_func( &vs->sse2_program );
-   
-   FREE(vs);
-   return NULL;
-}
-
-
-
-#else
-
-struct draw_vertex_shader *
-draw_create_vs_sse( struct draw_context *draw,
-                   const struct pipe_shader_state *templ )
-{
-   return (void *) 0;
-}
-
-
-#endif
-
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c
deleted file mode 100644 (file)
index 5614caf..0000000
+++ /dev/null
@@ -1,3106 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * Copyright 2009-2010 VMware, Inc.  All rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-#include "pipe/p_config.h"
-
-#include "tgsi/tgsi_sse2.h"
-
-#if defined(PIPE_ARCH_X86) && 0 /* See FIXME notes below */
-
-#include "util/u_debug.h"
-#include "pipe/p_shader_tokens.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#if defined(PIPE_ARCH_SSE)
-#include "util/u_sse.h"
-#endif
-#include "tgsi/tgsi_info.h"
-#include "tgsi/tgsi_parse.h"
-#include "tgsi/tgsi_util.h"
-#include "tgsi/tgsi_dump.h"
-#include "tgsi/tgsi_exec.h"
-
-#include "rtasm/rtasm_x86sse.h"
-
-/* for 1/sqrt()
- *
- * This costs about 100fps (close to 10%) in gears:
- */
-#define HIGH_PRECISION 1
-
-#define FAST_MATH 1
-
-
-#define FOR_EACH_CHANNEL( CHAN )\
-   for (CHAN = 0; CHAN < NUM_CHANNELS; CHAN++)
-
-#define IS_DST0_CHANNEL_ENABLED( INST, CHAN )\
-   ((INST).Dst[0].Register.WriteMask & (1 << (CHAN)))
-
-#define IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN )\
-   if (IS_DST0_CHANNEL_ENABLED( INST, CHAN ))
-
-#define FOR_EACH_DST0_ENABLED_CHANNEL( INST, CHAN )\
-   FOR_EACH_CHANNEL( CHAN )\
-      IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN )
-
-#define CHAN_X 0
-#define CHAN_Y 1
-#define CHAN_Z 2
-#define CHAN_W 3
-
-#define TEMP_ONE_I   TGSI_EXEC_TEMP_ONE_I
-#define TEMP_ONE_C   TGSI_EXEC_TEMP_ONE_C
-
-#define TEMP_R0   TGSI_EXEC_TEMP_R0
-#define TEMP_ADDR TGSI_EXEC_TEMP_ADDR
-#define TEMP_EXEC_MASK_I TGSI_EXEC_MASK_I
-#define TEMP_EXEC_MASK_C TGSI_EXEC_MASK_C
-
-
-/**
- * X86 utility functions.
- */
-
-static struct x86_reg
-make_xmm(
-   unsigned xmm )
-{
-   return x86_make_reg(
-      file_XMM,
-      (enum x86_reg_name) xmm );
-}
-
-/**
- * X86 register mapping helpers.
- */
-
-static struct x86_reg
-get_const_base( void )
-{
-   return x86_make_reg(
-      file_REG32,
-      reg_AX );
-}
-
-static struct x86_reg
-get_machine_base( void )
-{
-   return x86_make_reg(
-      file_REG32,
-      reg_CX );
-}
-
-static struct x86_reg
-get_input_base( void )
-{
-   /* FIXME: tgsi_exec_machine::Inputs is a pointer now! */
-   return x86_make_disp(
-      get_machine_base(),
-      Offset(struct tgsi_exec_machine, Inputs) );
-}
-
-static struct x86_reg
-get_output_base( void )
-{
-   /* FIXME: tgsi_exec_machine::Ouputs is a pointer now! */
-   return x86_make_disp(
-      get_machine_base(),
-      Offset(struct tgsi_exec_machine, Outputs) );
-}
-
-static struct x86_reg
-get_temp_base( void )
-{
-   return x86_make_disp(
-      get_machine_base(),
-      Offset(struct tgsi_exec_machine, Temps) );
-}
-
-static struct x86_reg
-get_coef_base( void )
-{
-   return x86_make_reg(
-      file_REG32,
-      reg_BX );
-}
-
-static struct x86_reg
-get_sampler_base( void )
-{
-   return x86_make_reg(
-      file_REG32,
-      reg_DI );
-}
-
-static struct x86_reg
-get_immediate_base( void )
-{
-   return x86_make_reg(
-      file_REG32,
-      reg_DX );
-}
-
-static struct x86_reg
-get_system_value_base( void )
-{
-   return x86_make_disp(
-      get_machine_base(),
-      Offset(struct tgsi_exec_machine, SystemValue) );
-}
-
-
-/**
- * Data access helpers.
- */
-
-
-static struct x86_reg
-get_immediate(
-   unsigned vec,
-   unsigned chan )
-{
-   return x86_make_disp(
-      get_immediate_base(),
-      (vec * 4 + chan) * 4 );
-}
-
-static struct x86_reg
-get_const(
-   unsigned vec,
-   unsigned chan )
-{
-   return x86_make_disp(
-      get_const_base(),
-      (vec * 4 + chan) * 4 );
-}
-
-static struct x86_reg
-get_sampler_ptr(
-   unsigned unit )
-{
-   return x86_make_disp(
-      get_sampler_base(),
-      unit * sizeof( struct tgsi_sampler * ) );
-}
-
-static struct x86_reg
-get_input(
-   unsigned vec,
-   unsigned chan )
-{
-   return x86_make_disp(
-      get_input_base(),
-      (vec * 4 + chan) * 16 );
-}
-
-static struct x86_reg
-get_output(
-   unsigned vec,
-   unsigned chan )
-{
-   return x86_make_disp(
-      get_output_base(),
-      (vec * 4 + chan) * 16 );
-}
-
-static struct x86_reg
-get_temp(
-   unsigned vec,
-   unsigned chan )
-{
-   return x86_make_disp(
-      get_temp_base(),
-      (vec * 4 + chan) * 16 );
-}
-
-static struct x86_reg
-get_system_value(
-   unsigned vec,
-   unsigned chan )
-{
-   return x86_make_disp(
-      get_system_value_base(), /* base */
-      (vec * 4 + chan) * 4 );  /* byte offset from base */
-}
-
-static struct x86_reg
-get_coef(
-   unsigned vec,
-   unsigned chan,
-   unsigned member )
-{
-   return x86_make_disp(
-      get_coef_base(),
-      ((vec * 3 + member) * 4 + chan) * 4 );
-}
-
-
-static void
-emit_ret(
-   struct x86_function  *func )
-{
-   x86_ret( func );
-}
-
-
-/**
- * Data fetch helpers.
- */
-
-/**
- * Copy a shader constant to xmm register
- * \param xmm  the destination xmm register
- * \param vec  the src const buffer index
- * \param chan  src channel to fetch (X, Y, Z or W)
- */
-static void
-emit_const(
-   struct x86_function *func,
-   uint xmm,
-   int vec,
-   uint chan,
-   uint indirect,
-   uint indirectFile,
-   int indirectIndex )
-{
-   if (indirect) {
-      /* 'vec' is the offset from the address register's value.
-       * We're loading CONST[ADDR+vec] into an xmm register.
-       */
-      struct x86_reg r0 = get_immediate_base();
-      struct x86_reg r1 = get_coef_base();
-      uint i;
-
-      assert( indirectFile == TGSI_FILE_ADDRESS );
-      assert( indirectIndex == 0 );
-      assert( r0.mod == mod_REG );
-      assert( r1.mod == mod_REG );
-
-      x86_push( func, r0 );
-      x86_push( func, r1 );
-
-      /*
-       * Loop over the four pixels or vertices in the quad.
-       * Get the value of the address (offset) register for pixel/vertex[i],
-       * add it to the src offset and index into the constant buffer.
-       * Note that we're working on SOA data.
-       * If any of the pixel/vertex execution channels are unused their
-       * values will be garbage.  It's very important that we don't use
-       * those garbage values as indexes into the constant buffer since
-       * that'll cause segfaults.
-       * The solution is to bitwise-AND the offset with the execution mask
-       * register whose values are either 0 or ~0.
-       * The caller must setup the execution mask register to indicate
-       * which channels are valid/alive before running the shader.
-       * The execution mask will also figure into loops and conditionals
-       * someday.
-       */
-      for (i = 0; i < QUAD_SIZE; i++) {
-         /* r1 = address register[i] */
-         x86_mov( func, r1, x86_make_disp( get_temp( TEMP_ADDR, CHAN_X ), i * 4 ) );
-         /* r0 = execution mask[i] */
-         x86_mov( func, r0, x86_make_disp( get_temp( TEMP_EXEC_MASK_I, TEMP_EXEC_MASK_C ), i * 4 ) );
-         /* r1 = r1 & r0 */
-         x86_and( func, r1, r0 );
-         /* r0 = 'vec', the offset */
-         x86_lea( func, r0, get_const( vec, chan ) );
-
-         /* Quick hack to multiply r1 by 16 -- need to add SHL to rtasm.
-          */
-         x86_add( func, r1, r1 );
-         x86_add( func, r1, r1 );
-         x86_add( func, r1, r1 );
-         x86_add( func, r1, r1 );
-
-         x86_add( func, r0, r1 );  /* r0 = r0 + r1 */
-         x86_mov( func, r1, x86_deref( r0 ) );
-         x86_mov( func, x86_make_disp( get_temp( TEMP_R0, CHAN_X ), i * 4 ), r1 );
-      }
-
-      x86_pop( func, r1 );
-      x86_pop( func, r0 );
-
-      sse_movaps(
-         func,
-         make_xmm( xmm ),
-         get_temp( TEMP_R0, CHAN_X ) );
-   }
-   else {
-      /* 'vec' is the index into the src register file, such as TEMP[vec] */
-      assert( vec >= 0 );
-
-      sse_movss(
-         func,
-         make_xmm( xmm ),
-         get_const( vec, chan ) );
-      sse_shufps(
-         func,
-         make_xmm( xmm ),
-         make_xmm( xmm ),
-         SHUF( 0, 0, 0, 0 ) );
-   }
-}
-
-static void
-emit_immediate(
-   struct x86_function *func,
-   unsigned xmm,
-   unsigned vec,
-   unsigned chan )
-{
-   sse_movss(
-      func,
-      make_xmm( xmm ),
-      get_immediate( vec, chan ) );
-   sse_shufps(
-      func,
-      make_xmm( xmm ),
-      make_xmm( xmm ),
-      SHUF( 0, 0, 0, 0 ) );
-}
-
-
-/**
- * Copy a shader input to xmm register
- * \param xmm  the destination xmm register
- * \param vec  the src input attrib
- * \param chan  src channel to fetch (X, Y, Z or W)
- */
-static void
-emit_inputf(
-   struct x86_function *func,
-   unsigned xmm,
-   unsigned vec,
-   unsigned chan )
-{
-   sse_movups(
-      func,
-      make_xmm( xmm ),
-      get_input( vec, chan ) );
-}
-
-/**
- * Store an xmm register to a shader output
- * \param xmm  the source xmm register
- * \param vec  the dest output attrib
- * \param chan  src dest channel to store (X, Y, Z or W)
- */
-static void
-emit_output(
-   struct x86_function *func,
-   unsigned xmm,
-   unsigned vec,
-   unsigned chan )
-{
-   sse_movups(
-      func,
-      get_output( vec, chan ),
-      make_xmm( xmm ) );
-}
-
-/**
- * Copy a shader temporary to xmm register
- * \param xmm  the destination xmm register
- * \param vec  the src temp register
- * \param chan  src channel to fetch (X, Y, Z or W)
- */
-static void
-emit_tempf(
-   struct x86_function *func,
-   unsigned xmm,
-   unsigned vec,
-   unsigned chan )
-{
-   sse_movaps(
-      func,
-      make_xmm( xmm ),
-      get_temp( vec, chan ) );
-}
-
-/**
- * Copy a system value to xmm register
- * \param xmm  the destination xmm register
- * \param vec  the source system value register
- * \param chan  src channel to fetch (X, Y, Z or W)
- */
-static void
-emit_system_value(
-   struct x86_function *func,
-   unsigned xmm,
-   unsigned vec,
-   unsigned chan )
-{
-   sse_movss(
-      func,
-      make_xmm( xmm ),
-      get_system_value( vec, chan ) );
-   sse_shufps(
-      func,
-      make_xmm( xmm ),
-      make_xmm( xmm ),
-      SHUF( 0, 0, 0, 0 ) );
-}
-
-/**
- * Load an xmm register with an input attrib coefficient (a0, dadx or dady)
- * \param xmm  the destination xmm register
- * \param vec  the src input/attribute coefficient index
- * \param chan  src channel to fetch (X, Y, Z or W)
- * \param member  0=a0, 1=dadx, 2=dady
- */
-static void
-emit_coef(
-   struct x86_function *func,
-   unsigned xmm,
-   unsigned vec,
-   unsigned chan,
-   unsigned member )
-{
-   sse_movss(
-      func,
-      make_xmm( xmm ),
-      get_coef( vec, chan, member ) );
-   sse_shufps(
-      func,
-      make_xmm( xmm ),
-      make_xmm( xmm ),
-      SHUF( 0, 0, 0, 0 ) );
-}
-
-/**
- * Data store helpers.
- */
-
-static void
-emit_inputs(
-   struct x86_function *func,
-   unsigned xmm,
-   unsigned vec,
-   unsigned chan )
-{
-   sse_movups(
-      func,
-      get_input( vec, chan ),
-      make_xmm( xmm ) );
-}
-
-static void
-emit_temps(
-   struct x86_function *func,
-   unsigned xmm,
-   unsigned vec,
-   unsigned chan )
-{
-   sse_movaps(
-      func,
-      get_temp( vec, chan ),
-      make_xmm( xmm ) );
-}
-
-static void
-emit_addrs(
-   struct x86_function *func,
-   unsigned xmm,
-   unsigned vec,
-   unsigned chan )
-{
-   assert( vec == 0 );
-
-   emit_temps(
-      func,
-      xmm,
-      vec + TGSI_EXEC_TEMP_ADDR,
-      chan );
-}
-
-/**
- * Coefficent fetch helpers.
- */
-
-static void
-emit_coef_a0(
-   struct x86_function *func,
-   unsigned xmm,
-   unsigned vec,
-   unsigned chan )
-{
-   emit_coef(
-      func,
-      xmm,
-      vec,
-      chan,
-      0 );
-}
-
-static void
-emit_coef_dadx(
-   struct x86_function *func,
-   unsigned xmm,
-   unsigned vec,
-   unsigned chan )
-{
-   emit_coef(
-      func,
-      xmm,
-      vec,
-      chan,
-      1 );
-}
-
-static void
-emit_coef_dady(
-   struct x86_function *func,
-   unsigned xmm,
-   unsigned vec,
-   unsigned chan )
-{
-   emit_coef(
-      func,
-      xmm,
-      vec,
-      chan,
-      2 );
-}
-
-/**
- * Function call helpers.
- */
-
-/**
- * NOTE: In gcc, if the destination uses the SSE intrinsics, then it must be 
- * defined with __attribute__((force_align_arg_pointer)), as we do not guarantee
- * that the stack pointer is 16 byte aligned, as expected.
- */
-static void
-emit_func_call(
-   struct x86_function *func,
-   unsigned xmm_save_mask,
-   const struct x86_reg *arg,
-   unsigned nr_args,
-   void (PIPE_CDECL *code)() )
-{
-   struct x86_reg ecx = x86_make_reg( file_REG32, reg_CX );
-   unsigned i, n;
-
-   x86_push(
-      func,
-      x86_make_reg( file_REG32, reg_AX) );
-   x86_push(
-      func,
-      x86_make_reg( file_REG32, reg_CX) );
-   x86_push(
-      func,
-      x86_make_reg( file_REG32, reg_DX) );
-   
-   /* Store XMM regs to the stack
-    */
-   for(i = 0, n = 0; i < 8; ++i)
-      if(xmm_save_mask & (1 << i))
-         ++n;
-   
-   x86_sub_imm(
-      func, 
-      x86_make_reg( file_REG32, reg_SP ),
-      n*16);
-
-   for(i = 0, n = 0; i < 8; ++i)
-      if(xmm_save_mask & (1 << i)) {
-         sse_movups(
-            func,
-            x86_make_disp( x86_make_reg( file_REG32, reg_SP ), n*16 ),
-            make_xmm( i ) );
-         ++n;
-      }
-
-   for (i = 0; i < nr_args; i++) {
-      /* Load the address of the buffer we use for passing arguments and
-       * receiving results:
-       */
-      x86_lea(
-        func,
-        ecx,
-        arg[i] );
-   
-      /* Push actual function arguments (currently just the pointer to
-       * the buffer above), and call the function:
-       */
-      x86_push( func, ecx );
-   }
-
-   x86_mov_reg_imm( func, ecx, (unsigned long) code );
-   x86_call( func, ecx );
-
-   /* Pop the arguments (or just add an immediate to esp)
-    */
-   for (i = 0; i < nr_args; i++) {
-      x86_pop(func, ecx );
-   }
-
-   /* Pop the saved XMM regs:
-    */
-   for(i = 0, n = 0; i < 8; ++i)
-      if(xmm_save_mask & (1 << i)) {
-         sse_movups(
-            func,
-            make_xmm( i ),
-            x86_make_disp( x86_make_reg( file_REG32, reg_SP ), n*16 ) );
-         ++n;
-      }
-   
-   x86_add_imm(
-      func, 
-      x86_make_reg( file_REG32, reg_SP ),
-      n*16);
-
-   /* Restore GP registers in a reverse order.
-    */
-   x86_pop(
-      func,
-      x86_make_reg( file_REG32, reg_DX) );
-   x86_pop(
-      func,
-      x86_make_reg( file_REG32, reg_CX) );
-   x86_pop(
-      func,
-      x86_make_reg( file_REG32, reg_AX) );
-}
-
-static void
-emit_func_call_dst_src1(
-   struct x86_function *func,
-   unsigned xmm_save, 
-   unsigned xmm_dst,
-   unsigned xmm_src0,
-   void (PIPE_CDECL *code)() )
-{
-   struct x86_reg store = get_temp( TEMP_R0, 0 );
-   unsigned xmm_mask = ((1 << xmm_save) - 1) & ~(1 << xmm_dst);
-   
-   /* Store our input parameters (in xmm regs) to the buffer we use
-    * for passing arguments.  We will pass a pointer to this buffer as
-    * the actual function argument.
-    */
-   sse_movaps(
-      func,
-      store,
-      make_xmm( xmm_src0 ) );
-
-   emit_func_call( func,
-                   xmm_mask,
-                   &store,
-                   1,
-                   code );
-
-   sse_movaps(
-      func,
-      make_xmm( xmm_dst ),
-      store );
-}
-
-
-static void
-emit_func_call_dst_src2(
-   struct x86_function *func,
-   unsigned xmm_save, 
-   unsigned xmm_dst,
-   unsigned xmm_src0,
-   unsigned xmm_src1,
-   void (PIPE_CDECL *code)() )
-{
-   struct x86_reg store = get_temp( TEMP_R0, 0 );
-   unsigned xmm_mask = ((1 << xmm_save) - 1) & ~(1 << xmm_dst);
-
-   /* Store two inputs to parameter buffer.
-    */
-   sse_movaps(
-      func,
-      store,
-      make_xmm( xmm_src0 ) );
-
-   sse_movaps(
-      func,
-      x86_make_disp( store, 4 * sizeof(float) ),
-      make_xmm( xmm_src1 ) );
-
-
-   /* Emit the call
-    */
-   emit_func_call( func,
-                   xmm_mask,
-                   &store,
-                   1,
-                   code );
-
-   /* Retrieve the results:
-    */
-   sse_movaps(
-      func,
-      make_xmm( xmm_dst ),
-      store );
-}
-
-
-
-
-
-#if defined(PIPE_ARCH_SSE)
-
-/*
- * Fast SSE2 implementation of special math functions.
- */
-
-#define POLY0(x, c0) _mm_set1_ps(c0)
-#define POLY1(x, c0, c1) _mm_add_ps(_mm_mul_ps(POLY0(x, c1), x), _mm_set1_ps(c0))
-#define POLY2(x, c0, c1, c2) _mm_add_ps(_mm_mul_ps(POLY1(x, c1, c2), x), _mm_set1_ps(c0))
-#define POLY3(x, c0, c1, c2, c3) _mm_add_ps(_mm_mul_ps(POLY2(x, c1, c2, c3), x), _mm_set1_ps(c0))
-#define POLY4(x, c0, c1, c2, c3, c4) _mm_add_ps(_mm_mul_ps(POLY3(x, c1, c2, c3, c4), x), _mm_set1_ps(c0))
-#define POLY5(x, c0, c1, c2, c3, c4, c5) _mm_add_ps(_mm_mul_ps(POLY4(x, c1, c2, c3, c4, c5), x), _mm_set1_ps(c0))
-
-#define EXP_POLY_DEGREE 3
-#define LOG_POLY_DEGREE 5
-
-/**
- * See http://www.devmaster.net/forums/showthread.php?p=43580
- */
-static INLINE __m128 
-exp2f4(__m128 x)
-{
-   __m128i ipart;
-   __m128 fpart, expipart, expfpart;
-
-   x = _mm_min_ps(x, _mm_set1_ps( 129.00000f));
-   x = _mm_max_ps(x, _mm_set1_ps(-126.99999f));
-
-   /* ipart = int(x - 0.5) */
-   ipart = _mm_cvtps_epi32(_mm_sub_ps(x, _mm_set1_ps(0.5f)));
-
-   /* fpart = x - ipart */
-   fpart = _mm_sub_ps(x, _mm_cvtepi32_ps(ipart));
-
-   /* expipart = (float) (1 << ipart) */
-   expipart = _mm_castsi128_ps(_mm_slli_epi32(_mm_add_epi32(ipart, _mm_set1_epi32(127)), 23));
-
-   /* minimax polynomial fit of 2**x, in range [-0.5, 0.5[ */
-#if EXP_POLY_DEGREE == 5
-   expfpart = POLY5(fpart, 9.9999994e-1f, 6.9315308e-1f, 2.4015361e-1f, 5.5826318e-2f, 8.9893397e-3f, 1.8775767e-3f);
-#elif EXP_POLY_DEGREE == 4
-   expfpart = POLY4(fpart, 1.0000026f, 6.9300383e-1f, 2.4144275e-1f, 5.2011464e-2f, 1.3534167e-2f);
-#elif EXP_POLY_DEGREE == 3
-   expfpart = POLY3(fpart, 9.9992520e-1f, 6.9583356e-1f, 2.2606716e-1f, 7.8024521e-2f);
-#elif EXP_POLY_DEGREE == 2
-   expfpart = POLY2(fpart, 1.0017247f, 6.5763628e-1f, 3.3718944e-1f);
-#else
-#error
-#endif
-
-   return _mm_mul_ps(expipart, expfpart);
-}
-
-
-/**
- * See http://www.devmaster.net/forums/showthread.php?p=43580
- */
-static INLINE __m128 
-log2f4(__m128 x)
-{
-   __m128i expmask = _mm_set1_epi32(0x7f800000);
-   __m128i mantmask = _mm_set1_epi32(0x007fffff);
-   __m128 one = _mm_set1_ps(1.0f);
-
-   __m128i i = _mm_castps_si128(x);
-
-   /* exp = (float) exponent(x) */
-   __m128 exp = _mm_cvtepi32_ps(_mm_sub_epi32(_mm_srli_epi32(_mm_and_si128(i, expmask), 23), _mm_set1_epi32(127)));
-
-   /* mant = (float) mantissa(x) */
-   __m128 mant = _mm_or_ps(_mm_castsi128_ps(_mm_and_si128(i, mantmask)), one);
-
-   __m128 logmant;
-
-   /* Minimax polynomial fit of log2(x)/(x - 1), for x in range [1, 2[ 
-    * These coefficients can be generate with 
-    * http://www.boost.org/doc/libs/1_36_0/libs/math/doc/sf_and_dist/html/math_toolkit/toolkit/internals2/minimax.html
-    */
-#if LOG_POLY_DEGREE == 6
-   logmant = POLY5(mant, 3.11578814719469302614f, -3.32419399085241980044f, 2.59883907202499966007f, -1.23152682416275988241f, 0.318212422185251071475f, -0.0344359067839062357313f);
-#elif LOG_POLY_DEGREE == 5
-   logmant = POLY4(mant, 2.8882704548164776201f, -2.52074962577807006663f, 1.48116647521213171641f, -0.465725644288844778798f, 0.0596515482674574969533f);
-#elif LOG_POLY_DEGREE == 4
-   logmant = POLY3(mant, 2.61761038894603480148f, -1.75647175389045657003f, 0.688243882994381274313f, -0.107254423828329604454f);
-#elif LOG_POLY_DEGREE == 3
-   logmant = POLY2(mant, 2.28330284476918490682f, -1.04913055217340124191f, 0.204446009836232697516f);
-#else
-#error
-#endif
-
-   /* This effectively increases the polynomial degree by one, but ensures that log2(1) == 0*/
-   logmant = _mm_mul_ps(logmant, _mm_sub_ps(mant, one));
-
-   return _mm_add_ps(logmant, exp);
-}
-
-
-static INLINE __m128
-powf4(__m128 x, __m128 y)
-{
-   return exp2f4(_mm_mul_ps(log2f4(x), y));
-}
-
-#endif /* PIPE_ARCH_SSE */
-
-
-
-/**
- * Low-level instruction translators.
- */
-
-static void
-emit_abs(
-   struct x86_function *func,
-   unsigned xmm )
-{
-   sse_andps(
-      func,
-      make_xmm( xmm ),
-      get_temp(
-         TGSI_EXEC_TEMP_7FFFFFFF_I,
-         TGSI_EXEC_TEMP_7FFFFFFF_C ) );
-}
-
-static void
-emit_add(
-   struct x86_function *func,
-   unsigned xmm_dst,
-   unsigned xmm_src )
-{
-   sse_addps(
-      func,
-      make_xmm( xmm_dst ),
-      make_xmm( xmm_src ) );
-}
-
-static void PIPE_CDECL
-cos4f(
-   float *store )
-{
-   store[0] = cosf( store[0] );
-   store[1] = cosf( store[1] );
-   store[2] = cosf( store[2] );
-   store[3] = cosf( store[3] );
-}
-
-static void
-emit_cos(
-   struct x86_function *func,
-   unsigned xmm_save, 
-   unsigned xmm_dst )
-{
-   emit_func_call_dst_src1(
-      func,
-      xmm_save, 
-      xmm_dst,
-      xmm_dst,
-      cos4f );
-}
-
-static void PIPE_CDECL
-#if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_SSE)
-__attribute__((force_align_arg_pointer))
-#endif
-ex24f(
-   float *store )
-{
-#if defined(PIPE_ARCH_SSE)
-   _mm_store_ps(&store[0], exp2f4( _mm_load_ps(&store[0]) ));
-#else
-   store[0] = util_fast_exp2( store[0] );
-   store[1] = util_fast_exp2( store[1] );
-   store[2] = util_fast_exp2( store[2] );
-   store[3] = util_fast_exp2( store[3] );
-#endif
-}
-
-static void
-emit_ex2(
-   struct x86_function *func,
-   unsigned xmm_save, 
-   unsigned xmm_dst )
-{
-   emit_func_call_dst_src1(
-      func,
-      xmm_save,
-      xmm_dst,
-      xmm_dst,
-      ex24f );
-}
-
-static void
-emit_f2it(
-   struct x86_function *func,
-   unsigned xmm )
-{
-   sse2_cvttps2dq(
-      func,
-      make_xmm( xmm ),
-      make_xmm( xmm ) );
-}
-
-static void
-emit_i2f(
-   struct x86_function *func,
-   unsigned xmm )
-{
-   sse2_cvtdq2ps(
-      func,
-      make_xmm( xmm ),
-      make_xmm( xmm ) );
-}
-
-static void PIPE_CDECL
-flr4f(
-   float *store )
-{
-   store[0] = floorf( store[0] );
-   store[1] = floorf( store[1] );
-   store[2] = floorf( store[2] );
-   store[3] = floorf( store[3] );
-}
-
-static void
-emit_flr(
-   struct x86_function *func,
-   unsigned xmm_save, 
-   unsigned xmm_dst )
-{
-   emit_func_call_dst_src1(
-      func,
-      xmm_save,
-      xmm_dst,
-      xmm_dst,
-      flr4f );
-}
-
-static void PIPE_CDECL
-frc4f(
-   float *store )
-{
-   store[0] -= floorf( store[0] );
-   store[1] -= floorf( store[1] );
-   store[2] -= floorf( store[2] );
-   store[3] -= floorf( store[3] );
-}
-
-static void
-emit_frc(
-   struct x86_function *func,
-   unsigned xmm_save, 
-   unsigned xmm_dst )
-{
-   emit_func_call_dst_src1(
-      func,
-      xmm_save,
-      xmm_dst,
-      xmm_dst,
-      frc4f );
-}
-
-static void PIPE_CDECL
-#if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_SSE)
-__attribute__((force_align_arg_pointer))
-#endif
-lg24f(
-   float *store )
-{
-#if defined(PIPE_ARCH_SSE)
-   _mm_store_ps(&store[0], log2f4( _mm_load_ps(&store[0]) ));
-#else
-   store[0] = util_fast_log2( store[0] );
-   store[1] = util_fast_log2( store[1] );
-   store[2] = util_fast_log2( store[2] );
-   store[3] = util_fast_log2( store[3] );
-#endif
-}
-
-static void
-emit_lg2(
-   struct x86_function *func,
-   unsigned xmm_save, 
-   unsigned xmm_dst )
-{
-   emit_func_call_dst_src1(
-      func,
-      xmm_save,
-      xmm_dst,
-      xmm_dst,
-      lg24f );
-}
-
-static void
-emit_MOV(
-   struct x86_function *func,
-   unsigned xmm_dst,
-   unsigned xmm_src )
-{
-   sse_movups(
-      func,
-      make_xmm( xmm_dst ),
-      make_xmm( xmm_src ) );
-}
-
-static void
-emit_mul (struct x86_function *func,
-          unsigned xmm_dst,
-          unsigned xmm_src)
-{
-   sse_mulps(
-      func,
-      make_xmm( xmm_dst ),
-      make_xmm( xmm_src ) );
-}
-
-static void
-emit_neg(
-   struct x86_function *func,
-   unsigned xmm )
-{
-   sse_xorps(
-      func,
-      make_xmm( xmm ),
-      get_temp(
-         TGSI_EXEC_TEMP_80000000_I,
-         TGSI_EXEC_TEMP_80000000_C ) );
-}
-
-static void PIPE_CDECL
-#if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_SSE)
-__attribute__((force_align_arg_pointer))
-#endif
-pow4f(
-   float *store )
-{
-#if defined(PIPE_ARCH_SSE)
-   _mm_store_ps(&store[0], powf4( _mm_load_ps(&store[0]), _mm_load_ps(&store[4]) ));
-#else
-   store[0] = util_fast_pow( store[0], store[4] );
-   store[1] = util_fast_pow( store[1], store[5] );
-   store[2] = util_fast_pow( store[2], store[6] );
-   store[3] = util_fast_pow( store[3], store[7] );
-#endif
-}
-
-static void
-emit_pow(
-   struct x86_function *func,
-   unsigned xmm_save, 
-   unsigned xmm_dst,
-   unsigned xmm_src0,
-   unsigned xmm_src1 )
-{
-   emit_func_call_dst_src2(
-      func,
-      xmm_save,
-      xmm_dst,
-      xmm_src0,
-      xmm_src1,
-      pow4f );
-}
-
-static void
-emit_rcp (
-   struct x86_function *func,
-   unsigned xmm_dst,
-   unsigned xmm_src )
-{
-   /* On Intel CPUs at least, this is only accurate to 12 bits -- not
-    * good enough.  Need to either emit a proper divide or use the
-    * iterative technique described below in emit_rsqrt().
-    */
-   sse2_rcpps(
-      func,
-      make_xmm( xmm_dst ),
-      make_xmm( xmm_src ) );
-}
-
-static void PIPE_CDECL
-rnd4f(
-   float *store )
-{
-   store[0] = floorf( store[0] + 0.5f );
-   store[1] = floorf( store[1] + 0.5f );
-   store[2] = floorf( store[2] + 0.5f );
-   store[3] = floorf( store[3] + 0.5f );
-}
-
-static void
-emit_rnd(
-   struct x86_function *func,
-   unsigned xmm_save, 
-   unsigned xmm_dst )
-{
-   emit_func_call_dst_src1(
-      func,
-      xmm_save,
-      xmm_dst,
-      xmm_dst,
-      rnd4f );
-}
-
-static void
-emit_rsqrt(
-   struct x86_function *func,
-   unsigned xmm_dst,
-   unsigned xmm_src )
-{
-#if HIGH_PRECISION
-   /* Although rsqrtps() and rcpps() are low precision on some/all SSE
-    * implementations, it is possible to improve its precision at
-    * fairly low cost, using a newton/raphson step, as below:
-    * 
-    * x1 = 2 * rcpps(a) - a * rcpps(a) * rcpps(a)
-    * x1 = 0.5 * rsqrtps(a) * [3.0 - (a * rsqrtps(a))* rsqrtps(a)]
-    *
-    * See: http://softwarecommunity.intel.com/articles/eng/1818.htm
-    */
-   {
-      struct x86_reg dst = make_xmm( xmm_dst );
-      struct x86_reg src = make_xmm( xmm_src );
-      struct x86_reg tmp0 = make_xmm( 2 );
-      struct x86_reg tmp1 = make_xmm( 3 );
-
-      assert( xmm_dst != xmm_src );
-      assert( xmm_dst != 2 && xmm_dst != 3 );
-      assert( xmm_src != 2 && xmm_src != 3 );
-
-      sse_movaps(  func, dst,  get_temp( TGSI_EXEC_TEMP_HALF_I, TGSI_EXEC_TEMP_HALF_C ) );
-      sse_movaps(  func, tmp0, get_temp( TGSI_EXEC_TEMP_THREE_I, TGSI_EXEC_TEMP_THREE_C ) );
-      sse_rsqrtps( func, tmp1, src  );
-      sse_mulps(   func, src,  tmp1 );
-      sse_mulps(   func, dst,  tmp1 );
-      sse_mulps(   func, src,  tmp1 );
-      sse_subps(   func, tmp0, src  );
-      sse_mulps(   func, dst,  tmp0 );
-   }
-#else
-   /* On Intel CPUs at least, this is only accurate to 12 bits -- not
-    * good enough.
-    */
-   sse_rsqrtps(
-      func,
-      make_xmm( xmm_dst ),
-      make_xmm( xmm_src ) );
-#endif
-}
-
-static void
-emit_setsign(
-   struct x86_function *func,
-   unsigned xmm )
-{
-   sse_orps(
-      func,
-      make_xmm( xmm ),
-      get_temp(
-         TGSI_EXEC_TEMP_80000000_I,
-         TGSI_EXEC_TEMP_80000000_C ) );
-}
-
-static void PIPE_CDECL
-sgn4f(
-   float *store )
-{
-   store[0] = store[0] < 0.0f ? -1.0f : store[0] > 0.0f ? 1.0f : 0.0f;
-   store[1] = store[1] < 0.0f ? -1.0f : store[1] > 0.0f ? 1.0f : 0.0f;
-   store[2] = store[2] < 0.0f ? -1.0f : store[2] > 0.0f ? 1.0f : 0.0f;
-   store[3] = store[3] < 0.0f ? -1.0f : store[3] > 0.0f ? 1.0f : 0.0f;
-}
-
-static void
-emit_sgn(
-   struct x86_function *func,
-   unsigned xmm_save, 
-   unsigned xmm_dst )
-{
-   emit_func_call_dst_src1(
-      func,
-      xmm_save,
-      xmm_dst,
-      xmm_dst,
-      sgn4f );
-}
-
-static void PIPE_CDECL
-sin4f(
-   float *store )
-{
-   store[0] = sinf( store[0] );
-   store[1] = sinf( store[1] );
-   store[2] = sinf( store[2] );
-   store[3] = sinf( store[3] );
-}
-
-static void
-emit_sin (struct x86_function *func,
-          unsigned xmm_save, 
-          unsigned xmm_dst)
-{
-   emit_func_call_dst_src1(
-      func,
-      xmm_save,
-      xmm_dst,
-      xmm_dst,
-      sin4f );
-}
-
-static void
-emit_sub(
-   struct x86_function *func,
-   unsigned xmm_dst,
-   unsigned xmm_src )
-{
-   sse_subps(
-      func,
-      make_xmm( xmm_dst ),
-      make_xmm( xmm_src ) );
-}
-
-/**
- * Register fetch.
- */
-static void
-emit_fetch(
-   struct x86_function *func,
-   unsigned xmm,
-   const struct tgsi_full_src_register *reg,
-   const unsigned chan_index )
-{
-   unsigned swizzle = tgsi_util_get_full_src_register_swizzle( reg, chan_index );
-
-   switch (swizzle) {
-   case TGSI_SWIZZLE_X:
-   case TGSI_SWIZZLE_Y:
-   case TGSI_SWIZZLE_Z:
-   case TGSI_SWIZZLE_W:
-      switch (reg->Register.File) {
-      case TGSI_FILE_CONSTANT:
-         emit_const(
-            func,
-            xmm,
-            reg->Register.Index,
-            swizzle,
-            reg->Register.Indirect,
-            reg->Indirect.File,
-            reg->Indirect.Index );
-         break;
-
-      case TGSI_FILE_IMMEDIATE:
-         emit_immediate(
-            func,
-            xmm,
-            reg->Register.Index,
-            swizzle );
-         break;
-
-      case TGSI_FILE_SYSTEM_VALUE:
-         emit_system_value(
-            func,
-            xmm,
-            reg->Register.Index,
-            swizzle );
-         break;
-
-      case TGSI_FILE_INPUT:
-         emit_inputf(
-            func,
-            xmm,
-            reg->Register.Index,
-            swizzle );
-         break;
-
-      case TGSI_FILE_TEMPORARY:
-         emit_tempf(
-            func,
-            xmm,
-            reg->Register.Index,
-            swizzle );
-         break;
-
-      default:
-         assert( 0 );
-      }
-      break;
-
-   default:
-      assert( 0 );
-   }
-
-   switch( tgsi_util_get_full_src_register_sign_mode( reg, chan_index ) ) {
-   case TGSI_UTIL_SIGN_CLEAR:
-      emit_abs( func, xmm );
-      break;
-
-   case TGSI_UTIL_SIGN_SET:
-      emit_setsign( func, xmm );
-      break;
-
-   case TGSI_UTIL_SIGN_TOGGLE:
-      emit_neg( func, xmm );
-      break;
-
-   case TGSI_UTIL_SIGN_KEEP:
-      break;
-   }
-}
-
-#define FETCH( FUNC, INST, XMM, INDEX, CHAN )\
-   emit_fetch( FUNC, XMM, &(INST).Src[INDEX], CHAN )
-
-/**
- * Register store.
- */
-static void
-emit_store(
-   struct x86_function *func,
-   unsigned xmm,
-   const struct tgsi_full_dst_register *reg,
-   const struct tgsi_full_instruction *inst,
-   unsigned chan_index )
-{
-   switch( inst->Instruction.Saturate ) {
-   case TGSI_SAT_NONE:
-      break;
-
-   case TGSI_SAT_ZERO_ONE:
-      sse_maxps(
-         func,
-         make_xmm( xmm ),
-         get_temp(
-            TGSI_EXEC_TEMP_00000000_I,
-            TGSI_EXEC_TEMP_00000000_C ) );
-
-      sse_minps(
-         func,
-         make_xmm( xmm ),
-         get_temp(
-            TGSI_EXEC_TEMP_ONE_I,
-            TGSI_EXEC_TEMP_ONE_C ) );
-      break;
-
-   case TGSI_SAT_MINUS_PLUS_ONE:
-      assert( 0 );
-      break;
-   }
-
-
-   switch( reg->Register.File ) {
-   case TGSI_FILE_OUTPUT:
-      emit_output(
-         func,
-         xmm,
-         reg->Register.Index,
-         chan_index );
-      break;
-
-   case TGSI_FILE_TEMPORARY:
-      emit_temps(
-         func,
-         xmm,
-         reg->Register.Index,
-         chan_index );
-      break;
-
-   case TGSI_FILE_ADDRESS:
-      emit_addrs(
-         func,
-         xmm,
-         reg->Register.Index,
-         chan_index );
-      break;
-
-   default:
-      assert( 0 );
-   }
-}
-
-#define STORE( FUNC, INST, XMM, INDEX, CHAN )\
-   emit_store( FUNC, XMM, &(INST).Dst[INDEX], &(INST), CHAN )
-
-
-static void PIPE_CDECL
-fetch_texel( struct tgsi_sampler **sampler,
-             float *store )
-{
-#if 0
-   uint j;
-
-   debug_printf("%s sampler: %p (%p) store: %p\n", 
-                __FUNCTION__,
-                sampler, *sampler,
-                store );
-
-   for (j = 0; j < 4; j++)
-      debug_printf("sample %d texcoord %f %f %f lodbias %f\n",
-                   j, 
-                   store[0+j],
-                   store[4+j],
-                   store[8 + j],
-                   store[12 + j]);
-#endif
-
-   {
-      float rgba[NUM_CHANNELS][QUAD_SIZE];
-      (*sampler)->get_samples(*sampler, 
-                              &store[0],  /* s */
-                              &store[4],  /* t */
-                              &store[8],  /* r */
-                              &store[12], /* lodbias */
-                              tgsi_sampler_lod_bias,
-                              rgba);      /* results */
-
-      memcpy( store, rgba, 16 * sizeof(float));
-   }
-
-#if 0
-   for (j = 0; j < 4; j++)
-      debug_printf("sample %d result %f %f %f %f\n", 
-                   j, 
-                   store[0+j],
-                   store[4+j],
-                   store[8+j],
-                   store[12+j]);
-#endif
-}
-
-/**
- * High-level instruction translators.
- */
-static void
-emit_tex( struct x86_function *func,
-          const struct tgsi_full_instruction *inst,
-          boolean lodbias,
-          boolean projected)
-{
-   const uint unit = inst->Src[1].Register.Index;
-   struct x86_reg args[2];
-   unsigned count;
-   unsigned i;
-
-   assert(inst->Instruction.Texture);
-   switch (inst->Texture.Texture) {
-   case TGSI_TEXTURE_1D:
-      count = 1;
-      break;
-   case TGSI_TEXTURE_2D:
-   case TGSI_TEXTURE_RECT:
-   case TGSI_TEXTURE_1D_ARRAY:
-      count = 2;
-      break;
-   case TGSI_TEXTURE_SHADOW1D:
-   case TGSI_TEXTURE_SHADOW2D:
-   case TGSI_TEXTURE_SHADOWRECT:
-   case TGSI_TEXTURE_3D:
-   case TGSI_TEXTURE_CUBE:
-   case TGSI_TEXTURE_2D_ARRAY:
-   case TGSI_TEXTURE_SHADOW1D_ARRAY:
-      count = 3;
-      break;
-   case TGSI_TEXTURE_SHADOW2D_ARRAY:
-      count = 4;
-      break;
-   default:
-      assert(0);
-      return;
-   }
-
-   if (lodbias) {
-      FETCH( func, *inst, 3, 0, 3 );
-   }
-   else {
-      emit_tempf(
-         func,
-         3,
-         TGSI_EXEC_TEMP_00000000_I,
-         TGSI_EXEC_TEMP_00000000_C );
-
-   }
-
-   /* store lodbias whether enabled or not -- fetch_texel currently
-    * respects it always.
-    */
-   sse_movaps( func,
-               get_temp( TEMP_R0, 3 ),
-               make_xmm( 3 ) );
-
-   if (projected) {
-      FETCH( func, *inst, 3, 0, 3 );
-
-      emit_rcp( func, 3, 3 );
-   }
-
-   for (i = 0; i < count; i++) {
-      FETCH( func, *inst, i, 0, i );
-
-      if (projected) {
-         sse_mulps(
-            func,
-            make_xmm( i ),
-            make_xmm( 3 ) );
-      }
-      
-      /* Store in the argument buffer:
-       */
-      sse_movaps(
-         func,
-         get_temp( TEMP_R0, i ),
-         make_xmm( i ) );
-   }
-
-   args[0] = get_temp( TEMP_R0, 0 );
-   args[1] = get_sampler_ptr( unit );
-
-   emit_func_call( func,
-                   0,
-                   args,
-                   Elements(args),
-                   fetch_texel );
-
-   /* If all four channels are enabled, could use a pointer to
-    * dst[0].x instead of TEMP_R0 for store?
-    */
-   FOR_EACH_DST0_ENABLED_CHANNEL( *inst, i ) {
-
-      sse_movaps(
-         func,
-         make_xmm( 0 ),
-         get_temp( TEMP_R0, i ) );
-
-      STORE( func, *inst, 0, 0, i );
-   }
-}
-
-
-static void
-emit_kil(
-   struct x86_function *func,
-   const struct tgsi_full_src_register *reg )
-{
-   unsigned uniquemask;
-   unsigned unique_count = 0;
-   unsigned chan_index;
-   unsigned i;
-
-   /* This mask stores component bits that were already tested. Note that
-    * we test if the value is less than zero, so 1.0 and 0.0 need not to be
-    * tested.
-    */
-   uniquemask = 0;
-
-   FOR_EACH_CHANNEL( chan_index ) {
-      unsigned swizzle;
-
-      /* unswizzle channel */
-      swizzle = tgsi_util_get_full_src_register_swizzle(
-         reg,
-         chan_index );
-
-      /* check if the component has not been already tested */
-      if( !(uniquemask & (1 << swizzle)) ) {
-         uniquemask |= 1 << swizzle;
-
-         /* allocate register */
-         emit_fetch(
-            func,
-            unique_count++,
-            reg,
-            chan_index );
-      }
-   }
-
-   x86_push(
-      func,
-      x86_make_reg( file_REG32, reg_AX ) );
-   x86_push(
-      func,
-      x86_make_reg( file_REG32, reg_DX ) );
-
-   for (i = 0 ; i < unique_count; i++ ) {
-      struct x86_reg dataXMM = make_xmm(i);
-
-      sse_cmpps(
-         func,
-         dataXMM,
-         get_temp(
-            TGSI_EXEC_TEMP_00000000_I,
-            TGSI_EXEC_TEMP_00000000_C ),
-         cc_LessThan );
-      
-      if( i == 0 ) {
-         sse_movmskps(
-            func,
-            x86_make_reg( file_REG32, reg_AX ),
-            dataXMM );
-      }
-      else {
-         sse_movmskps(
-            func,
-            x86_make_reg( file_REG32, reg_DX ),
-            dataXMM );
-         x86_or(
-            func,
-            x86_make_reg( file_REG32, reg_AX ),
-            x86_make_reg( file_REG32, reg_DX ) );
-      }
-   }
-
-   x86_or(
-      func,
-      get_temp(
-         TGSI_EXEC_TEMP_KILMASK_I,
-         TGSI_EXEC_TEMP_KILMASK_C ),
-      x86_make_reg( file_REG32, reg_AX ) );
-
-   x86_pop(
-      func,
-      x86_make_reg( file_REG32, reg_DX ) );
-   x86_pop(
-      func,
-      x86_make_reg( file_REG32, reg_AX ) );
-}
-
-
-static void
-emit_kilp(
-   struct x86_function *func )
-{
-   /* XXX todo / fix me */
-}
-
-
-static void
-emit_setcc(
-   struct x86_function *func,
-   struct tgsi_full_instruction *inst,
-   enum sse_cc cc )
-{
-   unsigned chan_index;
-
-   FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-      FETCH( func, *inst, 0, 0, chan_index );
-      FETCH( func, *inst, 1, 1, chan_index );
-      sse_cmpps(
-         func,
-         make_xmm( 0 ),
-         make_xmm( 1 ),
-         cc );
-      sse_andps(
-         func,
-         make_xmm( 0 ),
-         get_temp(
-            TEMP_ONE_I,
-            TEMP_ONE_C ) );
-      STORE( func, *inst, 0, 0, chan_index );
-   }
-}
-
-static void
-emit_cmp(
-   struct x86_function *func,
-   struct tgsi_full_instruction *inst )
-{
-   unsigned chan_index;
-
-   FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-      FETCH( func, *inst, 0, 0, chan_index );
-      FETCH( func, *inst, 1, 1, chan_index );
-      FETCH( func, *inst, 2, 2, chan_index );
-      sse_cmpps(
-         func,
-         make_xmm( 0 ),
-         get_temp(
-            TGSI_EXEC_TEMP_00000000_I,
-            TGSI_EXEC_TEMP_00000000_C ),
-         cc_LessThan );
-      sse_andps(
-         func,
-         make_xmm( 1 ),
-         make_xmm( 0 ) );
-      sse_andnps(
-         func,
-         make_xmm( 0 ),
-         make_xmm( 2 ) );
-      sse_orps(
-         func,
-         make_xmm( 0 ),
-         make_xmm( 1 ) );
-      STORE( func, *inst, 0, 0, chan_index );
-   }
-}
-
-
-/**
- * Check if inst src/dest regs use indirect addressing into temporary,
- * input or output register files.
- */
-static boolean
-indirect_reg_reference(const struct tgsi_full_instruction *inst)
-{
-   uint i;
-   for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
-      const struct tgsi_full_src_register *reg = &inst->Src[i];
-      if ((reg->Register.File == TGSI_FILE_TEMPORARY ||
-           reg->Register.File == TGSI_FILE_INPUT ||
-           reg->Register.File == TGSI_FILE_OUTPUT) &&
-          reg->Register.Indirect)
-         return TRUE;
-   }
-   for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
-      const struct tgsi_full_dst_register *reg = &inst->Dst[i];
-      if ((reg->Register.File == TGSI_FILE_TEMPORARY ||
-           reg->Register.File == TGSI_FILE_INPUT ||
-           reg->Register.File == TGSI_FILE_OUTPUT) &&
-          reg->Register.Indirect)
-         return TRUE;
-   }
-   return FALSE;
-}
-
-
-static int
-emit_instruction(
-   struct x86_function *func,
-   struct tgsi_full_instruction *inst )
-{
-   unsigned chan_index;
-
-   /* we can't handle indirect addressing into temp register file yet */
-   if (indirect_reg_reference(inst))
-      return FALSE;
-
-   switch (inst->Instruction.Opcode) {
-   case TGSI_OPCODE_ARL:
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( func, *inst, 0, 0, chan_index );
-         emit_flr(func, 0, 0);
-         emit_f2it( func, 0 );
-         STORE( func, *inst, 0, 0, chan_index );
-      }
-      break;
-
-   case TGSI_OPCODE_MOV:
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( func, *inst, 4 + chan_index, 0, chan_index );
-      }
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         STORE( func, *inst, 4 + chan_index, 0, chan_index );
-      }
-      break;
-
-   case TGSI_OPCODE_LIT:
-      if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) ||
-          IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) ) {
-         emit_tempf(
-            func,
-            0,
-            TEMP_ONE_I,
-            TEMP_ONE_C);
-         if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) ) {
-            STORE( func, *inst, 0, 0, CHAN_X );
-         }
-         if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) ) {
-            STORE( func, *inst, 0, 0, CHAN_W );
-         }
-      }
-      if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ||
-          IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) {
-         if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ) {
-            FETCH( func, *inst, 0, 0, CHAN_X );
-            sse_maxps(
-               func,
-               make_xmm( 0 ),
-               get_temp(
-                  TGSI_EXEC_TEMP_00000000_I,
-                  TGSI_EXEC_TEMP_00000000_C ) );
-            STORE( func, *inst, 0, 0, CHAN_Y );
-         }
-         if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) {
-            /* XMM[1] = SrcReg[0].yyyy */
-            FETCH( func, *inst, 1, 0, CHAN_Y );
-            /* XMM[1] = max(XMM[1], 0) */
-            sse_maxps(
-               func,
-               make_xmm( 1 ),
-               get_temp(
-                  TGSI_EXEC_TEMP_00000000_I,
-                  TGSI_EXEC_TEMP_00000000_C ) );
-            /* XMM[2] = SrcReg[0].wwww */
-            FETCH( func, *inst, 2, 0, CHAN_W );
-            /* XMM[2] = min(XMM[2], 128.0) */
-            sse_minps(
-               func,
-               make_xmm( 2 ),
-               get_temp(
-                  TGSI_EXEC_TEMP_128_I,
-                  TGSI_EXEC_TEMP_128_C ) );
-            /* XMM[2] = max(XMM[2], -128.0) */
-            sse_maxps(
-               func,
-               make_xmm( 2 ),
-               get_temp(
-                  TGSI_EXEC_TEMP_MINUS_128_I,
-                  TGSI_EXEC_TEMP_MINUS_128_C ) );
-            emit_pow( func, 3, 1, 1, 2 );
-            FETCH( func, *inst, 0, 0, CHAN_X );
-            sse_xorps(
-               func,
-               make_xmm( 2 ),
-               make_xmm( 2 ) );
-            sse_cmpps(
-               func,
-               make_xmm( 2 ),
-               make_xmm( 0 ),
-               cc_LessThan );
-            sse_andps(
-               func,
-               make_xmm( 2 ),
-               make_xmm( 1 ) );
-            STORE( func, *inst, 2, 0, CHAN_Z );
-         }
-      }
-      break;
-
-   case TGSI_OPCODE_RCP:
-      FETCH( func, *inst, 0, 0, CHAN_X );
-      emit_rcp( func, 0, 0 );
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         STORE( func, *inst, 0, 0, chan_index );
-      }
-      break;
-
-   case TGSI_OPCODE_RSQ:
-      FETCH( func, *inst, 0, 0, CHAN_X );
-      emit_abs( func, 0 );
-      emit_rsqrt( func, 1, 0 );
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         STORE( func, *inst, 1, 0, chan_index );
-      }
-      break;
-
-   case TGSI_OPCODE_EXP:
-      if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) ||
-          IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ||
-          IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z )) {
-         FETCH( func, *inst, 0, 0, CHAN_X );
-         if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) ||
-             IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y )) {
-            emit_MOV( func, 1, 0 );
-            emit_flr( func, 2, 1 );
-            /* dst.x = ex2(floor(src.x)) */
-            if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X )) {
-               emit_MOV( func, 2, 1 );
-               emit_ex2( func, 3, 2 );
-               STORE( func, *inst, 2, 0, CHAN_X );
-            }
-            /* dst.y = src.x - floor(src.x) */
-            if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y )) {
-               emit_MOV( func, 2, 0 );
-               emit_sub( func, 2, 1 );
-               STORE( func, *inst, 2, 0, CHAN_Y );
-            }
-         }
-         /* dst.z = ex2(src.x) */
-         if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z )) {
-            emit_ex2( func, 3, 0 );
-            STORE( func, *inst, 0, 0, CHAN_Z );
-         }
-      }
-      /* dst.w = 1.0 */
-      if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W )) {
-         emit_tempf( func, 0, TEMP_ONE_I, TEMP_ONE_C );
-         STORE( func, *inst, 0, 0, CHAN_W );
-      }
-      break;
-
-   case TGSI_OPCODE_LOG:
-      if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) ||
-          IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ||
-          IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z )) {
-         FETCH( func, *inst, 0, 0, CHAN_X );
-         emit_abs( func, 0 );
-         emit_MOV( func, 1, 0 );
-         emit_lg2( func, 2, 1 );
-         /* dst.z = lg2(abs(src.x)) */
-         if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z )) {
-            STORE( func, *inst, 1, 0, CHAN_Z );
-         }
-         if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) ||
-             IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y )) {
-            emit_flr( func, 2, 1 );
-            /* dst.x = floor(lg2(abs(src.x))) */
-            if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X )) {
-               STORE( func, *inst, 1, 0, CHAN_X );
-            }
-            /* dst.x = abs(src)/ex2(floor(lg2(abs(src.x)))) */
-            if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y )) {
-               emit_ex2( func, 2, 1 );
-               emit_rcp( func, 1, 1 );
-               emit_mul( func, 0, 1 );
-               STORE( func, *inst, 0, 0, CHAN_Y );
-            }
-         }
-      }
-      /* dst.w = 1.0 */
-      if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W )) {
-         emit_tempf( func, 0, TEMP_ONE_I, TEMP_ONE_C );
-         STORE( func, *inst, 0, 0, CHAN_W );
-      }
-      break;
-
-   case TGSI_OPCODE_MUL:
-      /* do all fetches and adds, storing results in temp regs */
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         int r = chan_index + 1;
-         FETCH( func, *inst, 0, 0, chan_index ); /* load xmm[0] */
-         FETCH( func, *inst, r, 1, chan_index ); /* load xmm[r] */
-         emit_mul( func, r, 0 );   /* xmm[r] = xmm[r] * xmm[0] */
-      }
-      /* do all stores of the temp regs */
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         int r = chan_index + 1;
-         STORE( func, *inst, r, 0, chan_index ); /* store xmm[r] */
-      }
-      break;
-
-   case TGSI_OPCODE_ADD:
-      /* do all fetches and adds, storing results in temp regs */
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         int r = chan_index + 1;
-         FETCH( func, *inst, 0, 0, chan_index ); /* load xmm[0] */
-         FETCH( func, *inst, r, 1, chan_index ); /* load xmm[r] */
-         emit_add( func, r, 0 );   /* xmm[r] = xmm[r] + xmm[0] */
-      }
-      /* do all stores of the temp regs */
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         int r = chan_index + 1;
-         STORE( func, *inst, r, 0, chan_index ); /* store xmm[r] */
-      }
-      break;
-
-   case TGSI_OPCODE_DP3:
-      FETCH( func, *inst, 0, 0, CHAN_X );
-      FETCH( func, *inst, 1, 1, CHAN_X );
-      emit_mul( func, 0, 1 );
-      FETCH( func, *inst, 1, 0, CHAN_Y );
-      FETCH( func, *inst, 2, 1, CHAN_Y );
-      emit_mul( func, 1, 2 );
-      emit_add( func, 0, 1 );
-      FETCH( func, *inst, 1, 0, CHAN_Z );
-      FETCH( func, *inst, 2, 1, CHAN_Z );
-      emit_mul( func, 1, 2 );
-      emit_add( func, 0, 1 );
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         STORE( func, *inst, 0, 0, chan_index );
-      }
-      break;
-
-   case TGSI_OPCODE_DP4:
-      FETCH( func, *inst, 0, 0, CHAN_X );
-      FETCH( func, *inst, 1, 1, CHAN_X );
-      emit_mul( func, 0, 1 );
-      FETCH( func, *inst, 1, 0, CHAN_Y );
-      FETCH( func, *inst, 2, 1, CHAN_Y );
-      emit_mul( func, 1, 2 );
-      emit_add( func, 0, 1 );
-      FETCH( func, *inst, 1, 0, CHAN_Z );
-      FETCH( func, *inst, 2, 1, CHAN_Z );
-      emit_mul(func, 1, 2 );
-      emit_add(func, 0, 1 );
-      FETCH( func, *inst, 1, 0, CHAN_W );
-      FETCH( func, *inst, 2, 1, CHAN_W );
-      emit_mul( func, 1, 2 );
-      emit_add( func, 0, 1 );
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         STORE( func, *inst, 0, 0, chan_index );
-      }
-      break;
-
-   case TGSI_OPCODE_DST:
-      IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) {
-         emit_tempf(
-            func,
-            0,
-            TEMP_ONE_I,
-            TEMP_ONE_C );
-         STORE( func, *inst, 0, 0, CHAN_X );
-      }
-      IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) {
-         FETCH( func, *inst, 0, 0, CHAN_Y );
-         FETCH( func, *inst, 1, 1, CHAN_Y );
-         emit_mul( func, 0, 1 );
-         STORE( func, *inst, 0, 0, CHAN_Y );
-      }
-      IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) {
-         FETCH( func, *inst, 0, 0, CHAN_Z );
-         STORE( func, *inst, 0, 0, CHAN_Z );
-      }
-      IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) {
-         FETCH( func, *inst, 0, 1, CHAN_W );
-         STORE( func, *inst, 0, 0, CHAN_W );
-      }
-      break;
-
-   case TGSI_OPCODE_MIN:
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( func, *inst, 0, 0, chan_index );
-         FETCH( func, *inst, 1, 1, chan_index );
-         sse_minps(
-            func,
-            make_xmm( 0 ),
-            make_xmm( 1 ) );
-         STORE( func, *inst, 0, 0, chan_index );
-      }
-      break;
-
-   case TGSI_OPCODE_MAX:
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( func, *inst, 0, 0, chan_index );
-         FETCH( func, *inst, 1, 1, chan_index );
-         sse_maxps(
-            func,
-            make_xmm( 0 ),
-            make_xmm( 1 ) );
-         STORE( func, *inst, 0, 0, chan_index );
-      }
-      break;
-
-   case TGSI_OPCODE_SLT:
-      emit_setcc( func, inst, cc_LessThan );
-      break;
-
-   case TGSI_OPCODE_SGE:
-      emit_setcc( func, inst, cc_NotLessThan );
-      break;
-
-   case TGSI_OPCODE_MAD:
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( func, *inst, 0, 0, chan_index );
-         FETCH( func, *inst, 1, 1, chan_index );
-         FETCH( func, *inst, 2, 2, chan_index );
-         emit_mul( func, 0, 1 );
-         emit_add( func, 0, 2 );
-         STORE( func, *inst, 0, 0, chan_index );
-      }
-      break;
-
-   case TGSI_OPCODE_SUB:
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( func, *inst, 0, 0, chan_index );
-         FETCH( func, *inst, 1, 1, chan_index );
-         emit_sub( func, 0, 1 );
-         STORE( func, *inst, 0, 0, chan_index );
-      }
-      break;
-
-   case TGSI_OPCODE_LRP:
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( func, *inst, 0, 0, chan_index );
-         FETCH( func, *inst, 1, 1, chan_index );
-         FETCH( func, *inst, 2, 2, chan_index );
-         emit_sub( func, 1, 2 );
-         emit_mul( func, 0, 1 );
-         emit_add( func, 0, 2 );
-         STORE( func, *inst, 0, 0, chan_index );
-      }
-      break;
-
-   case TGSI_OPCODE_CND:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_DP2A:
-      FETCH( func, *inst, 0, 0, CHAN_X );  /* xmm0 = src[0].x */
-      FETCH( func, *inst, 1, 1, CHAN_X );  /* xmm1 = src[1].x */
-      emit_mul( func, 0, 1 );              /* xmm0 = xmm0 * xmm1 */
-      FETCH( func, *inst, 1, 0, CHAN_Y );  /* xmm1 = src[0].y */
-      FETCH( func, *inst, 2, 1, CHAN_Y );  /* xmm2 = src[1].y */
-      emit_mul( func, 1, 2 );              /* xmm1 = xmm1 * xmm2 */
-      emit_add( func, 0, 1 );              /* xmm0 = xmm0 + xmm1 */
-      FETCH( func, *inst, 1, 2, CHAN_X );  /* xmm1 = src[2].x */
-      emit_add( func, 0, 1 );              /* xmm0 = xmm0 + xmm1 */
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         STORE( func, *inst, 0, 0, chan_index );  /* dest[ch] = xmm0 */
-      }
-      break;
-
-   case TGSI_OPCODE_FRC:
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( func, *inst, 0, 0, chan_index );
-         emit_frc( func, 0, 0 );
-         STORE( func, *inst, 0, 0, chan_index );
-      }
-      break;
-
-   case TGSI_OPCODE_CLAMP:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_FLR:
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( func, *inst, 0, 0, chan_index );
-         emit_flr( func, 0, 0 );
-         STORE( func, *inst, 0, 0, chan_index );
-      }
-      break;
-
-   case TGSI_OPCODE_ROUND:
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( func, *inst, 0, 0, chan_index );
-         emit_rnd( func, 0, 0 );
-         STORE( func, *inst, 0, 0, chan_index );
-      }
-      break;
-
-   case TGSI_OPCODE_EX2:
-      FETCH( func, *inst, 0, 0, CHAN_X );
-      emit_ex2( func, 0, 0 );
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         STORE( func, *inst, 0, 0, chan_index );
-      }
-      break;
-
-   case TGSI_OPCODE_LG2:
-      FETCH( func, *inst, 0, 0, CHAN_X );
-      emit_lg2( func, 0, 0 );
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         STORE( func, *inst, 0, 0, chan_index );
-      }
-      break;
-
-   case TGSI_OPCODE_POW:
-      FETCH( func, *inst, 0, 0, CHAN_X );
-      FETCH( func, *inst, 1, 1, CHAN_X );
-      emit_pow( func, 0, 0, 0, 1 );
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         STORE( func, *inst, 0, 0, chan_index );
-      }
-      break;
-
-   case TGSI_OPCODE_XPD:
-      /* Note: we do all stores after all operands have been fetched
-       * to avoid src/dst register aliasing issues for an instruction
-       * such as:  XPD TEMP[2].xyz, TEMP[0], TEMP[2];
-       */
-      if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) ||
-          IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ) {
-         FETCH( func, *inst, 1, 1, CHAN_Z ); /* xmm[1] = src[1].z */
-         FETCH( func, *inst, 3, 0, CHAN_Z ); /* xmm[3] = src[0].z */
-      }
-      if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) ||
-          IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) {
-         FETCH( func, *inst, 0, 0, CHAN_Y ); /* xmm[0] = src[0].y */
-         FETCH( func, *inst, 4, 1, CHAN_Y ); /* xmm[4] = src[1].y */
-      }
-      IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) {
-         emit_MOV( func, 7, 0 );  /* xmm[7] = xmm[0] */
-         emit_mul( func, 7, 1 );  /* xmm[7] = xmm[2] * xmm[1] */
-         emit_MOV( func, 5, 3 );  /* xmm[5] = xmm[3] */
-         emit_mul( func, 5, 4 );  /* xmm[5] = xmm[5] * xmm[4] */
-         emit_sub( func, 7, 5 );  /* xmm[7] = xmm[2] - xmm[5] */
-         /* store xmm[7] in dst.x below */
-      }
-      if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ||
-          IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) {
-         FETCH( func, *inst, 2, 1, CHAN_X ); /* xmm[2] = src[1].x */
-         FETCH( func, *inst, 5, 0, CHAN_X ); /* xmm[5] = src[0].x */
-      }
-      IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) {
-         emit_mul( func, 3, 2 );  /* xmm[3] = xmm[3] * xmm[2] */
-         emit_mul( func, 1, 5 );  /* xmm[1] = xmm[1] * xmm[5] */
-         emit_sub( func, 3, 1 );  /* xmm[3] = xmm[3] - xmm[1] */
-         /* store xmm[3] in dst.y below */
-      }
-      IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) {
-         emit_mul( func, 5, 4 );  /* xmm[5] = xmm[5] * xmm[4] */
-         emit_mul( func, 0, 2 );  /* xmm[0] = xmm[0] * xmm[2] */
-         emit_sub( func, 5, 0 );  /* xmm[5] = xmm[5] - xmm[0] */
-         STORE( func, *inst, 5, 0, CHAN_Z ); /* dst.z = xmm[5] */
-      }
-      IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) {
-         STORE( func, *inst, 7, 0, CHAN_X ); /* dst.x = xmm[7] */
-      }
-      IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) {
-         STORE( func, *inst, 3, 0, CHAN_Y ); /* dst.y = xmm[3] */
-      }
-      IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) {
-        emit_tempf(
-           func,
-           0,
-           TEMP_ONE_I,
-           TEMP_ONE_C );
-         STORE( func, *inst, 0, 0, CHAN_W );
-      }
-      break;
-
-   case TGSI_OPCODE_ABS:
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( func, *inst, 0, 0, chan_index );
-         emit_abs( func, 0) ;
-
-         STORE( func, *inst, 0, 0, chan_index );
-      }
-      break;
-
-   case TGSI_OPCODE_RCC:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_DPH:
-      FETCH( func, *inst, 0, 0, CHAN_X );
-      FETCH( func, *inst, 1, 1, CHAN_X );
-      emit_mul( func, 0, 1 );
-      FETCH( func, *inst, 1, 0, CHAN_Y );
-      FETCH( func, *inst, 2, 1, CHAN_Y );
-      emit_mul( func, 1, 2 );
-      emit_add( func, 0, 1 );
-      FETCH( func, *inst, 1, 0, CHAN_Z );
-      FETCH( func, *inst, 2, 1, CHAN_Z );
-      emit_mul( func, 1, 2 );
-      emit_add( func, 0, 1 );
-      FETCH( func, *inst, 1, 1, CHAN_W );
-      emit_add( func, 0, 1 );
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         STORE( func, *inst, 0, 0, chan_index );
-      }
-      break;
-
-   case TGSI_OPCODE_COS:
-      FETCH( func, *inst, 0, 0, CHAN_X );
-      emit_cos( func, 0, 0 );
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         STORE( func, *inst, 0, 0, chan_index );
-      }
-      break;
-
-   case TGSI_OPCODE_DDX:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_DDY:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_KILP:
-      /* predicated kill */
-      emit_kilp( func );
-      return 0; /* XXX fix me */
-      break;
-
-   case TGSI_OPCODE_KIL:
-      /* conditional kill */
-      emit_kil( func, &inst->Src[0] );
-      break;
-
-   case TGSI_OPCODE_PK2H:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_PK2US:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_PK4B:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_PK4UB:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_RFL:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_SEQ:
-      emit_setcc( func, inst, cc_Equal );
-      break;
-
-   case TGSI_OPCODE_SFL:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_SGT:
-      emit_setcc( func, inst, cc_NotLessThanEqual );
-      break;
-
-   case TGSI_OPCODE_SIN:
-      FETCH( func, *inst, 0, 0, CHAN_X );
-      emit_sin( func, 0, 0 );
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         STORE( func, *inst, 0, 0, chan_index );
-      }
-      break;
-
-   case TGSI_OPCODE_SLE:
-      emit_setcc( func, inst, cc_LessThanEqual );
-      break;
-
-   case TGSI_OPCODE_SNE:
-      emit_setcc( func, inst, cc_NotEqual );
-      break;
-
-   case TGSI_OPCODE_STR:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_TEX:
-      emit_tex( func, inst, FALSE, FALSE );
-      break;
-
-   case TGSI_OPCODE_TXD:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_UP2H:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_UP2US:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_UP4B:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_UP4UB:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_X2D:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_ARA:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_ARR:
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( func, *inst, 0, 0, chan_index );
-         emit_rnd( func, 0, 0 );
-         emit_f2it( func, 0 );
-         STORE( func, *inst, 0, 0, chan_index );
-      }
-      break;
-
-   case TGSI_OPCODE_BRA:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_CAL:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_RET:
-      emit_ret( func );
-      break;
-
-   case TGSI_OPCODE_END:
-      break;
-
-   case TGSI_OPCODE_SSG:
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( func, *inst, 0, 0, chan_index );
-         emit_sgn( func, 0, 0 );
-         STORE( func, *inst, 0, 0, chan_index );
-      }
-      break;
-
-   case TGSI_OPCODE_CMP:
-      emit_cmp (func, inst);
-      break;
-
-   case TGSI_OPCODE_SCS:
-      IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) {
-         FETCH( func, *inst, 0, 0, CHAN_X );
-         emit_cos( func, 0, 0 );
-         STORE( func, *inst, 0, 0, CHAN_X );
-      }
-      IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) {
-         FETCH( func, *inst, 0, 0, CHAN_X );
-         emit_sin( func, 0, 0 );
-         STORE( func, *inst, 0, 0, CHAN_Y );
-      }
-      IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) {
-        emit_tempf(
-           func,
-           0,
-           TGSI_EXEC_TEMP_00000000_I,
-           TGSI_EXEC_TEMP_00000000_C );
-         STORE( func, *inst, 0, 0, CHAN_Z );
-      }
-      IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) {
-        emit_tempf(
-           func,
-           0,
-           TEMP_ONE_I,
-           TEMP_ONE_C );
-         STORE( func, *inst, 0, 0, CHAN_W );
-      }
-      break;
-
-   case TGSI_OPCODE_TXB:
-      emit_tex( func, inst, TRUE, FALSE );
-      break;
-
-   case TGSI_OPCODE_NRM:
-      /* fall-through */
-   case TGSI_OPCODE_NRM4:
-      /* 3 or 4-component normalization */
-      {
-         uint dims = (inst->Instruction.Opcode == TGSI_OPCODE_NRM) ? 3 : 4;
-
-         if (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_X) ||
-             IS_DST0_CHANNEL_ENABLED(*inst, CHAN_Y) ||
-             IS_DST0_CHANNEL_ENABLED(*inst, CHAN_Z) ||
-             (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_W) && dims == 4)) {
-
-            /* NOTE: Cannot use xmm regs 2/3 here (see emit_rsqrt() above). */
-
-            /* xmm4 = src.x */
-            /* xmm0 = src.x * src.x */
-            FETCH(func, *inst, 0, 0, CHAN_X);
-            if (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_X)) {
-               emit_MOV(func, 4, 0);
-            }
-            emit_mul(func, 0, 0);
-
-            /* xmm5 = src.y */
-            /* xmm0 = xmm0 + src.y * src.y */
-            FETCH(func, *inst, 1, 0, CHAN_Y);
-            if (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_Y)) {
-               emit_MOV(func, 5, 1);
-            }
-            emit_mul(func, 1, 1);
-            emit_add(func, 0, 1);
-
-            /* xmm6 = src.z */
-            /* xmm0 = xmm0 + src.z * src.z */
-            FETCH(func, *inst, 1, 0, CHAN_Z);
-            if (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_Z)) {
-               emit_MOV(func, 6, 1);
-            }
-            emit_mul(func, 1, 1);
-            emit_add(func, 0, 1);
-
-            if (dims == 4) {
-               /* xmm7 = src.w */
-               /* xmm0 = xmm0 + src.w * src.w */
-               FETCH(func, *inst, 1, 0, CHAN_W);
-               if (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_W)) {
-                  emit_MOV(func, 7, 1);
-               }
-               emit_mul(func, 1, 1);
-               emit_add(func, 0, 1);
-            }
-
-            /* xmm1 = 1 / sqrt(xmm0) */
-            emit_rsqrt(func, 1, 0);
-
-            /* dst.x = xmm1 * src.x */
-            if (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_X)) {
-               emit_mul(func, 4, 1);
-               STORE(func, *inst, 4, 0, CHAN_X);
-            }
-
-            /* dst.y = xmm1 * src.y */
-            if (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_Y)) {
-               emit_mul(func, 5, 1);
-               STORE(func, *inst, 5, 0, CHAN_Y);
-            }
-
-            /* dst.z = xmm1 * src.z */
-            if (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_Z)) {
-               emit_mul(func, 6, 1);
-               STORE(func, *inst, 6, 0, CHAN_Z);
-            }
-
-            /* dst.w = xmm1 * src.w */
-            if (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_X) && dims == 4) {
-               emit_mul(func, 7, 1);
-               STORE(func, *inst, 7, 0, CHAN_W);
-            }
-         }
-
-         /* dst0.w = 1.0 */
-         if (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_W) && dims == 3) {
-            emit_tempf(func, 0, TEMP_ONE_I, TEMP_ONE_C);
-            STORE(func, *inst, 0, 0, CHAN_W);
-         }
-      }
-      break;
-
-   case TGSI_OPCODE_DIV:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_DP2:
-      FETCH( func, *inst, 0, 0, CHAN_X );  /* xmm0 = src[0].x */
-      FETCH( func, *inst, 1, 1, CHAN_X );  /* xmm1 = src[1].x */
-      emit_mul( func, 0, 1 );              /* xmm0 = xmm0 * xmm1 */
-      FETCH( func, *inst, 1, 0, CHAN_Y );  /* xmm1 = src[0].y */
-      FETCH( func, *inst, 2, 1, CHAN_Y );  /* xmm2 = src[1].y */
-      emit_mul( func, 1, 2 );              /* xmm1 = xmm1 * xmm2 */
-      emit_add( func, 0, 1 );              /* xmm0 = xmm0 + xmm1 */
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         STORE( func, *inst, 0, 0, chan_index );  /* dest[ch] = xmm0 */
-      }
-      break;
-
-   case TGSI_OPCODE_TXL:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_TXP:
-      emit_tex( func, inst, FALSE, TRUE );
-      break;
-      
-   case TGSI_OPCODE_BRK:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_IF:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_ELSE:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_ENDIF:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_PUSHA:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_POPA:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_CEIL:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_I2F:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_NOT:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_TRUNC:
-      FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( func, *inst, 0, 0, chan_index );
-         emit_f2it( func, 0 );
-         emit_i2f( func, 0 );
-         STORE( func, *inst, 0, 0, chan_index );
-      }
-      break;
-
-   case TGSI_OPCODE_SHL:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_ISHR:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_AND:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_OR:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_MOD:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_XOR:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_SAD:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_TXF:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_TXQ:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_CONT:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_EMIT:
-      return 0;
-      break;
-
-   case TGSI_OPCODE_ENDPRIM:
-      return 0;
-      break;
-
-   default:
-      return 0;
-   }
-   
-   return 1;
-}
-
-static void
-emit_declaration(
-   struct x86_function *func,
-   struct tgsi_full_declaration *decl )
-{
-   if( decl->Declaration.File == TGSI_FILE_INPUT ) {
-      unsigned first, last, mask;
-      unsigned i, j;
-
-      first = decl->Range.First;
-      last = decl->Range.Last;
-      mask = decl->Declaration.UsageMask;
-
-      for( i = first; i <= last; i++ ) {
-         for( j = 0; j < NUM_CHANNELS; j++ ) {
-            if( mask & (1 << j) ) {
-               switch( decl->Declaration.Interpolate ) {
-               case TGSI_INTERPOLATE_CONSTANT:
-                  emit_coef_a0( func, 0, i, j );
-                  emit_inputs( func, 0, i, j );
-                  break;
-
-               case TGSI_INTERPOLATE_LINEAR:
-                  emit_tempf( func, 0, 0, TGSI_SWIZZLE_X );
-                  emit_coef_dadx( func, 1, i, j );
-                  emit_tempf( func, 2, 0, TGSI_SWIZZLE_Y );
-                  emit_coef_dady( func, 3, i, j );
-                  emit_mul( func, 0, 1 );    /* x * dadx */
-                  emit_coef_a0( func, 4, i, j );
-                  emit_mul( func, 2, 3 );    /* y * dady */
-                  emit_add( func, 0, 4 );    /* x * dadx + a0 */
-                  emit_add( func, 0, 2 );    /* x * dadx + y * dady + a0 */
-                  emit_inputs( func, 0, i, j );
-                  break;
-
-               case TGSI_INTERPOLATE_PERSPECTIVE:
-                  emit_tempf( func, 0, 0, TGSI_SWIZZLE_X );
-                  emit_coef_dadx( func, 1, i, j );
-                  emit_tempf( func, 2, 0, TGSI_SWIZZLE_Y );
-                  emit_coef_dady( func, 3, i, j );
-                  emit_mul( func, 0, 1 );    /* x * dadx */
-                  emit_tempf( func, 4, 0, TGSI_SWIZZLE_W );
-                  emit_coef_a0( func, 5, i, j );
-                  emit_rcp( func, 4, 4 );    /* 1.0 / w */
-                  emit_mul( func, 2, 3 );    /* y * dady */
-                  emit_add( func, 0, 5 );    /* x * dadx + a0 */
-                  emit_add( func, 0, 2 );    /* x * dadx + y * dady + a0 */
-                  emit_mul( func, 0, 4 );    /* (x * dadx + y * dady + a0) / w */
-                  emit_inputs( func, 0, i, j );
-                  break;
-
-               default:
-                  assert( 0 );
-                 break;
-               }
-            }
-         }
-      }
-   }
-}
-
-static void aos_to_soa( struct x86_function *func, 
-                        uint arg_aos,
-                        uint arg_machine, 
-                        uint arg_num, 
-                        uint arg_stride )
-{
-   struct x86_reg soa_input = x86_make_reg( file_REG32, reg_AX );
-   struct x86_reg aos_input = x86_make_reg( file_REG32, reg_BX );
-   struct x86_reg num_inputs = x86_make_reg( file_REG32, reg_CX );
-   struct x86_reg stride = x86_make_reg( file_REG32, reg_DX );
-   int loop_top, loop_exit_fixup;
-
-   /* Save EBX */
-   x86_push( func, x86_make_reg( file_REG32, reg_BX ) );
-
-   x86_mov( func, aos_input,  x86_fn_arg( func, arg_aos ) );
-   x86_mov( func, soa_input,  x86_fn_arg( func, arg_machine ) );
-   /* FIXME: tgsi_exec_machine::Inputs is a pointer now! */
-   x86_lea( func, soa_input,  
-           x86_make_disp( soa_input, 
-                          Offset(struct tgsi_exec_machine, Inputs) ) );
-   x86_mov( func, num_inputs, x86_fn_arg( func, arg_num ) );
-   x86_mov( func, stride,     x86_fn_arg( func, arg_stride ) );
-
-   /* while (num_inputs != 0) */
-   loop_top = x86_get_label( func );
-   x86_cmp_imm( func, num_inputs, 0 );
-   loop_exit_fixup = x86_jcc_forward( func, cc_E );
-
-   {
-      x86_push( func, aos_input );
-      sse_movlps( func, make_xmm( 0 ), x86_make_disp( aos_input, 0 ) );
-      sse_movlps( func, make_xmm( 3 ), x86_make_disp( aos_input, 8 ) );
-      x86_add( func, aos_input, stride );
-      sse_movhps( func, make_xmm( 0 ), x86_make_disp( aos_input, 0 ) );
-      sse_movhps( func, make_xmm( 3 ), x86_make_disp( aos_input, 8 ) );
-      x86_add( func, aos_input, stride );
-      sse_movlps( func, make_xmm( 1 ), x86_make_disp( aos_input, 0 ) );
-      sse_movlps( func, make_xmm( 4 ), x86_make_disp( aos_input, 8 ) );
-      x86_add( func, aos_input, stride );
-      sse_movhps( func, make_xmm( 1 ), x86_make_disp( aos_input, 0 ) );
-      sse_movhps( func, make_xmm( 4 ), x86_make_disp( aos_input, 8 ) );
-      x86_pop( func, aos_input );
-
-      sse_movaps( func, make_xmm( 2 ), make_xmm( 0 ) );
-      sse_movaps( func, make_xmm( 5 ), make_xmm( 3 ) );
-      sse_shufps( func, make_xmm( 0 ), make_xmm( 1 ), 0x88 );
-      sse_shufps( func, make_xmm( 2 ), make_xmm( 1 ), 0xdd );
-      sse_shufps( func, make_xmm( 3 ), make_xmm( 4 ), 0x88 );
-      sse_shufps( func, make_xmm( 5 ), make_xmm( 4 ), 0xdd );
-
-      sse_movups( func, x86_make_disp( soa_input, 0 ), make_xmm( 0 ) );
-      sse_movups( func, x86_make_disp( soa_input, 16 ), make_xmm( 2 ) );
-      sse_movups( func, x86_make_disp( soa_input, 32 ), make_xmm( 3 ) );
-      sse_movups( func, x86_make_disp( soa_input, 48 ), make_xmm( 5 ) );
-
-      /* Advance to next input */
-      x86_lea( func, aos_input, x86_make_disp(aos_input, 16) );
-      x86_lea( func, soa_input, x86_make_disp(soa_input, 64) );
-   }
-   /* --num_inputs */
-   x86_dec( func, num_inputs );
-   x86_jmp( func, loop_top );
-   x86_fixup_fwd_jump( func, loop_exit_fixup );
-
-   /* Restore EBX */
-   x86_pop( func, x86_make_reg( file_REG32, reg_BX ) );
-}
-
-static void soa_to_aos( struct x86_function *func, 
-                       uint arg_aos, 
-                       uint arg_machine, 
-                       uint arg_num, 
-                       uint arg_stride )
-{
-   struct x86_reg soa_output = x86_make_reg( file_REG32, reg_AX );
-   struct x86_reg aos_output = x86_make_reg( file_REG32, reg_BX );
-   struct x86_reg num_outputs = x86_make_reg( file_REG32, reg_CX );
-   struct x86_reg temp = x86_make_reg( file_REG32, reg_DX );
-   int inner_loop;
-
-   /* Save EBX */
-   x86_push( func, x86_make_reg( file_REG32, reg_BX ) );
-
-   x86_mov( func, aos_output, x86_fn_arg( func, arg_aos ) );
-   x86_mov( func, soa_output, x86_fn_arg( func, arg_machine ) );
-   /* FIXME: tgsi_exec_machine::Ouputs is a pointer now! */
-   x86_lea( func, soa_output, 
-           x86_make_disp( soa_output, 
-                          Offset(struct tgsi_exec_machine, Outputs) ) );
-   x86_mov( func, num_outputs, x86_fn_arg( func, arg_num ) );
-
-   /* do */
-   inner_loop = x86_get_label( func );
-   {
-      sse_movups( func, make_xmm( 0 ), x86_make_disp( soa_output, 0 ) );
-      sse_movups( func, make_xmm( 1 ), x86_make_disp( soa_output, 16 ) );
-      sse_movups( func, make_xmm( 3 ), x86_make_disp( soa_output, 32 ) );
-      sse_movups( func, make_xmm( 4 ), x86_make_disp( soa_output, 48 ) );
-
-      sse_movaps( func, make_xmm( 2 ), make_xmm( 0 ) );
-      sse_movaps( func, make_xmm( 5 ), make_xmm( 3 ) );
-      sse_unpcklps( func, make_xmm( 0 ), make_xmm( 1 ) );
-      sse_unpckhps( func, make_xmm( 2 ), make_xmm( 1 ) );
-      sse_unpcklps( func, make_xmm( 3 ), make_xmm( 4 ) );
-      sse_unpckhps( func, make_xmm( 5 ), make_xmm( 4 ) );
-
-      x86_mov( func, temp, x86_fn_arg( func, arg_stride ) );
-      x86_push( func, aos_output );
-      sse_movlps( func, x86_make_disp( aos_output, 0 ), make_xmm( 0 ) );
-      sse_movlps( func, x86_make_disp( aos_output, 8 ), make_xmm( 3 ) );
-      x86_add( func, aos_output, temp );
-      sse_movhps( func, x86_make_disp( aos_output, 0 ), make_xmm( 0 ) );
-      sse_movhps( func, x86_make_disp( aos_output, 8 ), make_xmm( 3 ) );
-      x86_add( func, aos_output, temp );
-      sse_movlps( func, x86_make_disp( aos_output, 0 ), make_xmm( 2 ) );
-      sse_movlps( func, x86_make_disp( aos_output, 8 ), make_xmm( 5 ) );
-      x86_add( func, aos_output, temp );
-      sse_movhps( func, x86_make_disp( aos_output, 0 ), make_xmm( 2 ) );
-      sse_movhps( func, x86_make_disp( aos_output, 8 ), make_xmm( 5 ) );
-      x86_pop( func, aos_output );
-
-      /* Advance to next output */
-      x86_lea( func, aos_output, x86_make_disp(aos_output, 16) );
-      x86_lea( func, soa_output, x86_make_disp(soa_output, 64) );
-   }
-   /* while --num_outputs */
-   x86_dec( func, num_outputs );
-   x86_jcc( func, cc_NE, inner_loop );
-
-   /* Restore EBX */
-   x86_pop( func, x86_make_reg( file_REG32, reg_BX ) );
-}
-
-
-/**
- * Check if the instructions dst register is the same as any src
- * register and warn if there's a posible SOA dependency.
- */
-static boolean
-check_soa_dependencies(const struct tgsi_full_instruction *inst)
-{
-   uint opcode = inst->Instruction.Opcode;
-
-   /* XXX: we only handle src/dst aliasing in a few opcodes currently.
-    * Need to use an additional temporay to hold the result in the
-    * cases where the code is too opaque to fix.
-    */
-
-   switch (opcode) {
-   case TGSI_OPCODE_ADD:
-   case TGSI_OPCODE_MOV:
-   case TGSI_OPCODE_MUL:
-   case TGSI_OPCODE_RCP:
-   case TGSI_OPCODE_RSQ:
-   case TGSI_OPCODE_EXP:
-   case TGSI_OPCODE_LOG:
-   case TGSI_OPCODE_DP3:
-   case TGSI_OPCODE_DP4:
-   case TGSI_OPCODE_DP2A:
-   case TGSI_OPCODE_EX2:
-   case TGSI_OPCODE_LG2:
-   case TGSI_OPCODE_POW:
-   case TGSI_OPCODE_XPD:
-   case TGSI_OPCODE_DPH:
-   case TGSI_OPCODE_COS:
-   case TGSI_OPCODE_SIN:
-   case TGSI_OPCODE_TEX:
-   case TGSI_OPCODE_TXB:
-   case TGSI_OPCODE_TXP:
-   case TGSI_OPCODE_NRM:
-   case TGSI_OPCODE_NRM4:
-   case TGSI_OPCODE_DP2:
-      /* OK - these opcodes correctly handle SOA dependencies */
-      return TRUE;
-   default:
-      if (!tgsi_check_soa_dependencies(inst))
-         return TRUE;
-
-      debug_printf("Warning: src/dst aliasing in instruction"
-                   " is not handled:\n");
-      debug_printf("Warning: ");
-      tgsi_dump_instruction(inst, 1);
-
-      return FALSE;
-   }
-}
-
-
-/**
- * Translate a TGSI vertex/fragment shader to SSE2 code.
- * Slightly different things are done for vertex vs. fragment shaders.
- *
- * \param tokens  the TGSI input shader
- * \param func  the output SSE code/function
- * \param immediates  buffer to place immediates, later passed to SSE func
- * \param return  1 for success, 0 if translation failed
- */
-unsigned
-tgsi_emit_sse2(
-   const struct tgsi_token *tokens,
-   struct x86_function *func,
-   float (*immediates)[4],
-   boolean do_swizzles )
-{
-   struct tgsi_parse_context parse;
-   unsigned ok = 1;
-   uint num_immediates = 0;
-
-   util_init_math();
-
-   func->csr = func->store;
-
-   tgsi_parse_init( &parse, tokens );
-
-   /* Can't just use EDI, EBX without save/restoring them:
-    */
-   x86_push( func, x86_make_reg( file_REG32, reg_BX ) );
-   x86_push( func, x86_make_reg( file_REG32, reg_DI ) );
-
-   /*
-    * Different function args for vertex/fragment shaders:
-    */
-   if (parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX) {
-      if (do_swizzles)
-         aos_to_soa( func, 
-                     4,         /* aos_input */
-                     1,         /* machine */
-                     5,         /* num_inputs */
-                     6 );       /* input_stride */
-   }
-
-   x86_mov(
-      func,
-      get_machine_base(),
-      x86_fn_arg( func, 1 ) );
-   x86_mov(
-      func,
-      get_const_base(),
-      x86_fn_arg( func, 2 ) );
-   x86_mov(
-      func,
-      get_immediate_base(),
-      x86_fn_arg( func, 3 ) );
-
-   if (parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
-      x86_mov(
-        func,
-        get_coef_base(),
-        x86_fn_arg( func, 4 ) );
-   }
-
-   x86_mov(
-      func,
-      get_sampler_base(),
-      x86_make_disp( get_machine_base(),
-                     Offset( struct tgsi_exec_machine, Samplers ) ) );
-
-   while( !tgsi_parse_end_of_tokens( &parse ) && ok ) {
-      tgsi_parse_token( &parse );
-
-      switch( parse.FullToken.Token.Type ) {
-      case TGSI_TOKEN_TYPE_DECLARATION:
-         if (parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
-            emit_declaration(
-               func,
-               &parse.FullToken.FullDeclaration );
-         }
-         break;
-
-      case TGSI_TOKEN_TYPE_INSTRUCTION:
-         ok = emit_instruction(
-            func,
-            &parse.FullToken.FullInstruction );
-
-        if (!ok) {
-            uint opcode = parse.FullToken.FullInstruction.Instruction.Opcode;
-            uint proc = parse.FullHeader.Processor.Processor;
-           debug_printf("failed to translate tgsi opcode %d (%s) to SSE (%s)\n", 
-                        opcode,
-                         tgsi_get_opcode_name(opcode),
-                         tgsi_get_processor_name(proc));
-        }
-
-         if (ok)
-            ok = check_soa_dependencies(&parse.FullToken.FullInstruction);
-         break;
-
-      case TGSI_TOKEN_TYPE_IMMEDIATE:
-         /* simply copy the immediate values into the next immediates[] slot */
-         {
-            const uint size = parse.FullToken.FullImmediate.Immediate.NrTokens - 1;
-            uint i;
-            assert(size <= 4);
-            assert(num_immediates < TGSI_EXEC_NUM_IMMEDIATES);
-            for( i = 0; i < size; i++ ) {
-               immediates[num_immediates][i] =
-                 parse.FullToken.FullImmediate.u[i].Float;
-            }
-#if 0
-            debug_printf("SSE FS immediate[%d] = %f %f %f %f\n",
-                   num_immediates,
-                   immediates[num_immediates][0],
-                   immediates[num_immediates][1],
-                   immediates[num_immediates][2],
-                   immediates[num_immediates][3]);
-#endif
-            num_immediates++;
-         }
-         break;
-      case TGSI_TOKEN_TYPE_PROPERTY:
-         /* we just ignore them for now */
-         break;
-
-      default:
-        ok = 0;
-         assert( 0 );
-      }
-   }
-
-   if (parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX) {
-      if (do_swizzles)
-         soa_to_aos( func, 
-                    7,         /* aos_output */
-                    1,         /* machine */
-                    8,         /* num_outputs */
-                    9 );       /* output_stride */
-   }
-
-   /* Can't just use EBX, EDI without save/restoring them:
-    */
-   x86_pop( func, x86_make_reg( file_REG32, reg_DI ) );
-   x86_pop( func, x86_make_reg( file_REG32, reg_BX ) );
-
-   emit_ret( func );
-
-   tgsi_parse_free( &parse );
-
-   return ok;
-}
-
-#else /* !PIPE_ARCH_X86 */
-
-unsigned
-tgsi_emit_sse2(
-   const struct tgsi_token *tokens,
-   struct x86_function *func,
-   float (*immediates)[4],
-   boolean do_swizzles )
-{
-   return 0;
-}
-
-#endif /* !PIPE_ARCH_X86 */
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.h b/src/gallium/auxiliary/tgsi/tgsi_sse2.h
deleted file mode 100644 (file)
index 00aa8b8..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-#ifndef TGSI_SSE2_H
-#define TGSI_SSE2_H
-
-#if defined __cplusplus
-extern "C" {
-#endif
-
-#include "pipe/p_compiler.h"
-
-struct tgsi_exec_machine;
-struct tgsi_interp_coef;
-struct tgsi_token;
-struct x86_function;
-
-unsigned
-tgsi_emit_sse2(
-   const struct tgsi_token *tokens,
-   struct x86_function *function,
-   float (*immediates)[4],
-   boolean do_swizzles );
-
-
-/* This is the function prototype generated when do_swizzles is false
- * -- effectively for fragment shaders.
- */
-typedef void (PIPE_CDECL *tgsi_sse2_fs_function) (
-   struct tgsi_exec_machine *machine, /* 1 */
-   const float (*constant)[4],             /* 2 */
-   const float (*immediate)[4],                    /* 3 */
-   const struct tgsi_interp_coef *coef     /* 4 */
-   );
-
-
-/* This is the function prototype generated when do_swizzles is true
- * -- effectively for vertex shaders.
- */
-typedef void (PIPE_CDECL *tgsi_sse2_vs_func) (
-   struct tgsi_exec_machine *machine, /* 1 */
-   const float (*constant)[4],        /* 2 */
-   const float (*immediate)[4],       /* 3 */
-   const float (*aos_input)[4], /* 4 */
-   uint num_inputs,             /* 5 */
-   uint input_stride,           /* 6 */
-   float (*aos_output)[4],      /* 7 */
-   uint num_outputs,            /* 8 */
-   uint output_stride );        /* 9 */
-
-
-#if defined __cplusplus
-}
-#endif
-
-#endif /* TGSI_SSE2_H */
index d198fa5d0f2e8fb5cdcf9918fa680f4d55683e35..6a125a5d4120265d5c746d3f1bd5894740af41dc 100644 (file)
@@ -26,7 +26,6 @@ LOCAL_PATH := $(call my-dir)
 # from Makefile
 C_SOURCES = \
        sp_fs_exec.c \
-       sp_fs_sse.c \
        sp_clear.c \
        sp_fence.c \
        sp_flush.c \
index 9403e6cf0b89c964d7e25e57551091a9b17b7d99..27b5d991a75e14bd4aabb489cafcc6e1803bd074 100644 (file)
@@ -5,7 +5,6 @@ LIBNAME = softpipe
 
 C_SOURCES = \
        sp_fs_exec.c \
-       sp_fs_sse.c \
        sp_clear.c \
        sp_fence.c \
        sp_flush.c \
index ea10e8a9f986f5cbb7bd0933aaf1990abf4e3cfa..da2c93ee5fa47371dbc1fd21a0bc9e808cc90908 100644 (file)
@@ -6,7 +6,6 @@ softpipe = env.ConvenienceLibrary(
        target = 'softpipe',
        source = [
                'sp_fs_exec.c',
-               'sp_fs_sse.c',
                'sp_clear.c',
                'sp_context.c',
                'sp_draw_arrays.c',
index c97b0333035c9e1899c6143bb3a62dc4dd2ded8d..3a83e5870dcd4ff3a9b6d51f04cba2a3791762b1 100644 (file)
@@ -235,12 +235,6 @@ softpipe_create_context( struct pipe_screen *screen,
 
    util_init_math();
 
-#ifdef PIPE_ARCH_X86
-   softpipe->use_sse = !debug_get_bool_option( "GALLIUM_NOSSE", FALSE );
-#else
-   softpipe->use_sse = FALSE;
-#endif
-
    softpipe->dump_fs = debug_get_bool_option( "SOFTPIPE_DUMP_FS", FALSE );
    softpipe->dump_gs = debug_get_bool_option( "SOFTPIPE_DUMP_GS", FALSE );
 
index d51ce9fe3337c23a2018b394da5e04b8170ed139..5442aba9019f21d2e8723681cbb8db19024033a1 100644 (file)
@@ -190,7 +190,6 @@ struct softpipe_context {
    struct softpipe_tex_tile_cache *vertex_tex_cache[PIPE_MAX_VERTEX_SAMPLERS];
    struct softpipe_tex_tile_cache *geometry_tex_cache[PIPE_MAX_GEOMETRY_SAMPLERS];
 
-   unsigned use_sse : 1;
    unsigned dump_fs : 1;
    unsigned dump_gs : 1;
    unsigned no_rast : 1;
index d46d7d5a65782b4b678e277459e13fa8789411bf..db689b82bd5084e6cfec1472e085e3fec2f4c748 100644 (file)
@@ -36,10 +36,6 @@ struct sp_fragment_shader_variant *
 softpipe_create_fs_variant_exec(struct softpipe_context *softpipe,
                                 const struct pipe_shader_state *templ);
 
-struct sp_fragment_shader_variant *
-softpipe_create_fs_variant_sse(struct softpipe_context *softpipe,
-                               const struct pipe_shader_state *templ);
-
 
 struct tgsi_interp_coef;
 struct tgsi_exec_vector;
diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c
deleted file mode 100644 (file)
index c873af1..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-/**
- * Execute fragment shader using runtime SSE code generation.
- */
-
-#include "sp_context.h"
-#include "sp_state.h"
-#include "sp_fs.h"
-#include "sp_quad.h"
-
-#include "pipe/p_state.h"
-#include "pipe/p_defines.h"
-#include "util/u_memory.h"
-#include "tgsi/tgsi_exec.h"
-#include "tgsi/tgsi_sse2.h"
-
-
-#if defined(PIPE_ARCH_X86)
-
-#include "rtasm/rtasm_x86sse.h"
-
-
-
-/**
- * Subclass of sp_fragment_shader_variant
- */
-struct sp_sse_fragment_shader
-{
-   struct sp_fragment_shader_variant base;
-   struct x86_function sse2_program;
-   tgsi_sse2_fs_function func;
-   float immediates[TGSI_EXEC_NUM_IMMEDIATES][4];
-};
-
-
-/** cast wrapper */
-static INLINE struct sp_sse_fragment_shader *
-sp_sse_fragment_shader(const struct sp_fragment_shader_variant *base)
-{
-   return (struct sp_sse_fragment_shader *) base;
-}
-
-
-static void
-fs_sse_prepare( const struct sp_fragment_shader_variant *base,
-               struct tgsi_exec_machine *machine,
-               struct tgsi_sampler **samplers )
-{
-   machine->Samplers = samplers;
-}
-
-
-
-/**
- * Compute quad X,Y,Z,W for the four fragments in a quad.
- *
- * This should really be part of the compiled shader.
- */
-static void
-setup_pos_vector(const struct tgsi_interp_coef *coef,
-                   float x, float y,
-                   struct tgsi_exec_vector *quadpos)
-{
-   uint chan;
-   /* do X */
-   quadpos->xyzw[0].f[0] = x;
-   quadpos->xyzw[0].f[1] = x + 1;
-   quadpos->xyzw[0].f[2] = x;
-   quadpos->xyzw[0].f[3] = x + 1;
-
-   /* do Y */
-   quadpos->xyzw[1].f[0] = y;
-   quadpos->xyzw[1].f[1] = y;
-   quadpos->xyzw[1].f[2] = y + 1;
-   quadpos->xyzw[1].f[3] = y + 1;
-
-   /* do Z and W for all fragments in the quad */
-   for (chan = 2; chan < 4; chan++) {
-      const float dadx = coef->dadx[chan];
-      const float dady = coef->dady[chan];
-      const float a0 = coef->a0[chan] + dadx * x + dady * y;
-      quadpos->xyzw[chan].f[0] = a0;
-      quadpos->xyzw[chan].f[1] = a0 + dadx;
-      quadpos->xyzw[chan].f[2] = a0 + dady;
-      quadpos->xyzw[chan].f[3] = a0 + dadx + dady;
-   }
-}
-
-
-/* TODO: codegenerate the whole run function, skip this wrapper.
- * TODO: break dependency on tgsi_exec_machine struct
- * TODO: push Position calculation into the generated shader
- * TODO: process >1 quad at a time
- */
-static unsigned 
-fs_sse_run( const struct sp_fragment_shader_variant *base,
-           struct tgsi_exec_machine *machine,
-           struct quad_header *quad )
-{
-   struct sp_sse_fragment_shader *shader = sp_sse_fragment_shader(base);
-
-   /* Compute X, Y, Z, W vals for this quad -- place in temp[0] for now */
-   setup_pos_vector(quad->posCoef, 
-                    (float)quad->input.x0, (float)quad->input.y0, 
-                    machine->Temps);
-
-   /* init kill mask */
-   tgsi_set_kill_mask(machine, 0x0);
-   tgsi_set_exec_mask(machine, 1, 1, 1, 1);
-
-   shader->func( machine,
-                 (const float (*)[4])machine->Consts[0],
-                 (const float (*)[4])shader->immediates,
-                machine->InterpCoefs
-                /*, &machine->QuadPos*/
-      );
-
-   quad->inout.mask &= ~(machine->Temps[TGSI_EXEC_TEMP_KILMASK_I].xyzw[TGSI_EXEC_TEMP_KILMASK_C].u[0]);
-   if (quad->inout.mask == 0)
-      return FALSE;
-
-   /* store outputs */
-   {
-      const ubyte *sem_name = base->info.output_semantic_name;
-      const ubyte *sem_index = base->info.output_semantic_index;
-      const uint n = base->info.num_outputs;
-      uint i;
-      for (i = 0; i < n; i++) {
-         switch (sem_name[i]) {
-         case TGSI_SEMANTIC_COLOR:
-            {
-               uint cbuf = sem_index[i];
-
-               assert(sizeof(quad->output.color[cbuf]) ==
-                      sizeof(machine->Outputs[i]));
-
-               /* copy float[4][4] result */
-               memcpy(quad->output.color[cbuf],
-                      &machine->Outputs[i],
-                      sizeof(quad->output.color[0]) );
-            }
-            break;
-         case TGSI_SEMANTIC_POSITION:
-            {
-               uint j;
-               for (j = 0; j < 4; j++)
-                  quad->output.depth[j] = machine->Outputs[i].xyzw[2].f[j];
-            }
-            break;
-         case TGSI_SEMANTIC_STENCIL:
-            {
-               uint j;
-               for (j = 0; j < 4; j++)
-                  quad->output.stencil[j] = machine->Outputs[i].xyzw[1].f[j];
-            }
-            break;
-         }
-      }
-   }
-
-   return TRUE;
-}
-
-
-static void 
-fs_sse_delete( struct sp_fragment_shader_variant *base )
-{
-   struct sp_sse_fragment_shader *shader = sp_sse_fragment_shader(base);
-
-   x86_release_func( &shader->sse2_program );
-   FREE(shader);
-}
-
-
-struct sp_fragment_shader_variant *
-softpipe_create_fs_variant_sse(struct softpipe_context *softpipe,
-                               const struct pipe_shader_state *templ)
-{
-   struct sp_sse_fragment_shader *shader;
-
-   if (!softpipe->use_sse)
-      return NULL;
-
-   shader = CALLOC_STRUCT(sp_sse_fragment_shader);
-   if (!shader)
-      return NULL;
-
-   x86_init_func( &shader->sse2_program );
-   
-   if (!tgsi_emit_sse2( templ->tokens, &shader->sse2_program,
-                        shader->immediates, FALSE )) {
-      FREE(shader);
-      return NULL;
-   }
-
-   shader->func = (tgsi_sse2_fs_function) x86_get_func( &shader->sse2_program );
-   if (!shader->func) {
-      x86_release_func( &shader->sse2_program );
-      FREE(shader);
-      return NULL;
-   }
-
-   shader->base.prepare = fs_sse_prepare;
-   shader->base.run = fs_sse_run;
-   shader->base.delete = fs_sse_delete;
-
-   return &shader->base;
-}
-
-
-#else
-
-/* Maybe put this variant in the header file.
- */
-struct sp_fragment_shader_variant *
-softpipe_create_fs_variant_sse(struct softpipe_context *softpipe,
-                               const struct pipe_shader_state *templ)
-{
-   return NULL;
-}
-
-#endif
index 612dcb38eb41d3a7bbd81a7e5f0251bee9daa0af..6acb57b3fe6d8cb8a367e1231e549ff961e8385e 100644 (file)
@@ -65,10 +65,7 @@ create_fs_variant(struct softpipe_context *softpipe,
 #endif
 
    /* codegen, create variant object */
-   var = softpipe_create_fs_variant_sse(softpipe, curfs);
-   if (!var) {
-      var = softpipe_create_fs_variant_exec(softpipe, curfs);
-   }
+   var = softpipe_create_fs_variant_exec(softpipe, curfs);
 
    if (var) {
       var->key = *key;